You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/12/10 22:23:13 UTC

svn commit: r1044516 [9/22] - in /subversion/branches/ignore-mergeinfo: ./ build/ac-macros/ build/generator/ contrib/server-side/ notes/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subver...

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_diff/parse-diff.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_diff/parse-diff.c Fri Dec 10 21:23:03 2010
@@ -21,7 +21,6 @@
  * ====================================================================
  */
 
-#include <limits.h>  /* for ULONG_MAX */
 #include <stdlib.h>
 #include <string.h>
 
@@ -29,6 +28,7 @@
 #include "svn_error.h"
 #include "svn_io.h"
 #include "svn_pools.h"
+#include "svn_string.h"
 #include "svn_utf.h"
 #include "svn_dirent_uri.h"
 #include "svn_diff.h"
@@ -39,14 +39,14 @@
 #define starts_with(str, start)  \
   (strncmp((str), (start), strlen(start)) == 0)
 
-struct svn_hunk_t {
+struct svn_diff_hunk_t {
   /* Hunk texts (see include/svn_diff.h). */
   svn_stream_t *diff_text;
   svn_stream_t *original_text;
   svn_stream_t *modified_text;
 
-  /* Whether the hunk is being interpreted in reverse. */
-  svn_boolean_t reverse;
+  /* The patch this hunk belongs to. */
+  svn_patch_t *patch;
 
   /* Hunk ranges as they appeared in the patch file.
    * All numbers are lines, not bytes. */
@@ -61,55 +61,61 @@ struct svn_hunk_t {
 };
 
 svn_error_t *
-svn_diff_hunk_reset_diff_text(const svn_hunk_t *hunk)
+svn_diff_hunk_reset_diff_text(const svn_diff_hunk_t *hunk)
 {
   return svn_error_return(svn_stream_reset(hunk->diff_text));
 }
 
 svn_error_t *
-svn_diff_hunk_reset_original_text(const svn_hunk_t *hunk)
+svn_diff_hunk_reset_original_text(const svn_diff_hunk_t *hunk)
 {
-  return svn_error_return(svn_stream_reset(hunk->original_text));
+  if (hunk->patch->reverse)
+    return svn_error_return(svn_stream_reset(hunk->modified_text));
+  else
+    return svn_error_return(svn_stream_reset(hunk->original_text));
 }
 
 svn_error_t *
-svn_diff_hunk_reset_modified_text(const svn_hunk_t *hunk)
+svn_diff_hunk_reset_modified_text(const svn_diff_hunk_t *hunk)
 {
-  return svn_error_return(svn_stream_reset(hunk->modified_text));
+  if (hunk->patch->reverse)
+    return svn_error_return(svn_stream_reset(hunk->original_text));
+  else
+    return svn_error_return(svn_stream_reset(hunk->modified_text));
 }
 
 svn_linenum_t
-svn_diff_hunk_get_original_start(const svn_hunk_t *hunk)
+svn_diff_hunk_get_original_start(const svn_diff_hunk_t *hunk)
 {
-  return hunk->original_start;
+  return hunk->patch->reverse ? hunk->modified_start : hunk->original_start;
 }
 
 svn_linenum_t
-svn_diff_hunk_get_original_length(const svn_hunk_t *hunk)
+svn_diff_hunk_get_original_length(const svn_diff_hunk_t *hunk)
 {
-  return hunk->original_length;
+  return hunk->patch->reverse ? hunk->modified_length : hunk->original_length;
 }
 
 svn_linenum_t
-svn_diff_hunk_get_modified_start(const svn_hunk_t *hunk)
+svn_diff_hunk_get_modified_start(const svn_diff_hunk_t *hunk)
 {
-  return hunk->modified_start;
+  return hunk->patch->reverse ? hunk->original_start : hunk->modified_start;
 }
 
 svn_linenum_t
-svn_diff_hunk_get_modified_length(const svn_hunk_t *hunk)
+svn_diff_hunk_get_modified_length(const svn_diff_hunk_t *hunk)
 {
-  return hunk->modified_length;
+  return hunk->patch->reverse ? hunk->original_length : hunk->modified_length;
 }
 
 svn_linenum_t
-svn_diff_hunk_get_leading_context(const svn_hunk_t *hunk)
+svn_diff_hunk_get_leading_context(const svn_diff_hunk_t *hunk)
 {
   return hunk->leading_context;
 }
 
 svn_linenum_t
-svn_diff_hunk_get_trailing_context(const svn_hunk_t *hunk)
+svn_diff_hunk_get_trailing_context(const svn_diff_hunk_t *hunk)
 {
   return hunk->trailing_context;
 }
@@ -120,20 +126,18 @@ svn_diff_hunk_get_trailing_context(const
 static svn_boolean_t
 parse_offset(svn_linenum_t *offset, const char *number)
 {
-  apr_int64_t parsed_offset;
+  svn_error_t *err;
+  apr_uint64_t val;
 
-  errno = 0; /* apr_atoi64() in APR-0.9 does not always set errno */
-  parsed_offset = apr_atoi64(number);
-  if (errno == ERANGE || parsed_offset < 0)
-    return FALSE;
+  err = svn_cstring_strtoui64(&val, number, 0, SVN_LINENUM_MAX_VALUE, 10);
+  if (err)
+    {
+      svn_error_clear(err);
+      return FALSE;
+    }
 
-  /* In case we cannot fit 64 bits into an svn_linenum_t,
-   * check for overflow. */
-  if (sizeof(svn_linenum_t) < sizeof(parsed_offset) &&
-      parsed_offset > SVN_LINENUM_MAX_VALUE)
-    return FALSE;
+  *offset = (svn_linenum_t)val;
 
-  *offset = parsed_offset;
   return TRUE;
 }
 
@@ -179,11 +183,10 @@ parse_range(svn_linenum_t *start, svn_li
 /* Try to parse a hunk header in string HEADER, putting parsed information
  * into HUNK. Return TRUE if the header parsed correctly. ATAT is the
  * character string used to delimit the hunk header.
- * If REVERSE is TRUE, invert the hunk header while parsing it.
  * Do all allocations in POOL. */
 static svn_boolean_t
-parse_hunk_header(const char *header, svn_hunk_t *hunk,
-                  const char *atat, svn_boolean_t reverse, apr_pool_t *pool)
+parse_hunk_header(const char *header, svn_diff_hunk_t *hunk,
+                  const char *atat, apr_pool_t *pool)
 {
   const char *p;
   svn_stringbuf_t *range;
@@ -201,7 +204,7 @@ parse_hunk_header(const char *header, sv
   p++;
   while (*p && *p != ' ')
     {
-      svn_stringbuf_appendbytes(range, p, 1);
+      svn_stringbuf_appendbyte(range, *p);
       p++;
     }
   if (*p != ' ')
@@ -209,16 +212,8 @@ parse_hunk_header(const char *header, sv
     return FALSE;
 
   /* Try to parse the first range. */
-  if (reverse)
-    {
-      if (! parse_range(&hunk->modified_start, &hunk->modified_length, range->data))
-        return FALSE;
-    }
-  else
-    {
-      if (! parse_range(&hunk->original_start, &hunk->original_length, range->data))
-        return FALSE;
-    }
+  if (! parse_range(&hunk->original_start, &hunk->original_length, range->data))
+    return FALSE;
 
   /* Clear the stringbuf so we can reuse it for the second range. */
   svn_stringbuf_setempty(range);
@@ -230,7 +225,7 @@ parse_hunk_header(const char *header, sv
   p++;
   while (*p && *p != ' ')
     {
-      svn_stringbuf_appendbytes(range, p, 1);
+      svn_stringbuf_appendbyte(range, *p);
       p++;
     }
   if (*p != ' ')
@@ -246,16 +241,8 @@ parse_hunk_header(const char *header, sv
    * but we ignore that. */
 
   /* Try to parse the second range. */
-  if (reverse)
-    {
-      if (! parse_range(&hunk->original_start, &hunk->original_length, range->data))
-        return FALSE;
-    }
-  else
-    {
-      if (! parse_range(&hunk->modified_start, &hunk->modified_length, range->data))
-        return FALSE;
-    }
+  if (! parse_range(&hunk->modified_start, &hunk->modified_length, range->data))
+    return FALSE;
 
   /* Hunk header is good. */
   return TRUE;
@@ -374,7 +361,7 @@ hunk_readline(svn_stream_t *stream,
           else
             match = eol_str;
 
-          svn_stringbuf_appendbytes(str, &c, 1);
+          svn_stringbuf_appendbyte(str, c);
         }
 
       svn_stringbuf_chop(str, match - eol_str);
@@ -407,48 +394,54 @@ hunk_readline(svn_stream_t *stream,
 }
 
 svn_error_t *
-svn_diff_hunk_readline_original_text(const svn_hunk_t *hunk,
+svn_diff_hunk_readline_original_text(const svn_diff_hunk_t *hunk,
                                      svn_stringbuf_t **stringbuf,
                                      const char **eol,
                                      svn_boolean_t *eof,
                                      apr_pool_t *result_pool,
                                      apr_pool_t *scratch_pool)
 {
-  return svn_error_return(hunk_readline(hunk->original_text, stringbuf,
-                                        eol, eof, hunk->reverse ? '-' : '+',
+  return svn_error_return(hunk_readline(hunk->patch->reverse ?
+                                          hunk->modified_text :
+                                          hunk->original_text,
+                                        stringbuf, eol, eof,
+                                        hunk->patch->reverse ? '-' : '+',
                                         result_pool, scratch_pool));
 }
 
 svn_error_t *
-svn_diff_hunk_readline_modified_text(const svn_hunk_t *hunk,
+svn_diff_hunk_readline_modified_text(const svn_diff_hunk_t *hunk,
                                      svn_stringbuf_t **stringbuf,
                                      const char **eol,
                                      svn_boolean_t *eof,
                                      apr_pool_t *result_pool,
                                      apr_pool_t *scratch_pool)
 {
-  return svn_error_return(hunk_readline(hunk->modified_text, stringbuf,
-                                        eol, eof, hunk->reverse ? '+' : '-',
+  return svn_error_return(hunk_readline(hunk->patch->reverse ?
+                                          hunk->original_text :
+                                          hunk->modified_text,
+                                        stringbuf, eol, eof,
+                                        hunk->patch->reverse ? '+' : '-',
                                         result_pool, scratch_pool));
 }
 
 svn_error_t *
-svn_diff_hunk_readline_diff_text(const svn_hunk_t *hunk,
+svn_diff_hunk_readline_diff_text(const svn_diff_hunk_t *hunk,
                                  svn_stringbuf_t **stringbuf,
                                  const char **eol,
                                  svn_boolean_t *eof,
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
 {
-  svn_hunk_t dummy;
+  svn_diff_hunk_t dummy;
   svn_stringbuf_t *line;
 
   SVN_ERR(svn_stream_readline_detect_eol(hunk->diff_text, &line, eol, eof,
                                          result_pool));
   
-  if (hunk->reverse)
+  if (hunk->patch->reverse)
     {
-      if (parse_hunk_header(line->data, &dummy, "@@", FALSE, scratch_pool))
+      if (parse_hunk_header(line->data, &dummy, "@@", scratch_pool))
         {
           /* Line is a hunk header, reverse it. */
           *stringbuf = svn_stringbuf_createf(result_pool,
@@ -458,7 +451,7 @@ svn_diff_hunk_readline_diff_text(const s
                                              hunk->original_start,
                                              hunk->original_length);
         }
-      else if (parse_hunk_header(line->data, &dummy, "##", FALSE, scratch_pool))
+      else if (parse_hunk_header(line->data, &dummy, "##", scratch_pool))
         {
           /* Line is a hunk header, reverse it. */
           *stringbuf = svn_stringbuf_createf(result_pool,
@@ -489,6 +482,8 @@ static svn_error_t *
 parse_prop_name(const char **prop_name, const char *header, 
                 const char *indicator, apr_pool_t *result_pool)
 {
+  /* ### This can fail if the filename cannot be represented in the current
+   * ### locale's encoding. */
   SVN_ERR(svn_utf_cstring_to_utf8(prop_name,
                                   header + strlen(indicator),
                                   result_pool));
@@ -504,18 +499,16 @@ parse_prop_name(const char **prop_name, 
  * IS_PROPERTY to TRUE if we have a property hunk. If the returned HUNK is
  * the first belonging to a certain property, then PROP_NAME and
  * PROP_OPERATION will be set too. If we have a text hunk, PROP_NAME will be
- * NULL. If REVERSE is TRUE, invert the hunk while parsing it. If
- * IGNORE_WHiTESPACES is TRUE, let lines without leading spaces be
+ * NULL. If IGNORE_WHITESPACE is TRUE, let lines without leading spaces be
  * recognized as context lines.  Allocate results in
  * RESULT_POOL.  Use SCRATCH_POOL for all other allocations. */
 static svn_error_t *
-parse_next_hunk(svn_hunk_t **hunk,
+parse_next_hunk(svn_diff_hunk_t **hunk,
                 svn_boolean_t *is_property,
                 const char **prop_name,
                 svn_diff_operation_kind_t *prop_operation,
                 svn_patch_t *patch,
                 svn_stream_t *stream,
-                svn_boolean_t reverse,
                 svn_boolean_t ignore_whitespace,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
@@ -588,19 +581,8 @@ parse_next_hunk(svn_hunk_t **hunk,
       if (in_hunk)
         {
           char c;
-          char add;
-          char del;
-
-          if (reverse)
-            {
-              add = '-';
-              del = '+';
-            }
-          else
-            {
-              add = '+';
-              del = '-';
-            }
+          static const char add = '+';
+          static const char del = '-';
 
           if (! hunk_seen)
             {
@@ -661,11 +643,14 @@ parse_next_hunk(svn_hunk_t **hunk,
         }
       else
         {
+          /* ### Add an is_hunk_header() helper function that returns
+           * ### the proper atat string? Then we could collapse the
+           * ### following two if-clauses. */
           if (starts_with(line->data, text_atat))
             {
               /* Looks like we have a hunk header, try to rip it apart. */
               in_hunk = parse_hunk_header(line->data, *hunk, text_atat,
-                                          reverse, iterpool);
+                                          iterpool);
               if (in_hunk)
                 {
                   original_lines = (*hunk)->original_length;
@@ -678,7 +663,7 @@ parse_next_hunk(svn_hunk_t **hunk,
               /* Looks like we have a property hunk header, try to rip it
                * apart. */
               in_hunk = parse_hunk_header(line->data, *hunk, prop_atat,
-                                          reverse, iterpool);
+                                          iterpool);
               if (in_hunk)
                 {
                   original_lines = (*hunk)->original_length;
@@ -705,7 +690,7 @@ parse_next_hunk(svn_hunk_t **hunk,
               *prop_operation = svn_diff_op_modified;
             }
           else if (starts_with(line->data, minus)
-                   || starts_with(line->data, "git --diff "))
+                   || starts_with(line->data, "diff --git "))
             /* This could be a header of another patch. Bail out. */
             break;
         }
@@ -749,7 +734,7 @@ parse_next_hunk(svn_hunk_t **hunk,
                                                              result_pool);
 
       (*hunk)->diff_text = diff_text;
-      (*hunk)->reverse = reverse;
+      (*hunk)->patch = patch;
       (*hunk)->original_text = original_text;
       (*hunk)->modified_text = modified_text;
       (*hunk)->leading_context = leading_context;
@@ -767,8 +752,8 @@ parse_next_hunk(svn_hunk_t **hunk,
 static int
 compare_hunks(const void *a, const void *b)
 {
-  const svn_hunk_t *ha = *((const svn_hunk_t **)a);
-  const svn_hunk_t *hb = *((const svn_hunk_t **)b);
+  const svn_diff_hunk_t *ha = *((const svn_diff_hunk_t *const *)a);
+  const svn_diff_hunk_t *hb = *((const svn_diff_hunk_t *const *)b);
 
   if (ha->original_start < hb->original_start)
     return -1;
@@ -781,7 +766,7 @@ compare_hunks(const void *a, const void 
  * Ensure that all streams which were opened for HUNK are closed.
  */
 static svn_error_t *
-close_hunk(const svn_hunk_t *hunk)
+close_hunk(const svn_diff_hunk_t *hunk)
 {
   SVN_ERR(svn_stream_close(hunk->original_text));
   SVN_ERR(svn_stream_close(hunk->modified_text));
@@ -789,27 +774,30 @@ close_hunk(const svn_hunk_t *hunk)
   return SVN_NO_ERROR;
 }
 
+/* Possible states of the diff header parser. */
 enum parse_state
 {
-   state_start,
-   state_git_diff_seen,
-  /* if we have an add || del || cp src+dst || mv src+dst */
-   state_git_tree_seen, 
-   state_git_minus_seen,
-   state_git_plus_seen,
-   state_move_from_seen,
-   state_copy_from_seen,
-   state_minus_seen,
-   state_unidiff_found,
-   state_add_seen,
-   state_del_seen,
-   state_git_header_found
+   state_start,           /* initial */
+   state_git_diff_seen,   /* diff --git */
+   state_git_tree_seen,   /* a tree operation, rather then content change */
+   state_git_minus_seen,  /* --- /dev/null; or --- a/ */
+   state_git_plus_seen,   /* +++ /dev/null; or +++ a/ */
+   state_move_from_seen,  /* rename from foo.c */
+   state_copy_from_seen,  /* copy from foo.c */
+   state_minus_seen,      /* --- foo.c */
+   state_unidiff_found,   /* valid start of a regular unidiff header */
+   state_add_seen,        /* ### unused? */
+   state_del_seen,        /* ### unused? */
+   state_git_header_found /* valid start of a --git diff header */
 };
 
+/* Data type describing a valid state transition of the parser. */
 struct transition
 {
   const char *expected_input;
   enum parse_state required_state;
+
+  /* A callback called upon each parser state transition. */
   svn_error_t *(*fn)(enum parse_state *new_state, const char *input, 
                      svn_patch_t *patch, apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool);
@@ -826,6 +814,8 @@ grab_filename(const char **file_name, co
   /* Grab the filename and encode it in UTF-8. */
   /* TODO: Allow specifying the patch file's encoding.
    *       For now, we assume its encoding is native. */
+  /* ### This can fail if the filename cannot be represented in the current
+   * ### locale's encoding. */
   SVN_ERR(svn_utf_cstring_to_utf8(&utf8_path,
                                   line,
                                   scratch_pool));
@@ -896,7 +886,8 @@ git_start(enum parse_state *new_state, c
    * such substitution then the whole pathname is put in double quotes.
    */
 
-  /* Our line should look like this: 'git --diff a/path b/path'. 
+  /* Our line should look like this: 'diff --git a/path b/path'. 
+   *
    * If we find any deviations from that format, we return with state reset
    * to start.
    */
@@ -931,9 +922,9 @@ git_start(enum parse_state *new_state, c
   /* By now, we know that we have a line on the form '--git diff a/.+ b/.+'
    * We only need the filenames when we have deleted or added empty
    * files. In those cases the old_path and new_path is identical on the
-   * '--git diff' line.  For all other cases we fetch the filenames from
+   * 'diff --git' line.  For all other cases we fetch the filenames from
    * other header lines. */ 
-  old_path_start = line + strlen("--git diff a/");
+  old_path_start = line + strlen("diff --git a/");
   new_path_end = line + strlen(line);
   new_path_start = old_path_start;
 
@@ -1011,7 +1002,7 @@ git_plus(enum parse_state *new_state, co
    * the rest of the line which we can discard. */
   char *tab = strchr(line, '\t');
   if (tab)
-    *tab = '\0';
+    *tab = '\0'; /* ### indirectly modifying LINE, which is const */
 
   if (starts_with(line, "+++ /dev/null"))
     SVN_ERR(grab_filename(&patch->new_filename, "/dev/null",
@@ -1024,7 +1015,7 @@ git_plus(enum parse_state *new_state, co
   return SVN_NO_ERROR;
 }
 
-/* Parse the 'move from ' line of a git extended unidiff. */
+/* Parse the 'rename from ' line of a git extended unidiff. */
 static svn_error_t *
 git_move_from(enum parse_state *new_state, const char *line, svn_patch_t *patch,
               apr_pool_t *result_pool, apr_pool_t *scratch_pool)
@@ -1036,7 +1027,7 @@ git_move_from(enum parse_state *new_stat
   return SVN_NO_ERROR;
 }
 
-/* Parse the 'move to ' line fo a git extended unidiff. */
+/* Parse the 'rename to ' line fo a git extended unidiff. */
 static svn_error_t *
 git_move_to(enum parse_state *new_state, const char *line, svn_patch_t *patch,
             apr_pool_t *result_pool, apr_pool_t *scratch_pool)
@@ -1083,6 +1074,8 @@ git_new_file(enum parse_state *new_state
 {
   patch->operation = svn_diff_op_added;
 
+  /* Filename already retrieved from diff --git header. */
+
   *new_state = state_git_tree_seen;
   return SVN_NO_ERROR;
 }
@@ -1094,6 +1087,8 @@ git_deleted_file(enum parse_state *new_s
 {
   patch->operation = svn_diff_op_deleted;
 
+  /* Filename already retrieved from diff --git header. */
+
   *new_state = state_git_tree_seen;
   return SVN_NO_ERROR;
 }
@@ -1101,7 +1096,7 @@ git_deleted_file(enum parse_state *new_s
 /* Add a HUNK associated with the property PROP_NAME to PATCH. */
 static svn_error_t *
 add_property_hunk(svn_patch_t *patch, const char *prop_name, 
-                  svn_hunk_t *hunk, svn_diff_operation_kind_t operation,
+                  svn_diff_hunk_t *hunk, svn_diff_operation_kind_t operation,
                   apr_pool_t *result_pool)
 {
   svn_prop_patch_t *prop_patch;
@@ -1114,13 +1109,14 @@ add_property_hunk(svn_patch_t *patch, co
       prop_patch = apr_palloc(result_pool, sizeof(svn_prop_patch_t));
       prop_patch->name = prop_name;
       prop_patch->operation = operation;
-      prop_patch->hunks = apr_array_make(result_pool, 1, sizeof(svn_hunk_t *));
+      prop_patch->hunks = apr_array_make(result_pool, 1,
+                                         sizeof(svn_diff_hunk_t *));
 
       apr_hash_set(patch->prop_patches, prop_name, APR_HASH_KEY_STRING,
                    prop_patch);
     }
 
-  APR_ARRAY_PUSH(prop_patch->hunks, svn_hunk_t *) = hunk;
+  APR_ARRAY_PUSH(prop_patch->hunks, svn_diff_hunk_t *) = hunk;
 
   return SVN_NO_ERROR;
 }
@@ -1149,7 +1145,7 @@ svn_diff_parse_next_patch(svn_patch_t **
     {
       {"--- ",          state_start,            diff_minus},
       {"+++ ",          state_minus_seen,       diff_plus},
-      {"git --diff",    state_start,            git_start},
+      {"diff --git",    state_start,            git_start},
       {"--- a/",        state_git_diff_seen,    git_minus},
       {"--- a/",        state_git_tree_seen,    git_minus},
       {"--- /dev/null", state_git_tree_seen,    git_minus},
@@ -1244,6 +1240,7 @@ svn_diff_parse_next_patch(svn_patch_t **
 
     } while (! eof);
 
+  (*patch)->reverse = reverse;
   if (reverse)
     {
       const char *temp;
@@ -1259,21 +1256,22 @@ svn_diff_parse_next_patch(svn_patch_t **
     }
   else
     {
-      svn_hunk_t *hunk;
+      svn_diff_hunk_t *hunk;
       svn_boolean_t is_property;
       const char *last_prop_name;
       const char *prop_name;
       svn_diff_operation_kind_t prop_operation;
 
       /* Parse hunks. */
-      (*patch)->hunks = apr_array_make(result_pool, 10, sizeof(svn_hunk_t *));
+      (*patch)->hunks = apr_array_make(result_pool, 10,
+                                       sizeof(svn_diff_hunk_t *));
       (*patch)->prop_patches = apr_hash_make(result_pool);
       do
         {
           svn_pool_clear(iterpool);
 
           SVN_ERR(parse_next_hunk(&hunk, &is_property, &prop_name,
-                                  &prop_operation, *patch, stream, reverse,
+                                  &prop_operation, *patch, stream,
                                   ignore_whitespace,
                                   result_pool, iterpool));
 
@@ -1288,7 +1286,7 @@ svn_diff_parse_next_patch(svn_patch_t **
             }
           else if (hunk)
             {
-              APR_ARRAY_PUSH((*patch)->hunks, svn_hunk_t *) = hunk;
+              APR_ARRAY_PUSH((*patch)->hunks, svn_diff_hunk_t *) = hunk;
               last_prop_name = NULL;
             }
 
@@ -1313,15 +1311,34 @@ svn_diff_parse_next_patch(svn_patch_t **
 }
 
 svn_error_t *
-svn_diff_close_patch(const svn_patch_t *patch)
+svn_diff_close_patch(const svn_patch_t *patch, apr_pool_t *scratch_pool)
 {
   int i;
+  apr_hash_index_t *hi;
 
   for (i = 0; i < patch->hunks->nelts; i++)
     {
-      const svn_hunk_t *hunk = APR_ARRAY_IDX(patch->hunks, i, svn_hunk_t *);
+      const svn_diff_hunk_t *hunk = APR_ARRAY_IDX(patch->hunks, i,
+                                                  svn_diff_hunk_t *);
       SVN_ERR(close_hunk(hunk));
     }
 
+  for (hi = apr_hash_first(scratch_pool, patch->prop_patches);
+       hi;
+       hi = apr_hash_next(hi))
+    {
+          svn_prop_patch_t *prop_patch; 
+
+          prop_patch = svn__apr_hash_index_val(hi);
+
+          for (i = 0; i < prop_patch->hunks->nelts; i++)
+            {
+              const svn_diff_hunk_t *hunk;
+              
+              hunk = APR_ARRAY_IDX(prop_patch->hunks, i, svn_diff_hunk_t *);
+              SVN_ERR(close_hunk(hunk));
+            }
+    } 
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs/access.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs/access.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs/access.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs/access.c Fri Dec 10 21:23:03 2010
@@ -87,7 +87,7 @@ svn_fs_access_add_lock_token2(svn_fs_acc
                               const char *token)
 {
   apr_hash_set(access_ctx->lock_tokens,
-               token, APR_HASH_KEY_STRING, (void *) path);
+               token, APR_HASH_KEY_STRING, path);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/fs-history
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/fs-history?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/fs-history (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/fs-history Fri Dec 10 21:23:03 2010
@@ -63,7 +63,7 @@ under-the-hood is as follows:
    1. The root refers to a particular snapshot of the DAG node tree,
       and from this we can learn the node-revision ID of the node
       which represents the root directory ("/") as it appears in that
-      snaphot.  Given this node-revision ID, it's all DAG from here.
+      snapshot.  Given this node-revision ID, it's all DAG from here.
 
    2. The path is split into components and traversed, beginning with
       the root node, and walking down toward the full path.  Each

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/structure
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/structure?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/structure (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/structure Fri Dec 10 21:23:03 2010
@@ -141,7 +141,7 @@ Note that a node cannot change its kind 
 A directory node is always a directory; a file node is always a file;
 etc.  The fact that the node's kind is stored in each node revision,
 rather than in some revision-independent place, might suggest that
-it's possible for a node change kinds from revision to revision, but
+it's possible for a node to change kinds from revision to revision, but
 Subversion does not allow this.
 
 PROP-KEY is a key into the `representations' table (see REPRESENTATIONS 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/revs-txns.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/revs-txns.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/revs-txns.c Fri Dec 10 21:23:03 2010
@@ -270,7 +270,7 @@ svn_fs_base__set_rev_prop(svn_fs_t *fs,
               && !svn_string_compare(wanted_value, present_value)))
         {
           /* What we expected isn't what we found. */
-          return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+          return svn_error_createf(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL,
                                    _("revprop '%s' has unexpected value in "
                                      "filesystem"),
                                    name);

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/util/fs_skels.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/util/fs_skels.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/util/fs_skels.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/util/fs_skels.c Fri Dec 10 21:23:03 2010
@@ -31,6 +31,7 @@
 #include "svn_time.h"
 
 #include "private/svn_skel.h"
+#include "private/svn_dep_compat.h"
 
 #include "svn_checksum.h"
 #include "fs_skels.h"
@@ -550,32 +551,38 @@ svn_fs_base__parse_representation_skel(r
         {
           svn_skel_t *window_skel = chunk_skel->children->next;
           svn_skel_t *diff_skel = window_skel->children;
+          apr_int64_t val;
+          apr_uint64_t uval;
+          const char *str;
 
           /* Allocate a chunk and its window */
           chunk = apr_palloc(pool, sizeof(*chunk));
 
           /* Populate the window */
-          chunk->version
-            = (apr_byte_t)atoi(apr_pstrmemdup
-                               (pool,
-                                diff_skel->children->next->data,
-                                diff_skel->children->next->len));
+          str = apr_pstrmemdup(pool, diff_skel->children->next->data,
+                               diff_skel->children->next->len);
+          SVN_ERR(svn_cstring_strtoui64(&uval, str, 0, 255, 10));
+          chunk->version = (apr_byte_t)uval;
+
           chunk->string_key
             = apr_pstrmemdup(pool,
                              diff_skel->children->next->next->data,
                              diff_skel->children->next->next->len);
-          chunk->size
-            = atoi(apr_pstrmemdup(pool,
-                                  window_skel->children->next->data,
-                                  window_skel->children->next->len));
+
+          str = apr_pstrmemdup(pool, window_skel->children->next->data,
+                               window_skel->children->next->len);
+          SVN_ERR(svn_cstring_strtoui64(&uval, str, 0, APR_SIZE_MAX, 10));
+          chunk->size = (apr_size_t)uval;
+
           chunk->rep_key
             = apr_pstrmemdup(pool,
                              window_skel->children->next->next->data,
                              window_skel->children->next->next->len);
-          chunk->offset =
-            svn__atoui64(apr_pstrmemdup(pool,
-                                        chunk_skel->children->data,
-                                        chunk_skel->children->len));
+
+          str = apr_pstrmemdup(pool, chunk_skel->children->data,
+                               chunk_skel->children->len);
+          SVN_ERR(svn_cstring_strtoi64(&val, str, 0, APR_INT64_MAX, 10));
+          chunk->offset = (svn_filesize_t)val;
 
           /* Add this chunk to the array. */
           APR_ARRAY_PUSH(chunks, rep_delta_chunk_t *) = chunk;
@@ -633,24 +640,28 @@ svn_fs_base__parse_node_revision_skel(no
       noderev->predecessor_count = -1;
       if (cur_skel->next)
         {
+          const char *str;
+
           cur_skel = cur_skel->next;
           if (cur_skel->len)
-            noderev->predecessor_count = atoi(apr_pstrmemdup(pool,
-                                                             cur_skel->data,
-                                                             cur_skel->len));
+            {
+              str = apr_pstrmemdup(pool, cur_skel->data, cur_skel->len);
+              SVN_ERR(svn_cstring_atoi(&noderev->predecessor_count, str));
+            }
 
           /* HAS-MERGEINFO and MERGEINFO-COUNT */
           if (cur_skel->next)
             {
+              int val;
+
               cur_skel = cur_skel->next;
-              noderev->has_mergeinfo = atoi(apr_pstrmemdup(pool,
-                                                           cur_skel->data,
-                                                           cur_skel->len))
-                                         != 0;
-              noderev->mergeinfo_count =
-                apr_atoi64(apr_pstrmemdup(pool,
-                                          cur_skel->next->data,
-                                          cur_skel->next->len));
+              str = apr_pstrmemdup(pool, cur_skel->data, cur_skel->len);
+              SVN_ERR(svn_cstring_atoi(&val, str));
+              noderev->has_mergeinfo = (val != 0);
+
+              str = apr_pstrmemdup(pool, cur_skel->next->data,
+                                   cur_skel->next->len);
+              SVN_ERR(svn_cstring_atoi64(&noderev->mergeinfo_count, str));
             }
         }
     }

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c Fri Dec 10 21:23:03 2010
@@ -44,9 +44,11 @@
 #include "svn_hash.h"
 #include "svn_props.h"
 #include "svn_sorts.h"
+#include "svn_string.h"
 #include "svn_time.h"
 #include "svn_mergeinfo.h"
 #include "svn_config.h"
+#include "svn_ctype.h"
 
 #include "fs.h"
 #include "err.h"
@@ -150,6 +152,9 @@ read_min_unpacked_rev(svn_revnum_t *min_
 static svn_error_t *
 update_min_unpacked_rev(svn_fs_t *fs, apr_pool_t *pool);
 
+static svn_error_t *
+update_min_unpacked_revprop(svn_fs_t *fs, apr_pool_t *pool);
+
 /* Pathname helper functions */
 
 /* Return TRUE is REV is packed in FS, FALSE otherwise. */
@@ -567,7 +572,8 @@ get_lock_on_filesystem(const char *lock_
    BATON and that subpool, destroy the subpool (releasing the write
    lock) and return what BODY returned. */
 static svn_error_t *
-with_some_lock(svn_error_t *(*body)(void *baton,
+with_some_lock(svn_fs_t *fs,
+               svn_error_t *(*body)(void *baton,
                                     apr_pool_t *pool),
                void *baton,
                const char *lock_filename,
@@ -594,7 +600,14 @@ with_some_lock(svn_error_t *(*body)(void
   err = get_lock_on_filesystem(lock_filename, subpool);
 
   if (!err)
-    err = body(baton, subpool);
+    {
+      fs_fs_data_t *ffd = fs->fsap_data;
+      if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
+        SVN_ERR(update_min_unpacked_rev(fs, pool));
+      if (ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
+        SVN_ERR(update_min_unpacked_revprop(fs, pool));
+      err = body(baton, subpool);
+    }
 
   svn_pool_destroy(subpool);
 
@@ -622,7 +635,7 @@ svn_fs_fs__with_write_lock(svn_fs_t *fs,
   apr_thread_mutex_t *mutex = ffsd->fs_write_lock;
 #endif
 
-  return with_some_lock(body, baton,
+  return with_some_lock(fs, body, baton,
                         path_lock(fs, pool),
 #if SVN_FS_FS__USE_LOCK_MUTEX
                         mutex,
@@ -645,7 +658,7 @@ with_txn_current_lock(svn_fs_t *fs,
   apr_thread_mutex_t *mutex = ffsd->txn_current_lock;
 #endif
 
-  return with_some_lock(body, baton,
+  return with_some_lock(fs, body, baton,
                         path_txn_current_lock(fs, pool),
 #if SVN_FS_FS__USE_LOCK_MUTEX
                         mutex,
@@ -894,21 +907,21 @@ get_file_offset(apr_off_t *offset_p, apr
 }
 
 
-/* Check that BUF, a buffer of text from format file PATH, contains
-   only digits, raising error SVN_ERR_BAD_VERSION_FILE_FORMAT if not.
+/* Check that BUF, a nul-terminated buffer of text from format file PATH,
+   contains only digits at OFFSET and beyond, raising an error if not.
 
    Uses POOL for temporary allocation. */
 static svn_error_t *
-check_format_file_buffer_numeric(const char *buf, const char *path,
-                                 apr_pool_t *pool)
+check_format_file_buffer_numeric(const char *buf, apr_off_t offset,
+                                 const char *path, apr_pool_t *pool)
 {
   const char *p;
 
-  for (p = buf; *p; p++)
-    if (!apr_isdigit(*p))
+  for (p = buf + offset; *p; p++)
+    if (!svn_ctype_isdigit(*p))
       return svn_error_createf(SVN_ERR_BAD_VERSION_FILE_FORMAT, NULL,
-        _("Format file '%s' contains an unexpected non-digit"),
-        svn_dirent_local_style(path, pool));
+        _("Format file '%s' contains unexpected non-digit '%c' within '%s'"),
+        svn_dirent_local_style(path, pool), *p, buf);
 
   return SVN_NO_ERROR;
 }
@@ -962,8 +975,8 @@ read_format(int *pformat, int *max_files
   SVN_ERR(err);
 
   /* Check that the first line contains only digits. */
-  SVN_ERR(check_format_file_buffer_numeric(buf, path, pool));
-  *pformat = atoi(buf);
+  SVN_ERR(check_format_file_buffer_numeric(buf, 0, path, pool));
+  SVN_ERR(svn_cstring_atoi(pformat, buf));
 
   /* Set the default values for anything that can be set via an option. */
   *max_files_per_dir = 0;
@@ -993,8 +1006,8 @@ read_format(int *pformat, int *max_files
           if (strncmp(buf+7, "sharded ", 8) == 0)
             {
               /* Check that the argument is numeric. */
-              SVN_ERR(check_format_file_buffer_numeric(buf+15, path, pool));
-              *max_files_per_dir = atoi(buf+15);
+              SVN_ERR(check_format_file_buffer_numeric(buf, 15, path, pool));
+              SVN_ERR(svn_cstring_atoi(max_files_per_dir, buf + 15));
               continue;
             }
         }
@@ -1933,18 +1946,20 @@ get_packed_offset(apr_off_t *rev_offset,
     {
       svn_stringbuf_t *sb;
       svn_boolean_t eof;
+      apr_int64_t val;
+      svn_error_t *err;
 
       svn_pool_clear(iterpool);
       SVN_ERR(svn_stream_readline(manifest_stream, &sb, "\n", &eof, iterpool));
       if (eof)
         break;
 
-      errno = 0; /* apr_atoi64() in APR-0.9 does not always set errno */
-      APR_ARRAY_PUSH(manifest, apr_off_t) =
-                apr_atoi64(svn_string_create_from_buf(sb, iterpool)->data);
-      if (errno == ERANGE)
-        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                                "Manifest offset too large");
+      err = svn_cstring_atoi64(&val, sb->data);
+      if (err)
+        return svn_error_return(
+                 svn_error_create(SVN_ERR_FS_CORRUPT, err,
+                                  _("Manifest offset too large")));
+      APR_ARRAY_PUSH(manifest, apr_off_t) = (apr_off_t)val;
     }
   svn_pool_destroy(iterpool);
 
@@ -2045,6 +2060,7 @@ read_rep_offsets(representation_t **rep_
 {
   representation_t *rep;
   char *str, *last_str;
+  apr_int64_t val;
 
   rep = apr_pcalloc(pool, sizeof(*rep));
   *rep_p = rep;
@@ -2068,21 +2084,24 @@ read_rep_offsets(representation_t **rep_
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text representation offset line in node-rev"));
 
-  rep->offset = apr_atoi64(str);
+  SVN_ERR(svn_cstring_atoi64(&val, str));
+  rep->offset = (apr_off_t)val;
 
   str = apr_strtok(NULL, " ", &last_str);
   if (str == NULL)
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text representation offset line in node-rev"));
 
-  rep->size = apr_atoi64(str);
+  SVN_ERR(svn_cstring_atoi64(&val, str));
+  rep->size = (svn_filesize_t)val;
 
   str = apr_strtok(NULL, " ", &last_str);
   if (str == NULL)
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text representation offset line in node-rev"));
 
-  rep->expanded_size = apr_atoi64(str);
+  SVN_ERR(svn_cstring_atoi64(&val, str));
+  rep->expanded_size = (svn_filesize_t)val;
 
   /* Read in the MD5 hash. */
   str = apr_strtok(NULL, " ", &last_str);
@@ -2198,7 +2217,10 @@ svn_fs_fs__read_noderev(node_revision_t 
 
   /* Read the 'count' field. */
   value = apr_hash_get(headers, HEADER_COUNT, APR_HASH_KEY_STRING);
-  noderev->predecessor_count = (value == NULL) ? 0 : atoi(value);
+  if (value)
+    SVN_ERR(svn_cstring_atoi(&noderev->predecessor_count, value));
+  else
+    noderev->predecessor_count = 0;
 
   /* Get the properties location. */
   value = apr_hash_get(headers, HEADER_PROPS, APR_HASH_KEY_STRING);
@@ -2289,7 +2311,10 @@ svn_fs_fs__read_noderev(node_revision_t 
 
   /* Get the mergeinfo count. */
   value = apr_hash_get(headers, HEADER_MINFO_CNT, APR_HASH_KEY_STRING);
-  noderev->mergeinfo_count = (value == NULL) ? 0 : apr_atoi64(value);
+  if (value)
+    SVN_ERR(svn_cstring_atoi64(&noderev->mergeinfo_count, value));
+  else
+    noderev->mergeinfo_count = 0;
 
   /* Get whether *this* node has mergeinfo. */
   value = apr_hash_get(headers, HEADER_MINFO_HERE, APR_HASH_KEY_STRING);
@@ -2476,6 +2501,7 @@ read_rep_line(struct rep_args **rep_args
   apr_size_t limit;
   struct rep_args *rep_args;
   char *str, *last_str;
+  apr_int64_t val;
 
   limit = sizeof(buffer);
   SVN_ERR(svn_io_read_length_line(file, buffer, &limit, pool));
@@ -2503,24 +2529,30 @@ read_rep_line(struct rep_args **rep_args
 
   /* We have hopefully a DELTA vs. a non-empty base revision. */
   str = apr_strtok(buffer, " ", &last_str);
-  if (! str || (strcmp(str, REP_DELTA) != 0)) goto err;
+  if (! str || (strcmp(str, REP_DELTA) != 0))
+    goto error;
 
   str = apr_strtok(NULL, " ", &last_str);
-  if (! str) goto err;
+  if (! str)
+    goto error;
   rep_args->base_revision = SVN_STR_TO_REV(str);
 
   str = apr_strtok(NULL, " ", &last_str);
-  if (! str) goto err;
-  rep_args->base_offset = (apr_off_t) apr_atoi64(str);
+  if (! str)
+    goto error;
+  SVN_ERR(svn_cstring_atoi64(&val, str));
+  rep_args->base_offset = (apr_off_t)val;
 
   str = apr_strtok(NULL, " ", &last_str);
-  if (! str) goto err;
-  rep_args->base_length = (apr_size_t) apr_atoi64(str);
+  if (! str)
+    goto error;
+  SVN_ERR(svn_cstring_atoi64(&val, str));
+  rep_args->base_length = (apr_size_t)val;
 
   *rep_args_p = rep_args;
   return SVN_NO_ERROR;
 
- err:
+ error:
   return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                           _("Malformed representation header"));
 }
@@ -2583,6 +2615,7 @@ get_root_changes_offset(apr_off_t *root_
   apr_off_t rev_offset;
   char buf[64];
   int i, num_bytes;
+  const char *str;
   apr_size_t len;
   apr_seek_where_t seek_relative;
 
@@ -2637,7 +2670,8 @@ get_root_changes_offset(apr_off_t *root_
   /* Look for the next previous newline. */
   for (i = num_bytes - 2; i >= 0; i--)
     {
-      if (buf[i] == '\n') break;
+      if (buf[i] == '\n')
+        break;
     }
 
   if (i < 0)
@@ -2648,24 +2682,42 @@ get_root_changes_offset(apr_off_t *root_
     }
 
   i++;
-
-  if (root_offset)
-    *root_offset = rev_offset + apr_atoi64(&buf[i]);
+  str = &buf[i];
 
   /* find the next space */
   for ( ; i < (num_bytes - 2) ; i++)
-    if (buf[i] == ' ') break;
+    if (buf[i] == ' ')
+      break;
 
   if (i == (num_bytes - 2))
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Final line in revision file missing space"));
 
+  if (root_offset)
+    {
+      apr_int64_t val;
+
+      buf[i] = '\0';
+      SVN_ERR(svn_cstring_atoi64(&val, str));
+      *root_offset = rev_offset + (apr_off_t)val;
+    }
+
   i++;
+  str = &buf[i];
+
+  /* find the next newline */
+  for ( ; i < num_bytes; i++)
+    if (buf[i] == '\n')
+      break;
 
-  /* note that apr_atoi64() will stop reading as soon as it encounters
-     the final newline. */
   if (changes_offset)
-    *changes_offset = rev_offset + apr_atoi64(&buf[i]);
+    {
+      apr_int64_t val;
+
+      buf[i] = '\0';
+      SVN_ERR(svn_cstring_atoi64(&val, str));
+      *changes_offset = rev_offset + (apr_off_t)val;
+    }
 
   return SVN_NO_ERROR;
 }
@@ -4676,12 +4728,12 @@ get_txn_proplist(apr_hash_t *proplist,
 {
   svn_stream_t *stream;
 
-  /* The following error has been observed at least twice in real life when
-   * WANdisco software sends a DAV 'MERGE' command to a Subversion server:
-   * "Can't open file '[...]/db/transactions/props': No such file or directory"
-   * The path should be '[...]/db/transactions/<txn-id>/props'.
-   * The only way that could happen is if txn_id was NULL here. */
-  SVN_ERR_ASSERT(txn_id != NULL);
+  /* Check for issue #3696. (When we find and fix the cause, we can change
+   * this to an assertion.) */
+  if (txn_id == NULL)
+    return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+                            _("Internal error: a null transaction id was "
+                              "passed to get_txn_proplist()"));
 
   /* Open the transaction properties file. */
   SVN_ERR(svn_stream_open_readonly(&stream, path_txn_props(fs, txn_id, pool),
@@ -7260,7 +7312,7 @@ change_rev_prop_body(void *baton, apr_po
               && !svn_string_compare(wanted_value, present_value)))
         {
           /* What we expected isn't what we found. */
-          return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+          return svn_error_createf(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL,
                                    _("revprop '%s' has unexpected value in "
                                      "filesystem"),
                                    cb->name);

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/id.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/id.c Fri Dec 10 21:23:03 2010
@@ -275,6 +275,9 @@ svn_fs_fs__id_parse(const char *data,
 
   if (str[0] == 'r')
     {
+      apr_int64_t val;
+      svn_error_t *err;
+
       /* This is a revision type ID */
       pvt->txn_id = NULL;
 
@@ -286,7 +289,13 @@ svn_fs_fs__id_parse(const char *data,
       str = apr_strtok(NULL, "/", &last_str);
       if (str == NULL)
         return NULL;
-      pvt->offset = apr_atoi64(str);
+      err = svn_cstring_atoi64(&val, str);
+      if (err)
+        {
+          svn_error_clear(err);
+          return NULL;
+        }
+      pvt->offset = (apr_off_t)val;
     }
   else if (str[0] == 't')
     {

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c Fri Dec 10 21:23:03 2010
@@ -192,7 +192,7 @@ write_digest_file(apr_hash_t *children,
           svn_stringbuf_appendbytes(children_list,
                                     svn__apr_hash_index_key(hi),
                                     svn__apr_hash_index_klen(hi));
-          svn_stringbuf_appendbytes(children_list, "\n", 1);
+          svn_stringbuf_appendbyte(children_list, '\n');
         }
       hash_store(hash, CHILDREN_KEY, sizeof(CHILDREN_KEY)-1,
                  children_list->data, children_list->len, pool);

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure Fri Dec 10 21:23:03 2010
@@ -102,10 +102,8 @@ When representation sharing is enabled, 
 representation checksum and location mappings using a SQLite database in
 "rep-cache.db".  The database has a single table, which stores the sha1
 hash text as the primary key, mapped to the representation revision, offset,
-size and expanded size.  A final field, reuse count, is currently used
-for distinguishing representations which are shared.  This file is not
-required, and may be removed at an abritrary time, with the subsequent
-loss of rep-sharing capabilities.
+size and expanded size.  This file is not required, and may be removed at an
+abritrary time, with the subsequent loss of rep-sharing capabilities.
 
 Filesystem formats
 ------------------

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c Fri Dec 10 21:23:03 2010
@@ -641,6 +641,28 @@ svn_error_t *svn_ra_rev_prop(svn_ra_sess
   return session->vtable->rev_prop(session, rev, name, value, pool);
 }
 
+struct ccw_baton
+{
+  svn_commit_callback2_t original_callback;
+  void *original_baton;
+
+  svn_ra_session_t *session;
+};
+
+/* Wrapper which populates the repos_root field of the commit_info struct */
+static svn_error_t *
+commit_callback_wrapper(const svn_commit_info_t *commit_info,
+                        void *baton,
+                        apr_pool_t *pool)
+{
+  struct ccw_baton *ccwb = baton;
+  svn_commit_info_t *ci = svn_commit_info_dup(commit_info, pool);
+  
+  SVN_ERR(svn_ra_get_repos_root2(ccwb->session, &ci->repos_root, pool));
+
+  return ccwb->original_callback(ci, ccwb->original_baton, pool);
+}
+
 svn_error_t *svn_ra_get_commit_editor3(svn_ra_session_t *session,
                                        const svn_delta_editor_t **editor,
                                        void **edit_baton,
@@ -651,10 +673,21 @@ svn_error_t *svn_ra_get_commit_editor3(s
                                        svn_boolean_t keep_locks,
                                        apr_pool_t *pool)
 {
+  /* Allocate this in a pool, since the callback will be called long after
+     this function as returned. */
+  struct ccw_baton *ccwb = apr_palloc(pool, sizeof(*ccwb));
+
+  ccwb->original_callback = callback;
+  ccwb->original_baton = callback_baton;
+  ccwb->session = session;
+
   return session->vtable->get_commit_editor(session, editor, edit_baton,
-                                            revprop_table, callback,
-                                            callback_baton, lock_tokens,
-                                            keep_locks, pool);
+                                            revprop_table,
+                                            callback
+                                                ? commit_callback_wrapper
+                                                : NULL,
+                                            callback ? ccwb : NULL,
+                                            lock_tokens, keep_locks, pool);
 }
 
 svn_error_t *svn_ra_get_file(svn_ra_session_t *session,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c Fri Dec 10 21:23:03 2010
@@ -115,12 +115,12 @@ get_username(svn_ra_session_t *session,
   if (*sess->username)
     {
       SVN_ERR(svn_fs_create_access(&access_ctx, sess->username,
-                                   pool));
+                                   session->pool));
       SVN_ERR(svn_fs_set_access(sess->fs, access_ctx));
 
       /* Make sure this context is disassociated when the pool gets
          destroyed. */
-      apr_pool_cleanup_register(pool, sess->fs, cleanup_access,
+      apr_pool_cleanup_register(session->pool, sess->fs, cleanup_access,
                                 apr_pool_cleanup_null);
     }
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/lock.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/lock.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/lock.c Fri Dec 10 21:23:03 2010
@@ -32,6 +32,7 @@
 #include "svn_ra.h"
 #include "../libsvn_ra/ra_loader.h"
 #include "svn_path.h"
+#include "svn_string.h"
 #include "svn_time.h"
 #include "svn_private_config.h"
 
@@ -209,8 +210,9 @@ lock_from_baton(svn_lock_t **lock,
         {
           if (strncmp("Second-", timeout_str, strlen("Second-")) == 0)
             {
-              int time_offset = atoi(&(timeout_str[7]));
-
+              int time_offset;
+              
+              SVN_ERR(svn_cstring_atoi(&time_offset, &(timeout_str[7])));
               lck->expiration_date = lck->creation_date
                 + apr_time_from_sec(time_offset);
             }

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/options.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/options.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/options.c Fri Dec 10 21:23:03 2010
@@ -144,6 +144,8 @@ parse_capabilities(ne_request *req,
   *youngest_rev = SVN_INVALID_REVNUM;
 
   /* Start out assuming all capabilities are unsupported. */
+  apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,
+               APR_HASH_KEY_STRING, capability_no);
   apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_DEPTH,
                APR_HASH_KEY_STRING, capability_no);
   apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_MERGEINFO,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h Fri Dec 10 21:23:03 2010
@@ -57,6 +57,7 @@ extern "C" {
 #define SVN_RA_NEON__XML_CDATA   (1<<1)
 #define SVN_RA_NEON__XML_COLLECT ((1<<2) | SVN_RA_NEON__XML_CDATA)
 
+/* ### Related to anonymous enum below? */
 typedef int svn_ra_neon__xml_elmid;
 
 /** XML element */
@@ -674,7 +675,8 @@ typedef svn_error_t * (*svn_ra_neon__end
  * Register a pool cleanup on the pool of REQ to clean up any allocated
  * Neon resources.
  *
- * ACCPT indicates whether the parser wants read the response body
+ * Return the new parser.  Also attach it to REQ if ACCPT is non-null.
+ * ACCPT indicates whether the parser wants to read the response body
  * or not.  Pass NULL for ACCPT when you don't want the returned parser
  * to be attached to REQ.
  */
@@ -739,6 +741,7 @@ svn_ra_neon__check_parse_error(const cha
                                ne_xml_parser *xml_parser,
                                const char *url);
 
+/* ### Related to svn_ra_neon__xml_elmid? */
 /* ### add SVN_RA_NEON_ to these to prefix conflicts with (sys) headers? */
 enum {
   /* Redefine Neon elements */

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/util.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/util.c Fri Dec 10 21:23:03 2010
@@ -82,6 +82,7 @@ xml_parser_create(svn_ra_neon__request_t
  * for our custom error parser - could use the ne_basic.h interfaces.
  */
 
+/* List of XML elements expected in 207 Multi-Status responses. */
 static const svn_ra_neon__xml_elm_t multistatus_elements[] =
   { { "DAV:", "multistatus", ELEM_multistatus, 0 },
     { "DAV:", "response", ELEM_response, 0 },
@@ -99,6 +100,21 @@ static const svn_ra_neon__xml_elm_t mult
   };
 
 
+/* Sparse matrix listing the permitted child elements of each element.
+
+   The permitted direct children of the element named in the first column are
+   the elements named in the remainder of the row.
+
+   There may be any number of rows, and any number of columns in each row; any
+   non-positive value (such as SVN_RA_NEON__XML_INVALID) serves as a sentinel.
+
+   The last element in a row is returned if the head-of-row element is found
+   with a child that's not listed in the remainder of the row.  The singleton
+   element of the last (sentinel) row is returned if a tag-with-children is
+   found that isn't the head of any row.
+
+   See validate_element().
+ */
 static const int multistatus_nesting_table[][5] =
   { { ELEM_root, ELEM_multistatus, SVN_RA_NEON__XML_INVALID },
     { ELEM_multistatus, ELEM_response, ELEM_responsedescription,
@@ -115,6 +131,11 @@ static const int multistatus_nesting_tab
   };
 
 
+/* PARENT and CHILD are enum values of ELEM_* type.
+   Return a positive integer if CHILD is a valid direct child of PARENT, and
+   a negative integer (SVN_RA_NEON__XML_INVALID or SVN_RA_NEON__XML_DECLINE,
+   at the moment) otherwise.
+ */
 static int
 validate_element(int parent, int child)
 {
@@ -148,6 +169,7 @@ typedef struct
   svn_boolean_t contains_error;
 } multistatus_baton_t;
 
+/* Implements svn_ra_neon__startelm_cb_t. */
 static svn_error_t *
 start_207_element(int *elem, void *baton, int parent,
                   const char *nspace, const char *name, const char **atts)
@@ -193,6 +215,7 @@ start_207_element(int *elem, void *baton
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_ra_neon__endelm_cb_t . */
 static svn_error_t *
 end_207_element(void *baton, int state,
                 const char *nspace, const char *name)
@@ -269,23 +292,24 @@ end_207_element(void *baton, int state,
 }
 
 
-static ne_xml_parser *
+/* Create a status parser attached to the request REQ.  Detected errors
+   will be returned there. */
+static void
 multistatus_parser_create(svn_ra_neon__request_t *req)
 {
   multistatus_baton_t *b = apr_pcalloc(req->pool, sizeof(*b));
-  ne_xml_parser *multistatus_parser =
-    svn_ra_neon__xml_parser_create(req, ne_accept_207,
-                                   start_207_element,
-                                   svn_ra_neon__xml_collect_cdata,
-                                   end_207_element, b);
+
+  /* Create a parser, attached to REQ. (Ignore the return value.) */
+  svn_ra_neon__xml_parser_create(req, ne_accept_207,
+                                 start_207_element,
+                                 svn_ra_neon__xml_collect_cdata,
+                                 end_207_element, b);
   b->cdata = svn_stringbuf_create("", req->pool);
   b->description = svn_stringbuf_create("", req->pool);
   b->req = req;
 
   b->propname = svn_stringbuf_create("", req->pool);
   b->propstat_description = svn_stringbuf_create("", req->pool);
-
-  return multistatus_parser;
 }
 
 
@@ -403,6 +427,10 @@ compressed_body_reader_cleanup(void *bat
   return APR_SUCCESS;
 }
 
+/* Attach READER as a response reader for the request REQ, with the
+ * acceptance function ACCPT.  The response body data will be decompressed,
+ * if compressed, before being passed to READER.  USERDATA will be passed as
+ * the first argument to the acceptance and reader callbacks. */
 static void
 attach_ne_body_reader(svn_ra_neon__request_t *req,
                       ne_accept_response accpt,
@@ -747,7 +775,18 @@ start_err_element(void *baton, int paren
                                  atts);
 
         if (errcode_str && *err)
-          (*err)->apr_err = atoi(errcode_str);
+          {
+            apr_int64_t val;
+            svn_error_t *err2;
+
+            err2 = svn_cstring_atoi64(&val, errcode_str);
+            if (err2)
+              {
+                svn_error_clear(err2);
+                break;
+              }
+            (*err)->apr_err = (apr_status_t)val;
+          }
 
         break;
       }
@@ -1341,9 +1380,7 @@ svn_ra_neon__simple_request(int *code,
 
   SVN_ERR(svn_ra_neon__request_create(&req, ras, method, url, pool));
 
-  /* we don't need the status parser: it's attached to the request
-     and detected errors will be returned there... */
-  (void) multistatus_parser_create(req);
+  multistatus_parser_create(req);
 
   /* svn_ra_neon__request_dispatch() adds the custom error response
      reader.  Neon will take care of the Content-Length calculation */

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/commit.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/commit.c Fri Dec 10 21:23:03 2010
@@ -1061,6 +1061,18 @@ svndiff_stream_write(void *file_baton,
 
 /* POST against 'me' resource handlers. */
 
+/* Implements svn_ra_serf__request_body_delegate_t */
+static svn_error_t *
+create_txn_post_body(serf_bucket_t **body_bkt,
+                     void *baton,
+                     serf_bucket_alloc_t *alloc,
+                     apr_pool_t *pool)
+{
+  *body_bkt = SERF_BUCKET_SIMPLE_STRING("( create-txn )", alloc);
+  return SVN_NO_ERROR;
+}
+
+
 /* Handler baton for POST request. */
 typedef struct
 {
@@ -1140,6 +1152,9 @@ open_root(void *edit_baton,
       /* Create our activity URL now on the server. */
       handler = apr_pcalloc(ctx->pool, sizeof(*handler));
       handler->method = "POST";
+      handler->body_type = SVN_SKEL_MIME_TYPE;
+      handler->body_delegate = create_txn_post_body;
+      handler->body_delegate_baton = NULL;
       handler->path = ctx->session->me_resource;
       handler->conn = ctx->session->conns[0];
       handler->session = ctx->session;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/options.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/options.c Fri Dec 10 21:23:03 2010
@@ -396,6 +396,8 @@ options_response_handler(serf_request_t 
   serf_bucket_t *hdrs = serf_bucket_response_get_headers(response);
 
   /* Start out assuming all capabilities are unsupported. */
+  apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,
+               APR_HASH_KEY_STRING, capability_no);
   apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_DEPTH,
                APR_HASH_KEY_STRING, capability_no);
   apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_MERGEINFO,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c Fri Dec 10 21:23:03 2010
@@ -162,6 +162,16 @@ svn_ra_serf__get_ver_prop(apr_hash_t *pr
   return NULL;
 }
 
+const svn_string_t *
+svn_ra_serf__get_prop_string(apr_hash_t *props,
+                             const char *path,
+                             const char *ns,
+                             const char *name)
+{
+  return svn_ra_serf__get_ver_prop_string(props, path, SVN_INVALID_REVNUM,
+                                          ns, name);
+}
+
 const char *
 svn_ra_serf__get_prop(apr_hash_t *props,
                       const char *path,
@@ -788,7 +798,7 @@ svn_ra_serf__walk_all_props(apr_hash_t *
   return SVN_NO_ERROR;
 }
 
-void
+svn_error_t *
 svn_ra_serf__walk_all_paths(apr_hash_t *props,
                             svn_revnum_t rev,
                             svn_ra_serf__path_rev_walker_t walker,
@@ -802,7 +812,7 @@ svn_ra_serf__walk_all_paths(apr_hash_t *
 
   if (!ver_props)
     {
-      return;
+      return SVN_NO_ERROR;
     }
 
   for (path_hi = apr_hash_first(pool, ver_props); path_hi;
@@ -831,11 +841,13 @@ svn_ra_serf__walk_all_paths(apr_hash_t *
 
               apr_hash_this(name_hi, &prop_name, &prop_len, &prop_val);
               /* use a subpool? */
-              walker(baton, path_name, path_len, ns_name, ns_len,
-                     prop_name, prop_len, prop_val, pool);
+              SVN_ERR(walker(baton, path_name, path_len, ns_name, ns_len,
+                             prop_name, prop_len, prop_val, pool));
             }
         }
     }
+
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h Fri Dec 10 21:23:03 2010
@@ -994,7 +994,7 @@ typedef svn_error_t *
                                   const char *name, apr_ssize_t name_len,
                                   const svn_string_t *val,
                                   apr_pool_t *pool);
-void
+svn_error_t *
 svn_ra_serf__walk_all_paths(apr_hash_t *props,
                             svn_revnum_t rev,
                             svn_ra_serf__path_rev_walker_t walker,
@@ -1033,12 +1033,21 @@ const svn_string_t *
 svn_ra_serf__get_ver_prop_string(apr_hash_t *props,
                                  const char *path, svn_revnum_t rev,
                                  const char *ns, const char *name);
+
+/* Wraps svn_ra_serf__get_ver_prop_string(). */
 const char *
 svn_ra_serf__get_ver_prop(apr_hash_t *props,
                           const char *path, svn_revnum_t rev,
                           const char *ns, const char *name);
 
-/* Same as get_prop, but for the unknown revision */
+/* Same as get_ver_prop_string, but for the unknown revision */
+const svn_string_t *
+svn_ra_serf__get_prop_string(apr_hash_t *props,
+                             const char *path,
+                             const char *ns,
+                             const char *name);
+
+/* Same as get_ver_prop, but for the unknown revision */
 const char *
 svn_ra_serf__get_prop(apr_hash_t *props,
                       const char *path,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c Fri Dec 10 21:23:03 2010
@@ -90,7 +90,7 @@ typedef struct {
   replay_info_t *parent;
 } prop_info_t;
 
-typedef struct {
+typedef struct replay_context_t {
   apr_pool_t *src_rev_pool;
   apr_pool_t *dst_rev_pool;
 
@@ -118,6 +118,10 @@ typedef struct {
   /* Cached report target url */
   const char *report_target;
 
+  /* Target and revision to fetch revision properties on */
+  const char *revprop_target;
+  svn_revnum_t revprop_rev;
+
   /* Revision properties for this revision. */
   apr_hash_t *revs_props;
   apr_hash_t *props;
@@ -125,6 +129,9 @@ typedef struct {
   /* Keep a reference to the XML parser ctx to report any errors. */
   svn_ra_serf__xml_parser_t *parser_ctx;
 
+  /* The propfind for the revision properties of the current revision */
+  svn_ra_serf__propfind_context_t *prop_ctx;
+
 } replay_context_t;
 
 
@@ -180,11 +187,15 @@ start_replay(svn_ra_serf__xml_parser_t *
     {
       push_state(parser, ctx, REPORT);
 
+      /* Before we can continue, we need the revision properties. */
+      SVN_ERR_ASSERT(!ctx->prop_ctx
+                     || svn_ra_serf__propfind_is_done(ctx->prop_ctx));
+
       /* Create a pool for the commit editor. */
       ctx->dst_rev_pool = svn_pool_create(ctx->src_rev_pool);
       ctx->props = apr_hash_make(ctx->dst_rev_pool);
-      SVN_ERR(svn_ra_serf__walk_all_props(ctx->revs_props, ctx->report_target,
-                                          ctx->revision,
+      SVN_ERR(svn_ra_serf__walk_all_props(ctx->revs_props, ctx->revprop_target,
+                                          ctx->revprop_rev,
                                           svn_ra_serf__set_bare_props,
                                           ctx->props, ctx->dst_rev_pool));
       if (ctx->revstart_func)
@@ -751,13 +762,30 @@ svn_ra_serf__replay_range(svn_ra_session
           /* Request all properties of a certain revision. */
           replay_ctx->report_target = report_target;
           replay_ctx->revs_props = apr_hash_make(replay_ctx->src_rev_pool);
+
+          if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
+           {
+             replay_ctx->revprop_target = apr_psprintf(pool, "%s/%ld",
+                                                       session->rev_stub, rev);
+             replay_ctx->revprop_rev = SVN_INVALID_REVNUM;
+            }
+          else
+            {
+              replay_ctx->revprop_target = report_target;
+              replay_ctx->revprop_rev = rev;
+            }
+
           SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx,
                                              replay_ctx->revs_props, session,
-                                             session->conns[0], report_target,
-                                             rev,  "0", all_props,
+                                             session->conns[0],
+                                             replay_ctx->revprop_target,
+                                             replay_ctx->revprop_rev,
+                                             "0", all_props,
                                              TRUE, NULL,
                                              replay_ctx->src_rev_pool));
 
+          replay_ctx->prop_ctx = prop_ctx;
+
           /* Send the replay report request. */
           handler = apr_pcalloc(replay_ctx->src_rev_pool, sizeof(*handler));
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c Fri Dec 10 21:23:03 2010
@@ -721,7 +721,7 @@ dirent_walker(void *baton,
         }
       else if (strcmp(name, "getcontentlength") == 0)
         {
-          entry->size = apr_atoi64(val->data);
+          SVN_ERR(svn_cstring_atoi64(&entry->size, val->data));
         }
       else if (strcmp(name, "resourcetype") == 0)
         {
@@ -907,8 +907,8 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
       dirent_walk.base_paths = apr_hash_make(pool);
       dirent_walk.orig_path = svn_uri_canonicalize(path, pool);
 
-      svn_ra_serf__walk_all_paths(props, revision, path_dirent_walker,
-                                  &dirent_walk, pool);
+      SVN_ERR(svn_ra_serf__walk_all_paths(props, revision, path_dirent_walker,
+                                          &dirent_walk, pool));
 
       *dirents = dirent_walk.base_paths;
     }

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c Fri Dec 10 21:23:03 2010
@@ -36,6 +36,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_private_config.h"
+#include "svn_string.h"
 #include "svn_xml.h"
 #include "private/svn_dep_compat.h"
 
@@ -736,7 +737,10 @@ start_error(svn_ra_serf__xml_parser_t *p
       err_code = svn_xml_get_attr_value("errcode", attrs);
       if (err_code)
         {
-          ctx->error->apr_err = apr_atoi64(err_code);
+          apr_int64_t val;
+          
+          SVN_ERR(svn_cstring_atoi64(&val, err_code));
+          ctx->error->apr_err = (apr_status_t)val;
         }
       else
         {
@@ -1049,7 +1053,7 @@ svn_ra_serf__handle_multistatus_only(ser
           server_err->parser.cdata = cdata_207;
           server_err->parser.done = &ctx->done;
           server_err->parser.ignore_errors = TRUE;
-    }
+        }
       else
         {
           ctx->done = TRUE;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/editorp.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/editorp.c Fri Dec 10 21:23:03 2010
@@ -904,7 +904,9 @@ svn_error_t *svn_ra_svn_drive_editor2(sv
               svn_error_clear(editor->abort_edit(edit_baton, subpool));
               svn_ra_svn__set_block_handler(conn, blocked_write, &state);
             }
-          write_err = svn_ra_svn_write_cmd_failure(conn, subpool, err->child);
+          write_err = svn_ra_svn_write_cmd_failure(
+                          conn, subpool,
+                          svn_ra_svn__locate_real_error_child(err));
           if (!write_err)
             write_err = svn_ra_svn_flush(conn, subpool);
           svn_ra_svn__set_block_handler(conn, NULL, NULL);

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/marshal.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/marshal.c Fri Dec 10 21:23:03 2010
@@ -38,6 +38,7 @@
 #include "svn_pools.h"
 #include "svn_ra_svn.h"
 #include "svn_private_config.h"
+#include "svn_ctype.h"
 
 #include "ra_svn.h"
 
@@ -593,7 +594,7 @@ static svn_error_t *read_item(svn_ra_svn
   /* Determine the item type and read it in.  Make sure that c is the
    * first character at the end of the item so we can test to make
    * sure it's whitespace. */
-  if (apr_isdigit(c))
+  if (svn_ctype_isdigit(c))
     {
       /* It's a number or a string.  Read the number part, either way. */
       val = c - '0';
@@ -601,7 +602,7 @@ static svn_error_t *read_item(svn_ra_svn
         {
           prev_val = val;
           SVN_ERR(readbuf_getchar(conn, pool, &c));
-          if (!apr_isdigit(c))
+          if (!svn_ctype_isdigit(c))
             break;
           val = val * 10 + (c - '0');
           if ((val / 10) != prev_val) /* val wrapped past maximum value */
@@ -621,16 +622,16 @@ static svn_error_t *read_item(svn_ra_svn
           item->u.number = val;
         }
     }
-  else if (apr_isalpha(c))
+  else if (svn_ctype_isalpha(c))
     {
       /* It's a word. */
       str = svn_stringbuf_ncreate(&c, 1, pool);
       while (1)
         {
           SVN_ERR(readbuf_getchar(conn, pool, &c));
-          if (!apr_isalnum(c) && c != '-')
+          if (!svn_ctype_isalnum(c) && c != '-')
             break;
-          svn_stringbuf_appendbytes(str, &c, 1);
+          svn_stringbuf_appendbyte(str, c);
         }
       item->kind = SVN_RA_SVN_WORD;
       item->u.word = str->data;
@@ -831,6 +832,21 @@ svn_error_t *svn_ra_svn_parse_proplist(c
 
 /* --- READING AND WRITING COMMANDS AND RESPONSES --- */
 
+svn_error_t *svn_ra_svn__locate_real_error_child(svn_error_t *err)
+{
+  svn_error_t *this_link;
+
+  SVN_ERR_ASSERT(err);
+
+  for (this_link = err;
+       this_link && (this_link->apr_err == SVN_ERR_RA_SVN_CMD_ERR);
+       this_link = this_link->child)
+    ;
+
+  SVN_ERR_ASSERT(this_link);
+  return this_link;
+}
+
 svn_error_t *svn_ra_svn__handle_failure_status(const apr_array_header_t *params,
                                                apr_pool_t *pool)
 {
@@ -859,12 +875,27 @@ svn_error_t *svn_ra_svn__handle_failure_
          easily change that, so "" means a nonexistent message. */
       if (!*message)
         message = NULL;
-      err = svn_error_create((apr_status_t)apr_err, err, message);
-      err->file = apr_pstrdup(err->pool, file);
-      err->line = (long)line;
+      
+      /* Skip over links in the error chain that were intended only to
+         exist on the server (to wrap real errors intended for the
+         client) but accidentally got included in the server's actual
+         response. */
+      if ((apr_status_t)apr_err != SVN_ERR_RA_SVN_CMD_ERR)
+        {
+          err = svn_error_create((apr_status_t)apr_err, err, message);
+          err->file = apr_pstrdup(err->pool, file);
+          err->line = (long)line;
+        }
     }
 
   svn_pool_destroy(subpool);
+
+  /* If we get here, then we failed to find a real error in the error
+     chain that the server proported to be sending us.  That's bad. */
+  if (! err)
+    err = svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+                           _("Malformed error list"));
+    
   return err;
 }
 
@@ -940,7 +971,9 @@ svn_error_t *svn_ra_svn_handle_commands2
 
       if (err && err->apr_err == SVN_ERR_RA_SVN_CMD_ERR)
         {
-          write_err = svn_ra_svn_write_cmd_failure(conn, iterpool, err->child);
+          write_err = svn_ra_svn_write_cmd_failure(
+                          conn, iterpool,
+                          svn_ra_svn__locate_real_error_child(err));
           svn_error_clear(err);
           if (write_err)
             return write_err;

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/ra_svn.h?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/ra_svn.h Fri Dec 10 21:23:03 2010
@@ -122,6 +122,11 @@ svn_error_t *svn_ra_svn__cram_client(svn
                                      const char *user, const char *password,
                                      const char **message);
 
+/* Return a pointer to the error chain child of ERR which contains the
+ * first "real" error message, not merely one of the
+ * SVN_ERR_RA_SVN_CMD_ERR wrapper errors. */
+svn_error_t *svn_ra_svn__locate_real_error_child(svn_error_t *err);
+
 /* Return an error chain based on @a params (which contains a
  * command response indicating failure).  The error chain will be
  * in the same order as the errors indicated in @a params.  Use

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c Fri Dec 10 21:23:03 2010
@@ -42,6 +42,7 @@
 /*----------------------------------------------------------------------*/
 
 
+
 /* Compute the delta between OLDROOT/OLDPATH and NEWROOT/NEWPATH and
    store it into a new temporary file *TEMPFILE.  OLDROOT may be NULL,
    in which case the delta will be computed against an empty file, as

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c Fri Dec 10 21:23:03 2010
@@ -34,9 +34,11 @@
 #include "svn_mergeinfo.h"
 #include "svn_checksum.h"
 #include "svn_subst.h"
+#include "svn_ctype.h"
 
 #include <apr_lib.h>
 
+#include "private/svn_dep_compat.h"
 #include "private/svn_mergeinfo_private.h"
 
 /*----------------------------------------------------------------------*/
@@ -449,9 +451,11 @@ parse_property_block(svn_stream_t *strea
       else if ((buf[0] == 'K') && (buf[1] == ' '))
         {
           char *keybuf;
+          apr_uint64_t len;
 
+          SVN_ERR(svn_cstring_strtoui64(&len, buf + 2, 0, APR_SIZE_MAX, 10));
           SVN_ERR(read_key_or_val(&keybuf, actual_length,
-                                  stream, atoi(buf + 2), proppool));
+                                  stream, (apr_size_t)len, proppool));
 
           /* Read a val length line */
           SVN_ERR(svn_stream_readline(stream, &strbuf, "\n", &eof, proppool));
@@ -465,8 +469,10 @@ parse_property_block(svn_stream_t *strea
             {
               svn_string_t propstring;
               char *valbuf;
+              apr_int64_t val;
 
-              propstring.len = atoi(buf + 2);
+              SVN_ERR(svn_cstring_atoi64(&val, buf + 2));
+              propstring.len = (apr_size_t)val;
               SVN_ERR(read_key_or_val(&valbuf, actual_length,
                                       stream, propstring.len, proppool));
               propstring.data = valbuf;
@@ -523,9 +529,11 @@ parse_property_block(svn_stream_t *strea
       else if ((buf[0] == 'D') && (buf[1] == ' '))
         {
           char *keybuf;
+          apr_uint64_t len;
 
+          SVN_ERR(svn_cstring_strtoui64(&len, buf + 2, 0, APR_SIZE_MAX, 10));
           SVN_ERR(read_key_or_val(&keybuf, actual_length,
-                                  stream, atoi(buf + 2), proppool));
+                                  stream, (apr_size_t)len, proppool));
 
           /* We don't expect these in revision properties, and if we see
              one when we don't have a delete_node_property callback,
@@ -642,7 +650,7 @@ parse_format_version(const char *version
     return svn_error_create(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
                             _("Malformed dumpfile header"));
 
-  value = atoi(p+1);
+  SVN_ERR(svn_cstring_atoi(&value, p + 1));
 
   if (value > SVN_REPOS_DUMPFILE_FORMAT_VERSION)
     return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
@@ -735,7 +743,7 @@ svn_repos_parse_dumpstream2(svn_stream_t
             return stream_ran_dry();
         }
 
-      if ((linebuf->len == 0) || (apr_isspace(linebuf->data[0])))
+      if ((linebuf->len == 0) || (svn_ctype_isspace(linebuf->data[0])))
         continue; /* empty line ... loop */
 
       /*** Found the beginning of a new record. ***/
@@ -784,7 +792,7 @@ svn_repos_parse_dumpstream2(svn_stream_t
                                      APR_HASH_KEY_STRING)))
         {
           /* ### someday, switch modes of operation here. */
-          version = atoi(value);
+          SVN_ERR(svn_cstring_atoi(&version, value));
         }
       /* Or is this bogosity?! */
       else

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/reporter.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/reporter.c Fri Dec 10 21:23:03 2010
@@ -32,6 +32,7 @@
 #include "svn_props.h"
 #include "repos.h"
 #include "svn_private_config.h"
+#include "private/svn_dep_compat.h"
 
 #define NUM_CACHED_SOURCE_ROOTS 4
 
@@ -155,11 +156,6 @@ read_number(apr_uint64_t *num, apr_file_
   return SVN_NO_ERROR;
 }
 
-#ifndef APR_SIZE_MAX
-/* APR 0.9 doesn't define APR_SIZE_MAX */
-#define APR_SIZE_MAX    (~((apr_size_t)0))
-#endif
-
 static svn_error_t *
 read_string(const char **str, apr_file_t *temp, apr_pool_t *pool)
 {

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c Fri Dec 10 21:23:03 2010
@@ -34,6 +34,7 @@
 #include "svn_utf.h"
 #include "svn_pools.h"
 #include "svn_user.h"
+#include "svn_ctype.h"
 
 #include "svn_private_config.h"
 
@@ -121,7 +122,7 @@ skip_whitespace(parse_context_t *ctx, in
   int count = 0;
 
   SVN_ERR(parser_getc(ctx, &ch));
-  while (ch != EOF && ch != '\n' && apr_isspace(ch))
+  while (ch != EOF && ch != '\n' && svn_ctype_isspace(ch))
     {
       ++count;
       SVN_ERR(parser_getc(ctx, &ch));
@@ -162,7 +163,7 @@ parse_value(int *pch, parse_context_t *c
     /* last ch seen was ':' or '=' in parse_option. */
     {
       const char char_from_int = ch;
-      svn_stringbuf_appendbytes(ctx->value, &char_from_int, 1);
+      svn_stringbuf_appendbyte(ctx->value, char_from_int);
       SVN_ERR(parser_getc(ctx, &ch));
     }
   /* Leading and trailing whitespace is ignored. */
@@ -213,13 +214,12 @@ parse_value(int *pch, parse_context_t *c
               else
                 {
                   /* This is a continuation line. Read it. */
-                  svn_stringbuf_appendbytes(ctx->value, " ", 1);
+                  svn_stringbuf_appendbyte(ctx->value, ' ');
 
                   while (ch != EOF && ch != '\n')
                     {
                       const char char_from_int = ch;
-                      svn_stringbuf_appendbytes(ctx->value,
-                                                &char_from_int, 1);
+                      svn_stringbuf_appendbyte(ctx->value, char_from_int);
                       SVN_ERR(parser_getc(ctx, &ch));
                     }
                   /* Trailing whitespace is ignored. */
@@ -246,7 +246,7 @@ parse_option(int *pch, parse_context_t *
   while (ch != EOF && ch != ':' && ch != '=' && ch != '\n')
     {
       const char char_from_int = ch;
-      svn_stringbuf_appendbytes(ctx->option, &char_from_int, 1);
+      svn_stringbuf_appendbyte(ctx->option, char_from_int);
       SVN_ERR(parser_getc(ctx, &ch));
     }
 
@@ -289,7 +289,7 @@ parse_section_name(int *pch, parse_conte
   while (ch != EOF && ch != ']' && ch != '\n')
     {
       const char char_from_int = ch;
-      svn_stringbuf_appendbytes(ctx->section, &char_from_int, 1);
+      svn_stringbuf_appendbyte(ctx->section, char_from_int);
       SVN_ERR(parser_getc(ctx, &ch));
     }