Skip to contentSkip to conversation

Implement and use an xstrdup() function

PATCH In review Jon Loeliger 2 participants 3 messages Oct 3, 2008 – Oct 7, 2008 2 messages not in the archive Kbuild

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Implement and use an xstrdup() function

Many places in dtc use strdup(), but none of them actually check the return value to see if the implied allocation succeeded. This is a potential bug, which we fix in the patch below by replacing strdup() with an xstrdup() which in analogy to xmalloc() will quit with a fatal error if the allocation fails.

I felt the introduciton of util.[ch] was a better choice for utility oriented code than directly using srcpos.c for the new string function.

This patch is a re-factoring of Dave Gibson's similar patch.

---
 Makefile.convert-dtsv0 |    3 ++-
 Makefile.dtc           |   13 +++++++++++--
 convert-dtsv0-lexer.l  |    3 ++-
 dtc-lexer.l            |   14 +++++++-------
 dtc.h                  |    3 +++
 flattree.c             |    6 +++---
 fstree.c               |    4 ++--
 srcpos.c               |    4 ++--
 util.c                 |   30 ++++++++++++++++++++++++++++++
 util.h                 |   20 ++++++++++++++++++++
 10 files changed, 82 insertions(+), 18 deletions(-)
 create mode 100644 util.c
 create mode 100644 util.h
Makefile.convert-dtsv0 +2 -1
index a3f74c9..08ea40a 100644
@@ -5,7 +5,8 @@
 #
 
 CONVERT_SRCS = \
-	srcpos.c
+	srcpos.c \
+	util.c
 
 CONVERT_GEN_SRCS = convert-dtsv0-lexer.lex.c
 
Makefile.dtc +11 -2
index 6ddf9ec..bece49b 100644
@@ -3,7 +3,16 @@
 # This is not a complete Makefile of itself.  Instead, it is designed to
 # be easily embeddable into other systems of Makefiles.
 #
-DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
-	checks.c
+DTC_SRCS = \
+	checks.c \
+	data.c \
+	dtc.c \
+	flattree.c \
+	fstree.c \
+	livetree.c \
+	srcpos.c \
+	treesource.c \
+	util.c
+
 DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
 DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
convert-dtsv0-lexer.l +2 -1
index 12b45ea..194f635 100644
@@ -42,6 +42,7 @@ GAP		({WS}|{COMMENT}|{LINECOMMENT})*
 #include <fnmatch.h>
 
 #include "srcpos.h"
+#include "util.h"
 
 static int v1_tagged; /* = 0 */
 static int cbase = 16;
@@ -185,7 +186,7 @@ const struct {
 
 <PROPNODENAME>{PROPNODECHAR}+ {
 			ECHO;
-			last_name = strdup(yytext);
+			last_name = xstrdup(yytext);
 			BEGIN(INITIAL);
 		}
 
dtc-lexer.l +7 -7
index 6f8b7dd..35b39ca 100644
@@ -105,7 +105,7 @@ static int pop_input_file(void);
 			yylloc.file = srcpos_file;
 			yylloc.first_line = yylineno;
 			DPRINT("Label: %s\n", yytext);
-			yylval.labelref = strdup(yytext);
+			yylval.labelref = xstrdup(yytext);
 			yylval.labelref[yyleng-1] = '\0';
 			return DT_LABEL;
 		}
@@ -128,7 +128,7 @@ static int pop_input_file(void);
 <INITIAL>[0-9a-fA-F]+	{
 			yylloc.file = srcpos_file;
 			yylloc.first_line = yylineno;
-			yylval.literal = strdup(yytext);
+			yylval.literal = xstrdup(yytext);
 			DPRINT("Literal: '%s'\n", yylval.literal);
 			return DT_LEGACYLITERAL;
 		}
@@ -136,7 +136,7 @@ static int pop_input_file(void);
 <V1>[0-9]+|0[xX][0-9a-fA-F]+      {
 			yylloc.file = srcpos_file;
 			yylloc.first_line = yylineno;
-			yylval.literal = strdup(yytext);
+			yylval.literal = xstrdup(yytext);
 			DPRINT("Literal: '%s'\n", yylval.literal);
 			return DT_LITERAL;
 		}
@@ -145,7 +145,7 @@ static int pop_input_file(void);
 			yylloc.file = srcpos_file;
 			yylloc.first_line = yylineno;
 			DPRINT("Ref: %s\n", yytext+1);
-			yylval.labelref = strdup(yytext+1);
+			yylval.labelref = xstrdup(yytext+1);
 			return DT_REF;
 		}
 
@@ -154,7 +154,7 @@ static int pop_input_file(void);
 			yylloc.first_line = yylineno;
 			yytext[yyleng-1] = '\0';
 			DPRINT("Ref: %s\n", yytext+2);
-			yylval.labelref = strdup(yytext+2);
+			yylval.labelref = xstrdup(yytext+2);
 			return DT_REF;
 		}
 
