You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/12/12 19:40:27 UTC

svn commit: r1719717 - /subversion/trunk/subversion/libsvn_fs_x/revprops.c

Author: stefan2
Date: Sat Dec 12 18:40:27 2015
New Revision: 1719717

URL: http://svn.apache.org/viewvc?rev=1719717&view=rev
Log:
In FSX, add checksums to the packed revprop files.

Most of this is done by reusing code already written for the checksummed
manifest file.

* subversion/libsvn_fs_x/revprops.c
  (write_packed_data_checksummed): Factored out from ...
  (write_manifest): ... this.
  (read_packed_data_checksummed): Factored out from ...
  (read_manifest): ... this.
  (parse_packed_revprops,
   repack_revprops,
   copy_revprops): Call the new checksumming I/O functions for svn_packed_*.

Modified:
    subversion/trunk/subversion/libsvn_fs_x/revprops.c

Modified: subversion/trunk/subversion/libsvn_fs_x/revprops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/revprops.c?rev=1719717&r1=1719716&r2=1719717&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/revprops.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/revprops.c Sat Dec 12 18:40:27 2015
@@ -473,6 +473,32 @@ read_non_packed_revprop(apr_hash_t **pro
   return SVN_NO_ERROR;
 }
 
+/* Serialize ROOT into FILE and append a checksum to it.
+ * Use SCRATCH_POOL for temporary allocations.
+ */
+static svn_error_t *
+write_packed_data_checksummed(svn_packed__data_root_t *root,
+                              apr_file_t *file,
+                              apr_pool_t *scratch_pool)
+{
+  svn_checksum_t *checksum;
+  svn_stream_t *stream;
+
+  stream = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
+  stream = svn_checksum__wrap_write_stream(&checksum, stream,
+                                           svn_checksum_fnv1a_32x4,
+                                           scratch_pool);
+  SVN_ERR(svn_packed__data_write(stream, root, scratch_pool));
+  SVN_ERR(svn_stream_close(stream));
+
+  /* Append the checksum */
+  SVN_ERR(svn_io_file_write_full(file, checksum->digest,
+                                 svn_checksum_size(checksum), NULL,
+                                 scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* Serialize the packed revprops MANIFEST into FILE.
  * Use SCRATCH_POOL for temporary allocations.
  */
@@ -482,8 +508,6 @@ write_manifest(apr_file_t *file,
                apr_pool_t *scratch_pool)
 {
   int i;
-  svn_checksum_t *checksum;
-  svn_stream_t *stream;
   svn_packed__data_root_t *root = svn_packed__data_create_root(scratch_pool);
 
   /* one top-level stream per struct element */
@@ -501,48 +525,29 @@ write_manifest(apr_file_t *file,
     }
 
   /* Write to file and calculate the checksum. */
-  stream = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
-  stream = svn_checksum__wrap_write_stream(&checksum, stream,
-                                           svn_checksum_fnv1a_32x4,
-                                           scratch_pool);
-  SVN_ERR(svn_packed__data_write(stream, root, scratch_pool));
-  SVN_ERR(svn_stream_close(stream));
-
-  /* Append the checksum */
-  SVN_ERR(svn_io_file_write_full(file, checksum->digest,
-                                 svn_checksum_size(checksum), NULL,
-                                 scratch_pool));
+  SVN_ERR(write_packed_data_checksummed(root, file, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
-/* Read the packed revprops manifest from the CONTENT buffer and return it
- * in *MANIFEST, allocated in RESULT_POOL.  REVISION is the revision number
- * to put into error messages.  Use SCRATCH_POOL for temporary allocations.
+/* Read *ROOT from CONTENT and verify its checksum.  Allocate *ROOT in
+ * RESULT_POOL and use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-read_manifest(apr_array_header_t **manifest,
-              svn_stringbuf_t *content,
-              svn_revnum_t revision,
-              apr_pool_t *result_pool,
-              apr_pool_t *scratch_pool)
+read_packed_data_checksummed(svn_packed__data_root_t **root,
+                             svn_stringbuf_t *content,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
 {
   apr_size_t data_len;
-  apr_size_t i;
-  apr_size_t count;
-
-  svn_stream_t *stream;
-  svn_packed__data_root_t *root;
-  svn_packed__int_stream_t *start_rev_stream;
-  svn_packed__int_stream_t *tag_stream;
   const apr_byte_t *digest;
   svn_checksum_t *actual, *expected;
+  svn_stream_t *stream;
 
   /* Verify the checksum. */
   if (content->len < sizeof(apr_uint32_t))
-    return svn_error_createf(SVN_ERR_FS_CORRUPT_REVPROP_MANIFEST, NULL,
-                             "Revprop manifest too short for revision r%ld",
-                             revision);
+    return svn_error_create(SVN_ERR_CORRUPT_PACKED_DATA, NULL,
+                            "File too short");
 
   data_len = content->len - sizeof(apr_uint32_t);
   digest = (apr_byte_t *)content->data + data_len;
@@ -553,13 +558,38 @@ read_manifest(apr_array_header_t **manif
 
   if (!svn_checksum_match(actual, expected))
     SVN_ERR(svn_checksum_mismatch_err(expected, actual, scratch_pool, 
-                                      _("checksum mismatch in revprop "
-                                        "manifest for revision r%ld"),
-                                      revision));
+                                      "checksum mismatch"));
 
-  /* read everything from the buffer */
   stream = svn_stream_from_stringbuf(content, scratch_pool);
-  SVN_ERR(svn_packed__data_read(&root, stream, result_pool, scratch_pool));
+  SVN_ERR(svn_packed__data_read(root, stream, result_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Read the packed revprops manifest from the CONTENT buffer and return it
+ * in *MANIFEST, allocated in RESULT_POOL.  REVISION is the revision number
+ * to put into error messages.  Use SCRATCH_POOL for temporary allocations.
+ */
+static svn_error_t *
+read_manifest(apr_array_header_t **manifest,
+              svn_stringbuf_t *content,
+              svn_revnum_t revision,
+              apr_pool_t *result_pool,
+              apr_pool_t *scratch_pool)
+{
+  apr_size_t i;
+  apr_size_t count;
+
+  svn_packed__data_root_t *root;
+  svn_packed__int_stream_t *start_rev_stream;
+  svn_packed__int_stream_t *tag_stream;
+
+  /* Verify the checksum and decode packed data. */
+  SVN_ERR_W(read_packed_data_checksummed(&root, content, result_pool,
+                                         scratch_pool),
+            apr_psprintf(scratch_pool,
+                         "Revprop manifest file for r%ld is corrupt",
+                         revision));
 
   /* get streams */
   start_rev_stream = svn_packed__first_int_stream(root);
@@ -732,9 +762,12 @@ parse_packed_revprops(svn_fs_t *fs,
   svn_packed__byte_stream_t *revprops_stream;
   svn_revnum_t first_rev = revprops->entry.start_rev;
 
-  /* read everything from the buffer */
-  svn_stream_t *stream = svn_stream_from_stringbuf(content, scratch_pool);
-  SVN_ERR(svn_packed__data_read(&root, stream, result_pool, scratch_pool));
+  /* Verify the checksum and decode packed data. */
+  SVN_ERR_W(read_packed_data_checksummed(&root, content, result_pool,
+                                         scratch_pool),
+            apr_psprintf(scratch_pool,
+                         "Revprop pack file for r%ld is corrupt",
+                         first_rev));
 
   /* get streams */
   revprops_stream = svn_packed__first_byte_stream(root);
@@ -1065,7 +1098,6 @@ repack_revprops(svn_fs_t *fs,
                 apr_file_t *file,
                 apr_pool_t *scratch_pool)
 {
-  svn_stream_t *stream;
   int i;
 
   svn_packed__data_root_t *root = svn_packed__data_create_root(scratch_pool);
@@ -1082,9 +1114,7 @@ repack_revprops(svn_fs_t *fs,
     }
 
   /* Write to file. */
-  stream = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
-  SVN_ERR(svn_packed__data_write(stream, root, scratch_pool));
-  SVN_ERR(svn_stream_close(stream));
+  SVN_ERR(write_packed_data_checksummed(root, file, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1447,7 +1477,6 @@ copy_revprops(svn_fs_t *fs,
               void *cancel_baton,
               apr_pool_t *scratch_pool)
 {
-  svn_stream_t *pack_stream;
   apr_file_t *pack_file;
   svn_revnum_t rev;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
@@ -1481,9 +1510,7 @@ copy_revprops(svn_fs_t *fs,
                                           scratch_pool));
 
   /* write all to disk */
-  pack_stream = svn_stream_from_aprfile2(pack_file, TRUE, scratch_pool);
-  SVN_ERR(svn_packed__data_write(pack_stream, root, scratch_pool));
-  SVN_ERR(svn_stream_close(pack_stream));
+  SVN_ERR(write_packed_data_checksummed(root, pack_file, scratch_pool));
 
   svn_pool_destroy(iterpool);