[PATCH v2 2/4] help.c::exclude_cmds: realloc() before copy, plug a leak
- From
Tay Ray Chuan <rctay89@gmail.com>
- Date
- Jul 25, 2012, 16:16 UTC
- Message-ID
- <1343232982-10540-3-git-send-email-rctay89@gmail.com>
- In-Reply-To
- <1343232982-10540-2-git-send-email-rctay89@gmail.com>
Copying with structural assignment may not take into account that the LHS struct has sufficient memory, especially since the cmdname->name member is nonfixed in size. Be unambiguous about it by realloc()'ing it to be of sufficient size.
Additionally, free the unused cmdnames, which are no longer accessible anyway.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com> --- help.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/help.c b/help.c index 6991492..dfb2e9d 100644 --- a/help.c +++ b/help.c @@ -20,6 +20,17 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len) cmds->names[cmds->cnt++] = ent; } +static void copy_cmdname(struct cmdname **dest, struct cmdname *src) +{ + struct cmdname *ent = xrealloc(*dest, sizeof(*ent) + src->len + 1); + + ent->len = src->len; + memcpy(ent->name, src->name, src->len); + ent->name[src->len] = 0; + + *dest = ent; +} + static void clean_cmdnames(struct cmdnames *cmds) { int i; @@ -58,20 +69,25 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) { int ci, cj, ei; int cmp; + int last_cj; ci = cj = ei = 0; while (ci < cmds->cnt && ei < excludes->cnt) { cmp = strcmp(cmds->names[ci]->name, excludes->names[ei]->name); if (cmp < 0) - cmds->names[cj++] = cmds->names[ci++]; + copy_cmdname(&cmds->names[cj++], cmds->names[ci++]); else if (cmp == 0) ci++, ei++; else if (cmp > 0) ei++; } + last_cj = cj; while (ci < cmds->cnt) - cmds->names[cj++] = cmds->names[ci++]; + copy_cmdname(&cmds->names[cj++], cmds->names[ci++]); + + while (last_cj < cmds->cnt) + free(cmds->names[last_cj++]); cmds->cnt = cj; }
-- 1.7.11.1.116.g8228a23