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>

Jeff King committed Apr 5, 2013 at 17:15 UTC aaa07e3eee6f42d0adeac826dfb52d5ade26defc
1 file changed +8 -9
builtin/show-branch.c
+8 -9
@@ -162,29 +162,28 @@ static void name_commits(struct commit_list *list,
162 nth = 0;
163 while (parents) {
164 struct commit *p = parents->item;
165 - char newname[1000], *en;
165 + struct strbuf newname = STRBUF_INIT;
166 parents = parents->next;
167 nth++;
168 if (p->util)
169 continue;
170 - en = newname;
170 switch (n->generation) {
171 case 0:
173 - en += sprintf(en, "%s", n->head_name);
172 + strbuf_addstr(&newname, n->head_name);
173 break;
174 case 1:
176 - en += sprintf(en, "%s^", n->head_name);
175 + strbuf_addf(&newname, "%s^", n->head_name);
176 break;
177 default:
179 - en += sprintf(en, "%s~%d",
180 - n->head_name, n->generation);
178 + strbuf_addf(&newname, "%s~%d",
179 + n->head_name, n->generation);
180 break;
181 }
182 if (nth == 1)
184 - en += sprintf(en, "^");
183 + strbuf_addch(&newname, '^');
184 else
186 - en += sprintf(en, "^%d", nth);
187 - name_commit(p, xstrdup(newname), 0);
185 + strbuf_addf(&newname, "^%d", nth);
186 + name_commit(p, strbuf_detach(&newname, NULL), 0);
187 i++;
188 name_first_parent_chain(p);
189 }