You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2013/11/04 20:42:00 UTC

svn commit: r1538734 - in /subversion/branches/1.7.x-r1426762/subversion: libsvn_diff/diff_file.c tests/libsvn_diff/diff-diff3-test.c

Author: julianfoad
Date: Mon Nov  4 19:41:59 2013
New Revision: 1538734

URL: http://svn.apache.org/r1538734
Log:
On the 1.7.x-r1426762 branch, backport r1426762 from trunk.

Modified:
    subversion/branches/1.7.x-r1426762/subversion/libsvn_diff/diff_file.c
    subversion/branches/1.7.x-r1426762/subversion/tests/libsvn_diff/diff-diff3-test.c

Modified: subversion/branches/1.7.x-r1426762/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1426762/subversion/libsvn_diff/diff_file.c?rev=1538734&r1=1538733&r2=1538734&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1426762/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/1.7.x-r1426762/subversion/libsvn_diff/diff_file.c Mon Nov  4 19:41:59 2013
@@ -860,17 +860,24 @@ datasource_get_next_token(apr_uint32_t *
 
   last_chunk = offset_to_chunk(file->size);
 
-  if (curp == endp
-      && last_chunk == file->chunk)
+  /* Are we already at the end of a chunk? */
+  if (curp == endp)
     {
-      return SVN_NO_ERROR;
+      /* Are we at EOF */
+      if (last_chunk == file->chunk)
+        return SVN_NO_ERROR; /* EOF */
+
+      /* Or right before an identical suffix in the next chunk? */
+      if (file->chunk + 1 == file->suffix_start_chunk
+          && file->suffix_offset_in_chunk == 0)
+        return SVN_NO_ERROR;
     }
 
   /* Stop when we encounter the identical suffix. If suffix scanning was not
    * performed, suffix_start_chunk will be -1, so this condition will never
    * be true. */
   if (file->chunk == file->suffix_start_chunk
-      && curp - file->buffer == file->suffix_offset_in_chunk)
+      && (curp - file->buffer) == file->suffix_offset_in_chunk)
     return SVN_NO_ERROR;
 
   /* Allocate a new token, or fetch one from the "reusable tokens" list. */
