File fix-partial-context.diff of Package patch

From: Andreas Gruenbacher <agruen@suse.de>
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  <agruen@suse.de>
+
+	* 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  <eggert@twinsun.com>
 
 	* 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];
openSUSE Build Service is sponsored by