From: Andreas Gruenbacher Subject: Patch fails to apply hunks with asymmetric context correctly Patch assumes that hunks with fewer context lines at the top than at the bottom can only match at the beginning of the file, and hunks with fewer lines at the bottom can only match at the end. The result is that patches with such hunks will only apply with fuzz N if the prefix context is N lines longer or shorter than the suffix context. This makes no sense; hunks with asymmetric context are perfectly valid. --- ChangeLog | 7 +++++++ patch.c | 43 ++++--------------------------------------- 2 files changed, 11 insertions(+), 39 deletions(-) --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-11-02 Andreas Gruenbacher + + * patch.c (locate_hunk): Hunks that have fewer or more lines of + context at the beginning than at the end can match anywhere; the + assumption that this can only occur at the beginning or end of the + file is wrong. + 2003-05-20 Paul Eggert * NEWS, configure.ac (AC_INIT): Version 2.5.9 released. --- a/patch.c +++ b/patch.c @@ -849,10 +849,10 @@ locate_hunk (LINENUM fuzz) LINENUM pat_lines = pch_ptrn_lines(); LINENUM prefix_context = pch_prefix_context (); LINENUM suffix_context = pch_suffix_context (); - LINENUM context = (prefix_context < suffix_context - ? suffix_context : prefix_context); - LINENUM prefix_fuzz = fuzz + prefix_context - context; - LINENUM suffix_fuzz = fuzz + suffix_context - context; + LINENUM prefix_fuzz = (prefix_context < fuzz + ? prefix_context : fuzz); + LINENUM suffix_fuzz = (suffix_context < fuzz + ? suffix_context : fuzz); LINENUM max_where = input_lines - (pat_lines - suffix_fuzz) + 1; LINENUM min_where = last_frozen_line + 1 - (prefix_context - prefix_fuzz); LINENUM max_pos_offset = max_where - first_guess; @@ -867,41 +867,6 @@ locate_hunk (LINENUM fuzz) if (first_guess <= max_neg_offset) max_neg_offset = first_guess - 1; - if (prefix_fuzz < 0) - { - /* Can only match start of file. */ - - if (suffix_fuzz < 0) - /* Can only match entire file. */ - if (pat_lines != input_lines || prefix_context < last_frozen_line) - return 0; - - offset = 1 - first_guess; - if (last_frozen_line <= prefix_context - && offset <= max_pos_offset - && patch_match (first_guess, offset, (LINENUM) 0, suffix_fuzz)) - { - last_offset += offset; - return first_guess + offset; - } - else - return 0; - } - - if (suffix_fuzz < 0) - { - /* Can only match end of file. */ - offset = first_guess - (input_lines - pat_lines + 1); - if (offset <= max_neg_offset - && patch_match (first_guess, -offset, prefix_fuzz, (LINENUM) 0)) - { - last_offset -= offset; - return first_guess - offset; - } - else - return 0; - } - for (offset = 0; offset <= max_offset; offset++) { char numbuf0[LINENUM_LENGTH_BOUND + 1]; char numbuf1[LINENUM_LENGTH_BOUND + 1];