summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@gnu.org>2015-01-31 21:51:02 +0100
committerAndreas Gruenbacher <agruen@gnu.org>2015-01-31 22:14:01 +0100
commit38d87ecb9e8e0c1c5e234bf4888edb159f18af46 (patch)
treee4e67f1447660e26187b9c285467b87259b1b7e3
parent82b800c9552a088a241457948219d25ce0a407a4 (diff)
downloadpatch-38d87ecb9e8e0c1c5e234bf4888edb159f18af46.tar.gz
Fix indentation heuristic for context diffs
Diffs can be indented by a variable number of spaces, tabs, or X characters. Make sure that intuit_diff_type() only accepts context diffs where the first and second line are indented identically, or else another_hunk() will fail. * src/pch.c (intuit_diff_type): Remember the indentation of the last line. Only recognize context diff hunks with the same amount of indentation on the first and second line. * tests/garbage: New test case. * tests/Makefile.am (TESTS): Add test case.
-rw-r--r--src/pch.c7
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/garbage25
3 files changed, 31 insertions, 2 deletions
diff --git a/src/pch.c b/src/pch.c
index a831697..fd8885e 100644
--- a/src/pch.c
+++ b/src/pch.c
@@ -434,6 +434,7 @@ intuit_diff_type (bool need_header, mode_t *p_file_type)
int version_controlled[3];
enum diff retval;
mode_t file_type;
+ size_t indent = -1;
for (i = OLD; i <= INDEX; i++)
if (p_name[i]) {
@@ -480,11 +481,12 @@ intuit_diff_type (bool need_header, mode_t *p_file_type)
file_offset previous_line = this_line;
bool last_line_was_command = this_is_a_command;
bool stars_last_line = stars_this_line;
- size_t indent = 0;
+ size_t indent_last_line = indent;
char ed_command_letter;
bool strip_trailing_cr;
size_t chars_read;
+ indent = 0;
this_line = file_tell (pfp);
chars_read = pget_line (0, 0, false, false);
if (chars_read == (size_t) -1)
@@ -763,7 +765,8 @@ intuit_diff_type (bool need_header, mode_t *p_file_type)
if ((diff_type == NO_DIFF
|| diff_type == CONTEXT_DIFF
|| diff_type == NEW_CONTEXT_DIFF)
- && stars_last_line && strnEQ (s, "*** ", 4)) {
+ && stars_last_line && indent_last_line == indent
+ && strnEQ (s, "*** ", 4)) {
s += 4;
if (s[0] == '0' && !ISDIGIT (s[1]))
p_says_nonexistent[OLD] = 1 + ! p_timestamp[OLD].tv_sec;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4c53291..91c9dce 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -34,6 +34,7 @@ TESTS = \
file-modes \
filename-choice \
git-binary-diff \
+ garbage \
global-reject-files \
inname \
line-numbers \
diff --git a/tests/garbage b/tests/garbage
new file mode 100644
index 0000000..3ac5d9c
--- /dev/null
+++ b/tests/garbage
@@ -0,0 +1,25 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# in any medium, are permitted without royalty provided the copyright
+# notice and this notice are preserved.
+
+. $srcdir/test-lib.sh
+
+require cat
+use_local_patch
+use_tmpdir
+
+# ==============================================================
+
+cat > bad.diff <<EOF
+ ***************
+*** 0 ****
+--- 1 ----
++ foo
+EOF
+
+check 'patch foo -i bad.diff || echo "Status: $?"' <<EOF
+$PATCH: **** Only garbage was found in the patch input.
+Status: 2
+EOF