You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/10/15 10:52:18 UTC

svn commit: r1532250 [19/37] - in /subversion/branches/cache-server: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/emacs/ contrib/hook-scripts/ contrib/server-side/fsfsfixer/ contrib/se...

Modified: subversion/branches/cache-server/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_serf/xml.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_serf/xml.c Tue Oct 15 08:52:06 2013
@@ -26,6 +26,7 @@
 #include <apr_uri.h>
 #include <serf.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_pools.h"
 #include "svn_ra.h"
@@ -36,7 +37,6 @@
 #include "svn_delta.h"
 #include "svn_path.h"
 
-#include "svn_private_config.h"
 #include "private/svn_string_private.h"
 
 #include "ra_serf.h"
@@ -57,6 +57,7 @@ struct svn_ra_serf__xml_context_t {
   svn_ra_serf__xml_opened_t opened_cb;
   svn_ra_serf__xml_closed_t closed_cb;
   svn_ra_serf__xml_cdata_t cdata_cb;
+  svn_ra_serf__xml_done_t done_cb;
   void *baton;
 
   /* Linked list of free states.  */
@@ -458,11 +459,58 @@ lazy_create_pool(void *baton)
   return xes->state_pool;
 }
 
-void
-svn_ra_serf__xml_context_destroy(
-  svn_ra_serf__xml_context_t *xmlctx)
+svn_error_t *
+svn_ra_serf__xml_context_done(svn_ra_serf__xml_context_t *xmlctx)
 {
+  if (xmlctx->current->prev)
+    {
+      /* Probably unreachable as this would be an xml parser error */
+      return svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
+                               _("XML stream truncated: closing '%s' missing"),
+                               xmlctx->current->tag.name);
+    }
+  else if (! xmlctx->free_states)
+    {
+      /* If we have no items on the free_states list, we didn't push anything,
+         which tells us that we found an empty xml body */
+      const svn_ra_serf__xml_transition_t *scan;
+      const svn_ra_serf__xml_transition_t *document = NULL;
+      const char *msg;
+
+      for (scan = xmlctx->ttable; scan->ns != NULL; ++scan)
+        {
+          if (scan->from_state == XML_STATE_INITIAL)
+            {
+              if (document != NULL)
+                {
+                  document = NULL; /* Multiple document elements defined */
+                  break;
+                }
+              document = scan;
+            }
+        }
+
+      if (document)
+        msg = apr_psprintf(xmlctx->scratch_pool, "'%s' element not found",
+                            document->name);
+      else
+        msg = _("document element not found");
+
+      return svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
+                               _("XML stream truncated: %s"),
+                               msg);
+    }
+
+  if (xmlctx->done_cb != NULL)
+    {
+      START_CALLBACK(xmlctx);
+      SVN_ERR(xmlctx->done_cb(xmlctx->baton,
+                              xmlctx->scratch_pool));
+      END_CALLBACK(xmlctx);
+    }
+
   svn_pool_destroy(xmlctx->scratch_pool);
+  return SVN_NO_ERROR;
 }
 
 svn_ra_serf__xml_context_t *
