You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pr...@apache.org on 2013/06/05 11:22:51 UTC

svn commit: r1489765 [10/22] - in /subversion/branches/verify-keep-going: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/hook-scripts/ contrib/server-side/fsfsfixer/ contrib/server-side/fsfsfixer/fixer/ notes/ subversion...

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/marshal.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/marshal.c Wed Jun  5 09:22:43 2013
@@ -47,6 +47,7 @@
 #include "private/svn_string_private.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_error_private.h"
+#include "private/svn_subr_private.h"
 
 #define svn_iswhitespace(c) ((c) == ' ' || (c) == '\n')
 
@@ -56,19 +57,25 @@
 
 #define SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD (0x100000)
 
-/* When zero copy has been enabled, don't use blocking writes.  Instead,
- * time out after this many microseconds. */
-
-#define ZERO_COPY_TIMEOUT 1000000
+/* We don't use "words" longer than this in our protocol.  The longest word
+ * we are currently using is only about 16 chars long but we leave room for
+ * longer future capability and command names.
+ */
+#define MAX_WORD_LENGTH 31
+
+/* The generic parsers will use the following value to limit the recursion
+ * depth to some reasonable value.  The current protocol implementation
+ * actually uses only maximum item nesting level of around 5.  So, there is
+ * plenty of headroom here.
+ */
+#define ITEM_NESTING_LIMIT 64
 
 /* Return the APR socket timeout to be used for the connection depending
  * on whether there is a blockage handler or zero copy has been activated. */
 static apr_interval_time_t
 get_timeout(svn_ra_svn_conn_t *conn)
 {
-  return conn->block_handler ? 0
-                             : (conn->zero_copy_limit ? ZERO_COPY_TIMEOUT
-                                                      : -1);
+  return conn->block_handler ? 0 : -1;
 }
 
 /* --- CONNECTION INITIALIZATION --- */
