Merge branch 'js/rerere-forget-protect-against-NUL' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 22 Apr 2013 18:26:56 +0000 (11:26 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 22 Apr 2013 18:26:56 +0000 (11:26 -0700)
* js/rerere-forget-protect-against-NUL:
rerere forget: do not segfault if not all stages are present
rerere forget: grok files containing NUL

rerere.c
t/t2030-unresolve-info.sh
index a6a5cd57bef4aaf204f1bad293c18b5af6f57f53..98e3e294d0dc295290b7b891a834186c0791e43a 100644 (file)
--- a/rerere.c
+++ b/rerere.c
@@ -284,8 +284,10 @@ static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_)
        strbuf_release(sb);
        if (!io->input.len)
                return -1;
-       ep = strchrnul(io->input.buf, '\n');
-       if (*ep == '\n')
+       ep = memchr(io->input.buf, '\n', io->input.len);
+       if (!ep)
+               ep = io->input.buf + io->input.len;
+       else if (*ep == '\n')
                ep++;
        len = ep - io->input.buf;
        strbuf_add(sb, io->input.buf, len);
@@ -295,7 +297,7 @@ static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_)
 
 static int handle_cache(const char *path, unsigned char *sha1, const char *output)
 {
-       mmfile_t mmfile[3];
+       mmfile_t mmfile[3] = {{NULL}};
        mmbuffer_t result = {NULL, 0};
        struct cache_entry *ce;
        int pos, len, i, hunk_no;
@@ -314,17 +316,16 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
        for (i = 0; i < 3; i++) {
                enum object_type type;
                unsigned long size;
+               int j;
 
-               mmfile[i].size = 0;
-               mmfile[i].ptr = NULL;
                if (active_nr <= pos)
                        break;
                ce = active_cache[pos++];
-               if (ce_namelen(ce) != len || memcmp(ce->name, path, len)
-                   || ce_stage(ce) != i + 1)
-                       break;
-               mmfile[i].ptr = read_sha1_file(ce->sha1, &type, &size);
-               mmfile[i].size = size;
+               if (ce_namelen(ce) != len || memcmp(ce->name, path, len))
+                       continue;
+               j = ce_stage(ce) - 1;
+               mmfile[j].ptr = read_sha1_file(ce->sha1, &type, &size);
+               mmfile[j].size = size;
        }
        for (i = 0; i < 3; i++) {
                if (!mmfile[i].ptr && !mmfile[i].size)
index f2620650ce1d25252210c07db20e54f99bd515c6..309199bca272b63499ca69edbb953bcc8c770ecc 100755 (executable)
@@ -44,14 +44,21 @@ prime_resolve_undo () {
 
 test_expect_success setup '
        mkdir fi &&
+       printf "a\0a" >binary &&
+       git add binary &&
        test_commit initial fi/le first &&
        git branch side &&
        git branch another &&
+       printf "a\0b" >binary &&
+       git add binary &&
        test_commit second fi/le second &&
        git checkout side &&
        test_commit third fi/le third &&
+       git branch add-add &&
        git checkout another &&
        test_commit fourth fi/le fourth &&
+       git checkout add-add &&
+       test_commit fifth add-differently &&
        git checkout master
 '
 
@@ -167,4 +174,22 @@ test_expect_success 'rerere and rerere forget (subdirectory)' '
        test_cmp expect actual
 '
 
+test_expect_success 'rerere forget (binary)' '
+       git checkout -f side &&
+       printf "a\0c" >binary &&
+       git commit -a -m binary &&
+       test_must_fail git merge second &&
+       git rerere forget binary
+'
+
+test_expect_success 'rerere forget (add-add conflict)' '
+       git checkout -f master &&
+       echo master >add-differently &&
+       git add add-differently &&
+       git commit -m "add differently" &&
+       test_must_fail git merge fifth &&
+       git rerere forget add-differently 2>actual &&
+       test_i18ngrep "no remembered" actual
+'
+
 test_done