@@ -471,6 +519,7 @@ svn_ra_serf__xml_context_create(
   svn_ra_serf__xml_opened_t opened_cb,
   svn_ra_serf__xml_closed_t closed_cb,
   svn_ra_serf__xml_cdata_t cdata_cb,
+  svn_ra_serf__xml_done_t done_cb,
   void *baton,
   apr_pool_t *result_pool)
 {
@@ -482,6 +531,7 @@ svn_ra_serf__xml_context_create(
   xmlctx->opened_cb = opened_cb;
   xmlctx->closed_cb = closed_cb;
   xmlctx->cdata_cb = cdata_cb;
+  xmlctx->done_cb = done_cb;
   xmlctx->baton = baton;
   xmlctx->scratch_pool = svn_pool_create(result_pool);
 
@@ -615,6 +665,14 @@ svn_ra_serf__xml_cb_start(svn_ra_serf__x
     }
   if (scan->ns == NULL)
     {
+      if (current->state == XML_STATE_INITIAL)
+        {
+          return svn_error_createf(
+                        SVN_ERR_XML_UNEXPECTED_ELEMENT, NULL,
+                        _("XML Parsing failed: Unexpected root element '%s'"),
+                        elemname.name);
+        }
+
       xmlctx->waiting = elemname;
       /* ### return?  */
       return SVN_NO_ERROR;
@@ -669,10 +727,11 @@ svn_ra_serf__xml_cb_start(svn_ra_serf__x
                   name = *saveattr;
                   value = svn_xml_get_attr_value(name, attrs);
                   if (value == NULL)
-                    return svn_error_createf(SVN_ERR_XML_ATTRIB_NOT_FOUND,
-                                             NULL,
-                                             _("Missing XML attribute: '%s'"),
-                                             name);
+                    return svn_error_createf(
+                                SVN_ERR_XML_ATTRIB_NOT_FOUND,
+                                NULL,
+                                _("Missing XML attribute '%s' on '%s' element"),
+                                name, scan->name);
                 }
 
               if (value)

Modified: subversion/branches/cache-server/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/client.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/client.c Tue Oct 15 08:52:06 2013
@@ -32,6 +32,7 @@
 #include <apr_network_io.h>
 #include <apr_uri.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_types.h"
 #include "svn_string.h"
@@ -47,9 +48,8 @@
 #include "svn_mergeinfo.h"
 #include "svn_version.h"
 
-#include "svn_private_config.h"
-
 #include "private/svn_fspath.h"
+#include "private/svn_subr_private.h"
 
 #include "../libsvn_ra/ra_loader.h"
 
@@ -561,14 +561,42 @@ static svn_error_t *parse_url(const char
   return SVN_NO_ERROR;
 }
 
+/* This structure is used as a baton for the pool cleanup function to
+   store tunnel parameters used by the close-tunnel callback. */
+struct tunnel_data_t {
+  void *tunnel_context;
+  void *tunnel_baton;
+  const char *tunnel_name;
+  const char *user;
+  const char *hostname;
+  int port;
+  svn_ra_close_tunnel_func_t close_tunnel;
+};
+
+/* Pool cleanup function that invokes the close-tunel callback. */
+static apr_status_t close_tunnel_cleanup(void *baton)
+{
+  const struct tunnel_data_t *const td = baton;
+  svn_error_t *const err =
+    svn_error_root_cause(td->close_tunnel(td->tunnel_context, td->tunnel_baton,
+                                          td->tunnel_name, td->user,
+                                          td->hostname, td->port));
+  const apr_status_t ret = (err ? err->apr_err : 0);
+  svn_error_clear(err);
+  return ret;
+}
+
 /* Open a session to URL, returning it in *SESS_P, allocating it in POOL.
    URI is a parsed version of URL.  CALLBACKS and CALLBACKS_BATON
-   are provided by the caller of ra_svn_open. If tunnel_argv is non-null,
-   it points to a program argument list to use when invoking the tunnel agent.
+   are provided by the caller of ra_svn_open. If TUNNEL_NAME is not NULL,
+   it is the name of the tunnel type parsed from the URL scheme.
+   If TUNNEL_ARGV is not NULL, it points to a program argument list to use
+   when invoking the tunnel agent.
 */
 static svn_error_t *open_session(svn_ra_svn__session_baton_t **sess_p,
                                  const char *url,
                                  const apr_uri_t *uri,
+                                 const char *tunnel_name,
                                  const char **tunnel_argv,
                                  const svn_ra_callbacks2_t *callbacks,
                                  void *callbacks_baton,
@@ -583,19 +611,52 @@ static svn_error_t *open_session(svn_ra_
 
   sess = apr_palloc(pool, sizeof(*sess));
   sess->pool = pool;
-  sess->is_tunneled = (tunnel_argv != NULL);
+  sess->is_tunneled = (tunnel_name != NULL);
   sess->url = apr_pstrdup(pool, url);
   sess->user = uri->user;
   sess->hostname = uri->hostname;
   sess->realm_prefix = apr_psprintf(pool, "<svn://%s:%d>", uri->hostname,
                                     uri->port);
+  sess->tunnel_name = tunnel_name;
   sess->tunnel_argv = tunnel_argv;
   sess->callbacks = callbacks;
   sess->callbacks_baton = callbacks_baton;
   sess->bytes_read = sess->bytes_written = 0;
 
-  if (tunnel_argv)
-    SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));
+  if (tunnel_name)
+    {
+      if (tunnel_argv)
+        SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));
+      else
+        {
+          void *tunnel_context;
+          apr_file_t *request;
+          apr_file_t *response;
+          SVN_ERR(callbacks->open_tunnel_func(
+                      &request, &response, &tunnel_context,
+                      callbacks->tunnel_baton, tunnel_name,
+                      uri->user, uri->hostname, uri->port,
+                      pool));
+          if (callbacks->close_tunnel_func)
+            {
+              struct tunnel_data_t *const td = apr_palloc(pool, sizeof(*td));
+              td->tunnel_context = tunnel_context;
+              td->tunnel_baton = callbacks->tunnel_baton;
+              td->tunnel_name = apr_pstrdup(pool, tunnel_name);
+              td->user = apr_pstrdup(pool, uri->user);
+              td->hostname = apr_pstrdup(pool, uri->hostname);
+              td->port = uri->port;
+              td->close_tunnel = callbacks->close_tunnel_func;
+              apr_pool_cleanup_register(pool, td, close_tunnel_cleanup,
+                                        apr_pool_cleanup_null);
+            }
+
+          conn = svn_ra_svn_create_conn3(NULL, response, request,
+                                         SVN_DELTA_COMPRESSION_LEVEL_DEFAULT,
+                                         0, 0, pool);
+          SVN_ERR(svn_ra_svn__skip_leading_garbage(conn, pool));
+        }
+    }
   else
     {
       SVN_ERR(make_connection(uri->hostname, uri->port, &sock, pool));
@@ -701,7 +762,7 @@ static svn_error_t *open_session(svn_ra_
   N_("Module for accessing a repository using the svn network protocol.")
 #endif
 
-static const char *ra_svn_get_description(void)
+static const char *ra_svn_get_description(apr_pool_t *pool)
 {
   return _(RA_SVN_DESCRIPTION);
 }
@@ -738,7 +799,14 @@ static svn_error_t *ra_svn_open(svn_ra_s
 
   parse_tunnel(url, &tunnel, pool);
 
-  if (tunnel)
+  /* Use the default tunnel implementation if we got a tunnel name,
+     but either do not have tunnel handler callbacks installed, or
+     the handlers don't like the tunnel name. */
+  if (tunnel
+      && (!callbacks->open_tunnel_func
+          || (callbacks->check_tunnel_func && callbacks->open_tunnel_func
+              && !callbacks->check_tunnel_func(callbacks->tunnel_baton,
+                                               tunnel))))
     SVN_ERR(find_tunnel_agent(tunnel, uri.hostinfo, &tunnel_argv, config,
                               pool));
   else
@@ -755,7 +823,7 @@ static svn_error_t *ra_svn_open(svn_ra_s
 
   /* We open the session in a subpool so we can get rid of it if we
      reparent with a server that doesn't support reparenting. */
-  SVN_ERR(open_session(&sess, url, &uri, tunnel_argv,
+  SVN_ERR(open_session(&sess, url, &uri, tunnel, tunnel_argv,
                        callbacks, callback_baton, sess_pool));
   session->priv = sess;
 
@@ -791,7 +859,7 @@ static svn_error_t *ra_svn_reparent(svn_
   sess_pool = svn_pool_create(ra_session->pool);
   err = parse_url(url, &uri, sess_pool);
   if (! err)
-    err = open_session(&new_sess, url, &uri, sess->tunnel_argv,
+    err = open_session(&new_sess, url, &uri, sess->tunnel_name, sess->tunnel_argv,
                        sess->callbacks, sess->callbacks_baton, sess_pool);
   /* We destroy the new session pool on error, since it is allocated in
      the main session pool. */
@@ -977,6 +1045,28 @@ static svn_error_t *ra_svn_commit(svn_ra
   const svn_string_t *log_msg = svn_hash_gets(revprop_table,
                                               SVN_PROP_REVISION_LOG);
 
+  if (log_msg == NULL &&
+      ! svn_ra_svn_has_capability(conn, SVN_RA_SVN_CAP_COMMIT_REVPROPS))
+    {
+      return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+                               _("ra_svn does not support not specifying "
+                                 "a log message with pre-1.5 servers; "
+                                 "consider passing an empty one, or upgrading "
+                                 "the server"));
+    } 
+  else if (log_msg == NULL)
+    /* 1.5+ server.  Set LOG_MSG to something, since the 'logmsg' argument
+       to the 'commit' protocol command is non-optional; on the server side,
+       only REVPROP_TABLE will be used, and LOG_MSG will be ignored.  The 
+       "svn:log" member of REVPROP_TABLE table is NULL, therefore the commit
+       will have a NULL log message (not just "", really NULL).
+
+       svnserve 1.5.x+ has always ignored LOG_MSG when REVPROP_TABLE was
+       present; this was elevated to a protocol promise in r1498550 (and
+       later documented in this comment) in order to fix the segmentation
+       fault bug described in the log message of r1498550.*/
+    log_msg = svn_string_create("", pool);
+
   /* If we're sending revprops other than svn:log, make sure the server won't
      silently ignore them. */
   if (apr_hash_count(revprop_table) > 1 &&
@@ -1095,7 +1185,7 @@ parse_iproplist(apr_array_header_t **inh
       new_iprop->path_or_url = svn_path_url_add_component2(repos_root_url,
                                                            parent_rel_path,
                                                            result_pool);
-      new_iprop->prop_hash = apr_hash_make(result_pool);
+      new_iprop->prop_hash = svn_hash__make(result_pool);
       for (hi = apr_hash_first(iterpool, iprops);
            hi;
            hi = apr_hash_next(hi))
@@ -1234,7 +1324,7 @@ static svn_error_t *ra_svn_get_dir(svn_r
     return SVN_NO_ERROR;
 
   /* Interpret the directory list. */
-  *dirents = apr_hash_make(pool);
+  *dirents = svn_hash__make(pool);
   for (i = 0; i < dirlist->nelts; i++)
     {
       const char *name, *kind, *cdate, *cauthor;
@@ -1322,7 +1412,7 @@ static svn_error_t *ra_svn_get_mergeinfo
   *catalog = NULL;
   if (mergeinfo_tuple->nelts > 0)
     {
-      *catalog = apr_hash_make(pool);
+      *catalog = svn_hash__make(pool);
       for (i = 0; i < mergeinfo_tuple->nelts; i++)
         {
           svn_mergeinfo_t for_path;
@@ -1456,16 +1546,20 @@ static svn_error_t *ra_svn_diff(svn_ra_s
 }
 
 
-static svn_error_t *ra_svn_log(svn_ra_session_t *session,
-                               const apr_array_header_t *paths,
-                               svn_revnum_t start, svn_revnum_t end,
-                               int limit,
-                               svn_boolean_t discover_changed_paths,
-                               svn_boolean_t strict_node_history,
-                               svn_boolean_t include_merged_revisions,
-                               const apr_array_header_t *revprops,
-                               svn_log_entry_receiver_t receiver,
-                               void *receiver_baton, apr_pool_t *pool)
+static svn_error_t *
+perform_ra_svn_log(svn_error_t **outer_error,
+                   svn_ra_session_t *session,
+                   const apr_array_header_t *paths,
+                   svn_revnum_t start, svn_revnum_t end,
+                   int limit,
+                   svn_boolean_t discover_changed_paths,
+                   svn_boolean_t strict_node_history,
+                   svn_boolean_t include_merged_revisions,
+                   svn_move_behavior_t move_behavior,
+                   const apr_array_header_t *revprops,
+                   svn_log_entry_receiver_t receiver,
+                   void *receiver_baton,
+                   apr_pool_t *pool)
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
@@ -1475,6 +1569,10 @@ static svn_error_t *ra_svn_log(svn_ra_se
   const char *path;
   char *name;
   svn_boolean_t want_custom_revprops;
+  svn_boolean_t want_author = FALSE;
+  svn_boolean_t want_message = FALSE;
+  svn_boolean_t want_date = FALSE;
+  int nreceived = 0;
 
   SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "log"));
   if (paths)
@@ -1497,17 +1595,27 @@ static svn_error_t *ra_svn_log(svn_ra_se
         {
           name = APR_ARRAY_IDX(revprops, i, char *);
           SVN_ERR(svn_ra_svn__write_cstring(conn, pool, name));
-          if (!want_custom_revprops
-              && strcmp(name, SVN_PROP_REVISION_AUTHOR) != 0
-              && strcmp(name, SVN_PROP_REVISION_DATE) != 0
-              && strcmp(name, SVN_PROP_REVISION_LOG) != 0)
+
+          if (strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
+            want_author = TRUE;
+          else if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
+            want_date = TRUE;
+          else if (strcmp(name, SVN_PROP_REVISION_LOG) == 0)
+            want_message = TRUE;
+          else
             want_custom_revprops = TRUE;
         }
-      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!))"));
+      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)n)",
+                                      (apr_uint64_t) move_behavior));
     }
   else
     {
-      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!w())", "all-revprops"));
+      SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!w()n)", "all-revprops",
+                                      (apr_uint64_t) move_behavior));
+
+      want_author = TRUE;
+      want_date = TRUE;
+      want_message = TRUE;
       want_custom_revprops = TRUE;
     }
 
@@ -1528,7 +1636,6 @@ static svn_error_t *ra_svn_log(svn_ra_se
       svn_ra_svn_item_t *item;
       apr_hash_t *cphash;
       svn_revnum_t rev;
-      int nreceived;
 
       svn_pool_clear(iterpool);
       SVN_ERR(svn_ra_svn__read_item(conn, iterpool, &item));
@@ -1571,11 +1678,12 @@ static svn_error_t *ra_svn_log(svn_ra_se
       if (cplist->nelts > 0)
         {
           /* Interpret the changed-paths list. */
-          cphash = apr_hash_make(iterpool);
+          cphash = svn_hash__make(iterpool);
           for (i = 0; i < cplist->nelts; i++)
             {
               svn_log_changed_path2_t *change;
-              const char *copy_path, *action, *cpath, *kind_str;
+              svn_string_t *cpath;
+              const char *copy_path, *action, *kind_str;
               apr_uint64_t text_mods, prop_mods;
               svn_revnum_t copy_rev;
               svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(cplist, i,
@@ -1584,14 +1692,19 @@ static svn_error_t *ra_svn_log(svn_ra_se
               if (elt->kind != SVN_RA_SVN_LIST)
                 return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                         _("Changed-path entry not a list"));
-              SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool,
-                                              "cw(?cr)?(?c?BB)",
+              SVN_ERR(svn_ra_svn__read_data_log_changed_entry(elt->u.list,
                                               &cpath, &action, &copy_path,
                                               &copy_rev, &kind_str,
                                               &text_mods, &prop_mods));
-              cpath = svn_fspath__canonicalize(cpath, iterpool);
-              if (copy_path)
+
+              if (!svn_fspath__is_canonical(cpath->data))
+                {
+                  cpath->data = svn_fspath__canonicalize(cpath->data, iterpool);
+                  cpath->len = strlen(cpath->data);
+                }
+              if (copy_path && !svn_fspath__is_canonical(copy_path))
                 copy_path = svn_fspath__canonicalize(copy_path, iterpool);
+
               change = svn_log_changed_path2_create(iterpool);
               change->action = *action;
               change->copyfrom_path = copy_path;
@@ -1599,15 +1712,20 @@ static svn_error_t *ra_svn_log(svn_ra_se
               change->node_kind = svn_node_kind_from_word(kind_str);
               change->text_modified = optbool_to_tristate(text_mods);
               change->props_modified = optbool_to_tristate(prop_mods);
-              svn_hash_sets(cphash, cpath, change);
+              apr_hash_set(cphash, cpath->data, cpath->len, change);
             }
         }
       else
         cphash = NULL;
 
-      nreceived = 0;
-      if (! (limit && (nest_level == 0) && (++nreceived > limit)))
+      /* Invoke RECEIVER
+          - Except if the server sends more than a >= 1 limit top level items
+          - Or when the callback reported a SVN_ERR_CEASE_INVOCATION
+            in an earlier invocation. */
+      if (! (limit && (nest_level == 0) && (++nreceived > limit))
+          && ! *outer_error)
         {
+          svn_error_t *err;
           log_entry = svn_log_entry_create(iterpool);
 
           log_entry->changed_paths = cphash;
@@ -1619,38 +1737,27 @@ static svn_error_t *ra_svn_log(svn_ra_se
             SVN_ERR(svn_ra_svn__parse_proplist(rplist, iterpool,
                                                &log_entry->revprops));
           if (log_entry->revprops == NULL)
-            log_entry->revprops = apr_hash_make(iterpool);
-          if (revprops == NULL)
+            log_entry->revprops = svn_hash__make(iterpool);
+
+          if (author && want_author)
+            svn_hash_sets(log_entry->revprops,
+                          SVN_PROP_REVISION_AUTHOR, author);
+          if (date && want_date)
+            svn_hash_sets(log_entry->revprops,
+                          SVN_PROP_REVISION_DATE, date);
+          if (message && want_message)
+            svn_hash_sets(log_entry->revprops,
+                          SVN_PROP_REVISION_LOG, message);
+
+          err = receiver(receiver_baton, log_entry, iterpool);
+          if (err && err->apr_err == SVN_ERR_CEASE_INVOCATION)
             {
-              /* Caller requested all revprops; set author/date/log. */
-              if (author)
-                svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
-                              author);
-              if (date)
-                svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_DATE,
-                              date);
-              if (message)
-                svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_LOG,
-                              message);
+              *outer_error = svn_error_trace(
+                                svn_error_compose_create(*outer_error, err));
             }
           else
-            {
-              /* Caller requested some; maybe set author/date/log. */
-              for (i = 0; i < revprops->nelts; i++)
-                {
-                  name = APR_ARRAY_IDX(revprops, i, char *);
-                  if (author && strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
-                    svn_hash_sets(log_entry->revprops,
-                                  SVN_PROP_REVISION_AUTHOR, author);
-                  if (date && strcmp(name, SVN_PROP_REVISION_DATE) == 0)
-                    svn_hash_sets(log_entry->revprops,
-                                  SVN_PROP_REVISION_DATE, date);
-                  if (message && strcmp(name, SVN_PROP_REVISION_LOG) == 0)
-                    svn_hash_sets(log_entry->revprops,
-                                  SVN_PROP_REVISION_LOG, message);
-                }
-            }
-          SVN_ERR(receiver(receiver_baton, log_entry, iterpool));
+            SVN_ERR(err);
+
           if (log_entry->has_children)
             {
               nest_level++;
@@ -1665,10 +1772,42 @@ static svn_error_t *ra_svn_log(svn_ra_se
   svn_pool_destroy(iterpool);
 
   /* Read the response. */
-  return svn_ra_svn__read_cmd_response(conn, pool, "");
+  return svn_error_trace(svn_ra_svn__read_cmd_response(conn, pool, ""));
+}
+
+static svn_error_t *
+ra_svn_log(svn_ra_session_t *session,
+           const apr_array_header_t *paths,
+           svn_revnum_t start, svn_revnum_t end,
+           int limit,
+           svn_boolean_t discover_changed_paths,
+           svn_boolean_t strict_node_history,
+           svn_boolean_t include_merged_revisions,
+           svn_move_behavior_t move_behavior,
+           const apr_array_header_t *revprops,
+           svn_log_entry_receiver_t receiver,
+           void *receiver_baton, apr_pool_t *pool)
+{
+  svn_error_t *outer_error = NULL;
+  svn_error_t *err;
+
+  err = svn_error_trace(perform_ra_svn_log(&outer_error,
+                                           session, paths,
+                                           start, end,
+                                           limit,
+                                           discover_changed_paths,
+                                           strict_node_history,
+                                           include_merged_revisions,
+                                           move_behavior, revprops,
+                                           receiver, receiver_baton,
+                                           pool));
+  return svn_error_trace(
+            svn_error_compose_create(outer_error,
+                                     err));
 }
 
 
+
 static svn_error_t *ra_svn_check_path(svn_ra_session_t *session,
                                       const char *path, svn_revnum_t rev,
                                       svn_node_kind_t *kind, apr_pool_t *pool)
@@ -1942,7 +2081,7 @@ static svn_error_t *ra_svn_get_file_revs
         {
           svn_stream_t *stream;
 
-          if (d_handler)
+          if (d_handler && d_handler != svn_delta_noop_window_handler)
             stream = svn_txdelta_parse_svndiff(d_handler, d_baton, TRUE,
                                                rev_pool);
           else
@@ -2709,7 +2848,7 @@ svn_ra_svn__init(const svn_version_t *lo
       { NULL, NULL }
     };
 
-  SVN_ERR(svn_ver_check_list(svn_ra_svn_version(), checklist));
+  SVN_ERR(svn_ver_check_list2(svn_ra_svn_version(), checklist, svn_ver_equal));
 
   /* Simplified version check to make sure we can safely use the
      VTABLE parameter. The RA loader does a more exhaustive check. */

Propchange: subversion/branches/cache-server/subversion/libsvn_ra_svn/deprecated.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/cache-server/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/editorp.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/editorp.c Tue Oct 15 08:52:06 2013
@@ -28,6 +28,7 @@
 #include <apr_general.h>
 #include <apr_strings.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_types.h"
 #include "svn_string.h"
@@ -37,7 +38,6 @@
 #include "svn_ra_svn.h"
 #include "svn_path.h"
 #include "svn_pools.h"
-#include "svn_private_config.h"
 
 #include "private/svn_fspath.h"
 #include "private/svn_editor.h"

Modified: subversion/branches/cache-server/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/marshal.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/marshal.c Tue Oct 15 08:52:06 2013
@@ -32,13 +32,13 @@
 #include <apr_lib.h>
 #include <apr_strings.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_types.h"
 #include "svn_string.h"
 #include "svn_error.h"
 #include "svn_pools.h"
 #include "svn_ra_svn.h"
-#include "svn_private_config.h"
 #include "svn_ctype.h"
 #include "svn_time.h"
 
@@ -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,6 +57,19 @@
 
 #define SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD (0x100000)
 
+/* 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
@@ -397,7 +411,7 @@ static svn_error_t *readbuf_fill(svn_ra_
   return SVN_NO_ERROR;
 }
 
-static APR_INLINE svn_error_t *
+static SVN__FORCE_INLINE svn_error_t *
 readbuf_getchar(svn_ra_svn_conn_t *conn, apr_pool_t *pool, char *result)
 {
   if (conn->read_ptr == conn->read_end)
@@ -511,21 +525,32 @@ svn_ra_svn__write_number(svn_ra_svn_conn
   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_string(svn_ra_svn_conn_t *conn,
+                         apr_pool_t *pool,
+                         const svn_string_t *str)
+{
+  svn_ra_svn__write_ncstring(conn, pool, str->data, str->len);
   return SVN_NO_ERROR;
 }
 
@@ -534,19 +559,7 @@ svn_ra_svn__write_cstring(svn_ra_svn_con
                           apr_pool_t *pool,
                           const char *s)
 {
-  apr_size_t len = strlen(s);
-
-  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_ERR(writebuf_write(conn, pool, s, len));
-  SVN_ERR(writebuf_writechar(conn, pool, ' '));
-
+  svn_ra_svn__write_ncstring(conn, pool, s, strlen(s));
   return SVN_NO_ERROR;
 }
 
@@ -562,31 +575,45 @@ svn_ra_svn__write_word(svn_ra_svn_conn_t
 }
 
 svn_error_t *
+svn_ra_svn__write_boolean(svn_ra_svn_conn_t *conn,
+                          apr_pool_t *pool,
+                          svn_boolean_t value)
+{
+  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)
 {
-  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;
 }
@@ -704,8 +731,7 @@ vwrite_tuple_number(svn_ra_svn_conn_t *c
 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 *
@@ -780,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 *
@@ -929,7 +954,6 @@ svn_ra_svn__write_tuple(svn_ra_svn_conn_
 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;
@@ -940,58 +964,60 @@ 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;
-
-      /* 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);
+  /* 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;
+
+          /* 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;
 }
 
 /* Given the first non-whitespace character FIRST_CHAR, read an item
  * into the already allocated structure ITEM.  LEVEL should be set
- * to 0 for the first call and is used to enforce a recurssion limit
+ * to 0 for the first call and is used to enforce a recursion limit
  * on the parser. */
 static svn_error_t *read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                               svn_ra_svn_item_t *item, char first_char,
@@ -999,12 +1025,11 @@ static svn_error_t *read_item(svn_ra_svn
 {
   char c = first_char;
   apr_uint64_t val;
-  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
@@ -1022,7 +1047,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"));
         }
@@ -1041,31 +1067,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));
     }
@@ -1202,14 +1269,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)
@@ -1221,6 +1289,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)
@@ -1230,13 +1302,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
@@ -1268,6 +1344,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;
@@ -1342,7 +1421,7 @@ svn_ra_svn__parse_proplist(const apr_arr
   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);
@@ -1455,6 +1534,58 @@ svn_ra_svn__read_cmd_response(svn_ra_svn
                            status);
 }
 
+static svn_error_t *
+svn_ra_svn__handle_command(svn_boolean_t *terminate,
+                           apr_hash_t *cmd_hash,
+                           void *baton,
+                           svn_ra_svn_conn_t *conn,
+                           svn_boolean_t error_on_disconnect,
+                           apr_pool_t *iterpool)
+{
+  const char *cmdname;
+  svn_error_t *err, *write_err;
+  apr_array_header_t *params;
+  const svn_ra_svn_cmd_entry_t *command;
+
+  err = svn_ra_svn__read_tuple(conn, iterpool, "wl", &cmdname, &params);
+  if (err)
+    {
+      if (!error_on_disconnect
+          && err->apr_err == SVN_ERR_RA_SVN_CONNECTION_CLOSED)
+        {
+          svn_error_clear(err);
+          *terminate = TRUE;
+          return SVN_NO_ERROR;
+        }
+      return err;
+    }
+  command = svn_hash_gets(cmd_hash, cmdname);
+
+  if (command)
+    err = (*command->handler)(conn, iterpool, params, baton);
+  else
+    {
+      err = svn_error_createf(SVN_ERR_RA_SVN_UNKNOWN_CMD, NULL,
+                              _("Unknown editor command '%s'"), cmdname);
+      err = svn_error_create(SVN_ERR_RA_SVN_CMD_ERR, err, NULL);
+    }
+
+  if (err && err->apr_err == SVN_ERR_RA_SVN_CMD_ERR)
+    {
+      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;
+    }
+  else if (err)
+    return err;
+
+  *terminate = (command && command->terminate);
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_ra_svn__handle_commands2(svn_ra_svn_conn_t *conn,
                              apr_pool_t *pool,
@@ -1464,10 +1595,7 @@ svn_ra_svn__handle_commands2(svn_ra_svn_
 {
   apr_pool_t *subpool = svn_pool_create(pool);
   apr_pool_t *iterpool = svn_pool_create(subpool);
-  const char *cmdname;
   const svn_ra_svn_cmd_entry_t *command;
-  svn_error_t *err, *write_err;
-  apr_array_header_t *params;
   apr_hash_t *cmd_hash = apr_hash_make(subpool);
 
   for (command = commands; command->cmdname; command++)
@@ -1475,43 +1603,18 @@ svn_ra_svn__handle_commands2(svn_ra_svn_
 
   while (1)
     {
+      svn_boolean_t terminate;
+      svn_error_t *err;
       svn_pool_clear(iterpool);
-      err = svn_ra_svn__read_tuple(conn, iterpool, "wl", &cmdname, &params);
-      if (err)
-        {
-          if (!error_on_disconnect
-              && err->apr_err == SVN_ERR_RA_SVN_CONNECTION_CLOSED)
-            {
-              svn_error_clear(err);
-              svn_pool_destroy(subpool);
-              return SVN_NO_ERROR;
-            }
-          return err;
-        }
-      command = svn_hash_gets(cmd_hash, cmdname);
 
-      if (command)
-        err = (*command->handler)(conn, iterpool, params, baton);
-      else
-        {
-          err = svn_error_createf(SVN_ERR_RA_SVN_UNKNOWN_CMD, NULL,
-                                  _("Unknown editor command '%s'"), cmdname);
-          err = svn_error_create(SVN_ERR_RA_SVN_CMD_ERR, err, NULL);
-        }
-
-      if (err && err->apr_err == SVN_ERR_RA_SVN_CMD_ERR)
+      err = svn_ra_svn__handle_command(&terminate, cmd_hash, baton, conn,
+                                       error_on_disconnect, iterpool);
+      if (err)
         {
-          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;
+          svn_pool_destroy(subpool);
+          return svn_error_trace(err);
         }
-      else if (err)
-        return err;
-
-      if (command && command->terminate)
+      if (terminate)
         break;
     }
   svn_pool_destroy(iterpool);
@@ -2287,3 +2390,217 @@ svn_error_t *svn_ra_svn__write_cmd_failu
     }
   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,
+                                 unsigned 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;
+}
+
+/* If condition COND is not met, return a "malformed network data" error.
+ */
+#define CHECK_PROTOCOL_COND(cond)\
+  if (!(cond)) \
+    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL, \
+                            _("Malformed network data"));
+
+/* In *RESULT, return the SVN-style string at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_string(const apr_array_header_t *items,
+                        int idx,
+                        svn_string_t **result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_STRING);
+  *result = elt->u.string;
+    
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the C-style string at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_cstring(const apr_array_header_t *items,
+                         int idx,
+                         const char **result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_STRING);
+  *result = elt->u.string->data;
+    
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the word at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_word(const apr_array_header_t *items,
+                      int idx,
+                      const char **result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_WORD);
+  *result = elt->u.word;
+   
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the revision at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_revision(const apr_array_header_t *items,
+                          int idx,
+                          svn_revnum_t *result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_NUMBER);
+  *result = (svn_revnum_t)elt->u.number;
+    
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the boolean at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_boolean(const apr_array_header_t *items,
+                         int idx,
+                         apr_uint64_t *result)
+{
+  svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_WORD);
+  if (elt->u.word[0] == 't' && strcmp(elt->u.word, "true") == 0)
+    *result = TRUE;
+  else if (strcmp(elt->u.word, "false") == 0)
+    *result = FALSE;
+  else
+    CHECK_PROTOCOL_COND(FALSE);
+    
+  return SVN_NO_ERROR;
+}
+
+/* In *RESULT, return the tuple at index IDX in tuple ITEMS.
+ */
+static svn_error_t *
+svn_ra_svn__read_list(const apr_array_header_t *items,
+                      int idx,
+                      const apr_array_header_t **result)
+{
+  svn_ra_svn_item_t *elt  = &APR_ARRAY_IDX(items, idx, svn_ra_svn_item_t);
+  CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_LIST);
+
+  *result = elt->u.list;
+  return SVN_NO_ERROR;
+}
+
+/* Verify the tuple ITEMS contains at least MIN and at most MAX elements.
+ */
+static svn_error_t *
+svn_ra_svn__read_check_array_size(const apr_array_header_t *items,
+                                  int min,
+                                  int max)
+{
+  CHECK_PROTOCOL_COND(items->nelts >= min && items->nelts <= max);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__read_data_log_changed_entry(const apr_array_header_t *items,
+                                        svn_string_t **cpath,
+                                        const char **action,
+                                        const char **copy_path,
+                                        svn_revnum_t *copy_rev,
+                                        const char **kind_str,
+                                        apr_uint64_t *text_mods,
+                                        apr_uint64_t *prop_mods)
+{
+  const apr_array_header_t *sub_items;
+
+  /* initialize optional values */
+  *copy_path = NULL;
+  *copy_rev = SVN_INVALID_REVNUM;
+  *kind_str = NULL;
+  *text_mods = SVN_RA_SVN_UNSPECIFIED_NUMBER;
+  *prop_mods = SVN_RA_SVN_UNSPECIFIED_NUMBER;
+
+  /* top-level elements (mandatory) */
+  SVN_ERR(svn_ra_svn__read_check_array_size(items, 3, 4));
+  SVN_ERR(svn_ra_svn__read_string(items, 0, cpath));
+  SVN_ERR(svn_ra_svn__read_word(items, 1, action));
+
+  /* first sub-structure (mandatory) */
+  SVN_ERR(svn_ra_svn__read_list(items, 2, &sub_items));
+  if (sub_items->nelts)
+    {
+      SVN_ERR(svn_ra_svn__read_check_array_size(sub_items, 2, 2));
+      SVN_ERR(svn_ra_svn__read_cstring(sub_items, 0, copy_path));
+      SVN_ERR(svn_ra_svn__read_revision(sub_items, 1, copy_rev));
+    }
+
+  /* second sub-structure (optional) */
+  if (items->nelts == 4)
+    {
+      SVN_ERR(svn_ra_svn__read_list(items, 3, &sub_items));
+      SVN_ERR(svn_ra_svn__read_check_array_size(sub_items, 0, 3));
+
+      switch (sub_items->nelts)
+        {
+          case 3 : SVN_ERR(svn_ra_svn__read_boolean(sub_items, 2, prop_mods));
+          case 2 : SVN_ERR(svn_ra_svn__read_boolean(sub_items, 1, text_mods));
+          case 1 : SVN_ERR(svn_ra_svn__read_cstring(sub_items, 0, kind_str));
+          default: break;
+        }
+    }
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/cache-server/subversion/libsvn_ra_svn/protocol
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/protocol?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/protocol (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/protocol Tue Oct 15 08:52:06 2013
@@ -294,8 +294,12 @@ second place for auth-request point as n
     Upon receiving response, client switches to editor command set.
     Upon successful completion of edit, server sends auth-request.
     After auth exchange completes, server sends commit-info.
+    If rev-props is present, logmsg is ignored.  Only the svn:log entry in
+    rev-props (if any) will be used.
     commit-info: ( new-rev:number date:string author:string
                    ? ( post-commit-err:string ) )
+    NOTE: when revving this, make 'logmsg' optional, or delete that parameter
+          and have the log message specified in 'rev-props'.
 
   get-file
     params:   ( path:string [ rev:number ] want-props:bool want-contents:bool
@@ -378,11 +382,13 @@ second place for auth-request point as n
                 [ end-rev:number ] changed-paths:bool strict-node:bool
                 ? limit:number
                 ? include-merged-revisions:bool
-                all-revprops | revprops ( revprop:string ... ) )
+                all-revprops | revprops ( revprop:string ... )
+                ? move-behavior:number )
     Before sending response, server sends log entries, ending with "done".
     If a client does not want to specify a limit, it should send 0 as the
     limit parameter.  rev-props excludes author, date, and log; they are
     sent separately for backwards-compatibility.
+    Move-behavior is encoded like enum svn_move_behavior_t.
     log-entry: ( ( change:changed-path-entry ... ) rev:number
                  [ author:string ] [ date:string ] [ message:string ]
                  ? has-children:bool invalid-revnum:bool
@@ -591,7 +597,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/cache-server/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_ra_svn/ra_svn.h?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/cache-server/subversion/libsvn_ra_svn/ra_svn.h Tue Oct 15 08:52:06 2013
@@ -127,6 +127,7 @@ struct svn_ra_svn__session_baton_t {
   const char *user;
   const char *hostname; /* The remote hostname. */
   const char *realm_prefix;
+  const char *tunnel_name;
   const char **tunnel_argv;
   const svn_ra_callbacks2_t *callbacks;
   void *callbacks_baton;

Modified: subversion/branches/cache-server/subversion/libsvn_repos/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_repos/authz.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_repos/authz.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_repos/authz.c Tue Oct 15 08:52:06 2013
@@ -26,6 +26,7 @@
 #include <apr_pools.h>
 #include <apr_file_io.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_pools.h"
 #include "svn_error.h"
@@ -853,23 +854,9 @@ authz_retrieve_config_repo(svn_config_t 
   return SVN_NO_ERROR;
 }
 
-/* Given a PATH which might be a relative repo URL (^/), an absolute
- * local repo URL (file://), an absolute path outside of the repo
- * or a location in the Windows registry.
- *
- * Retrieve the configuration data that PATH points at and parse it into
- * CFG_P allocated in POOL.
- *
- * If PATH cannot be parsed as a config file then an error is returned.  The
- * contents of CFG_P is then undefined.  If MUST_EXIST is TRUE, a missing
- * authz file is also an error.
- *
- * REPOS_ROOT points at the root of the repos you are
- * going to apply the authz against, can be NULL if you are sure that you
- * don't have a repos relative URL in PATH. */
-static svn_error_t *
-authz_retrieve_config(svn_config_t **cfg_p, const char *path,
-                      svn_boolean_t must_exist, apr_pool_t *pool)
+svn_error_t *
+svn_repos__retrieve_config(svn_config_t **cfg_p, const char *path,
+                           svn_boolean_t must_exist, apr_pool_t *pool)
 {
   if (svn_path_is_url(path))
     {
@@ -942,7 +929,7 @@ svn_repos__authz_read(svn_authz_t **auth
 
   /* Load the authz file */
   if (accept_urls)
-    SVN_ERR(authz_retrieve_config(&authz->cfg, path, must_exist, pool));
+    SVN_ERR(svn_repos__retrieve_config(&authz->cfg, path, must_exist, pool));
   else
     SVN_ERR(svn_config_read3(&authz->cfg, path, must_exist, TRUE, TRUE, pool));
 
@@ -953,8 +940,8 @@ svn_repos__authz_read(svn_authz_t **auth
 
       /* Load the groups file */
       if (accept_urls)
-        SVN_ERR(authz_retrieve_config(&groups_cfg, groups_path, must_exist,
-                                      pool));
+        SVN_ERR(svn_repos__retrieve_config(&groups_cfg, groups_path,
+                                           must_exist, pool));
       else
         SVN_ERR(svn_config_read3(&groups_cfg, groups_path, must_exist,
                                  TRUE, TRUE, pool));

Modified: subversion/branches/cache-server/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_repos/commit.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_repos/commit.c Tue Oct 15 08:52:06 2013
@@ -26,6 +26,7 @@
 #include <apr_pools.h>
 #include <apr_file_io.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_compat.h"
 #include "svn_pools.h"
@@ -39,7 +40,6 @@
 #include "svn_ctype.h"
 #include "svn_props.h"
 #include "svn_mergeinfo.h"
-#include "svn_private_config.h"
 
 #include "repos.h"
 
@@ -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);
@@ -1192,15 +1120,15 @@ static svn_error_t *
 alter_file_cb(void *baton,
               const char *relpath,
               svn_revnum_t revision,
-              apr_hash_t *props,
               const svn_checksum_t *checksum,
               svn_stream_t *contents,
+              apr_hash_t *props,
               apr_pool_t *scratch_pool)
 {
   struct ev2_baton *eb = baton;
 
-  SVN_ERR(svn_editor_alter_file(eb->inner, relpath, revision, props,
-                                checksum, contents));
+  SVN_ERR(svn_editor_alter_file(eb->inner, relpath, revision,
+                                checksum, contents, props));
   return SVN_NO_ERROR;
 }
 
@@ -1210,14 +1138,14 @@ static svn_error_t *
 alter_symlink_cb(void *baton,
                  const char *relpath,
                  svn_revnum_t revision,
-                 apr_hash_t *props,
                  const char *target,
+                 apr_hash_t *props,
                  apr_pool_t *scratch_pool)
 {
   struct ev2_baton *eb = baton;
 
-  SVN_ERR(svn_editor_alter_symlink(eb->inner, relpath, revision, props,
-                                   target));
+  SVN_ERR(svn_editor_alter_symlink(eb->inner, relpath, revision,
+                                   target, props));
   return SVN_NO_ERROR;
 }
 
@@ -1270,20 +1198,6 @@ move_cb(void *baton,
 }
 
 
-/* This implements svn_editor_cb_rotate_t */
-static svn_error_t *
-rotate_cb(void *baton,
-          const apr_array_header_t *relpaths,
-          const apr_array_header_t *revisions,
-          apr_pool_t *scratch_pool)
-{
-  struct ev2_baton *eb = baton;
-
-  SVN_ERR(svn_editor_rotate(eb->inner, relpaths, revisions));
-  return SVN_NO_ERROR;
-}
-
-
 /* This implements svn_editor_cb_complete_t */
 static svn_error_t *
 complete_cb(void *baton,
@@ -1405,7 +1319,6 @@ svn_repos__get_commit_ev2(svn_editor_t *
     delete_cb,
     copy_cb,
     move_cb,
-    rotate_cb,
     complete_cb,
     abort_cb
   };

Modified: subversion/branches/cache-server/subversion/libsvn_repos/delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_repos/delta.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_repos/delta.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_repos/delta.c Tue Oct 15 08:52:06 2013
@@ -24,6 +24,7 @@
 
 #include <apr_hash.h>
 
+#include "svn_private_config.h"
 #include "svn_hash.h"
 #include "svn_types.h"
 #include "svn_delta.h"
@@ -33,7 +34,6 @@
 #include "svn_repos.h"
 #include "svn_pools.h"
 #include "svn_props.h"
-#include "svn_private_config.h"
 #include "repos.h"
 
 
@@ -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)

Modified: subversion/branches/cache-server/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/libsvn_repos/deprecated.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/cache-server/subversion/libsvn_repos/deprecated.c Tue Oct 15 08:52:06 2013
@@ -26,13 +26,12 @@
    deprecated functions in this file. */
 #define SVN_DEPRECATED
 
+#include "svn_private_config.h"
 #include "svn_repos.h"
 #include "svn_compat.h"
 #include "svn_hash.h"
 #include "svn_props.h"
 
-#include "svn_private_config.h"
-
 #include "repos.h"
 
 
@@ -473,6 +472,30 @@ svn_repos_fs_get_locks(apr_hash_t **lock
 
 /*** From logs.c ***/
 svn_error_t *
+svn_repos_get_logs4(svn_repos_t *repos,
+                    const apr_array_header_t *paths,
+                    svn_revnum_t start,
+                    svn_revnum_t end,
+                    int limit,
+                    svn_boolean_t discover_changed_paths,
+                    svn_boolean_t strict_node_history,
+                    svn_boolean_t include_merged_revisions,
+                    const apr_array_header_t *revprops,
+                    svn_repos_authz_func_t authz_read_func,
+                    void *authz_read_baton,
+                    svn_log_entry_receiver_t receiver,
+                    void *receiver_baton,
+                    apr_pool_t *pool)
+{
+  return svn_repos_get_logs5(repos, paths, start, end, limit,
+                             discover_changed_paths, strict_node_history,
+                             include_merged_revisions,
+                             svn_move_behavior_no_moves, revprops,
+                             authz_read_func, authz_read_baton,
+                             receiver, receiver_baton, pool);
+}
+
+svn_error_t *
 svn_repos_get_logs3(svn_repos_t *repos,
                     const apr_array_header_t *paths,
                     svn_revnum_t start,
@@ -727,6 +750,27 @@ svn_repos_dump_fs2(svn_repos_t *repos,
 }
 
 svn_error_t *
+svn_repos_verify_fs2(svn_repos_t *repos,
+                     svn_revnum_t start_rev,
+                     svn_revnum_t end_rev,
+                     svn_repos_notify_func_t notify_func,
+                     void *notify_baton,
+                     svn_cancel_func_t cancel_func,
+                     void *cancel_baton,
+                     apr_pool_t *pool)
+{
+  return svn_error_trace(svn_repos_verify_fs3(repos,
+                                              start_rev,
+                                              end_rev,
+                                              FALSE,
+                                              notify_func,
+                                              notify_baton,
+                                              cancel_func,
+                                              cancel_baton,
+                                              pool));
+}
+
+svn_error_t *
 svn_repos_verify_fs(svn_repos_t *repos,
                     svn_stream_t *feedback_stream,
                     svn_revnum_t start_rev,