@@ -277,7 +284,7 @@ static svn_error_t *writebuf_write(svn_r
     {
       if (conn->write_pos > 0)
         SVN_ERR(writebuf_flush(conn, pool));
-      
+
       return writebuf_output(conn, pool, data, len);
     }
 
@@ -510,85 +517,110 @@ static svn_error_t *write_number(svn_ra_
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_number(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
-                                     apr_uint64_t number)
+svn_error_t *
+svn_ra_svn__write_number(svn_ra_svn_conn_t *conn,
+                         apr_pool_t *pool,
+                         apr_uint64_t number)
 {
   return write_number(conn, pool, number, ' ');
 }
 
-svn_error_t *svn_ra_svn_write_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
-                                     const svn_string_t *str)
+static svn_error_t *
+svn_ra_svn__write_ncstring(svn_ra_svn_conn_t *conn,
+                           apr_pool_t *pool,
+                           const char *s,
+                           apr_size_t len)
 {
-  if (str->len < 10)
+  if (len < 10)
     {
-      SVN_ERR(writebuf_writechar(conn, pool, (char)(str->len + '0')));
+      SVN_ERR(writebuf_writechar(conn, pool, (char)(len + '0')));
       SVN_ERR(writebuf_writechar(conn, pool, ':'));
     }
   else
-    SVN_ERR(write_number(conn, pool, str->len, ':'));
+    SVN_ERR(write_number(conn, pool, len, ':'));
 
-  SVN_ERR(writebuf_write(conn, pool, str->data, str->len));
+  SVN_ERR(writebuf_write(conn, pool, s, len));
   SVN_ERR(writebuf_writechar(conn, pool, ' '));
+
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cstring(svn_ra_svn_conn_t *conn,
-                                      apr_pool_t *pool, const char *s)
+svn_error_t *
+svn_ra_svn__write_string(svn_ra_svn_conn_t *conn,
+                         apr_pool_t *pool,
+                         const svn_string_t *str)
 {
-  apr_size_t len = strlen(s);
+  svn_ra_svn__write_ncstring(conn, pool, str->data, str->len);
+  return SVN_NO_ERROR;
+}
 
-  if (len < 10)
-    {
-      SVN_ERR(writebuf_writechar(conn, pool, (char)(len + '0')));
-      SVN_ERR(writebuf_writechar(conn, pool, ':'));
-    }
-  else
-    SVN_ERR(write_number(conn, pool, len, ':'));
+svn_error_t *
+svn_ra_svn__write_cstring(svn_ra_svn_conn_t *conn,
+                          apr_pool_t *pool,
+                          const char *s)
+{
+  svn_ra_svn__write_ncstring(conn, pool, s, strlen(s));
+  return SVN_NO_ERROR;
+}
 
-  SVN_ERR(writebuf_write(conn, pool, s, len));
+svn_error_t *
+svn_ra_svn__write_word(svn_ra_svn_conn_t *conn,
+                       apr_pool_t *pool,
+                       const char *word)
+{
+  SVN_ERR(writebuf_write_short_string(conn, pool, word, strlen(word)));
   SVN_ERR(writebuf_writechar(conn, pool, ' '));
 
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_word(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
-                                   const char *word)
+svn_error_t *
+svn_ra_svn__write_boolean(svn_ra_svn_conn_t *conn,
+                          apr_pool_t *pool,
+                          svn_boolean_t value)
 {
-  SVN_ERR(writebuf_write_short_string(conn, pool, word, strlen(word)));
-  SVN_ERR(writebuf_writechar(conn, pool, ' '));
+  if (value)
+    SVN_ERR(writebuf_write_short_string(conn, pool, "true ", 5));
+  else
+    SVN_ERR(writebuf_write_short_string(conn, pool, "false ", 6));
 
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_proplist(svn_ra_svn_conn_t *conn,
-                                       apr_pool_t *pool, apr_hash_t *props)
+svn_error_t *
+svn_ra_svn__write_proplist(svn_ra_svn_conn_t *conn,
+                           apr_pool_t *pool,
+                           apr_hash_t *props)
 {
-  apr_pool_t *iterpool;
   apr_hash_index_t *hi;
-  const void *key;
-  void *val;
   const char *propname;
   svn_string_t *propval;
+  apr_size_t len;
 
+  /* One might use an iterpool here but that would only be used when the
+     send buffer gets flushed and only by the CONN's progress callback.
+     That should happen at most once for typical prop lists and even then
+     use only a few bytes at best.
+   */
   if (props)
-    {
-      iterpool = svn_pool_create(pool);
-      for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
-        {
-          svn_pool_clear(iterpool);
-          apr_hash_this(hi, &key, NULL, &val);
-          propname = key;
-          propval = val;
-          SVN_ERR(svn_ra_svn_write_tuple(conn, iterpool, "cs",
-                                         propname, propval));
-        }
-      svn_pool_destroy(iterpool);
-    }
+    for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
+      {
+        apr_hash_this(hi, (const void **)&propname, 
+                          (apr_ssize_t *)&len,
+                          (void **)&propval);
+
+        SVN_ERR(svn_ra_svn__start_list(conn, pool));
+        SVN_ERR(svn_ra_svn__write_ncstring(conn, pool, propname, len));
+        SVN_ERR(svn_ra_svn__write_string(conn, pool, propval));
+        SVN_ERR(svn_ra_svn__end_list(conn, pool));
+      }
 
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_start_list(svn_ra_svn_conn_t *conn, apr_pool_t *pool)
+svn_error_t *
+svn_ra_svn__start_list(svn_ra_svn_conn_t *conn,
+                       apr_pool_t *pool)
 {
   if (conn->write_pos + 2 <= sizeof(conn->write_buf))
     {
@@ -601,7 +633,9 @@ svn_error_t *svn_ra_svn_start_list(svn_r
   return writebuf_write(conn, pool, "( ", 2);
 }
 
-svn_error_t *svn_ra_svn_end_list(svn_ra_svn_conn_t *conn, apr_pool_t *pool)
+svn_error_t *
+svn_ra_svn__end_list(svn_ra_svn_conn_t *conn,
+                     apr_pool_t *pool)
 {
   if (conn->write_pos + 2 <= sizeof(conn->write_buf))
   {
@@ -614,7 +648,9 @@ svn_error_t *svn_ra_svn_end_list(svn_ra_
   return writebuf_write(conn, pool, ") ", 2);
 }
 
-svn_error_t *svn_ra_svn_flush(svn_ra_svn_conn_t *conn, apr_pool_t *pool)
+svn_error_t *
+svn_ra_svn__flush(svn_ra_svn_conn_t *conn,
+                  apr_pool_t *pool)
 {
   SVN_ERR(writebuf_flush(conn, pool));
   conn->may_check_for_error = TRUE;
@@ -629,14 +665,14 @@ vwrite_tuple_cstring(svn_ra_svn_conn_t *
 {
   const char *cstr = va_arg(*ap, const char *);
   SVN_ERR_ASSERT(cstr);
-  return svn_ra_svn_write_cstring(conn, pool, cstr);
+  return svn_ra_svn__write_cstring(conn, pool, cstr);
 }
 
 static svn_error_t *
 vwrite_tuple_cstring_opt(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
 {
   const char *cstr = va_arg(*ap, const char *);
-  return cstr ? svn_ra_svn_write_cstring(conn, pool, cstr) : SVN_NO_ERROR;
+  return cstr ? svn_ra_svn__write_cstring(conn, pool, cstr) : SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -644,14 +680,14 @@ vwrite_tuple_string(svn_ra_svn_conn_t *c
 {
   const svn_string_t *str = va_arg(*ap, const svn_string_t *);
   SVN_ERR_ASSERT(str);
-  return svn_ra_svn_write_string(conn, pool, str);
+  return svn_ra_svn__write_string(conn, pool, str);
 }
 
 static svn_error_t *
 vwrite_tuple_string_opt(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
 {
   const svn_string_t *str = va_arg(*ap, const svn_string_t *);
-  return str ? svn_ra_svn_write_string(conn, pool, str) : SVN_NO_ERROR;
+  return str ? svn_ra_svn__write_string(conn, pool, str) : SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -659,14 +695,14 @@ vwrite_tuple_word(svn_ra_svn_conn_t *con
 {
   const char *cstr = va_arg(*ap, const char *);
   SVN_ERR_ASSERT(cstr);
-  return svn_ra_svn_write_word(conn, pool, cstr);
+  return svn_ra_svn__write_word(conn, pool, cstr);
 }
 
 static svn_error_t *
 vwrite_tuple_word_opt(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
 {
   const char *cstr = va_arg(*ap, const char *);
-  return cstr ? svn_ra_svn_write_word(conn, pool, cstr) : SVN_NO_ERROR;
+  return cstr ? svn_ra_svn__write_word(conn, pool, cstr) : SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -674,7 +710,7 @@ vwrite_tuple_revision(svn_ra_svn_conn_t 
 {
   svn_revnum_t rev = va_arg(*ap, svn_revnum_t);
   SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(rev));
-  return svn_ra_svn_write_number(conn, pool, rev);
+  return svn_ra_svn__write_number(conn, pool, rev);
 }
 
 static svn_error_t *
@@ -682,21 +718,20 @@ vwrite_tuple_revision_opt(svn_ra_svn_con
 {
   svn_revnum_t rev = va_arg(*ap, svn_revnum_t);
   return SVN_IS_VALID_REVNUM(rev)
-       ? svn_ra_svn_write_number(conn, pool, rev)
+       ? svn_ra_svn__write_number(conn, pool, rev)
        : SVN_NO_ERROR;
 }
 
 static svn_error_t *
 vwrite_tuple_number(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
 {
-  return svn_ra_svn_write_number(conn, pool, va_arg(*ap, apr_uint64_t));
+  return svn_ra_svn__write_number(conn, pool, va_arg(*ap, apr_uint64_t));
 }
 
 static svn_error_t *
 vwrite_tuple_boolean(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
 {
-  const char *cstr = va_arg(*ap, svn_boolean_t) ? "true" : "false";
-  return svn_ra_svn_write_word(conn, pool, cstr);
+  return svn_ra_svn__write_boolean(conn, pool, va_arg(*ap, svn_boolean_t));
 }
 
 static svn_error_t *
@@ -705,7 +740,7 @@ write_tuple_cstring(svn_ra_svn_conn_t *c
                     const char *cstr)
 {
   SVN_ERR_ASSERT(cstr);
-  return svn_ra_svn_write_cstring(conn, pool, cstr);
+  return svn_ra_svn__write_cstring(conn, pool, cstr);
 }
 
 static svn_error_t *
@@ -713,7 +748,7 @@ write_tuple_cstring_opt(svn_ra_svn_conn_
                         apr_pool_t *pool,
                         const char *cstr)
 {
-  return cstr ? svn_ra_svn_write_cstring(conn, pool, cstr) : SVN_NO_ERROR;
+  return cstr ? svn_ra_svn__write_cstring(conn, pool, cstr) : SVN_NO_ERROR;
 }
 
 static svn_error_t *
@@ -722,7 +757,7 @@ write_tuple_string(svn_ra_svn_conn_t *co
                    const svn_string_t *str)
 {
   SVN_ERR_ASSERT(str);
-  return svn_ra_svn_write_string(conn, pool, str);
+  return svn_ra_svn__write_string(conn, pool, str);
 }
 
 static svn_error_t *
@@ -730,21 +765,21 @@ write_tuple_string_opt(svn_ra_svn_conn_t
                        apr_pool_t *pool,
                        const svn_string_t *str)
 {
-  return str ? svn_ra_svn_write_string(conn, pool, str) : SVN_NO_ERROR;
+  return str ? svn_ra_svn__write_string(conn, pool, str) : SVN_NO_ERROR;
 }
 
 static svn_error_t *
 write_tuple_start_list(svn_ra_svn_conn_t *conn,
                        apr_pool_t *pool)
 {
-  return svn_ra_svn_start_list(conn, pool);
+  return svn_ra_svn__start_list(conn, pool);
 }
 
 static svn_error_t *
 write_tuple_end_list(svn_ra_svn_conn_t *conn,
                      apr_pool_t *pool)
 {
-  return svn_ra_svn_end_list(conn, pool);
+  return svn_ra_svn__end_list(conn, pool);
 }
 
 static svn_error_t *
@@ -753,7 +788,7 @@ write_tuple_revision(svn_ra_svn_conn_t *
                      svn_revnum_t rev)
 {
   SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(rev));
-  return svn_ra_svn_write_number(conn, pool, rev);
+  return svn_ra_svn__write_number(conn, pool, rev);
 }
 
 static svn_error_t *
@@ -762,7 +797,7 @@ write_tuple_revision_opt(svn_ra_svn_conn
                          svn_revnum_t rev)
 {
   return SVN_IS_VALID_REVNUM(rev)
-       ? svn_ra_svn_write_number(conn, pool, rev)
+       ? svn_ra_svn__write_number(conn, pool, rev)
        : SVN_NO_ERROR;
 }
 
@@ -771,8 +806,7 @@ write_tuple_boolean(svn_ra_svn_conn_t *c
                     apr_pool_t *pool,
                     svn_boolean_t value)
 {
-  const char *cstr = value ? "true" : "false";
-  return svn_ra_svn_write_word(conn, pool, cstr);
+  return svn_ra_svn__write_boolean(conn, pool, value);
 }
 
 static svn_error_t *
@@ -780,7 +814,7 @@ write_tuple_depth(svn_ra_svn_conn_t *con
                   apr_pool_t *pool,
                   svn_depth_t depth)
 {
-  return svn_ra_svn_write_word(conn, pool, svn_depth_to_word(depth));
+  return svn_ra_svn__write_word(conn, pool, svn_depth_to_word(depth));
 }
 
 
@@ -861,7 +895,7 @@ static svn_error_t *vwrite_tuple(svn_ra_
   if (*fmt == '!')
     fmt++;
   else
-    SVN_ERR(svn_ra_svn_start_list(conn, pool));
+    SVN_ERR(svn_ra_svn__start_list(conn, pool));
   for (; *fmt; fmt++)
     {
       if (*fmt == 'c')
@@ -894,12 +928,14 @@ static svn_error_t *vwrite_tuple(svn_ra_
       else
         SVN_ERR_MALFUNCTION();
     }
-  SVN_ERR(svn_ra_svn_end_list(conn, pool));
+  SVN_ERR(svn_ra_svn__end_list(conn, pool));
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
-                                    const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__write_tuple(svn_ra_svn_conn_t *conn,
+                        apr_pool_t *pool,
+                        const char *fmt, ...)
 {
   svn_error_t *err;
   va_list ap;
@@ -918,7 +954,6 @@ svn_error_t *svn_ra_svn_write_tuple(svn_
 static svn_error_t *read_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                 svn_ra_svn_item_t *item, apr_uint64_t len64)
 {
-  svn_stringbuf_t *stringbuf;
   apr_size_t len = (apr_size_t)len64;
   apr_size_t readbuf_len;
   char *dest;
@@ -929,51 +964,53 @@ static svn_error_t *read_string(svn_ra_s
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                             _("String length larger than maximum"));
 
-  /* Read the string in chunks.  The chunk size is large enough to avoid
-   * re-allocation in typical cases, and small enough to ensure we do not
-   * pre-allocate an unreasonable amount of memory if (perhaps due to
-   * network data corruption or a DOS attack), we receive a bogus claim that
-   * a very long string is going to follow.  In that case, we start small
-   * and wait for all that data to actually show up.  This does not fully
-   * prevent DOS attacks but makes them harder (you have to actually send
-   * gigabytes of data). */
-  readbuf_len = len < SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD
-                    ? len
-                    : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
-  stringbuf = svn_stringbuf_create_ensure(readbuf_len, pool);
-  dest = stringbuf->data;
-
-  /* Read remaining string data directly into the string structure.
-   * Do it iteratively, if necessary.  */
-  while (readbuf_len)
-    {
-      SVN_ERR(readbuf_read(conn, pool, dest, readbuf_len));
-
-      stringbuf->len += readbuf_len;
-      len -= readbuf_len;
-
-      /* Early exit. In most cases, strings can be read in the first
-       * iteration. */
-      if (len == 0)
-        break;
+  /* Shorter strings can be copied directly from the read buffer. */
+  if (conn->read_ptr + len <= conn->read_end)
+    {
+      item->kind = SVN_RA_SVN_STRING;
+      item->u.string = svn_string_ncreate(conn->read_ptr, len, pool);
+      conn->read_ptr += len;
+    }
+  else
+    {
+      /* Read the string in chunks.  The chunk size is large enough to avoid
+       * re-allocation in typical cases, and small enough to ensure we do
+       * not pre-allocate an unreasonable amount of memory if (perhaps due
+       * to network data corruption or a DOS attack), we receive a bogus
+       * claim that a very long string is going to follow.  In that case, we
+       * start small and wait for all that data to actually show up.  This
+       * does not fully prevent DOS attacks but makes them harder (you have
+       * to actually send gigabytes of data). */
+      svn_stringbuf_t *stringbuf = svn_stringbuf_create_empty(pool);
+
+      /* Read string data directly into the string structure.
+       * Do it iteratively.  */
+      do      
+        {
+          /* Determine length of chunk to read and re-alloc the buffer. */
+          readbuf_len
+            = len < SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD
+                  ? len
+                  : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
+
+          svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len);
+          dest = stringbuf->data + stringbuf->len;
 
-      /* Prepare next iteration: determine length of chunk to read
-       * and re-alloc the string buffer. */
-      readbuf_len
-        = len < SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD
-              ? len
-              : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
-
-      svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len);
-      dest = stringbuf->data + stringbuf->len;
-    }
-
-  /* zero-terminate the string */
-  stringbuf->data[stringbuf->len] = '\0';
-
-  /* Return the string properly wrapped into an RA_SVN item. */
-  item->kind = SVN_RA_SVN_STRING;
-  item->u.string = svn_stringbuf__morph_into_string(stringbuf);
+          /* read data & update length info */
+          SVN_ERR(readbuf_read(conn, pool, dest, readbuf_len));
+
+          stringbuf->len += readbuf_len;
+          len -= readbuf_len;
+        }
+      while (len);
+      
+      /* zero-terminate the string */
+      stringbuf->data[stringbuf->len] = '\0';
+
+      /* Return the string properly wrapped into an RA_SVN item. */
+      item->kind = SVN_RA_SVN_STRING;
+      item->u.string = svn_stringbuf__morph_into_string(stringbuf);
+    }
 
   return SVN_NO_ERROR;
 }
@@ -991,9 +1028,9 @@ static svn_error_t *read_item(svn_ra_svn
   svn_stringbuf_t *str;
   svn_ra_svn_item_t *listitem;
 
-  if (++level >= 64)
+  if (++level >= ITEM_NESTING_LIMIT)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
-                            _("Too many nested items"));
+                            _("Items are nested too deeply"));
 
 
   /* Determine the item type and read it in.  Make sure that c is the
@@ -1011,7 +1048,8 @@ static svn_error_t *read_item(svn_ra_svn
             break;
           val = val * 10 + (c - '0');
           /* val wrapped past maximum value? */
-          if (prev_val >= (APR_UINT64_MAX / 10) && (val / 10) != prev_val)
+          if ((prev_val >= (APR_UINT64_MAX / 10))
+              && (val < APR_UINT64_MAX - 10))
             return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                     _("Number is larger than maximum"));
         }
@@ -1030,31 +1068,72 @@ static svn_error_t *read_item(svn_ra_svn
     }
   else if (svn_ctype_isalpha(c))
     {
-      /* It's a word. */
-      str = svn_stringbuf_create_ensure(16, pool);
-      svn_stringbuf_appendbyte(str, c);
+      /* It's a word.  Read it into a buffer of limited size. */
+      char *buffer = apr_palloc(pool, MAX_WORD_LENGTH + 1);
+      char *end = buffer + MAX_WORD_LENGTH;
+      char *p = buffer + 1;
+
+      buffer[0] = c;
       while (1)
         {
-          SVN_ERR(readbuf_getchar(conn, pool, &c));
-          if (!svn_ctype_isalnum(c) && c != '-')
+          SVN_ERR(readbuf_getchar(conn, pool, p));
+          if (!svn_ctype_isalnum(*p) && *p != '-')
             break;
-          svn_stringbuf_appendbyte(str, c);
+
+          if (++p == end)
+            return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+                                    _("Word is too long"));
         }
+
+      c = *p;
+      *p = '\0';
+
       item->kind = SVN_RA_SVN_WORD;
-      item->u.word = str->data;
+      item->u.word = buffer;
     }
   else if (c == '(')
     {
-      /* Read in the list items. */
+      /* Allocate an APR array with room for (initially) 4 items.
+       * We do this manually because lists are the most frequent protocol
+       * element, often used to frame a single, optional value.  We save
+       * about 20% of total protocol handling time. */
+      char *buffer = apr_palloc(pool, sizeof(apr_array_header_t)
+                                      + 4 * sizeof(svn_ra_svn_item_t));
+      svn_ra_svn_item_t *data
+        = (svn_ra_svn_item_t *)(buffer + sizeof(apr_array_header_t));
+
       item->kind = SVN_RA_SVN_LIST;
-      item->u.list = apr_array_make(pool, 4, sizeof(svn_ra_svn_item_t));
+      item->u.list = (apr_array_header_t *)buffer;
+      item->u.list->elts = (char *)data;
+      item->u.list->pool = pool;
+      item->u.list->elt_size = sizeof(*data);
+      item->u.list->nelts = 0; 
+      item->u.list->nalloc = 4;
+
+      listitem = data;
+
+      /* Read in the list items. */
       while (1)
         {
           SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));
           if (c == ')')
             break;
-          listitem = apr_array_push(item->u.list);
+
+          /* increase array capacity if necessary */
+          if (item->u.list->nelts == item->u.list->nalloc)
+            {
+              data = apr_palloc(pool, 2 * item->u.list->nelts * sizeof(*data));
+              memcpy(data, item->u.list->elts, item->u.list->nelts * sizeof(*data));
+              item->u.list->elts = (char *)data;
+              item->u.list->nalloc *= 2;
+              listitem = data + item->u.list->nelts;
+            }
+
+          /* read next protocol item */
           SVN_ERR(read_item(conn, pool, listitem, c, level));
+
+          listitem++; 
+          item->u.list->nelts++;
         }
       SVN_ERR(readbuf_getchar(conn, pool, &c));
     }
@@ -1106,7 +1185,7 @@ read_command_only(svn_ra_svn_conn_t *con
       if (item)
         {
           /* This is the word we want to read */
-          
+
           char *buf = apr_palloc(pool, 32);
           apr_size_t len = 1;
           buf[0] = c;
@@ -1154,8 +1233,10 @@ read_command_only(svn_ra_svn_conn_t *con
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
-                                  svn_ra_svn_item_t **item)
+svn_error_t *
+svn_ra_svn__read_item(svn_ra_svn_conn_t *conn,
+                      apr_pool_t *pool,
+                      svn_ra_svn_item_t **item)
 {
   char c;
 
@@ -1166,8 +1247,9 @@ svn_error_t *svn_ra_svn_read_item(svn_ra
   return read_item(conn, pool, *item, c, 0);
 }
 
-svn_error_t *svn_ra_svn_skip_leading_garbage(svn_ra_svn_conn_t *conn,
-                                             apr_pool_t *pool)
+svn_error_t *
+svn_ra_svn__skip_leading_garbage(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool)
 {
   return readbuf_skip_leading_garbage(conn, pool);
 }
@@ -1188,14 +1270,15 @@ static svn_error_t *vparse_tuple(const a
       if (**fmt == '?')
         (*fmt)++;
       elt = &APR_ARRAY_IDX(items, count, svn_ra_svn_item_t);
-      if (**fmt == 'n' && elt->kind == SVN_RA_SVN_NUMBER)
-        *va_arg(*ap, apr_uint64_t *) = elt->u.number;
-      else if (**fmt == 'r' && elt->kind == SVN_RA_SVN_NUMBER)
-        *va_arg(*ap, svn_revnum_t *) = (svn_revnum_t) elt->u.number;
-      else if (**fmt == 's' && elt->kind == SVN_RA_SVN_STRING)
-        *va_arg(*ap, svn_string_t **) = elt->u.string;
+      if (**fmt == '(' && elt->kind == SVN_RA_SVN_LIST)
+        {
+          (*fmt)++;
+          SVN_ERR(vparse_tuple(elt->u.list, pool, fmt, ap));
+        }
       else if (**fmt == 'c' && elt->kind == SVN_RA_SVN_STRING)
         *va_arg(*ap, const char **) = elt->u.string->data;
+      else if (**fmt == 's' && elt->kind == SVN_RA_SVN_STRING)
+        *va_arg(*ap, svn_string_t **) = elt->u.string;
       else if (**fmt == 'w' && elt->kind == SVN_RA_SVN_WORD)
         *va_arg(*ap, const char **) = elt->u.word;
       else if (**fmt == 'b' && elt->kind == SVN_RA_SVN_WORD)
@@ -1207,6 +1290,10 @@ static svn_error_t *vparse_tuple(const a
           else
             break;
         }
+      else if (**fmt == 'n' && elt->kind == SVN_RA_SVN_NUMBER)
+        *va_arg(*ap, apr_uint64_t *) = elt->u.number;
+      else if (**fmt == 'r' && elt->kind == SVN_RA_SVN_NUMBER)
+        *va_arg(*ap, svn_revnum_t *) = (svn_revnum_t) elt->u.number;
       else if (**fmt == 'B' && elt->kind == SVN_RA_SVN_WORD)
         {
           if (strcmp(elt->u.word, "true") == 0)
@@ -1216,13 +1303,17 @@ static svn_error_t *vparse_tuple(const a
           else
             break;
         }
-      else if (**fmt == 'l' && elt->kind == SVN_RA_SVN_LIST)
-        *va_arg(*ap, apr_array_header_t **) = elt->u.list;
-      else if (**fmt == '(' && elt->kind == SVN_RA_SVN_LIST)
+      else if (**fmt == '3' && elt->kind == SVN_RA_SVN_WORD)
         {
-          (*fmt)++;
-          SVN_ERR(vparse_tuple(elt->u.list, pool, fmt, ap));
+          if (strcmp(elt->u.word, "true") == 0)
+            *va_arg(*ap, svn_tristate_t *) = svn_tristate_true;
+          else if (strcmp(elt->u.word, "false") == 0)
+            *va_arg(*ap, svn_tristate_t *) = svn_tristate_false;
+          else
+            break;
         }
+      else if (**fmt == 'l' && elt->kind == SVN_RA_SVN_LIST)
+        *va_arg(*ap, apr_array_header_t **) = elt->u.list;
       else if (**fmt == ')')
         return SVN_NO_ERROR;
       else
@@ -1254,6 +1345,9 @@ static svn_error_t *vparse_tuple(const a
             case 'n':
               *va_arg(*ap, apr_uint64_t *) = SVN_RA_SVN_UNSPECIFIED_NUMBER;
               break;
+            case '3':
+              *va_arg(*ap, svn_tristate_t *) = svn_tristate_unknown;
+              break;
             case '(':
               nesting_level++;
               break;
@@ -1272,9 +1366,10 @@ static svn_error_t *vparse_tuple(const a
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_parse_tuple(const apr_array_header_t *list,
-                                    apr_pool_t *pool,
-                                    const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__parse_tuple(const apr_array_header_t *list,
+                        apr_pool_t *pool,
+                        const char *fmt, ...)
 {
   svn_error_t *err;
   va_list ap;
@@ -1285,14 +1380,16 @@ svn_error_t *svn_ra_svn_parse_tuple(cons
   return err;
 }
 
-svn_error_t *svn_ra_svn_read_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
-                                   const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__read_tuple(svn_ra_svn_conn_t *conn,
+                       apr_pool_t *pool,
+                       const char *fmt, ...)
 {
   va_list ap;
   svn_ra_svn_item_t *item;
   svn_error_t *err;
 
-  SVN_ERR(svn_ra_svn_read_item(conn, pool, &item));
+  SVN_ERR(svn_ra_svn__read_item(conn, pool, &item));
   if (item->kind != SVN_RA_SVN_LIST)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                             _("Malformed network data"));
@@ -1302,9 +1399,10 @@ svn_error_t *svn_ra_svn_read_tuple(svn_r
   return err;
 }
 
-svn_error_t *svn_ra_svn__read_command_only(svn_ra_svn_conn_t *conn,
-                                           apr_pool_t *pool,
-                                           const char **command)
+svn_error_t *
+svn_ra_svn__read_command_only(svn_ra_svn_conn_t *conn,
+                              apr_pool_t *pool,
+                              const char **command)
 {
   char c;
   SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));
@@ -1314,23 +1412,25 @@ svn_error_t *svn_ra_svn__read_command_on
 }
 
 
-svn_error_t *svn_ra_svn_parse_proplist(const apr_array_header_t *list,
-                                       apr_pool_t *pool,
-                                       apr_hash_t **props)
+svn_error_t *
+svn_ra_svn__parse_proplist(const apr_array_header_t *list,
+                           apr_pool_t *pool,
+                           apr_hash_t **props)
 {
   char *name;
   svn_string_t *value;
   svn_ra_svn_item_t *elt;
   int i;
 
-  *props = apr_hash_make(pool);
+  *props = svn_hash__make(pool);
   for (i = 0; i < list->nelts; i++)
     {
       elt = &APR_ARRAY_IDX(list, i, svn_ra_svn_item_t);
       if (elt->kind != SVN_RA_SVN_LIST)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Proplist element not a list"));
-      SVN_ERR(svn_ra_svn_parse_tuple(elt->u.list, pool, "cs", &name, &value));
+      SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "cs",
+                                      &name, &value));
       svn_hash_sets(*props, name, value);
     }
 
@@ -1377,8 +1477,8 @@ svn_error_t *svn_ra_svn__handle_failure_
       if (elt->kind != SVN_RA_SVN_LIST)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Malformed error list"));
-      SVN_ERR(svn_ra_svn_parse_tuple(elt->u.list, subpool, "nccn", &apr_err,
-                                      &message, &file, &line));
+      SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, subpool, "nccn",
+                                      &apr_err, &message, &file, &line));
       /* The message field should have been optional, but we can't
          easily change that, so "" means a nonexistent message. */
       if (!*message)
@@ -1407,16 +1507,17 @@ svn_error_t *svn_ra_svn__handle_failure_
   return err;
 }
 
-svn_error_t *svn_ra_svn_read_cmd_response(svn_ra_svn_conn_t *conn,
-                                          apr_pool_t *pool,
-                                          const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__read_cmd_response(svn_ra_svn_conn_t *conn,
+                              apr_pool_t *pool,
+                              const char *fmt, ...)
 {
   va_list ap;
   const char *status;
   apr_array_header_t *params;
   svn_error_t *err;
 
-  SVN_ERR(svn_ra_svn_read_tuple(conn, pool, "wl", &status, &params));
+  SVN_ERR(svn_ra_svn__read_tuple(conn, pool, "wl", &status, &params));
   if (strcmp(status, "success") == 0)
     {
       va_start(ap, fmt);
@@ -1434,11 +1535,12 @@ svn_error_t *svn_ra_svn_read_cmd_respons
                            status);
 }
 
-svn_error_t *svn_ra_svn_handle_commands2(svn_ra_svn_conn_t *conn,
-                                         apr_pool_t *pool,
-                                         const svn_ra_svn_cmd_entry_t *commands,
-                                         void *baton,
-                                         svn_boolean_t error_on_disconnect)
+svn_error_t *
+svn_ra_svn__handle_commands2(svn_ra_svn_conn_t *conn,
+                             apr_pool_t *pool,
+                             const svn_ra_svn_cmd_entry_t *commands,
+                             void *baton,
+                             svn_boolean_t error_on_disconnect)
 {
   apr_pool_t *subpool = svn_pool_create(pool);
   apr_pool_t *iterpool = svn_pool_create(subpool);
@@ -1454,7 +1556,7 @@ svn_error_t *svn_ra_svn_handle_commands2
   while (1)
     {
       svn_pool_clear(iterpool);
-      err = svn_ra_svn_read_tuple(conn, iterpool, "wl", &cmdname, &params);
+      err = svn_ra_svn__read_tuple(conn, iterpool, "wl", &cmdname, &params);
       if (err)
         {
           if (!error_on_disconnect
@@ -1479,7 +1581,7 @@ 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(
+          write_err = svn_ra_svn__write_cmd_failure(
                           conn, iterpool,
                           svn_ra_svn__locate_real_error_child(err));
           svn_error_clear(err);
@@ -1497,31 +1599,10 @@ svn_error_t *svn_ra_svn_handle_commands2
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_handle_commands(svn_ra_svn_conn_t *conn,
-                                        apr_pool_t *pool,
-                                        const svn_ra_svn_cmd_entry_t *commands,
-                                        void *baton)
-{
-  return svn_ra_svn_handle_commands2(conn, pool, commands, baton, TRUE);
-}
-
-svn_error_t *svn_ra_svn_write_cmd(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
-                                  const char *cmdname, const char *fmt, ...)
-{
-  va_list ap;
-  svn_error_t *err;
-
-  SVN_ERR(svn_ra_svn_start_list(conn, pool));
-  SVN_ERR(svn_ra_svn_write_word(conn, pool, cmdname));
-  va_start(ap, fmt);
-  err = vwrite_tuple(conn, pool, fmt, &ap);
-  va_end(ap);
-  return err ? svn_error_trace(err) : svn_ra_svn_end_list(conn, pool);
-}
-
-svn_error_t *svn_ra_svn_write_cmd_target_rev(svn_ra_svn_conn_t *conn,
-                                             apr_pool_t *pool,
-                                             svn_revnum_t rev)
+svn_error_t *
+svn_ra_svn__write_cmd_target_rev(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool,
+                                 svn_revnum_t rev)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( target-rev ( ", 15));
   SVN_ERR(write_tuple_revision(conn, pool, rev));
@@ -1530,10 +1611,11 @@ svn_error_t *svn_ra_svn_write_cmd_target
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_open_root(svn_ra_svn_conn_t *conn,
-                                            apr_pool_t *pool,
-                                            svn_revnum_t rev,
-                                            const char *token)
+svn_error_t *
+svn_ra_svn__write_cmd_open_root(svn_ra_svn_conn_t *conn,
+                                apr_pool_t *pool,
+                                svn_revnum_t rev,
+                                const char *token)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( open-root ( ", 14));
   SVN_ERR(write_tuple_start_list(conn, pool));
@@ -1545,11 +1627,12 @@ svn_error_t *svn_ra_svn_write_cmd_open_r
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_delete_entry(svn_ra_svn_conn_t *conn,
-                                               apr_pool_t *pool,
-                                               const char *path,
-                                               svn_revnum_t rev,
-                                               const char *token)
+svn_error_t *
+svn_ra_svn__write_cmd_delete_entry(svn_ra_svn_conn_t *conn,
+                                   apr_pool_t *pool,
+                                   const char *path,
+                                   svn_revnum_t rev,
+                                   const char *token)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( delete-entry ( ", 17));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -1562,13 +1645,14 @@ svn_error_t *svn_ra_svn_write_cmd_delete
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_add_dir(svn_ra_svn_conn_t *conn,
-                                          apr_pool_t *pool,
-                                          const char *path,
-                                          const char *parent_token,
-                                          const char *token,
-                                          const char *copy_path,
-                                          svn_revnum_t copy_rev)
+svn_error_t *
+svn_ra_svn__write_cmd_add_dir(svn_ra_svn_conn_t *conn,
+                              apr_pool_t *pool,
+                              const char *path,
+                              const char *parent_token,
+                              const char *token,
+                              const char *copy_path,
+                              svn_revnum_t copy_rev)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( add-dir ( ", 12));
   SVN_ERR(write_cmd_add_node(conn, pool, path, parent_token, token,
@@ -1578,12 +1662,13 @@ svn_error_t *svn_ra_svn_write_cmd_add_di
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_open_dir(svn_ra_svn_conn_t *conn,
-                                           apr_pool_t *pool,
-                                           const char *path,
-                                           const char *parent_token,
-                                           const char *token,
-                                           svn_revnum_t rev)
+svn_error_t *
+svn_ra_svn__write_cmd_open_dir(svn_ra_svn_conn_t *conn,
+                               apr_pool_t *pool,
+                               const char *path,
+                               const char *parent_token,
+                               const char *token,
+                               svn_revnum_t rev)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( open-dir ( ", 13));
   SVN_ERR(write_cmd_open_node(conn, pool, path, parent_token, token, rev));
@@ -1592,11 +1677,12 @@ svn_error_t *svn_ra_svn_write_cmd_open_d
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_change_dir_prop(svn_ra_svn_conn_t *conn,
-                                                  apr_pool_t *pool,
-                                                  const char *token,
-                                                  const char *name,
-                                                  const svn_string_t *value)
+svn_error_t *
+svn_ra_svn__write_cmd_change_dir_prop(svn_ra_svn_conn_t *conn,
+                                      apr_pool_t *pool,
+                                      const char *token,
+                                      const char *name,
+                                      const svn_string_t *value)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( change-dir-prop ( ", 20));
   SVN_ERR(write_cmd_change_node_prop(conn, pool, token, name, value));
@@ -1605,9 +1691,10 @@ svn_error_t *svn_ra_svn_write_cmd_change
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_close_dir(svn_ra_svn_conn_t *conn,
-                                            apr_pool_t *pool,
-                                            const char *token)
+svn_error_t *
+svn_ra_svn__write_cmd_close_dir(svn_ra_svn_conn_t *conn,
+                                apr_pool_t *pool,
+                                const char *token)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( close-dir ( ", 14));
   SVN_ERR(write_tuple_cstring(conn, pool, token));
@@ -1616,10 +1703,11 @@ svn_error_t *svn_ra_svn_write_cmd_close_
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_absent_dir(svn_ra_svn_conn_t *conn,
-                                             apr_pool_t *pool,
-                                             const char *path,
-                                             const char *parent_token)
+svn_error_t *
+svn_ra_svn__write_cmd_absent_dir(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool,
+                                 const char *path,
+                                 const char *parent_token)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( absent-dir ( ", 15));
   SVN_ERR(write_cmd_absent_node(conn, pool, path, parent_token));
@@ -1628,13 +1716,14 @@ svn_error_t *svn_ra_svn_write_cmd_absent
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_add_file(svn_ra_svn_conn_t *conn,
-                                           apr_pool_t *pool,
-                                           const char *path,
-                                           const char *parent_token,
-                                           const char *token,
-                                           const char *copy_path,
-                                           svn_revnum_t copy_rev)
+svn_error_t *
+svn_ra_svn__write_cmd_add_file(svn_ra_svn_conn_t *conn,
+                               apr_pool_t *pool,
+                               const char *path,
+                               const char *parent_token,
+                               const char *token,
+                               const char *copy_path,
+                               svn_revnum_t copy_rev)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( add-file ( ", 13));
   SVN_ERR(write_cmd_add_node(conn, pool, path, parent_token, token,
@@ -1644,12 +1733,13 @@ svn_error_t *svn_ra_svn_write_cmd_add_fi
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_open_file(svn_ra_svn_conn_t *conn,
-                                            apr_pool_t *pool,
-                                            const char *path,
-                                            const char *parent_token,
-                                            const char *token,
-                                            svn_revnum_t rev)
+svn_error_t *
+svn_ra_svn__write_cmd_open_file(svn_ra_svn_conn_t *conn,
+                                apr_pool_t *pool,
+                                const char *path,
+                                const char *parent_token,
+                                const char *token,
+                                svn_revnum_t rev)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( open-file ( ", 14));
   SVN_ERR(write_cmd_open_node(conn, pool, path, parent_token, token, rev));
@@ -1658,11 +1748,12 @@ svn_error_t *svn_ra_svn_write_cmd_open_f
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_change_file_prop(svn_ra_svn_conn_t *conn,
-                                                   apr_pool_t *pool,
-                                                   const char *token,
-                                                   const char *name,
-                                                   const svn_string_t *value)
+svn_error_t *
+svn_ra_svn__write_cmd_change_file_prop(svn_ra_svn_conn_t *conn,
+                                       apr_pool_t *pool,
+                                       const char *token,
+                                       const char *name,
+                                       const svn_string_t *value)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( change-file-prop ( ", 21));
   SVN_ERR(write_cmd_change_node_prop(conn, pool, token, name, value));
@@ -1671,10 +1762,11 @@ svn_error_t *svn_ra_svn_write_cmd_change
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_close_file(svn_ra_svn_conn_t *conn,
-                                             apr_pool_t *pool,
-                                             const char *token,
-                                             const char *text_checksum)
+svn_error_t *
+svn_ra_svn__write_cmd_close_file(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool,
+                                 const char *token,
+                                 const char *text_checksum)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( close-file ( ", 15));
   SVN_ERR(write_tuple_cstring(conn, pool, token));
@@ -1686,10 +1778,11 @@ svn_error_t *svn_ra_svn_write_cmd_close_
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_absent_file(svn_ra_svn_conn_t *conn,
-                                              apr_pool_t *pool,
-                                              const char *path,
-                                              const char *parent_token)
+svn_error_t *
+svn_ra_svn__write_cmd_absent_file(svn_ra_svn_conn_t *conn,
+                                  apr_pool_t *pool,
+                                  const char *path,
+                                  const char *parent_token)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( absent-file ( ", 16));
   SVN_ERR(write_cmd_absent_node(conn, pool, path, parent_token));
@@ -1698,10 +1791,11 @@ svn_error_t *svn_ra_svn_write_cmd_absent
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_textdelta_chunk(svn_ra_svn_conn_t *conn,
-                                                  apr_pool_t *pool,
-                                                  const char *token,
-                                                  const svn_string_t *chunk)
+svn_error_t *
+svn_ra_svn__write_cmd_textdelta_chunk(svn_ra_svn_conn_t *conn,
+                                      apr_pool_t *pool,
+                                      const char *token,
+                                      const svn_string_t *chunk)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( textdelta-chunk ( ", 20));
   SVN_ERR(write_tuple_cstring(conn, pool, token));
@@ -1711,9 +1805,10 @@ svn_error_t *svn_ra_svn_write_cmd_textde
   return SVN_NO_ERROR;
 }
 
-svn_error_t *svn_ra_svn_write_cmd_textdelta_end(svn_ra_svn_conn_t *conn,
-                                                apr_pool_t *pool,
-                                                const char *token)
+svn_error_t *
+svn_ra_svn__write_cmd_textdelta_end(svn_ra_svn_conn_t *conn,
+                                    apr_pool_t *pool,
+                                    const char *token)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( textdelta-end ( ", 18));
   SVN_ERR(write_tuple_cstring(conn, pool, token));
@@ -1723,10 +1818,10 @@ svn_error_t *svn_ra_svn_write_cmd_textde
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_apply_textdelta(svn_ra_svn_conn_t *conn,
-                                     apr_pool_t *pool,
-                                     const char *token,
-                                     const char *base_checksum)
+svn_ra_svn__write_cmd_apply_textdelta(svn_ra_svn_conn_t *conn,
+                                      apr_pool_t *pool,
+                                      const char *token,
+                                      const char *base_checksum)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( apply-textdelta ( ", 20));
   SVN_ERR(write_tuple_cstring(conn, pool, token));
@@ -1739,27 +1834,27 @@ svn_ra_svn_write_cmd_apply_textdelta(svn
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_close_edit(svn_ra_svn_conn_t *conn,
-                                apr_pool_t *pool)
+svn_ra_svn__write_cmd_close_edit(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool)
 {
   return writebuf_write_short_string(conn, pool, "( close-edit ( ) ) ", 19);
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_abort_edit(svn_ra_svn_conn_t *conn,
-                                apr_pool_t *pool)
+svn_ra_svn__write_cmd_abort_edit(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool)
 {
   return writebuf_write_short_string(conn, pool, "( abort-edit ( ) ) ", 19);
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_set_path(svn_ra_svn_conn_t *conn,
-                              apr_pool_t *pool,
-                              const char *path,
-                              svn_revnum_t rev,
-                              svn_boolean_t start_empty,
-                              const char *lock_token,
-                              svn_depth_t depth)
+svn_ra_svn__write_cmd_set_path(svn_ra_svn_conn_t *conn,
+                               apr_pool_t *pool,
+                               const char *path,
+                               svn_revnum_t rev,
+                               svn_boolean_t start_empty,
+                               const char *lock_token,
+                               svn_depth_t depth)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( set-path ( ", 13));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -1775,9 +1870,9 @@ svn_ra_svn_write_cmd_set_path(svn_ra_svn
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_delete_path(svn_ra_svn_conn_t *conn,
-                                 apr_pool_t *pool,
-                                 const char *path)
+svn_ra_svn__write_cmd_delete_path(svn_ra_svn_conn_t *conn,
+                                  apr_pool_t *pool,
+                                  const char *path)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( delete-path ( ", 16));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -1787,14 +1882,14 @@ svn_ra_svn_write_cmd_delete_path(svn_ra_
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_link_path(svn_ra_svn_conn_t *conn,
-                               apr_pool_t *pool,
-                               const char *path,
-                               const char *url,
-                               svn_revnum_t rev,
-                               svn_boolean_t start_empty,
-                               const char *lock_token,
-                               svn_depth_t depth)
+svn_ra_svn__write_cmd_link_path(svn_ra_svn_conn_t *conn,
+                                apr_pool_t *pool,
+                                const char *path,
+                                const char *url,
+                                svn_revnum_t rev,
+                                svn_boolean_t start_empty,
+                                const char *lock_token,
+                                svn_depth_t depth)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( link-path ( ", 14));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -1811,23 +1906,23 @@ svn_ra_svn_write_cmd_link_path(svn_ra_sv
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_finish_report(svn_ra_svn_conn_t *conn,
-                                   apr_pool_t *pool)
+svn_ra_svn__write_cmd_finish_report(svn_ra_svn_conn_t *conn,
+                                    apr_pool_t *pool)
 {
   return writebuf_write_short_string(conn, pool, "( finish-report ( ) ) ", 22);
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_abort_report(svn_ra_svn_conn_t *conn,
-                                  apr_pool_t *pool)
+svn_ra_svn__write_cmd_abort_report(svn_ra_svn_conn_t *conn,
+                                   apr_pool_t *pool)
 {
   return writebuf_write_short_string(conn, pool, "( abort-report ( ) ) ", 21);
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_reparent(svn_ra_svn_conn_t *conn,
-                              apr_pool_t *pool,
-                              const char *url)
+svn_ra_svn__write_cmd_reparent(svn_ra_svn_conn_t *conn,
+                               apr_pool_t *pool,
+                               const char *url)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( reparent ( ", 13));
   SVN_ERR(write_tuple_cstring(conn, pool, url));
@@ -1837,16 +1932,16 @@ svn_ra_svn_write_cmd_reparent(svn_ra_svn
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_get_latest_rev(svn_ra_svn_conn_t *conn,
-                                  apr_pool_t *pool)
+svn_ra_svn__write_cmd_get_latest_rev(svn_ra_svn_conn_t *conn,
+                                   apr_pool_t *pool)
 {
   return writebuf_write_short_string(conn, pool, "( get-latest-rev ( ) ) ", 23);
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_get_dated_rev(svn_ra_svn_conn_t *conn,
-                                   apr_pool_t *pool,
-                                   apr_time_t tm)
+svn_ra_svn__write_cmd_get_dated_rev(svn_ra_svn_conn_t *conn,
+                                    apr_pool_t *pool,
+                                    apr_time_t tm)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( get-dated-rev ( ", 18));
   SVN_ERR(write_tuple_cstring(conn, pool, svn_time_to_cstring(tm, pool)));
@@ -1856,13 +1951,13 @@ svn_ra_svn_write_cmd_get_dated_rev(svn_r
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_change_rev_prop2(svn_ra_svn_conn_t *conn,
-                                      apr_pool_t *pool,
-                                      svn_revnum_t rev,
-                                      const char *name,
-                                      const svn_string_t *value,
-                                      svn_boolean_t dont_care,
-                                      const svn_string_t *old_value)
+svn_ra_svn__write_cmd_change_rev_prop2(svn_ra_svn_conn_t *conn,
+                                       apr_pool_t *pool,
+                                       svn_revnum_t rev,
+                                       const char *name,
+                                       const svn_string_t *value,
+                                       svn_boolean_t dont_care,
+                                       const svn_string_t *old_value)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( change-rev-prop2 ( ", 21));
   SVN_ERR(write_tuple_revision(conn, pool, rev));
@@ -1880,11 +1975,11 @@ svn_ra_svn_write_cmd_change_rev_prop2(sv
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_change_rev_prop(svn_ra_svn_conn_t *conn,
-                                     apr_pool_t *pool,
-                                     svn_revnum_t rev,
-                                     const char *name,
-                                     const svn_string_t *value)
+svn_ra_svn__write_cmd_change_rev_prop(svn_ra_svn_conn_t *conn,
+                                      apr_pool_t *pool,
+                                      svn_revnum_t rev,
+                                      const char *name,
+                                      const svn_string_t *value)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( change-rev-prop ( ", 20));
   SVN_ERR(write_tuple_revision(conn, pool, rev));
@@ -1896,9 +1991,9 @@ svn_ra_svn_write_cmd_change_rev_prop(svn
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_rev_proplist(svn_ra_svn_conn_t *conn,
-                                  apr_pool_t *pool,
-                                  svn_revnum_t rev)
+svn_ra_svn__write_cmd_rev_proplist(svn_ra_svn_conn_t *conn,
+                                   apr_pool_t *pool,
+                                   svn_revnum_t rev)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( rev-proplist ( ", 17));
   SVN_ERR(write_tuple_revision(conn, pool, rev));
@@ -1908,10 +2003,10 @@ svn_ra_svn_write_cmd_rev_proplist(svn_ra
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_rev_prop(svn_ra_svn_conn_t *conn,
-                              apr_pool_t *pool,
-                              svn_revnum_t rev,
-                              const char *name)
+svn_ra_svn__write_cmd_rev_prop(svn_ra_svn_conn_t *conn,
+                               apr_pool_t *pool,
+                               svn_revnum_t rev,
+                               const char *name)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( rev-prop ( ", 13));
   SVN_ERR(write_tuple_revision(conn, pool, rev));
@@ -1922,12 +2017,12 @@ svn_ra_svn_write_cmd_rev_prop(svn_ra_svn
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_get_file(svn_ra_svn_conn_t *conn,
-                              apr_pool_t *pool,
-                              const char *path,
-                              svn_revnum_t rev,
-                              svn_boolean_t props,
-                              svn_boolean_t stream)
+svn_ra_svn__write_cmd_get_file(svn_ra_svn_conn_t *conn,
+                               apr_pool_t *pool,
+                               const char *path,
+                               svn_revnum_t rev,
+                               svn_boolean_t props,
+                               svn_boolean_t stream)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( get-file ( ", 13));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -1942,14 +2037,14 @@ svn_ra_svn_write_cmd_get_file(svn_ra_svn
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_update(svn_ra_svn_conn_t *conn,
-                            apr_pool_t *pool,
-                            svn_revnum_t rev,
-                            const char *target,
-                            svn_boolean_t recurse,
-                            svn_depth_t depth,
-                            svn_boolean_t send_copyfrom_args,
-                            svn_boolean_t ignore_ancestry)
+svn_ra_svn__write_cmd_update(svn_ra_svn_conn_t *conn,
+                             apr_pool_t *pool,
+                             svn_revnum_t rev,
+                             const char *target,
+                             svn_boolean_t recurse,
+                             svn_depth_t depth,
+                             svn_boolean_t send_copyfrom_args,
+                             svn_boolean_t ignore_ancestry)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( update ( ", 11));
   SVN_ERR(write_tuple_start_list(conn, pool));
@@ -1966,15 +2061,15 @@ svn_ra_svn_write_cmd_update(svn_ra_svn_c
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_switch(svn_ra_svn_conn_t *conn,
-                            apr_pool_t *pool,
-                            svn_revnum_t rev,
-                            const char *target,
-                            svn_boolean_t recurse,
-                            const char *switch_url,
-                            svn_depth_t depth,
-                            svn_boolean_t send_copyfrom_args,
-                            svn_boolean_t ignore_ancestry)
+svn_ra_svn__write_cmd_switch(svn_ra_svn_conn_t *conn,
+                             apr_pool_t *pool,
+                             svn_revnum_t rev,
+                             const char *target,
+                             svn_boolean_t recurse,
+                             const char *switch_url,
+                             svn_depth_t depth,
+                             svn_boolean_t send_copyfrom_args,
+                             svn_boolean_t ignore_ancestry)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( switch ( ", 11));
   SVN_ERR(write_tuple_start_list(conn, pool));
@@ -1992,12 +2087,12 @@ svn_ra_svn_write_cmd_switch(svn_ra_svn_c
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_status(svn_ra_svn_conn_t *conn,
-                            apr_pool_t *pool,
-                            const char *target,
-                            svn_boolean_t recurse,
-                            svn_revnum_t rev,
-                            svn_depth_t depth)
+svn_ra_svn__write_cmd_status(svn_ra_svn_conn_t *conn,
+                             apr_pool_t *pool,
+                             const char *target,
+                             svn_boolean_t recurse,
+                             svn_revnum_t rev,
+                             svn_depth_t depth)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( status ( ", 11));
   SVN_ERR(write_tuple_cstring(conn, pool, target));
@@ -2012,15 +2107,15 @@ svn_ra_svn_write_cmd_status(svn_ra_svn_c
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_diff(svn_ra_svn_conn_t *conn,
-                          apr_pool_t *pool,
-                          svn_revnum_t rev,
-                          const char *target,
-                          svn_boolean_t recurse,
-                          svn_boolean_t ignore_ancestry,
-                          const char *versus_url,
-                          svn_boolean_t text_deltas,
-                          svn_depth_t depth)
+svn_ra_svn__write_cmd_diff(svn_ra_svn_conn_t *conn,
+                           apr_pool_t *pool,
+                           svn_revnum_t rev,
+                           const char *target,
+                           svn_boolean_t recurse,
+                           svn_boolean_t ignore_ancestry,
+                           const char *versus_url,
+                           svn_boolean_t text_deltas,
+                           svn_depth_t depth)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( diff ( ", 9));
   SVN_ERR(write_tuple_start_list(conn, pool));
@@ -2038,10 +2133,10 @@ svn_ra_svn_write_cmd_diff(svn_ra_svn_con
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_check_path(svn_ra_svn_conn_t *conn,
-                                apr_pool_t *pool,
-                                const char *path,
-                                svn_revnum_t rev)
+svn_ra_svn__write_cmd_check_path(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool,
+                                 const char *path,
+                                 svn_revnum_t rev)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( check-path ( ", 15));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -2054,10 +2149,10 @@ svn_ra_svn_write_cmd_check_path(svn_ra_s
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_stat(svn_ra_svn_conn_t *conn,
-                          apr_pool_t *pool,
-                          const char *path,
-                          svn_revnum_t rev)
+svn_ra_svn__write_cmd_stat(svn_ra_svn_conn_t *conn,
+                           apr_pool_t *pool,
+                           const char *path,
+                           svn_revnum_t rev)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( stat ( ", 9));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -2070,12 +2165,12 @@ svn_ra_svn_write_cmd_stat(svn_ra_svn_con
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_get_file_revs(svn_ra_svn_conn_t *conn,
-                                   apr_pool_t *pool,
-                                   const char *path,
-                                   svn_revnum_t start,
-                                   svn_revnum_t end,
-                                   svn_boolean_t include_merged_revisions)
+svn_ra_svn__write_cmd_get_file_revs(svn_ra_svn_conn_t *conn,
+                                    apr_pool_t *pool,
+                                    const char *path,
+                                    svn_revnum_t start,
+                                    svn_revnum_t end,
+                                    svn_boolean_t include_merged_revisions)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( get-file-revs ( ", 18));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -2092,12 +2187,12 @@ svn_ra_svn_write_cmd_get_file_revs(svn_r
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_lock(svn_ra_svn_conn_t *conn,
-                          apr_pool_t *pool,
-                          const char *path,
-                          const char *comment,
-                          svn_boolean_t steal_lock,
-                          svn_revnum_t revnum)
+svn_ra_svn__write_cmd_lock(svn_ra_svn_conn_t *conn,
+                           apr_pool_t *pool,
+                           const char *path,
+                           const char *comment,
+                           svn_boolean_t steal_lock,
+                           svn_revnum_t revnum)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( lock ( ", 9));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -2114,11 +2209,11 @@ svn_ra_svn_write_cmd_lock(svn_ra_svn_con
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_unlock(svn_ra_svn_conn_t *conn,
-                            apr_pool_t *pool,
-                            const char *path,
-                            const char *token,
-                            svn_boolean_t break_lock)
+svn_ra_svn__write_cmd_unlock(svn_ra_svn_conn_t *conn,
+                             apr_pool_t *pool,
+                             const char *path,
+                             const char *token,
+                             svn_boolean_t break_lock)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( unlock ( ", 11));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -2132,9 +2227,9 @@ svn_ra_svn_write_cmd_unlock(svn_ra_svn_c
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_get_lock(svn_ra_svn_conn_t *conn,
-                              apr_pool_t *pool,
-                              const char *path)
+svn_ra_svn__write_cmd_get_lock(svn_ra_svn_conn_t *conn,
+                               apr_pool_t *pool,
+                               const char *path)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( get-lock ( ", 13));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -2144,10 +2239,10 @@ svn_ra_svn_write_cmd_get_lock(svn_ra_svn
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_get_locks(svn_ra_svn_conn_t *conn,
-                               apr_pool_t *pool,
-                               const char *path,
-                               svn_depth_t depth)
+svn_ra_svn__write_cmd_get_locks(svn_ra_svn_conn_t *conn,
+                                apr_pool_t *pool,
+                                const char *path,
+                                svn_depth_t depth)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( get-locks ( ", 14));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -2160,11 +2255,11 @@ svn_ra_svn_write_cmd_get_locks(svn_ra_sv
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_replay(svn_ra_svn_conn_t *conn,
-                            apr_pool_t *pool,
-                            svn_revnum_t rev,
-                            svn_revnum_t low_water_mark,
-                            svn_boolean_t send_deltas)
+svn_ra_svn__write_cmd_replay(svn_ra_svn_conn_t *conn,
+                             apr_pool_t *pool,
+                             svn_revnum_t rev,
+                             svn_revnum_t low_water_mark,
+                             svn_boolean_t send_deltas)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( replay ( ", 11));
   SVN_ERR(write_tuple_revision(conn, pool, rev));
@@ -2176,12 +2271,12 @@ svn_ra_svn_write_cmd_replay(svn_ra_svn_c
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_replay_range(svn_ra_svn_conn_t *conn,
-                                  apr_pool_t *pool,
-                                  svn_revnum_t start_revision,
-                                  svn_revnum_t end_revision,
-                                  svn_revnum_t low_water_mark,
-                                  svn_boolean_t send_deltas)
+svn_ra_svn__write_cmd_replay_range(svn_ra_svn_conn_t *conn,
+                                   apr_pool_t *pool,
+                                   svn_revnum_t start_revision,
+                                   svn_revnum_t end_revision,
+                                   svn_revnum_t low_water_mark,
+                                   svn_boolean_t send_deltas)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( replay-range ( ", 17));
   SVN_ERR(write_tuple_revision(conn, pool, start_revision));
@@ -2194,11 +2289,11 @@ svn_ra_svn_write_cmd_replay_range(svn_ra
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_get_deleted_rev(svn_ra_svn_conn_t *conn,
-                                     apr_pool_t *pool,
-                                     const char *path,
-                                     svn_revnum_t peg_revision,
-                                     svn_revnum_t end_revision)
+svn_ra_svn__write_cmd_get_deleted_rev(svn_ra_svn_conn_t *conn,
+                                      apr_pool_t *pool,
+                                      const char *path,
+                                      svn_revnum_t peg_revision,
+                                      svn_revnum_t end_revision)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( get-deleted-rev ( ", 20));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -2210,10 +2305,10 @@ svn_ra_svn_write_cmd_get_deleted_rev(svn
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_get_iprops(svn_ra_svn_conn_t *conn,
-                                apr_pool_t *pool,
-                                const char *path,
-                                svn_revnum_t revision)
+svn_ra_svn__write_cmd_get_iprops(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool,
+                                 const char *path,
+                                 svn_revnum_t revision)
 {
   SVN_ERR(writebuf_write_short_string(conn, pool, "( get-iprops ( ", 15));
   SVN_ERR(write_tuple_cstring(conn, pool, path));
@@ -2226,15 +2321,15 @@ svn_ra_svn_write_cmd_get_iprops(svn_ra_s
 }
 
 svn_error_t *
-svn_ra_svn_write_cmd_finish_replay(svn_ra_svn_conn_t *conn,
-                                   apr_pool_t *pool)
+svn_ra_svn__write_cmd_finish_replay(svn_ra_svn_conn_t *conn,
+                                    apr_pool_t *pool)
 {
   return writebuf_write_short_string(conn, pool, "( finish-replay ( ) ) ", 22);
 }
 
-svn_error_t *svn_ra_svn_write_cmd_response(svn_ra_svn_conn_t *conn,
-                                           apr_pool_t *pool,
-                                           const char *fmt, ...)
+svn_error_t *svn_ra_svn__write_cmd_response(svn_ra_svn_conn_t *conn,
+                                            apr_pool_t *pool,
+                                            const char *fmt, ...)
 {
   va_list ap;
   svn_error_t *err;
@@ -2243,11 +2338,11 @@ svn_error_t *svn_ra_svn_write_cmd_respon
   va_start(ap, fmt);
   err = vwrite_tuple(conn, pool, fmt, &ap);
   va_end(ap);
-  return err ? svn_error_trace(err) : svn_ra_svn_end_list(conn, pool);
+  return err ? svn_error_trace(err) : svn_ra_svn__end_list(conn, pool);
 }
 
-svn_error_t *svn_ra_svn_write_cmd_failure(svn_ra_svn_conn_t *conn,
-                                          apr_pool_t *pool, svn_error_t *err)
+svn_error_t *svn_ra_svn__write_cmd_failure(svn_ra_svn_conn_t *conn,
+                                           apr_pool_t *pool, svn_error_t *err)
 {
   char buffer[128];
   SVN_ERR(writebuf_write_short_string(conn, pool, "( failure ( ", 12));
@@ -2264,11 +2359,67 @@ svn_error_t *svn_ra_svn_write_cmd_failur
 
       /* The message string should have been optional, but we can't
          easily change that, so marshal nonexistent messages as "". */
-      SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "nccn",
-                                     (apr_uint64_t) err->apr_err,
-                                     msg ? msg : "",
-                                     err->file ? err->file : "",
-                                     (apr_uint64_t) err->line));
+      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "nccn",
+                                      (apr_uint64_t) err->apr_err,
+                                      msg ? msg : "",
+                                      err->file ? err->file : "",
+                                      (apr_uint64_t) err->line));
     }
   return writebuf_write_short_string(conn, pool, ") ) ", 4);
 }
+
+svn_error_t *
+svn_ra_svn__write_data_log_changed_path(svn_ra_svn_conn_t *conn,
+                                        apr_pool_t *pool,
+                                        const char *path,
+                                        char action,
+                                        const char *copyfrom_path,
+                                        svn_revnum_t copyfrom_rev,
+                                        svn_node_kind_t node_kind,
+                                        svn_boolean_t text_modified,
+                                        svn_boolean_t props_modified)
+{
+  SVN_ERR(write_tuple_start_list(conn, pool));
+
+  SVN_ERR(write_tuple_cstring(conn, pool, path));
+  SVN_ERR(writebuf_writechar(conn, pool, action));
+  SVN_ERR(writebuf_writechar(conn, pool, ' '));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_cstring_opt(conn, pool, copyfrom_path));
+  SVN_ERR(write_tuple_revision_opt(conn, pool, copyfrom_rev));
+  SVN_ERR(write_tuple_end_list(conn, pool));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_cstring(conn, pool, svn_node_kind_to_word(node_kind)));
+  SVN_ERR(write_tuple_boolean(conn, pool, text_modified));
+  SVN_ERR(write_tuple_boolean(conn, pool, props_modified));
+
+  return writebuf_write_short_string(conn, pool, ") ) ", 4);
+}
+
+svn_error_t *
+svn_ra_svn__write_data_log_entry(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool,
+                                 svn_revnum_t revision,
+                                 const svn_string_t *author,
+                                 const svn_string_t *date,
+                                 const svn_string_t *message,
+                                 svn_boolean_t has_children,
+                                 svn_boolean_t invalid_revnum,
+                                 int revprop_count)
+{
+  SVN_ERR(write_tuple_revision(conn, pool, revision));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_string_opt(conn, pool, author));
+  SVN_ERR(write_tuple_end_list(conn, pool));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_string_opt(conn, pool, date));
+  SVN_ERR(write_tuple_end_list(conn, pool));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_string_opt(conn, pool, message));
+  SVN_ERR(write_tuple_end_list(conn, pool));
+  SVN_ERR(write_tuple_boolean(conn, pool, has_children));
+  SVN_ERR(write_tuple_boolean(conn, pool, invalid_revnum));
+  SVN_ERR(svn_ra_svn__write_number(conn, pool, revprop_count));
+  
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/protocol
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/protocol?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/protocol (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_ra_svn/protocol Wed Jun  5 09:22:43 2013
@@ -591,7 +591,13 @@ desirability:
   * The protocol version may be bumped.  Clients and servers can then
     choose to any range of protocol versions.
 
-4.1. Extending existing commands
+4.1. Limitations
+
+The current implementation limits the length of a word to 31 characters.
+Longer words, such as capability names, will be cause an error on the
+receiver side.
+
+4.2. Extending existing commands
 
 Extending an existing command is normally done by indicating that its
 tuple is allowed to end where it currently ends, for backwards

Modified: subversion/branches/verify-keep-going/subversion/libsvn_repos/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_repos/authz.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_repos/authz.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_repos/authz.c Wed Jun  5 09:22:43 2013
@@ -824,7 +824,7 @@ authz_retrieve_config_repo(svn_config_t 
     {
       if (!must_exist)
         {
-          SVN_ERR(svn_config_create(cfg_p, TRUE, result_pool));
+          SVN_ERR(svn_config_create2(cfg_p, TRUE, TRUE, result_pool));
           return SVN_NO_ERROR;
         }
       else
@@ -842,11 +842,11 @@ authz_retrieve_config_repo(svn_config_t 
     }
 
   SVN_ERR(svn_fs_file_contents(&contents, root, fs_path, scratch_pool));
-  err = svn_config_parse(cfg_p, contents, TRUE, result_pool);
+  err = svn_config_parse(cfg_p, contents, TRUE, TRUE, result_pool);
 
   /* Add the URL to the error stack since the parser doesn't have it. */
   if (err != SVN_NO_ERROR)
-    return svn_error_createf(err->apr_err, err, 
+    return svn_error_createf(err->apr_err, err,
                              "Error while parsing config file: '%s' in repo '%s':",
                              fs_path, repos_root_dirent);
 
@@ -875,7 +875,7 @@ authz_retrieve_config(svn_config_t **cfg
     {
       const char *dirent;
       svn_error_t *err;
-      apr_pool_t *scratch_pool = svn_pool_create(pool); 
+      apr_pool_t *scratch_pool = svn_pool_create(pool);
 
       err = svn_uri_get_dirent_from_file_url(&dirent, path, scratch_pool);
 
@@ -891,7 +891,7 @@ authz_retrieve_config(svn_config_t **cfg
   else
     {
       /* Outside of repo file or Windows registry*/
-      SVN_ERR(svn_config_read2(cfg_p, path, must_exist, TRUE, pool));
+      SVN_ERR(svn_config_read3(cfg_p, path, must_exist, TRUE, TRUE, pool));
     }
 
   return SVN_NO_ERROR;
@@ -944,7 +944,7 @@ svn_repos__authz_read(svn_authz_t **auth
   if (accept_urls)
     SVN_ERR(authz_retrieve_config(&authz->cfg, path, must_exist, pool));
   else
-    SVN_ERR(svn_config_read2(&authz->cfg, path, must_exist, TRUE, pool));
+    SVN_ERR(svn_config_read3(&authz->cfg, path, must_exist, TRUE, TRUE, pool));
 
   if (groups_path)
     {
@@ -956,8 +956,8 @@ svn_repos__authz_read(svn_authz_t **auth
         SVN_ERR(authz_retrieve_config(&groups_cfg, groups_path, must_exist,
                                       pool));
       else
-        SVN_ERR(svn_config_read2(&groups_cfg, groups_path, must_exist,
-                                 TRUE, pool));
+        SVN_ERR(svn_config_read3(&groups_cfg, groups_path, must_exist,
+                                 TRUE, TRUE, pool));
 
       /* Copy the groups from groups_cfg into authz. */
       err = authz_copy_groups(authz, groups_cfg, pool);
@@ -992,20 +992,20 @@ svn_repos_authz_read2(svn_authz_t **auth
 
 
 svn_error_t *
-svn_repos_authz_parse(svn_authz_t **authz_p, svn_stream_t *stream, 
+svn_repos_authz_parse(svn_authz_t **authz_p, svn_stream_t *stream,
                       svn_stream_t *groups_stream, apr_pool_t *pool)
 {
   svn_authz_t *authz = apr_palloc(pool, sizeof(*authz));
 
   /* Parse the authz stream */
-  SVN_ERR(svn_config_parse(&authz->cfg, stream, TRUE, pool));
+  SVN_ERR(svn_config_parse(&authz->cfg, stream, TRUE, TRUE, pool));
 
   if (groups_stream)
     {
       svn_config_t *groups_cfg;
 
       /* Parse the groups stream */
-      SVN_ERR(svn_config_parse(&groups_cfg, groups_stream, TRUE, pool));
+      SVN_ERR(svn_config_parse(&groups_cfg, groups_stream, TRUE, TRUE, pool));
 
       SVN_ERR(authz_copy_groups(authz, groups_cfg, pool));
     }

Modified: subversion/branches/verify-keep-going/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_repos/commit.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_repos/commit.c Wed Jun  5 09:22:43 2013
@@ -259,79 +259,6 @@ make_dir_baton(struct edit_baton *edit_b
   return db;
 }
 
-/* Return a copy of PATH, allocated from POOL, for which control
-   characters have been escaped using the form \NNN (where NNN is the
-   octal representation of the byte's ordinal value).  */
-static const char *
-illegal_path_escape(const char *path, apr_pool_t *pool)
-{
-  svn_stringbuf_t *retstr;
-  apr_size_t i, copied = 0;
-  int c;
-
-  /* At least one control character:
-      strlen - 1 (control) + \ + N + N + N + null . */
-  retstr = svn_stringbuf_create_ensure(strlen(path) + 4, pool);
-  for (i = 0; path[i]; i++)
-    {
-      c = (unsigned char)path[i];
-      if (! svn_ctype_iscntrl(c))
-        continue;
-
-      /* If we got here, we're looking at a character that isn't
-         supported by the (or at least, our) URI encoding scheme.  We
-         need to escape this character.  */
-
-      /* First things first, copy all the good stuff that we haven't
-         yet copied into our output buffer. */
-      if (i - copied)
-        svn_stringbuf_appendbytes(retstr, path + copied,
-                                  i - copied);
-
-      /* Make sure buffer is big enough for '\' 'N' 'N' 'N' (and NUL) */
-      svn_stringbuf_ensure(retstr, retstr->len + 4);
-      /*### The backslash separator doesn't work too great with Windows,
-         but it's what we'll use for consistency with invalid utf8
-         formatting (until someone has a better idea) */
-      apr_snprintf(retstr->data + retstr->len, 5, "\\%03o", (unsigned char)c);
-      retstr->len += 4;
-
-      /* Finally, update our copy counter. */
-      copied = i + 1;
-    }
-
-  /* If we didn't encode anything, we don't need to duplicate the string. */
-  if (retstr->len == 0)
-    return path;
-
-  /* Anything left to copy? */
-  if (i - copied)
-    svn_stringbuf_appendbytes(retstr, path + copied, i - copied);
-
-  /* retstr is null-terminated either by apr_snprintf or the svn_stringbuf
-     functions. */
-
-  return retstr->data;
-}
-
-/* Reject paths which contain control characters (related to issue #4340). */
-static svn_error_t *
-check_valid_path(const char *path,
-                 apr_pool_t *pool)
-{
-  const char *c;
-
-  for (c = path; *c; c++)
-    {
-      if (svn_ctype_iscntrl(*c))
-        return svn_error_createf(SVN_ERR_FS_PATH_SYNTAX, NULL,
-           _("Invalid control character '0x%02x' in path '%s'"),
-           (unsigned char)*c, illegal_path_escape(path, pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
 /* This function is the shared guts of add_file() and add_directory(),
    which see for the meanings of the parameters.  The only extra
    parameter here is IS_DIR, which is TRUE when adding a directory,
@@ -351,7 +278,8 @@ add_file_or_directory(const char *path,
   svn_boolean_t was_copied = FALSE;
   const char *full_path;
 
-  SVN_ERR(check_valid_path(path, pool));
+  /* Reject paths which contain control characters (related to issue #4340). */
+  SVN_ERR(svn_path_check_valid(path, pool));
 
   full_path = svn_fspath__join(eb->base_path,
                                svn_relpath_canonicalize(path, pool), pool);

Modified: subversion/branches/verify-keep-going/subversion/libsvn_repos/delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_repos/delta.c?rev=1489765&r1=1489764&r2=1489765&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_repos/delta.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_repos/delta.c Wed Jun  5 09:22:43 2013
@@ -196,17 +196,6 @@ authz_root_check(svn_fs_root_t *root,
 }
 
 
-static svn_error_t *
-not_a_dir_error(const char *role,
-                const char *path)
-{
-  return svn_error_createf
-    (SVN_ERR_FS_NOT_DIRECTORY, 0,
-     "Invalid %s directory '%s'",
-     role, path ? path : "(null)");
-}
-
-
 /* Public interface to computing directory deltas.  */
 svn_error_t *
 svn_repos_dir_delta2(svn_fs_root_t *src_root,
@@ -237,7 +226,8 @@ svn_repos_dir_delta2(svn_fs_root_t *src_
   if (src_parent_dir)
     src_parent_dir = svn_relpath_canonicalize(src_parent_dir, pool);
   else
-    return not_a_dir_error("source parent", src_parent_dir);
+    return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, 0,
+                            "Invalid source parent directory '(null)'");
 
   /* TGT_FULLPATH must be valid. */
   if (tgt_fullpath)