Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 1AF3810A8A for ; Mon, 4 Nov 2013 19:42:22 +0000 (UTC) Received: (qmail 50228 invoked by uid 500); 4 Nov 2013 19:42:22 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 50210 invoked by uid 500); 4 Nov 2013 19:42:22 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 50191 invoked by uid 99); 4 Nov 2013 19:42:21 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 04 Nov 2013 19:42:21 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 04 Nov 2013 19:42:20 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 701A723888CD; Mon, 4 Nov 2013 19:42:00 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1538734 - in /subversion/branches/1.7.x-r1426762/subversion: libsvn_diff/diff_file.c tests/libsvn_diff/diff-diff3-test.c Date: Mon, 04 Nov 2013 19:42:00 -0000 To: commits@subversion.apache.org From: julianfoad@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131104194200.701A723888CD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 };