Author: philip
Date: Thu Mar 28 11:16:56 2013
New Revision: 1462041
URL: http://svn.apache.org/r1462041
Log:
Additional fix for issue 4339, diff suffix scanning invalid read
at last chunk boundary.
* subversion/libsvn_diff/diff_file.c
(find_identical_suffix): Handle file ending at end of chunk in all cases.
* subversion/tests/libsvn_diff/diff-diff3-test.c
(test_token_compare): Extend.
Patch by: jcorvel, me
Modified:
subversion/trunk/subversion/libsvn_diff/diff_file.c
subversion/trunk/subversion/tests/libsvn_diff/diff-diff3-test.c
Modified: subversion/trunk/subversion/libsvn_diff/diff_file.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/diff_file.c?rev=1462041&r1=1462040&r2=1462041&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/trunk/subversion/libsvn_diff/diff_file.c Thu Mar 28 11:16:56 2013
@@ -544,18 +544,17 @@ find_identical_suffix(apr_off_t *suffix_
file_for_suffix[i].chunk =
(int) offset_to_chunk(file_for_suffix[i].size); /* last chunk */
length[i] = offset_in_chunk(file_for_suffix[i].size);
- if (file_for_suffix[i].chunk == file[i].chunk)
+ if (length[i] == 0)
{
- /* Prefix ended in last chunk, so we can reuse the prefix buffer */
- file_for_suffix[i].buffer = file[i].buffer;
+ /* last chunk is an empty chunk -> start at next-to-last chunk */
+ file_for_suffix[i].chunk = file_for_suffix[i].chunk - 1;
+ length[i] = CHUNK_SIZE;
}
- else if (!length[i] && file_for_suffix[i].chunk == file[i].chunk + 1)
+
+ if (file_for_suffix[i].chunk == file[i].chunk)
{
- /* Prefix ended at end of last chunk, so we can reuse the
- prefix buffer */
- file_for_suffix[i].chunk = file[i].chunk;
+ /* Prefix ended in last chunk, so we can reuse the prefix buffer */
file_for_suffix[i].buffer = file[i].buffer;
- length[i] = CHUNK_SIZE;
}
else
{
Modified: subversion/trunk/subversion/tests/libsvn_diff/diff-diff3-test.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=1462041&r1=1462040&r2=1462041&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_diff/diff-diff3-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_diff/diff-diff3-test.c Thu Mar 28
11:16:56 2013
@@ -2571,16 +2571,16 @@ test_token_compare(apr_pool_t *pool)
diff_opts->ignore_space = svn_diff_file_ignore_space_all;
+ original = svn_stringbuf_create_ensure(chunk_size * 2 + 8, pool);
/* CHUNK_SIZE bytes */
- original = svn_stringbuf_create_ensure(chunk_size, pool);
while (original->len < chunk_size - 8)
{
svn_stringbuf_appendcstr(original, pattern);
}
svn_stringbuf_appendcstr(original, " @@@\n");
+ modified = svn_stringbuf_create_ensure(chunk_size * 2 + 9, pool);
/* CHUNK_SIZE+1 bytes, one ' ' more than original */
- modified = svn_stringbuf_create_ensure(chunk_size + 1, pool);
while (modified->len < chunk_size - 8)
{
svn_stringbuf_appendcstr(modified, pattern);
@@ -2611,6 +2611,36 @@ test_token_compare(apr_pool_t *pool)
1 +(unsigned int)chunk_size - 8 + 1 - 3),
diff_opts, pool));
+ /* CHUNK_SIZE*2 bytes */
+ while (original->len <= chunk_size * 2 - 8)
+ {
+ svn_stringbuf_appendcstr(original, pattern);
+ }
+
+ /* CHUNK_SIZE*2+1 bytes, one ' ' more than original */
+ while (modified->len <= chunk_size * 2 - 7)
+ {
+ svn_stringbuf_appendcstr(modified, pattern);
+ }
+
+ SVN_ERR(two_way_diff("token-compare-original2", "token-compare-modified2",
+ original->data, modified->data,
+ apr_psprintf(pool,
+ "--- token-compare-original2" NL
+ "+++ token-compare-modified2" NL
+ "@@ -%u,7 +%u,7 @@" NL
+ " \n"
+ " \n"
+ " @@@\n"
+ "-aaaaaaa\n"
+ "+bbbbbbb\n"
+ " \n"
+ " \n"
+ " \n",
+ 1 +(unsigned int)chunk_size - 8 + 1 - 3,
+ 1 +(unsigned int)chunk_size - 8 + 1 - 3),
+ diff_opts, pool));
+
return SVN_NO_ERROR;
}