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.
This commit is contained in:
Andreas Gruenbacher 2015-01-31 21:51:02 +01:00
parent 82b800c955
commit 38d87ecb9e
3 changed files with 31 additions and 2 deletions

View File

@ -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;

View File

@ -34,6 +34,7 @@ TESTS = \
file-modes \
filename-choice \
git-binary-diff \
garbage \
global-reject-files \
inname \
line-numbers \

25
tests/garbage Normal file
View File

@ -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