Browse Source

Delay xstrdup() of node and property names coming from a flat tree

The 'name' field of 'struct node' is supposed to be an (individually)
malloc()ed string.  So, when taking a name from a flattened blob we need
to strdup() it.

Currently that happens in flat_read_string() as we take it from the
flattened structure itself.  That obscures what's going on because it's
several steps removed from actually inserting it into node->name.  It also
means we need an additional strdup() and free() for the case of old dtb
formats where we need to extract just the final path component from the
blob for the name.

While we're scanning the blob, we're doing so read-only, so it's fine to
have pointers into it.  Therefore simplify things a bit by delaying the
xstrdup() to the point where we're actually inserting into node->name.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
main
David Gibson 2 years ago
parent
commit
4718189c4c
  1. 21
      flattree.c

21
flattree.c

@ -604,11 +604,11 @@ static void flat_realign(struct inbuf *inb, int align)
die("Premature end of data parsing flat device tree\n"); die("Premature end of data parsing flat device tree\n");
} }


static char *flat_read_string(struct inbuf *inb) static const char *flat_read_string(struct inbuf *inb)
{ {
int len = 0; int len = 0;
const char *p = inb->ptr; const char *p = inb->ptr;
char *str; const char *str;


do { do {
if (p >= inb->limit) if (p >= inb->limit)
@ -616,7 +616,7 @@ static char *flat_read_string(struct inbuf *inb)
len++; len++;
} while ((*p++) != '\0'); } while ((*p++) != '\0');


str = xstrdup(inb->ptr); str = inb->ptr;


inb->ptr += len; inb->ptr += len;


@ -711,7 +711,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
} }




static char *nodename_from_path(const char *ppath, const char *cpath) static const char *nodename_from_path(const char *ppath, const char *cpath)
{ {
int plen; int plen;


@ -725,7 +725,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath)
if (!streq(ppath, "/")) if (!streq(ppath, "/"))
plen++; plen++;


return xstrdup(cpath + plen); return cpath + plen;
} }


static struct node *unflatten_tree(struct inbuf *dtbuf, static struct node *unflatten_tree(struct inbuf *dtbuf,
@ -733,7 +733,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
const char *parent_flatname, int flags) const char *parent_flatname, int flags)
{ {
struct node *node; struct node *node;
char *flatname; const char *flatname;
uint32_t val; uint32_t val;


node = build_node(NULL, NULL, NULL); node = build_node(NULL, NULL, NULL);
@ -741,9 +741,10 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
flatname = flat_read_string(dtbuf); flatname = flat_read_string(dtbuf);


if (flags & FTF_FULLPATH) if (flags & FTF_FULLPATH)
node->name = nodename_from_path(parent_flatname, flatname); node->name = xstrdup(nodename_from_path(parent_flatname,
flatname));
else else
node->name = flatname; node->name = xstrdup(flatname);


do { do {
struct property *prop; struct property *prop;
@ -785,10 +786,6 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
} }
} while (val != FDT_END_NODE); } while (val != FDT_END_NODE);


if (node->name != flatname) {
free(flatname);
}

return node; return node;
} }



Loading…
Cancel
Save