fix "git apply --index ..." not to deref NULL

I noticed this when "git am CORRUPTED" unexpectedly failed with an odd diagnostic, and even removed one of the files it was supposed to have patched. Reproduce with any valid old/new patch from which you have removed the "+++ b/FILE" line. You'll see a diagnostic like this fatal: unable to write file '(null)' mode 100644: Bad address and you'll find that FILE has been removed. The above is on glibc-based systems. On other systems, rather than getting "null", you may provoke a segfault as git tries to dereference the NULL file name. Signed-off-by: Jim Meyering <meyering@redhat.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jim Meyering committed Oct 12, 2011 at 16:33 UTC 2c93286ab2ca5271e26779ffd1ecfd1c7a082a41
2 files changed +46
builtin/apply.c
+3
@@ -1405,6 +1405,9 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
1405 "%d leading pathname components (line %d)" , p_value, linenr);
1406 patch->old_name = patch->new_name = patch->def_name;
1407 }
1408 + if (!patch->is_delete && !patch->new_name)
1409 + die("git diff header lacks filename information "
1410 + "(line %d)", linenr);
1411 patch->is_toplevel_relative = 1;
1412 *hdrsize = git_hdr_len;
1413 return offset;
t/t4254-am-corrupt.sh new
+43
@@ -0,0 +1,43 @@
1 +#!/bin/sh
2 +
3 +test_description='git am with corrupt input'
4 +. ./test-lib.sh
5 +
6 +# Note the missing "+++" line:
7 +cat > bad-patch.diff <<'EOF'
8 +From: A U Thor <au.thor@example.com>
9 +diff --git a/f b/f
10 +index 7898192..6178079 100644
11 +--- a/f
12 +@@ -1 +1 @@
13 +-a
14 ++b
15 +EOF
16 +
17 +test_expect_success setup '
18 + test $? = 0 &&
19 + echo a > f &&
20 + git add f &&
21 + test_tick &&
22 + git commit -m initial
23 +'
24 +
25 +# This used to fail before, too, but with a different diagnostic.
26 +# fatal: unable to write file '(null)' mode 100644: Bad address
27 +# Also, it had the unwanted side-effect of deleting f.
28 +test_expect_success 'try to apply corrupted patch' '
29 + git am bad-patch.diff 2> actual
30 + test $? = 1
31 +'
32 +
33 +cat > expected <<EOF
34 +fatal: git diff header lacks filename information (line 4)
35 +EOF
36 +
37 +test_expect_success 'compare diagnostic; ensure file is still here' '
38 + test $? = 0 &&
39 + test -f f &&
40 + test_cmp expected actual
41 +'
42 +
43 +test_done