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