subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1766352 - /subversion/trunk/subversion/libsvn_fs_fs/cached_data.c
Date Mon, 24 Oct 2016 06:01:50 GMT
Author: stefan2
Date: Mon Oct 24 06:01:50 2016
New Revision: 1766352

URL: http://svn.apache.org/viewvc?rev=1766352&view=rev
Log:
Fix a long-standing FSFS bug that causes read errors on valid / non-corrupted
representations.  The problem occurs if

    * the representation is a DELTA against a PLAIN one,
    * spans multiple delta windows, and
    * has a matching sub-string in some window after there were no matches
      in the previous window.

Because we used to read the PLAIN base window only if it was really needed
due to a matching sub-string In that case, the read offset inside the PLAIN
rep would not be updated.  As a result, when the next window needs to be
read as the delta base, the previous one is read instead.  This would almost
certainly result in a corrupted reconstructed fulltext.  The read will
ultimately fail due to a checksum mismatch.

A test case and issue tracker entry will follow.

* subversion/libsvn_fs_fs/cached_data.c
  (skip_plain_window): New function.
  (get_combined_window): Always move the offset within the base rep in sync
                         with the delta rep.

Modified:
    subversion/trunk/subversion/libsvn_fs_fs/cached_data.c

Modified: subversion/trunk/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/cached_data.c?rev=1766352&r1=1766351&r2=1766352&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/cached_data.c Mon Oct 24 06:01:50 2016
@@ -1660,6 +1660,17 @@ read_plain_window(svn_stringbuf_t **nwin
   return SVN_NO_ERROR;
 }
 
+/* Skip SIZE bytes from the PLAIN representation RS. */
+static svn_error_t *
+skip_plain_window(rep_state_t *rs,
+                  apr_size_t size)
+{
+  /* Update RS. */
+  rs->current += (apr_off_t)size;
+
+  return SVN_NO_ERROR;
+}
+
 /* Get the undeltified window that is a result of combining all deltas
    from the current desired representation identified in *RB with its
    base representation.  Store the window in *RESULT. */
@@ -1717,9 +1728,18 @@ get_combined_window(svn_stringbuf_t **re
          Also note that we may have short-cut reading the delta chain --
          in which case SRC_OPS is 0 and it might not be a PLAIN rep. */
       source = buf;
-      if (source == NULL && rb->src_state != NULL && window->src_ops)
-        SVN_ERR(read_plain_window(&source, rb->src_state, window->sview_len,
-                                  pool, iterpool));
+      if (source == NULL && rb->src_state != NULL)
+        {
+          /* Even if we don't need the source rep now, we still must keep
+           * its read offset in sync with what we might need for the next
+           * window. */
+          if (window->src_ops)
+            SVN_ERR(read_plain_window(&source, rb->src_state,
+                                      window->sview_len,
+                                      pool, iterpool));
+          else
+            SVN_ERR(skip_plain_window(rb->src_state, window->sview_len));
+        }
 
       /* Combine this window with the current one. */
       new_pool = svn_pool_create(rb->pool);



Mime
View raw message