@@ -162,7 +162,7 @@ static int pop_input_file(void);
 			yylloc.file = srcpos_file;
 			yylloc.first_line = yylineno;
 			DPRINT("Ref: %s\n", yytext+1);
-			yylval.labelref = strdup(yytext+1);
+			yylval.labelref = xstrdup(yytext+1);
 			return DT_REF;
 		}
 
@@ -186,7 +186,7 @@ static int pop_input_file(void);
 			yylloc.file = srcpos_file;
 			yylloc.first_line = yylineno;
 			DPRINT("PropNodeName: %s\n", yytext);
-			yylval.propnodename = strdup(yytext);
+			yylval.propnodename = xstrdup(yytext);
 			BEGIN_DEFAULT();
 			return DT_PROPNODENAME;
 		}
dtc.h +3 -0
index 08d54c8..5ead895 100644
@@ -34,7 +34,10 @@
 #include <libfdt_env.h>
 #include <fdt.h>
 
+#include "util.h"
+
 #define DEFAULT_FDT_VERSION	17
+
 /*
  * Command line options
  */
flattree.c +3 -3
index 76acd28..50190b8 100644
@@ -601,7 +601,7 @@ static char *flat_read_string(struct inbuf *inb)
 		len++;
 	} while ((*p++) != '\0');
 
-	str = strdup(inb->ptr);
+	str = xstrdup(inb->ptr);
 
 	inb->ptr += len;
 
@@ -643,7 +643,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset)
 		p++;
 	}
 
-	return strdup(inb->base + offset);
+	return xstrdup(inb->base + offset);
 }
 
 static struct property *flat_read_property(struct inbuf *dtbuf,
@@ -710,7 +710,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath)
 	if (!streq(ppath, "/"))
 		plen++;
 
-	return strdup(cpath + plen);
+	return xstrdup(cpath + plen);
 }
 
 static struct node *unflatten_tree(struct inbuf *dtbuf,
fstree.c +2 -2
index 766b269..7aee982 100644
@@ -58,7 +58,7 @@ static struct node *read_fstree(const char *dirname)
 					"WARNING: Cannot open %s: %s\n",
 					tmpnam, strerror(errno));
 			} else {
-				prop = build_property(strdup(de->d_name),
+				prop = build_property(xstrdup(de->d_name),
 						      data_copy_file(pfile,
 								     st.st_size),
 						      NULL);
@@ -69,7 +69,7 @@ static struct node *read_fstree(const char *dirname)
 			struct node *newchild;
 
 			newchild = read_fstree(tmpnam);
-			newchild = name_node(newchild, strdup(de->d_name),
+			newchild = name_node(newchild, xstrdup(de->d_name),
 					     NULL);
 			add_child(tree, newchild);
 		}
srcpos.c +2 -2
index 9641b76..d5a4b2a 100644
@@ -39,7 +39,7 @@ static int dtc_open_one(struct dtc_file *file,
 		strcat(fullname, "/");
 		strcat(fullname, fname);
 	} else {
-		fullname = strdup(fname);
+		fullname = xstrdup(fname);
 	}
 
 	file->file = fopen(fullname, "r");
@@ -85,7 +85,7 @@ struct dtc_file *dtc_open_file(const char *fname,
 		if (!file->file)
 			goto fail;
 
-		file->name = strdup(fname);
+		file->name = xstrdup(fname);
 		return file;
 	}
 
util.c new file +30 -0
new file mode 100644
index 0000000..33631ce
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *                                                                   USA
+ */
+
+#include "dtc.h"
+
+char *xstrdup(const char *s)
+{
+	int len = strlen(s) + 1;
+	char *dup = xmalloc(len);
+
+	memcpy(dup, s, len);
+
+	return dup;
+}
util.h new file +20 -0
new file mode 100644
index 0000000..1fa78eb
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *                                                                   USA
+ */
+
+extern char *xstrdup(const char *s);
Signature · 1 line
1.6.0.90.g436ed

A message that is not in the archive (sent off-list or not yet received): 1223054108-22342-1-git-send-email-jdl-CYoMK+44s/[email protected]

Acked-by
#2 lore raw
Quoted 9 lines · Jon Loeliger

Many places in dtc use strdup(), but none of them actually check the return value to see if the implied allocation succeeded. This is a potential bug, which we fix in the patch below by replacing strdup() with an xstrdup() which in analogy to xmalloc() will quit with a fatal error if the allocation fails.

I felt the introduciton of util.[ch] was a better choice for utility oriented code than directly using srcpos.c for the new string function.

Fair enough. Now that we have a util.c, we should move die() and xmalloc() in there as well which are currently duplicated between dtc and convert-dtsv0.

Quoted 3 lines

This patch is a re-factoring of Dave Gibson's similar patch.

Signature · 4 lines
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

A message that is not in the archive (sent off-list or not yet received): [email protected]

#4 lore raw
Quoted 4 lines

Fair enough. Now that we have a util.c, we should move die() and xmalloc() in there as well which are currently duplicated between dtc and convert-dtsv0.

Agreed. I'll get there if you don't beat me to it.

(I'm catching up here some...)

jdl