Hi,

I was reviewing r1931334 nomination and noticed that svn__adler32() uses
apr_off_t for buffer size. The apr_off_t stands for an offset in a file. It
can be larger or even smaller than maximum addressable size (apr_size_t).

I have prepared patch that fixes this. Patch changes the diff code which
very complicated, so review will be much appreciated.

Log message:
[[[
Use apr_size_t instead of apr_off_t for buffer size in svn__adler32().

The apr_off_t stands for an offset in a file. It can be larger or even
smaller
than maximum addressable size (apr_size_t).

Update all callers.

* subversion/include/private/svn_adler32.h
* subversion/libsvn_subr/adler32.c
  (svn__adler32): Use apr_size_t instead of apr_off_t for SIZE argument.

* subversion/libsvn_diff/diff.h
* subversion/libsvn_diff/util.c
  (svn_diff__normalize_buffer): Use apr_size_t instead of apr_off_t for
   LENGTGP argument.

* subversion/libsvn_diff/diff_file.c
  (datasource_get_next_token): Use apr_size_t instead of apr_off_t for
   local variable LENGTH.
  (token_compare): Rewrite a code a bit to make it clear that size is
   apr_size_t.

* subversion/libsvn_diff/diff_memory.c
  (datasource_get_next_token, token_compare): Use apr_size_t instead of
   apr_off_t for local variables to match source type.
]]]

-- 
Ivan Zhakov
Index: subversion/include/private/svn_adler32.h
===================================================================
--- subversion/include/private/svn_adler32.h    (revision 1934976)
+++ subversion/include/private/svn_adler32.h    (working copy)
@@ -41,7 +41,7 @@
  * @since New in 1.7.
  */
 apr_uint32_t
-svn__adler32(apr_uint32_t checksum, const char *data, apr_off_t len);
+svn__adler32(apr_uint32_t checksum, const char *data, apr_size_t len);
 
 
 #ifdef __cplusplus
Index: subversion/libsvn_diff/diff.h
===================================================================
--- subversion/libsvn_diff/diff.h       (revision 1934976)
+++ subversion/libsvn_diff/diff.h       (working copy)
@@ -179,7 +179,7 @@
  */
 void
 svn_diff__normalize_buffer(char **tgt,
-                           apr_off_t *lengthp,
+                           apr_size_t *lengthp,
                            svn_diff__normalize_state_t *statep,
                            const char *buf,
                            const svn_diff_file_options_t *opts);
Index: subversion/libsvn_diff/diff_file.c
===================================================================
--- subversion/libsvn_diff/diff_file.c  (revision 1934976)
+++ subversion/libsvn_diff/diff_file.c  (working copy)
@@ -748,7 +748,7 @@
   char *curp;
   char *eol;
   apr_off_t last_chunk;
-  apr_off_t length;
+  apr_size_t length;
   apr_uint32_t h = 0;
   /* Did the last chunk end in a CR character? */
   svn_boolean_t had_cr = FALSE;
@@ -980,6 +980,8 @@
         {
           if (length[i] == 0)
             {
+              apr_size_t read_length;
+
               /* Error if raw_length is 0, that's an unexpected change
                * of the file that can happen when ignoring whitespace
                * and that can lead to an infinite loop. */
@@ -992,20 +994,21 @@
 
               /* Read a chunk from disk into a buffer */
               bufp[i] = buffer[i];
-              length[i] = raw_length[i] > COMPARE_CHUNK_SIZE ?
+              read_length = raw_length[i] > COMPARE_CHUNK_SIZE ?
                 COMPARE_CHUNK_SIZE : raw_length[i];
-
               SVN_ERR(read_chunk(file[i]->file,
-                                 bufp[i], length[i], offset[i],
+                                 bufp[i], read_length, offset[i],
                                  file_baton->pool));
-              offset[i] += length[i];
-              raw_length[i] -= length[i];
+              length[i] = read_length;
+              offset[i] += read_length;
+              raw_length[i] -= read_length;
               /* bufp[i] gets reset to buffer[i] before reading each chunk,
                  so, overwriting it isn't a problem */
-              svn_diff__normalize_buffer(&bufp[i], &length[i], &state[i],
+              svn_diff__normalize_buffer(&bufp[i], &read_length, &state[i],
                                          bufp[i], file_baton->options);
 
               /* assert(length[i] == file_token[i]->length); */
+              length[i] = read_length;
             }
         }
 
Index: subversion/libsvn_diff/diff_memory.c
===================================================================
--- subversion/libsvn_diff/diff_memory.c        (revision 1934976)
+++ subversion/libsvn_diff/diff_memory.c        (working copy)
@@ -132,7 +132,7 @@
       char *buf = mem_baton->normalization_buf[0];
       svn_string_t *tok = (*token)
         = APR_ARRAY_IDX(src->tokens, src->next_token, svn_string_t *);
-      apr_off_t len = tok->len;
+      apr_size_t len = tok->len;
       svn_diff__normalize_state_t state
         = svn_diff__normalize_state_normal;
 
@@ -158,8 +158,8 @@
   svn_string_t *t2 = token2;
   char *buf1 = btn->normalization_buf[0];
   char *buf2 = btn->normalization_buf[1];
-  apr_off_t len1 = t1->len;
-  apr_off_t len2 = t2->len;
+  apr_size_t len1 = t1->len;
+  apr_size_t len2 = t2->len;
   svn_diff__normalize_state_t state = svn_diff__normalize_state_normal;
 
   svn_diff__normalize_buffer(&buf1, &len1, &state, t1->data,
Index: subversion/libsvn_diff/util.c
===================================================================
--- subversion/libsvn_diff/util.c       (revision 1934976)
+++ subversion/libsvn_diff/util.c       (working copy)
@@ -145,7 +145,7 @@
 
 void
 svn_diff__normalize_buffer(char **tgt,
-                           apr_off_t *lengthp,
+                           apr_size_t *lengthp,
                            svn_diff__normalize_state_t *statep,
                            const char *buf,
                            const svn_diff_file_options_t *opts)
Index: subversion/libsvn_subr/adler32.c
===================================================================
--- subversion/libsvn_subr/adler32.c    (revision 1934976)
+++ subversion/libsvn_subr/adler32.c    (working copy)
@@ -70,7 +70,7 @@
  * of DATA sized LEN.
  */
 SVN__ADLER32_STATIC apr_uint32_t
-svn__adler32(apr_uint32_t checksum, const char *data, apr_off_t len)
+svn__adler32(apr_uint32_t checksum, const char *data, apr_size_t len)
 {
   /* Process large amounts of data in max-sized chunks.
    *

Reply via email to