This is a minimum fix for a crash with a long ref name. Note that if the refname is too long (for example if you use 100 instead of 50 in the test script) you could get an error like: fatal: cannot lock ref 'refs/heads/1_2_3_4_ ... _98_99_100_': Unable to create '... /.git/refs/heads/1_2_3_4_ ... _98_99_100_.lock': File name too long when creating the ref instead of a crash when using show-branch and that would be ok. So a simpler fix could have been just something like: - char head[128]; + char head[1024]; But if the filesystem ever allows filenames longer than 1024 characters then the crash could appear again. Reported by: Maxim Kuvyrkov <maxim.kuvyrkov@xxxxxxxxxx> Signed-off-by: Christian Couder <chriscool@xxxxxxxxxxxxx> --- builtin/show-branch.c | 14 +++++++------- t/t3204-show-branch-refname.sh | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100755 t/t3204-show-branch-refname.sh diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 974f3403ab..3c0fe55eec 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -620,7 +620,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) int all_heads = 0, all_remotes = 0; int all_mask, all_revs; enum rev_sort_order sort_order = REV_SORT_IN_GRAPH_ORDER; - char head[128]; + char *head_cpy; const char *head_p; int head_len; struct object_id head_oid; @@ -791,11 +791,11 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) head_oid.hash, NULL); if (head_p) { head_len = strlen(head_p); - memcpy(head, head_p, head_len + 1); + head_cpy = xstrdup(head_p); } else { head_len = 0; - head[0] = 0; + head_cpy = xstrdup(""); } if (with_current_branch && head_p) { @@ -804,15 +804,15 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) /* We are only interested in adding the branch * HEAD points at. */ - if (rev_is_head(head, + if (rev_is_head(head_cpy, head_len, ref_name[i], head_oid.hash, NULL)) has_head++; } if (!has_head) { - int offset = starts_with(head, "refs/heads/") ? 11 : 0; - append_one_rev(head + offset); + int offset = starts_with(head_cpy, "refs/heads/") ? 11 : 0; + append_one_rev(head_cpy + offset); } } @@ -865,7 +865,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) if (1 < num_rev || extra < 0) { for (i = 0; i < num_rev; i++) { int j; - int is_head = rev_is_head(head, + int is_head = rev_is_head(head_cpy, head_len, ref_name[i], head_oid.hash, diff --git a/t/t3204-show-branch-refname.sh b/t/t3204-show-branch-refname.sh new file mode 100755 index 0000000000..83b64e3032 --- /dev/null +++ b/t/t3204-show-branch-refname.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +test_description='test show-branch with long refname' + +. ./test-lib.sh + +test_expect_success 'setup' ' + + test_commit first && + long_refname=$(printf "%s_" $(seq 1 50)) && + git checkout -b "$long_refname" +' + +test_expect_success 'show-branch with long refname' ' + + git show-branch first +' + +test_done -- 2.12.0.rc0