@@ -939,6 +946,14 @@ datasource_get_next_token(apr_uint32_t *
       endp += length;
       file->endp = endp;
 
+      /* Issue #4283: Normally we should have checked for reaching the skipped
+         suffix here, but because we assume that a suffix always starts on a
+         line and token boundary we rely on catching the suffix earlier in this
+         function.
+
+         When changing things here, make sure the whitespace settings are
+         applied, or we mught not reach the exact suffix boundary as token
+         boundary. */
       SVN_ERR(read_chunk(file->file, file->path,
                          curp, length,
                          chunk_to_offset(file->chunk),

Modified: subversion/branches/1.7.x-r1426762/subversion/tests/libsvn_diff/diff-diff3-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1426762/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=1538734&r1=1538733&r2=1538734&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1426762/subversion/tests/libsvn_diff/diff-diff3-test.c (original)
+++ subversion/branches/1.7.x-r1426762/subversion/tests/libsvn_diff/diff-diff3-test.c Mon Nov  4 19:41:59 2013
@@ -2526,6 +2526,123 @@ test_token_compare(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+/* A back-ported copy of the 1.8 public function of the same name. */
+static void
+svn_stringbuf_insert(svn_stringbuf_t *str,
+                     apr_size_t pos,
+                     const char *bytes,
+                     apr_size_t count)
+{
+  if (bytes + count > str->data && bytes < str->data + str->blocksize)
+    {
+      /* special case: BYTES overlaps with this string -> copy the source */
+      const char *temp = apr_pstrndup(str->pool, bytes, count);
+      svn_stringbuf_insert(str, pos, temp, count);
+    }
+  else
+    {
+      if (pos > str->len)
+        pos = str->len;
+
+      svn_stringbuf_ensure(str, str->len + count);
+      memmove(str->data + pos + count, str->data + pos, str->len - pos + 1);
+      memcpy(str->data + pos, bytes, count);
+
+      str->len += count;
+    }
+}
+
+/* Issue #4283, 'When identical suffix started at a chunk boundary,
+   incorrect diff was generated'.
+   The magic number used in this test, (1<<17) and 50 are CHUNK_SIZE
+   and SUFFIX_LINES_TO_KEEP from ../../libsvn_diff/diff_file.c, respectively.
+ */
+#define ORIGINAL_CONTENTS_PATTERN "0123456789abcde\n"
+#define INSERTED_LINE "0123456789ABCDE\n"
+static svn_error_t *
+test_identical_suffix(apr_pool_t *pool)
+{
+  apr_size_t lines_in_chunk = (1 << 17)
+                              / (sizeof(ORIGINAL_CONTENTS_PATTERN) - 1);
+  /* To let identical suffix start at a chunk boundary,
+     insert a line at before (SUFFIX_LINES_TO_KEEP + 1) lines
+     from tail of the previous chunk. */
+  apr_size_t insert_pos = lines_in_chunk
+#ifdef SUFFIX_LINES_TO_KEEP
+                          - SUFFIX_LINES_TO_KEEP
+#else
+                          - 50
+#endif
+                          - 1;
+  apr_size_t i;
+  svn_stringbuf_t *original, *modified;
+
+  /* The original contents become like this.
+
+     $ hexdump -C identical-suffix-original
+     00000000  30 31 32 33 34 35 36 37  38 39 61 62 63 64 65 0a  |0123456789abcde.|
+     *
+     00020400
+   */
+  original = svn_stringbuf_create_ensure((1 << 17) + 1024, pool);
+  for (i = 0; i < lines_in_chunk + 64; i++)
+    {
+      svn_stringbuf_appendbytes(original, ORIGINAL_CONTENTS_PATTERN,
+                                sizeof(ORIGINAL_CONTENTS_PATTERN) - 1);
+    }
+
+  /* The modified contents become like this.
+
+     $ hexdump -C identical-suffix-modified
+     00000000  30 31 32 33 34 35 36 37  38 39 61 62 63 64 65 0a  |0123456789abcde.|
+     *
+     00000400  30 31 32 33 34 35 36 37  38 39 41 42 43 44 45 0a  |0123456789ABCDE.|
+     00000410  30 31 32 33 34 35 36 37  38 39 61 62 63 64 65 0a  |0123456789abcde.|
+     *
+     0001fcd0  30 31 32 33 34 35 36 37  38 39 41 42 43 44 45 0a  |0123456789ABCDE.|
+     0001fce0  30 31 32 33 34 35 36 37  38 39 61 62 63 64 65 0a  |0123456789abcde.|
+     *
+     00020420
+   */
+  modified = svn_stringbuf_dup(original, pool);
+  svn_stringbuf_insert(modified,
+                       64 * (sizeof(ORIGINAL_CONTENTS_PATTERN) - 1),
+                       INSERTED_LINE, sizeof(INSERTED_LINE) - 1);
+  svn_stringbuf_insert(modified,
+                       insert_pos * (sizeof(ORIGINAL_CONTENTS_PATTERN) - 1),
+                       INSERTED_LINE, sizeof(INSERTED_LINE) - 1);
+
+  SVN_ERR(two_way_diff("identical-suffix-original",
+                       "identical-suffix-modified",
+                       original->data, modified->data,
+                       apr_psprintf(pool,
+                                    "--- identical-suffix-original" NL
+                                    "+++ identical-suffix-modified" NL
+                                    "@@ -62,6 +62,7 @@" NL
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    "+" INSERTED_LINE
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    "@@ -%u,6 +%u,7 @@" NL
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    "+" INSERTED_LINE
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    " " ORIGINAL_CONTENTS_PATTERN
+                                    " " ORIGINAL_CONTENTS_PATTERN,
+                                    1 + (unsigned int)insert_pos - 3 - 1,
+                                    1 + (unsigned int)insert_pos - 3),
+                       NULL, pool));
+
+  return SVN_NO_ERROR;
+}
+#undef ORIGINAL_CONTENTS_PATTERN
+#undef INSERTED_LINE
+
 /* ========================================================================== */
 
 struct svn_test_descriptor_t test_funcs[] =
@@ -2559,5 +2676,7 @@ struct svn_test_descriptor_t test_funcs[
                    "offset of the normalized token"),
     SVN_TEST_PASS2(test_token_compare,
                    "compare tokes at the chunk boundary"),
+    SVN_TEST_PASS2(test_identical_suffix,
+                   "identical suffix starts at the boundary of a chunk"),
     SVN_TEST_NULL
   };