subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1616600 - in /subversion/trunk/subversion: include/svn_error_codes.h libsvn_fs_x/pack.c libsvn_fs_x/reps.c libsvn_fs_x/reps.h tests/libsvn_fs_x/fs-x-pack-test.c
Date Thu, 07 Aug 2014 21:35:02 GMT
Author: stefan2
Date: Thu Aug  7 21:35:01 2014
New Revision: 1616600

URL: http://svn.apache.org/r1616600
Log:
Explicitly limit the dimensions of a star delta container which allows us
to cast sizes to 32 bits.

* subversion/include/svn_error_codes.h
  (SVN_ERR_FS_CONTAINER_SIZE): Declare new error code.

* subversion/libsvn_fs_x/reps.h
  (svn_fs_x__reps_add): Allow for error returns.

* subversion/libsvn_fs_x/reps.c
  (MAX_TEXT_BODY,
   MAX_INSTRUCTIONS): Formally declare dimensional limit to the star
                      delta container.
  (svn_fs_x__reps_add_base): Update caller. Explicitly cast index to 32 bits.
  (add_new_text): Explicitly cast length values to 32 bits. They have been
                  limited to < 2GB be the caller already.
  (svn_fs_x__reps_add): Make sure the container size stays within set limits.

* subversion/libsvn_fs_x/pack.c
  (write_reps_containers): Update caller.

* subversion/tests/libsvn_fs_x/fs-x-pack-test.c
  (test_reps): Same.

Modified:
    subversion/trunk/subversion/include/svn_error_codes.h
    subversion/trunk/subversion/libsvn_fs_x/pack.c
    subversion/trunk/subversion/libsvn_fs_x/reps.c
    subversion/trunk/subversion/libsvn_fs_x/reps.h
    subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c

Modified: subversion/trunk/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_error_codes.h?rev=1616600&r1=1616599&r2=1616600&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_error_codes.h (original)
+++ subversion/trunk/subversion/include/svn_error_codes.h Thu Aug  7 21:35:01 2014
@@ -851,6 +851,11 @@ SVN_ERROR_START
              SVN_ERR_FS_CATEGORY_START + 60,
              "Unsupported FS type")
 
