show-branch: use strbuf instead of static buffer

When we generate relative names (e.g., "master~20^2"), we
format the name into a static buffer, then xstrdup the
result to attach it to the commit. Since the first thing we
add into the static buffer is the already-computed name of
the child commit, the names may get longer and longer as
the traversal gets deeper, and we may eventually overflow
the fixed-size buffer.

Fix this by converting the fixed-size buffer into a dynamic
strbuf.  The performance implications should be minimal, as
we end up allocating a heap copy of the name anyway (and now
we can just detach the heap copy from the strbuf).

Reported-by: Eric Roman <eroman@chromium.org>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2013-04-05 17:15:50 -04:00 committed by Junio C Hamano
parent 15999998fb
commit aaa07e3eee

View File

@ -162,29 +162,28 @@ static void name_commits(struct commit_list *list,
nth = 0;
while (parents) {
struct commit *p = parents->item;
char newname[1000], *en;
struct strbuf newname = STRBUF_INIT;
parents = parents->next;
nth++;
if (p->util)
continue;
en = newname;
switch (n->generation) {
case 0:
en += sprintf(en, "%s", n->head_name);
strbuf_addstr(&newname, n->head_name);
break;
case 1:
en += sprintf(en, "%s^", n->head_name);
strbuf_addf(&newname, "%s^", n->head_name);
break;
default:
en += sprintf(en, "%s~%d",
n->head_name, n->generation);
strbuf_addf(&newname, "%s~%d",
n->head_name, n->generation);
break;
}
if (nth == 1)
en += sprintf(en, "^");
strbuf_addch(&newname, '^');
else
en += sprintf(en, "^%d", nth);
name_commit(p, xstrdup(newname), 0);
strbuf_addf(&newname, "^%d", nth);
name_commit(p, strbuf_detach(&newname, NULL), 0);
i++;
name_first_parent_chain(p);
}