wt-status: correct and simplify check for detached HEAD
authorRené Scharfe <l.s.r@web.de>
Wed, 25 Nov 2015 14:10:18 +0000 (15:10 +0100)
committerJeff King <peff@peff.net>
Sat, 28 Nov 2015 17:30:18 +0000 (12:30 -0500)
If a branch name is longer than four characters then memcmp() reads over
the end of the static string "HEAD". This causes the following test
failures with AddressSanitizer:

t3203-branch-output.sh (Wstat: 256 Tests: 18 Failed: 4)
Failed tests: 12, 15-17
Non-zero exit status: 1
t3412-rebase-root.sh (Wstat: 256 Tests: 31 Failed: 3)
Failed tests: 28-29, 31
Non-zero exit status: 1
t3507-cherry-pick-conflict.sh (Wstat: 256 Tests: 31 Failed: 4)
Failed tests: 14, 29-31
Non-zero exit status: 1
t3510-cherry-pick-sequence.sh (Wstat: 256 Tests: 39 Failed: 14)
Failed tests: 17, 22-26, 28-30, 34-35, 37-39
Non-zero exit status: 1
t3420-rebase-autostash.sh (Wstat: 256 Tests: 28 Failed: 4)
Failed tests: 24-27
Non-zero exit status: 1
t3404-rebase-interactive.sh (Wstat: 256 Tests: 91 Failed: 57)
Failed tests: 17, 19, 21-42, 44, 46-74, 77, 81-82
Non-zero exit status: 1
t3900-i18n-commit.sh (Wstat: 256 Tests: 34 Failed: 1)
Failed test: 34
Non-zero exit status: 1
t5407-post-rewrite-hook.sh (Wstat: 256 Tests: 14 Failed: 6)
Failed tests: 9-14
Non-zero exit status: 1
t7001-mv.sh (Wstat: 256 Tests: 46 Failed: 5)
Failed tests: 39-43
Non-zero exit status: 1
t7509-commit.sh (Wstat: 256 Tests: 12 Failed: 2)
Failed tests: 11-12
Non-zero exit status: 1
t7512-status-help.sh (Wstat: 256 Tests: 39 Failed: 35)
Failed tests: 5-39
Non-zero exit status: 1
t6030-bisect-porcelain.sh (Wstat: 256 Tests: 70 Failed: 1)
Failed test: 13
Non-zero exit status: 1

And if a branch is named "H", "HE", or "HEA" then the current if clause
erroneously considers it as matching "HEAD" because it only compares
up to the end of the branch name.

Fix that by doing the comparison using strcmp() and only after the
branch name is extracted. This way neither too less nor too many
characters are checked. While at it call strchrnul() to find the end
of the branch name instead of open-coding it.

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Jeff King <peff@peff.net>
wt-status.c
index 435fc2806ec0a59acf390ee89ed2efc79f229a0e..ced53dd1d49eb641f5505a8a75502e95de356c3c 100644 (file)
@@ -1317,15 +1317,14 @@ static int grab_1st_switch(unsigned char *osha1, unsigned char *nsha1,
        target += strlen(" to ");
        strbuf_reset(&cb->buf);
        hashcpy(cb->nsha1, nsha1);
-       for (end = target; *end && *end != '\n'; end++)
-               ;
-       if (!memcmp(target, "HEAD", end - target)) {
+       end = strchrnul(target, '\n');
+       strbuf_add(&cb->buf, target, end - target);
+       if (!strcmp(cb->buf.buf, "HEAD")) {
                /* HEAD is relative. Resolve it to the right reflog entry. */
+               strbuf_reset(&cb->buf);
                strbuf_addstr(&cb->buf,
                              find_unique_abbrev(nsha1, DEFAULT_ABBREV));
-               return 1;
        }
-       strbuf_add(&cb->buf, target, end - target);
        return 1;
 }