+  /** @since New in 1.9. */
+  SVN_ERRDEF(SVN_ERR_FS_CONTAINER_SIZE,
+             SVN_ERR_FS_CATEGORY_START + 61,
+             "Container capacity exceeded.")
+
   /* repos errors */
 
   SVN_ERRDEF(SVN_ERR_REPOS_LOCKED,

Modified: subversion/trunk/subversion/libsvn_fs_x/pack.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/pack.c?rev=1616600&r1=1616599&r2=1616600&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/pack.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/pack.c Thu Aug  7 21:35:01 2014
@@ -1343,8 +1343,8 @@ write_reps_containers(pack_context_t *co
       SVN_ERR(svn_stream_read_full(stream, contents->data, &contents->len));
       SVN_ERR(svn_stream_close(stream));
 
-      list_index = svn_fs_x__reps_add(container,
-                                svn_stringbuf__morph_into_string(contents));
+      SVN_ERR(svn_fs_x__reps_add(&list_index, container,
+                                 svn_stringbuf__morph_into_string(contents)));
       SVN_ERR_ASSERT(list_index == sub_items->nelts);
       block_left -= entry->size;
 

Modified: subversion/trunk/subversion/libsvn_fs_x/reps.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/reps.c?rev=1616600&r1=1616599&r2=1616600&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/reps.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/reps.c Thu Aug  7 21:35:01 2014
@@ -27,6 +27,8 @@
 #include "private/svn_packed_data.h"
 #include "private/svn_temp_serializer.h"
 
+#include "svn_private_config.h"
+
 #include "cached_data.h"
 
 /* Length of the text chunks we hash and match.  The algorithm will find
@@ -38,6 +40,16 @@
  */
 #define MATCH_BLOCKSIZE 64
 
+/* Limit the total text body within a container to 16MB.  Larger values
+ * of up to 2GB are possible but become increasingly impractical as the
+ * container has to be loaded in its entirety before any of it can be read.
+ */
+#define MAX_TEXT_BODY 0x1000000
+
+/* Limit the size of the instructions stream.  This should not exceed the
+ * text body size limit. */
+#define MAX_INSTRUCTIONS (MAX_TEXT_BODY / 8)
+
 /* value of unused hash buckets */
 #define NO_OFFSET ((apr_uint32_t)(-1))
 
@@ -398,15 +410,17 @@ svn_fs_x__reps_add_base(svn_fs_x__reps_b
 
   svn_stream_t *stream;
   svn_string_t *contents;
+  apr_size_t idx;
   SVN_ERR(svn_fs_x__get_contents(&stream, builder->fs, rep, FALSE,
                                  scratch_pool));
   SVN_ERR(svn_string_from_stream(&contents, stream, scratch_pool,
                                  scratch_pool));
+  SVN_ERR(svn_fs_x__reps_add(&idx, builder, contents));
 
   base.revision = svn_fs_x__get_revnum(rep->id.change_set);
   base.item_index = rep->id.number;
   base.priority = priority;
-  base.rep = (apr_uint32_t)svn_fs_x__reps_add(builder, contents);
+  base.rep = (apr_uint32_t)idx;
 
   APR_ARRAY_PUSH(builder->bases, base_t) = base;
   builder->base_text_len += builder->text->len - text_start_offset;
@@ -430,8 +444,8 @@ add_new_text(svn_fs_x__reps_builder_t *b
     return;
 
   /* new instruction */
-  instruction.offset = builder->text->len;
-  instruction.count = len;
+  instruction.offset = (apr_int32_t)builder->text->len;
+  instruction.count = (apr_uint32_t)len;
   APR_ARRAY_PUSH(builder->instructions, instruction_t) = instruction;
 
   /* add to text corpus */
@@ -462,8 +476,9 @@ add_new_text(svn_fs_x__reps_builder_t *b
     }
 }
 
-apr_size_t
-svn_fs_x__reps_add(svn_fs_x__reps_builder_t *builder,
+svn_error_t *
+svn_fs_x__reps_add(apr_size_t *rep_idx,
+                   svn_fs_x__reps_builder_t *builder,
                    const svn_string_t *contents)
 {
   rep_t rep;
@@ -472,8 +487,16 @@ svn_fs_x__reps_add(svn_fs_x__reps_builde
   const char *end = current + contents->len;
   const char *last_to_test = end - MATCH_BLOCKSIZE - 1;
 
-  rep.first_instruction = (apr_uint32_t)builder->instructions->nelts;
+  if (builder->text->len + contents->len > MAX_TEXT_BODY)
+    return svn_error_create(SVN_ERR_FS_CONTAINER_SIZE, NULL,
+                      _("Text body exceeds star delta container capacity"));
+
+  if (  builder->instructions->nelts + 2 * contents->len / MATCH_BLOCKSIZE
+      > MAX_INSTRUCTIONS)
+    return svn_error_create(SVN_ERR_FS_CONTAINER_SIZE, NULL,
+              _("Instruction count exceeds star delta container capacity"));
 
+  rep.first_instruction = (apr_uint32_t)builder->instructions->nelts;
   while (current < last_to_test)
     {
       hash_key_t key = hash_key(current);
@@ -501,7 +524,7 @@ svn_fs_x__reps_add(svn_fs_x__reps_builde
       if (current < last_to_test)
         {
           instruction_t instruction;
-          
+
           /* extend the match */
 
           size_t prefix_match
@@ -536,7 +559,8 @@ svn_fs_x__reps_add(svn_fs_x__reps_builde
                         - rep.first_instruction;
   APR_ARRAY_PUSH(builder->reps, rep_t) = rep;
 
-  return (apr_size_t)(builder->reps->nelts - 1);
+  *rep_idx = (apr_size_t)(builder->reps->nelts - 1);
+  return SVN_NO_ERROR;
 }
 
 apr_size_t

Modified: subversion/trunk/subversion/libsvn_fs_x/reps.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/reps.h?rev=1616600&r1=1616599&r2=1616600&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/reps.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/reps.h Thu Aug  7 21:35:01 2014
@@ -96,10 +96,11 @@ svn_fs_x__reps_add_base(svn_fs_x__reps_b
                         apr_pool_t *scratch_pool);
 
 /* Add the byte string CONTENTS to BUILDER.  Return the item index under
- * which the fulltext can be retrieved from the final container.
+ * which the fulltext can be retrieved from the final container in *REP_IDX.
  */
-apr_size_t
-svn_fs_x__reps_add(svn_fs_x__reps_builder_t *builder,
+svn_error_t *
+svn_fs_x__reps_add(apr_size_t *rep_idx,
+                   svn_fs_x__reps_builder_t *builder,
                    const svn_string_t *contents);
 
 /* Return a rough estimate in bytes for the serialized representation

Modified: subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c?rev=1616600&r1=1616599&r2=1616600&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c Thu Aug  7 21:35:01 2014
@@ -814,11 +814,12 @@ test_reps(const svn_test_opts_t *opts,
   builder = svn_fs_x__reps_builder_create(fs, pool);
   for (i = 10000; i > 10; --i)
     {
+      apr_size_t idx;
       svn_string_t string;
       string.data = contents->data;
       string.len = i;
 
-      svn_fs_x__reps_add(builder, &string);
+      SVN_ERR(svn_fs_x__reps_add(&idx, builder, &string));
     }
 
   serialized = svn_stringbuf_create_empty(pool);



Mime
View raw message