subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ar...@apache.org
Subject svn commit: r1367002 [10/21] - in /subversion/branches/svn-bisect: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/client-side/emacs/ contrib/server-side/mod_dontdothat/ notes/ notes/api-errata/1.7/ notes/http-and-webdav/...
Date Mon, 30 Jul 2012 06:39:38 GMT
Modified: subversion/branches/svn-bisect/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_fs_fs/fs_fs.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_fs_fs/fs_fs.h Mon Jul 30 06:39:28 2012
@@ -42,13 +42,21 @@ svn_error_t *svn_fs_fs__upgrade(svn_fs_t
 svn_error_t *svn_fs_fs__verify(svn_fs_t *fs,
                                svn_cancel_func_t cancel_func,
                                void *cancel_baton,
+                               svn_revnum_t start,
+                               svn_revnum_t end,
                                apr_pool_t *pool);
 
-/* Copy the fsfs filesystem at SRC_PATH into a new copy at DST_PATH.
-   Use POOL for temporary allocations. */
-svn_error_t *svn_fs_fs__hotcopy(const char *src_path,
-                                const char *dst_path,
-                                apr_pool_t *pool);
+/* Copy the fsfs filesystem SRC_FS at SRC_PATH into a new copy DST_FS at
+ * DST_PATH. If INCREMENTAL is TRUE, do not re-copy data which already
+ * exists in DST_FS. Use POOL for temporary allocations. */
+svn_error_t * svn_fs_fs__hotcopy(svn_fs_t *src_fs,
+                                 svn_fs_t *dst_fs,
+                                 const char *src_path,
+                                 const char *dst_path,
+                                 svn_boolean_t incremental,
+                                 svn_cancel_func_t cancel_func,
+                                 void *cancel_baton,
+                                 apr_pool_t *pool);
 
 /* Recover the fsfs associated with filesystem FS.
    Use optional CANCEL_FUNC/CANCEL_BATON for cancellation support.
@@ -100,6 +108,12 @@ svn_error_t *svn_fs_fs__youngest_rev(svn
                                      svn_fs_t *fs,
                                      apr_pool_t *pool);
 
+/* Return an error iff REV does not exist in FS. */
+svn_error_t *
+svn_fs_fs__revision_exists(svn_revnum_t rev,
+                           svn_fs_t *fs,
+                           apr_pool_t *pool);
+
 /* Set *ROOT_ID to the node-id for the root of revision REV in
    filesystem FS.  Do any allocations in POOL. */
 svn_error_t *svn_fs_fs__rev_get_root(svn_fs_id_t **root_id,
@@ -117,14 +131,15 @@ svn_error_t *svn_fs_fs__rep_contents_dir
                                          apr_pool_t *pool);
 
 /* Set *DIRENT to the entry identified by NAME in the directory given
-   by NODEREV in filesystem FS.  The returned object is allocated in POOL,
-   which is also used for temporary allocations. */
+   by NODEREV in filesystem FS.  The returned object is allocated in
+   RESULT_POOL; SCRATCH_POOL used for temporary allocations. */
 svn_error_t *
 svn_fs_fs__rep_contents_dir_entry(svn_fs_dirent_t **dirent,
                                   svn_fs_t *fs,
                                   node_revision_t *noderev,
                                   const char *name,
-                                  apr_pool_t *pool);
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool);
 
 /* Set *CONTENTS to be a readable svn_stream_t that receives the text
    representation of node-revision NODEREV as seen in filesystem FS.

Modified: subversion/branches/svn-bisect/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_fs_fs/id.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_fs_fs/id.c Mon Jul 30 06:39:28 2012
@@ -242,7 +242,7 @@ svn_fs_fs__id_parse(const char *data,
 {
   svn_fs_id_t *id;
   id_private_t *pvt;
-  char *data_copy, *str, *last_str;
+  char *data_copy, *str;
 
   /* Dup the ID data into POOL.  Our returned ID will have references
      into this memory. */
@@ -255,24 +255,25 @@ svn_fs_fs__id_parse(const char *data,
   id->fsap_data = pvt;
 
   /* Now, we basically just need to "split" this data on `.'
-     characters.  We will use apr_strtok, which will put terminators
-     where each of the '.'s used to be.  Then our new id field will
-     reference string locations inside our duplicate string.*/
+     characters.  We will use svn_cstring_tokenize, which will put
+     terminators where each of the '.'s used to be.  Then our new
+     id field will reference string locations inside our duplicate
+     string.*/
 
   /* Node Id */
-  str = apr_strtok(data_copy, ".", &last_str);
+  str = svn_cstring_tokenize(".", &data_copy);
   if (str == NULL)
     return NULL;
   pvt->node_id = str;
 
   /* Copy Id */
-  str = apr_strtok(NULL, ".", &last_str);
+  str = svn_cstring_tokenize(".", &data_copy);
   if (str == NULL)
     return NULL;
   pvt->copy_id = str;
 
   /* Txn/Rev Id */
-  str = apr_strtok(NULL, ".", &last_str);
+  str = svn_cstring_tokenize(".", &data_copy);
   if (str == NULL)
     return NULL;
 
@@ -284,12 +285,13 @@ svn_fs_fs__id_parse(const char *data,
       /* This is a revision type ID */
       pvt->txn_id = NULL;
 
-      str = apr_strtok(str + 1, "/", &last_str);
+      data_copy = str + 1;
+      str = svn_cstring_tokenize("/", &data_copy);
       if (str == NULL)
         return NULL;
       pvt->rev = SVN_STR_TO_REV(str);
 
-      str = apr_strtok(NULL, "/", &last_str);
+      str = svn_cstring_tokenize("/", &data_copy);
       if (str == NULL)
         return NULL;
       err = svn_cstring_atoi64(&val, str);

Modified: subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache-db.sql
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache-db.sql (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache-db.sql Mon Jul 30 06:39:28 2012
@@ -47,8 +47,19 @@ INSERT OR FAIL INTO rep_cache (hash, rev
 VALUES (?1, ?2, ?3, ?4, ?5)
 
 
--- STMT_GET_ALL_REPS
+-- STMT_GET_REPS_FOR_RANGE
 SELECT hash, revision, offset, size, expanded_size
 FROM rep_cache
+WHERE revision >= ?1 AND revision <= ?2
+
+
+-- STMT_GET_MAX_REV
+SELECT MAX(revision)
+FROM rep_cache
+
+
+-- STMT_DEL_REPS_YOUNGER_THAN_REV
+DELETE FROM rep_cache
+WHERE revision > ?1
 
 

Modified: subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache.c Mon Jul 30 06:39:28 2012
@@ -56,24 +56,9 @@ rep_has_been_born(representation_t *rep,
                   svn_fs_t *fs,
                   apr_pool_t *pool)
 {
-  fs_fs_data_t *ffd = fs->fsap_data;
-  svn_revnum_t youngest;
-
   SVN_ERR_ASSERT(rep);
 
-  youngest = ffd->youngest_rev_cache;
-  if (youngest < rep->revision)
-  {
-    /* Stale cache. */
-    SVN_ERR(svn_fs_fs__youngest_rev(&youngest, fs, pool));
-
-    /* Fresh cache. */
-    if (youngest < rep->revision)
-      return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
-                               _("Youngest revision is r%ld, but "
-                                 "rep-cache contains r%ld"),
-                               youngest, rep->revision);
-  }
+  SVN_ERR(svn_fs_fs__revision_exists(rep->revision, fs, pool));
 
   return SVN_NO_ERROR;
 }
@@ -146,6 +131,8 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
                               void *walker_baton,
                               svn_cancel_func_t cancel_func,
                               void *cancel_baton,
+                              svn_revnum_t start,
+                              svn_revnum_t end,
                               apr_pool_t *pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
@@ -161,9 +148,25 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
   if (! ffd->rep_cache_db)
     SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
 
+  /* Check global invariants. */
+  if (start == 0)
+    {
+      svn_sqlite__stmt_t *stmt2;
+      svn_revnum_t max;
+
+      SVN_ERR(svn_sqlite__get_statement(&stmt2, ffd->rep_cache_db,
+                                        STMT_GET_MAX_REV));
+      SVN_ERR(svn_sqlite__step(&have_row, stmt2));
+      max = svn_sqlite__column_revnum(stmt2, 0);
+      SVN_ERR(svn_fs_fs__revision_exists(max, fs, iterpool));
+      SVN_ERR(svn_sqlite__reset(stmt2));
+    }
+
   /* Get the statement. (There are no arguments to bind.) */
   SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db,
-                                    STMT_GET_ALL_REPS));
+                                    STMT_GET_REPS_FOR_RANGE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "rr",
+                            start, end));
 
   /* Walk the cache entries. */
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
@@ -191,10 +194,6 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
       rep->size = svn_sqlite__column_int64(stmt, 3);
       rep->expanded_size = svn_sqlite__column_int64(stmt, 4);
 
-      /* Sanity check. */
-      if (rep)
-        SVN_ERR(rep_has_been_born(rep, fs, iterpool));
-
       /* Walk. */
       SVN_ERR(walker(rep, walker_baton, fs, iterpool));
 
@@ -331,3 +330,24 @@ svn_fs_fs__set_rep_reference(svn_fs_t *f
 
   return SVN_NO_ERROR;
 }
+
+
+svn_error_t *
+svn_fs_fs__del_rep_reference(svn_fs_t *fs,
+                             svn_revnum_t youngest,
+                             apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  svn_sqlite__stmt_t *stmt;
+
+  SVN_ERR_ASSERT(ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT);
+  if (! ffd->rep_cache_db)
+    SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db,
+                                    STMT_DEL_REPS_YOUNGER_THAN_REV));
+  SVN_ERR(svn_sqlite__bindf(stmt, "r", youngest));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache.h (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_fs_fs/rep-cache.h Mon Jul 30 06:39:28 2012
@@ -55,6 +55,8 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
                               void *walker_baton,
                               svn_cancel_func_t cancel_func,
                               void *cancel_baton,
+                              svn_revnum_t start,
+                              svn_revnum_t end,
                               apr_pool_t *pool);
 
 /* Return the representation REP in FS which has fulltext CHECKSUM.
@@ -79,6 +81,13 @@ svn_fs_fs__set_rep_reference(svn_fs_t *f
                              svn_boolean_t reject_dup,
                              apr_pool_t *pool);
 
+/* Delete from the cache all reps corresponding to revisions younger
+   than YOUNGEST. */
+svn_error_t *
+svn_fs_fs__del_rep_reference(svn_fs_t *fs,
+                             svn_revnum_t youngest,
+                             apr_pool_t *pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/svn-bisect/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_fs_fs/structure?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_fs_fs/structure Mon Jul 30 06:39:28 2012
@@ -266,7 +266,7 @@ Within a revision:
   "r<rev>/<offset>" txn-id fields.
 
   In Format 3 and above, this uniqueness is done by changing a temporary
-  id of "_<base36>" to "<rev>-<base36>".  Note that this means that the
+  id of "_<base36>" to "<base36>-<rev>".  Note that this means that the
   originating revision of a line of history or a copy can be determined
   by looking at the node ID.
 

Modified: subversion/branches/svn-bisect/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_fs_fs/tree.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_fs_fs/tree.c Mon Jul 30 06:39:28 2012
@@ -115,7 +115,7 @@ typedef struct fs_rev_root_data_t
 typedef struct fs_txn_root_data_t
 {
   /* Cache of txn DAG nodes (without their nested noderevs, because
-   * it's mutable). */
+   * it's mutable). Same keys/values as ffd->rev_node_cache. */
   svn_cache__t *txn_node_cache;
 } fs_txn_root_data_t;
 
@@ -2144,7 +2144,7 @@ fs_copied_from(svn_revnum_t *rev_p,
   dag_node_t *node;
   const char *copyfrom_path, *copyfrom_str = NULL;
   svn_revnum_t copyfrom_rev;
-  char *str, *last_str, *buf;
+  char *str, *buf;
 
   /* Check to see if there is a cached version of this copyfrom
      entry. */
@@ -2166,9 +2166,9 @@ fs_copied_from(svn_revnum_t *rev_p,
         {
           /* Parse the copyfrom string for our cached entry. */
           buf = apr_pstrdup(pool, copyfrom_str);
-          str = apr_strtok(buf, " ", &last_str);
+          str = svn_cstring_tokenize(" ", &buf);
           copyfrom_rev = SVN_STR_TO_REV(str);
-          copyfrom_path = last_str;
+          copyfrom_path = buf;
         }
     }
   else
@@ -2807,8 +2807,10 @@ find_youngest_copyroot(svn_revnum_t *rev
                        parent_path_t *parent_path,
                        apr_pool_t *pool)
 {
-  svn_revnum_t rev_mine, rev_parent = -1;
-  const char *path_mine, *path_parent;
+  svn_revnum_t rev_mine;
+  svn_revnum_t rev_parent = SVN_INVALID_REVNUM;
+  const char *path_mine;
+  const char *path_parent = NULL;
 
   /* First find our parent's youngest copyroot. */
   if (parent_path->parent)

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra/ra_loader.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra/ra_loader.c Mon Jul 30 06:39:28 2012
@@ -1304,6 +1304,15 @@ svn_ra_print_ra_libraries(svn_stringbuf_
 }
 
 
+svn_error_t *
+svn_ra__register_editor_shim_callbacks(svn_ra_session_t *session,
+                                       svn_delta_shim_callbacks_t *callbacks)
+{
+  SVN_ERR(session->vtable->register_editor_shim_callbacks(session, callbacks));
+  return SVN_NO_ERROR;
+}
+
+
 /* Return the library version number. */
 const svn_version_t *
 svn_ra_version(void)

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra/ra_loader.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra/ra_loader.h Mon Jul 30 06:39:28 2012
@@ -293,6 +293,8 @@ typedef struct svn_ra__vtable_t {
                                   svn_revnum_t end_revision,
                                   svn_revnum_t *revision_deleted,
                                   apr_pool_t *pool);
+  svn_error_t *(*register_editor_shim_callbacks)(svn_ra_session_t *session,
+                                    svn_delta_shim_callbacks_t *callbacks);
 
 } svn_ra__vtable_t;
 

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_local/ra_plugin.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_local/ra_plugin.c Mon Jul 30 06:39:28 2012
@@ -1505,6 +1505,15 @@ svn_ra_local__get_deleted_rev(svn_ra_ses
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+svn_ra_local__register_editor_shim_callbacks(svn_ra_session_t *session,
+                                    svn_delta_shim_callbacks_t *callbacks)
+{
+  /* This is currenly a no-op, since we don't provide our own editor, just
+     use the one the libsvn_repos hands back to us. */
+  return SVN_NO_ERROR;
+}
+
 /*----------------------------------------------------------------*/
 
 static const svn_version_t *
@@ -1551,7 +1560,8 @@ static const svn_ra__vtable_t ra_local_v
   svn_ra_local__replay,
   svn_ra_local__has_capability,
   svn_ra_local__replay_range,
-  svn_ra_local__get_deleted_rev
+  svn_ra_local__get_deleted_rev,
+  svn_ra_local__register_editor_shim_callbacks
 };
 
 

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_neon/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_neon/commit.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_neon/commit.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_neon/commit.c Mon Jul 30 06:39:28 2012
@@ -1570,8 +1570,6 @@ svn_error_t * svn_ra_neon__get_commit_ed
   svn_delta_editor_t *commit_editor;
   commit_ctx_t *cc;
   apr_hash_index_t *hi;
-  svn_delta_shim_callbacks_t *shim_callbacks =
-                                svn_delta_shim_callbacks_default(pool);
 
   /* Build the main commit editor's baton. */
   cc = apr_pcalloc(pool, sizeof(*cc));
@@ -1622,7 +1620,7 @@ svn_error_t * svn_ra_neon__get_commit_ed
   *edit_baton = cc;
 
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
-                                   shim_callbacks, pool, pool));
+                                   ras->shim_callbacks, pool, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_neon/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_neon/log.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_neon/log.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_neon/log.c Mon Jul 30 06:39:28 2012
@@ -32,6 +32,7 @@
 #include "svn_error.h"
 #include "svn_pools.h"
 #include "svn_path.h"
+#include "svn_base64.h"
 #include "svn_xml.h"
 #include "svn_props.h"
 
@@ -52,6 +53,8 @@ struct log_baton
   */
   svn_stringbuf_t *want_cdata;
   svn_stringbuf_t *cdata;
+  const char *cdata_encoding; /* encoding of CDATA (NULL or "base64") */
+
   /* Allocate log message information.
    * NOTE: this pool may be cleared multiple times as log messages are
    * received.
@@ -162,14 +165,27 @@ log_start_element(int *elem, void *baton
     case ELEM_comment:
       lb->want_cdata = lb->cdata;
       svn_stringbuf_setempty(lb->cdata);
+      lb->cdata_encoding = NULL;
+          
+      /* Some tags might contain encoded CDATA. */
+      if ((elm->id == ELEM_comment) ||
+          (elm->id == ELEM_creator_displayname) ||
+          (elm->id == ELEM_log_date) ||
+          (elm->id == ELEM_rev_prop))
+        {
+          lb->cdata_encoding = svn_xml_get_attr_value("encoding", atts);
+          if (lb->cdata_encoding)
+            lb->cdata_encoding = apr_pstrdup(lb->subpool, lb->cdata_encoding);
+        }
+
+      /* revprop tags have names. */
       if (elm->id == ELEM_revprop)
         {
-          lb->revprop_name = apr_pstrdup(lb->subpool,
-                                         svn_xml_get_attr_value("name",
-                                                                atts));
-          if (lb->revprop_name == NULL)
+          const char *revprop_name = svn_xml_get_attr_value("name", atts);
+          if (revprop_name == NULL)
             return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                      _("Missing name attr in revprop element"));
+          lb->revprop_name = apr_pstrdup(lb->subpool, revprop_name);
         }
       break;
     case ELEM_has_children:
@@ -235,6 +251,36 @@ log_start_element(int *elem, void *baton
   return SVN_NO_ERROR;
 }
 
+/*
+ * Set *DECODED_CDATA to a copy of current CDATA being tracked in LB,
+ * decoded as necessary, and allocated from LB->subpool.
+ */
+static svn_error_t *
+maybe_decode_log_cdata(const svn_string_t **decoded_cdata,
+                       struct log_baton *lb)
+{
+  if (lb->cdata_encoding)
+    {
+      svn_string_t in;
+      in.data = lb->cdata->data;
+      in.len = lb->cdata->len;
+
+      /* Check for a known encoding type.  This is easy -- there's
+         only one.  */
+      if (strcmp(lb->cdata_encoding, "base64") != 0)
+        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
+
+      *decoded_cdata = svn_base64_decode_string(&in, lb->subpool);
+    }
+  else
+    {
+      *decoded_cdata = svn_string_create_from_buf(lb->cdata, lb->subpool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+                       
 
 /*
  * This implements the `svn_ra_neon__xml_endelm_cb' prototype.
@@ -244,6 +290,10 @@ log_end_element(void *baton, int state,
                 const char *nspace, const char *name)
 {
   struct log_baton *lb = baton;
+  const svn_string_t *decoded_cdata;
+
+  if (lb->want_cdata)
+    SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, lb));
 
   switch (state)
     {
@@ -256,8 +306,7 @@ log_end_element(void *baton, int state,
           if (! lb->log_entry->revprops)
             lb->log_entry->revprops = apr_hash_make(lb->subpool);
           apr_hash_set(lb->log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
-                       APR_HASH_KEY_STRING,
-                       svn_string_create_from_buf(lb->cdata, lb->subpool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       break;
     case ELEM_log_date:
@@ -266,8 +315,7 @@ log_end_element(void *baton, int state,
           if (! lb->log_entry->revprops)
             lb->log_entry->revprops = apr_hash_make(lb->subpool);
           apr_hash_set(lb->log_entry->revprops, SVN_PROP_REVISION_DATE,
-                       APR_HASH_KEY_STRING,
-                       svn_string_create_from_buf(lb->cdata, lb->subpool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       break;
     case ELEM_added_path:
@@ -289,8 +337,7 @@ log_end_element(void *baton, int state,
       if (! lb->log_entry->revprops)
         lb->log_entry->revprops = apr_hash_make(lb->subpool);
       apr_hash_set(lb->log_entry->revprops, lb->revprop_name,
-                   APR_HASH_KEY_STRING,
-                   svn_string_create_from_buf(lb->cdata, lb->subpool));
+                   APR_HASH_KEY_STRING, decoded_cdata);
       break;
     case ELEM_comment:
       if (lb->want_message)
@@ -298,8 +345,7 @@ log_end_element(void *baton, int state,
           if (! lb->log_entry->revprops)
             lb->log_entry->revprops = apr_hash_make(lb->subpool);
           apr_hash_set(lb->log_entry->revprops, SVN_PROP_REVISION_LOG,
-                       APR_HASH_KEY_STRING,
-                       svn_string_create_from_buf(lb->cdata, lb->subpool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       break;
     case ELEM_log_item:
@@ -380,8 +426,8 @@ svn_error_t * svn_ra_neon__get_log(svn_r
      Maybe Greg can explain?  Meanwhile, I'm tentatively using
      "request_*" for my local vars below. */
 
-  static const char log_request_head[]
-    = "<S:log-report xmlns:S=\"" SVN_XML_NAMESPACE "\">" DEBUG_CR;
+  static const char log_request_head[] = "<S:log-report xmlns:S=\""
+    SVN_XML_NAMESPACE "\">" DEBUG_CR "<S:encode-binary-props/>";
 
   static const char log_request_tail[] = "</S:log-report>" DEBUG_CR;
 
@@ -404,23 +450,17 @@ svn_error_t * svn_ra_neon__get_log(svn_r
 
   if (discover_changed_paths)
     {
-      svn_stringbuf_appendcstr(request_body,
-                               apr_psprintf(pool,
-                                            "<S:discover-changed-paths/>"));
+      svn_stringbuf_appendcstr(request_body, "<S:discover-changed-paths/>");
     }
 
   if (strict_node_history)
     {
-      svn_stringbuf_appendcstr(request_body,
-                               apr_psprintf(pool,
-                                            "<S:strict-node-history/>"));
+      svn_stringbuf_appendcstr(request_body, "<S:strict-node-history/>");
     }
 
   if (include_merged_revisions)
     {
-      svn_stringbuf_appendcstr(request_body,
-                               apr_psprintf(pool,
-                                            "<S:include-merged-revisions/>"));
+      svn_stringbuf_appendcstr(request_body, "<S:include-merged-revisions/>");
     }
 
   if (revprops)
@@ -449,9 +489,7 @@ svn_error_t * svn_ra_neon__get_log(svn_r
     }
   else
     {
-      svn_stringbuf_appendcstr(request_body,
-                               apr_psprintf(pool,
-                                            "<S:all-revprops/>"));
+      svn_stringbuf_appendcstr(request_body, "<S:all-revprops/>");
       lb.want_author = lb.want_date = lb.want_message = TRUE;
       want_custom_revprops = TRUE;
     }
@@ -494,6 +532,7 @@ svn_error_t * svn_ra_neon__get_log(svn_r
   lb.cdata = svn_stringbuf_create_empty(pool);
   lb.log_entry = svn_log_entry_create(pool);
   lb.want_cdata = NULL;
+  lb.cdata_encoding = NULL;
   reset_log_item(&lb);
 
   /* ras's URL may not exist in HEAD, and thus it's not safe to send

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_neon/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_neon/merge.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_neon/merge.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_neon/merge.c Mon Jul 30 06:39:28 2012
@@ -576,29 +576,22 @@ svn_error_t * svn_ra_neon__assemble_lock
                                                    apr_hash_t *lock_tokens,
                                                    apr_pool_t *pool)
 {
-  apr_hash_index_t *hi;
-  apr_size_t buf_size;
-  const char *closing_tag = "</S:lock-token-list>";
-  apr_size_t closing_tag_size = strlen(closing_tag);
-  apr_pool_t *tmppool = svn_pool_create(pool);
-  apr_hash_t *xml_locks = apr_hash_make(tmppool);
-  svn_stringbuf_t *lockbuf = svn_stringbuf_create
-    ("<S:lock-token-list xmlns:S=\"" SVN_XML_NAMESPACE "\">" DEBUG_CR, pool);
-
-  buf_size = lockbuf->len;
-
+#define SVN_LOCK_TOKEN_LIST \
+          "<S:lock-token-list xmlns:S=\"" SVN_XML_NAMESPACE "\">" DEBUG_CR
 #define SVN_LOCK "<S:lock>" DEBUG_CR
-#define SVN_LOCK_LEN sizeof(SVN_LOCK)-1
 #define SVN_LOCK_CLOSE "</S:lock>" DEBUG_CR
-#define SVN_LOCK_CLOSE_LEN sizeof(SVN_LOCK_CLOSE)-1
 #define SVN_LOCK_PATH "<S:lock-path>"
-#define SVN_LOCK_PATH_LEN sizeof(SVN_LOCK_PATH)-1
 #define SVN_LOCK_PATH_CLOSE "</S:lock-path>" DEBUG_CR
-#define SVN_LOCK_PATH_CLOSE_LEN sizeof(SVN_LOCK_CLOSE)-1
 #define SVN_LOCK_TOKEN "<S:lock-token>"
-#define SVN_LOCK_TOKEN_LEN sizeof(SVN_LOCK_TOKEN)-1
 #define SVN_LOCK_TOKEN_CLOSE "</S:lock-token>" DEBUG_CR
-#define SVN_LOCK_TOKEN_CLOSE_LEN sizeof(SVN_LOCK_TOKEN_CLOSE)-1
+#define SVN_LOCK_TOKEN_LIST_CLOSE "</S:lock-token-list>"
+#define SVN_LEN(str) (sizeof(str) - 1)
+
+  apr_hash_index_t *hi;
+  apr_pool_t *tmppool = svn_pool_create(pool);
+  apr_hash_t *xml_locks = apr_hash_make(tmppool);
+  svn_stringbuf_t *lockbuf = svn_stringbuf_create(SVN_LOCK_TOKEN_LIST, pool);
+  apr_size_t buf_size = lockbuf->len;
 
   /* First, figure out how much string data we're talking about,
      and allocate a stringbuf big enough to hold it all... we *never*
@@ -622,17 +615,17 @@ svn_error_t * svn_ra_neon__assemble_lock
       apr_hash_set(xml_locks, lock_path_xml->data, lock_path_xml->len, val);
 
       /* Now, on with the stringbuf calculations. */
-      buf_size += SVN_LOCK_LEN;
-      buf_size += SVN_LOCK_PATH_LEN;
+      buf_size += SVN_LEN(SVN_LOCK);
+      buf_size += SVN_LEN(SVN_LOCK_PATH);
       buf_size += lock_path_xml->len;
-      buf_size += SVN_LOCK_PATH_CLOSE_LEN;
-      buf_size += SVN_LOCK_TOKEN_LEN;
+      buf_size += SVN_LEN(SVN_LOCK_PATH_CLOSE);
+      buf_size += SVN_LEN(SVN_LOCK_TOKEN);
       buf_size += strlen(val);
-      buf_size += SVN_LOCK_TOKEN_CLOSE_LEN;
-      buf_size += SVN_LOCK_CLOSE_LEN;
+      buf_size += SVN_LEN(SVN_LOCK_TOKEN_CLOSE);
+      buf_size += SVN_LEN(SVN_LOCK_CLOSE);
     }
 
-  buf_size += closing_tag_size;
+  buf_size += SVN_LEN(SVN_LOCK_TOKEN_LIST_CLOSE);
 
   svn_stringbuf_ensure(lockbuf, buf_size + 1);
 
@@ -659,25 +652,25 @@ svn_error_t * svn_ra_neon__assemble_lock
       svn_stringbuf_appendcstr(lockbuf, SVN_LOCK_CLOSE);
     }
 
-  svn_stringbuf_appendcstr(lockbuf, closing_tag);
+  svn_stringbuf_appendcstr(lockbuf, SVN_LOCK_TOKEN_LIST_CLOSE);
+
+  /* Check our size calculation was correct */
+  SVN_ERR_ASSERT(lockbuf->len == buf_size);
 
+  *body = lockbuf;
+
+  svn_pool_destroy(tmppool);
+  return SVN_NO_ERROR;
+
+#undef SVN_LOCK_TOKEN_LIST
 #undef SVN_LOCK
-#undef SVN_LOCK_LEN
 #undef SVN_LOCK_CLOSE
-#undef SVN_LOCK_CLOSE_LEN
 #undef SVN_LOCK_PATH
-#undef SVN_LOCK_PATH_LEN
 #undef SVN_LOCK_PATH_CLOSE
-#undef SVN_LOCK_PATH_CLOSE_LEN
 #undef SVN_LOCK_TOKEN
-#undef SVN_LOCK_TOKEN_LEN
 #undef SVN_LOCK_TOKEN_CLOSE
-#undef SVN_LOCK_TOKEN_CLOSE_LEN
-
-  *body = lockbuf;
-
-  svn_pool_destroy(tmppool);
-  return SVN_NO_ERROR;
+#undef SVN_LOCK_TOKEN_LIST_CLOSE
+#undef SVN_LEN
 }
 
 

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_neon/ra_neon.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_neon/ra_neon.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_neon/ra_neon.h (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_neon/ra_neon.h Mon Jul 30 06:39:28 2012
@@ -131,6 +131,9 @@ typedef struct svn_ra_neon__session_t {
      deadprop-count property.*/
   svn_tristate_t supports_deadprop_count;
 
+  /* Ev2 shim callbacks. */
+  svn_delta_shim_callbacks_t *shim_callbacks;
+
   /*** HTTP v2 protocol stuff. ***
    *
    * We assume that if mod_dav_svn sends one of the special v2 OPTIONs
@@ -1181,6 +1184,10 @@ svn_ra_neon__get_deadprop_count_support(
                                         const char *final_url,
                                         apr_pool_t *pool);
 
+svn_error_t *
+svn_ra_neon__register_editor_shim_callbacks(svn_ra_session_t *session,
+                                    svn_delta_shim_callbacks_t *callbacks);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_neon/session.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_neon/session.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_neon/session.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_neon/session.c Mon Jul 30 06:39:28 2012
@@ -590,10 +590,10 @@ static svn_error_t *get_server_settings(
 #ifdef SVN_NEON_0_26
   if (http_auth_types)
     {
-      char *token, *last;
+      char *token;
       char *auth_types_list = apr_palloc(pool, strlen(http_auth_types) + 1);
       apr_collapse_spaces(auth_types_list, http_auth_types);
-      while ((token = apr_strtok(auth_types_list, ";", &last)) != NULL)
+      while ((token = svn_cstring_tokenize(";", &auth_types_list)) != NULL)
         {
           auth_types_list = NULL;
           if (svn_cstring_casecmp("basic", token) == 0)
@@ -985,13 +985,15 @@ svn_ra_neon__open(svn_ra_session_t *sess
 
       if (authorities != NULL)
         {
-          char *files, *file, *last;
-          files = apr_pstrdup(pool, authorities);
+          int i;
+          apr_array_header_t *files = svn_cstring_split(authorities, ";", TRUE,
+                                                        pool);
 
-          while ((file = apr_strtok(files, ";", &last)) != NULL)
+          for (i = 0; i < files->nelts; ++i)
             {
               ne_ssl_certificate *ca_cert;
-              files = NULL;
+              const char *file = APR_ARRAY_IDX(files, i, const char *);
+
               ca_cert = ne_ssl_cert_read(file);
               if (ca_cert == NULL)
                 {
@@ -1227,7 +1229,8 @@ static const svn_ra__vtable_t neon_vtabl
   svn_ra_neon__replay,
   svn_ra_neon__has_capability,
   svn_ra_neon__replay_range,
-  svn_ra_neon__get_deleted_rev
+  svn_ra_neon__get_deleted_rev,
+  svn_ra_neon__register_editor_shim_callbacks
 };
 
 svn_error_t *

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_neon/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_neon/util.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_neon/util.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_neon/util.c Mon Jul 30 06:39:28 2012
@@ -38,6 +38,7 @@
 #include "svn_utf.h"
 #include "svn_xml.h"
 #include "svn_props.h"
+#include "../libsvn_ra/ra_loader.h"
 
 #include "private/svn_fspath.h"
 #include "svn_private_config.h"
@@ -1649,3 +1650,13 @@ svn_ra_neon__get_deadprop_count_support(
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_ra_neon__register_editor_shim_callbacks(svn_ra_session_t *session,
+                                    svn_delta_shim_callbacks_t *callbacks)
+{
+  svn_ra_neon__session_t *ras = session->priv;
+
+  ras->shim_callbacks = callbacks;
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_serf/commit.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_serf/commit.c Mon Jul 30 06:39:28 2012
@@ -2319,8 +2319,6 @@ svn_ra_serf__get_commit_editor(svn_ra_se
   svn_delta_editor_t *editor;
   commit_context_t *ctx;
   apr_hash_index_t *hi;
-  svn_delta_shim_callbacks_t *shim_callbacks =
-                                    svn_delta_shim_callbacks_default(pool);
 
   ctx = apr_pcalloc(pool, sizeof(*ctx));
 
@@ -2368,7 +2366,8 @@ svn_ra_serf__get_commit_editor(svn_ra_se
   *edit_baton = ctx;
 
   SVN_ERR(svn_editor__insert_shims(ret_editor, edit_baton, *ret_editor,
-                                   *edit_baton, shim_callbacks, pool, pool));
+                                   *edit_baton, session->shim_callbacks,
+                                   pool, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_serf/locks.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_serf/locks.c Mon Jul 30 06:39:28 2012
@@ -412,7 +412,7 @@ handle_lock(serf_request_t *request,
       if (err && APR_STATUS_IS_EOF(err->apr_err))
         {
           ctx->done = TRUE;
-          err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED,
+          err = svn_error_createf(SVN_ERR_RA_DAV_FORBIDDEN,
                                   err,
                                   _("Lock request failed: %d %s"),
                                   ctx->status_code, ctx->reason);
@@ -572,44 +572,43 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
                   svn_boolean_t force,
                   svn_ra_lock_callback_t lock_func,
                   void *lock_baton,
-                  apr_pool_t *pool)
+                  apr_pool_t *scratch_pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   apr_hash_index_t *hi;
-  apr_pool_t *subpool;
+  apr_pool_t *iterpool;
 
-  subpool = svn_pool_create(pool);
+  iterpool = svn_pool_create(scratch_pool);
 
   /* ### TODO for issue 2263: Send all the locks over the wire at once.  This
      loop is just a temporary shim. */
-  for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(scratch_pool, path_revs);
+       hi;
+       hi = apr_hash_next(hi))
     {
       svn_ra_serf__handler_t *handler;
       svn_ra_serf__xml_parser_t *parser_ctx;
       const char *req_url;
       lock_info_t *lock_ctx;
-      const void *key;
-      void *val;
       svn_error_t *err;
       svn_error_t *new_err = NULL;
 
-      svn_pool_clear(subpool);
+      svn_pool_clear(iterpool);
 
-      lock_ctx = apr_pcalloc(subpool, sizeof(*lock_ctx));
+      lock_ctx = apr_pcalloc(iterpool, sizeof(*lock_ctx));
 
-      apr_hash_this(hi, &key, NULL, &val);
-      lock_ctx->pool = subpool;
-      lock_ctx->path = key;
-      lock_ctx->revision = *((svn_revnum_t*)val);
-      lock_ctx->lock = svn_lock_create(subpool);
-      lock_ctx->lock->path = key;
+      lock_ctx->pool = iterpool;
+      lock_ctx->path = svn__apr_hash_index_key(hi);
+      lock_ctx->revision = *((svn_revnum_t*)svn__apr_hash_index_val(hi));
+      lock_ctx->lock = svn_lock_create(iterpool);
+      lock_ctx->lock->path = lock_ctx->path;
       lock_ctx->lock->comment = comment;
 
       lock_ctx->force = force;
       req_url = svn_path_url_add_component2(session->session_url.path,
-                                            lock_ctx->path, subpool);
+                                            lock_ctx->path, iterpool);
 
-      handler = apr_pcalloc(subpool, sizeof(*handler));
+      handler = apr_pcalloc(iterpool, sizeof(*handler));
 
       handler->method = "LOCK";
       handler->path = req_url;
@@ -617,9 +616,9 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
       handler->conn = session->conns[0];
       handler->session = session;
 
-      parser_ctx = apr_pcalloc(subpool, sizeof(*parser_ctx));
+      parser_ctx = apr_pcalloc(iterpool, sizeof(*parser_ctx));
 
-      parser_ctx->pool = subpool;
+      parser_ctx->pool = iterpool;
       parser_ctx->user_data = lock_ctx;
       parser_ctx->start = start_lock;
       parser_ctx->end = end_lock;
@@ -636,16 +635,18 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
       handler->response_baton = parser_ctx;
 
       svn_ra_serf__request_create(handler);
-      err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, subpool);
+      err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, iterpool);
 
       if (lock_func)
         new_err = lock_func(lock_baton, lock_ctx->path, TRUE, lock_ctx->lock,
-                            err, subpool);
+                            err, iterpool);
       svn_error_clear(err);
 
       SVN_ERR(new_err);
     }
 
+  svn_pool_destroy(iterpool);
+
   return SVN_NO_ERROR;
 }
 
@@ -677,40 +678,41 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
                     svn_boolean_t force,
                     svn_ra_lock_callback_t lock_func,
                     void *lock_baton,
-                    apr_pool_t *pool)
+                    apr_pool_t *scratch_pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   apr_hash_index_t *hi;
-  apr_pool_t *subpool;
+  apr_pool_t *iterpool;
 
-  subpool = svn_pool_create(pool);
+  iterpool = svn_pool_create(scratch_pool);
 
   /* ### TODO for issue 2263: Send all the locks over the wire at once.  This
      loop is just a temporary shim. */
-  for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(scratch_pool, path_tokens);
+       hi;
+       hi = apr_hash_next(hi))
     {
       svn_ra_serf__handler_t *handler;
       svn_ra_serf__simple_request_context_t *ctx;
       const char *req_url, *path, *token;
-      const void *key;
-      void *val;
       svn_lock_t *existing_lock = NULL;
       struct unlock_context_t unlock_ctx;
-      svn_error_t *lock_err = NULL;
+      svn_error_t *err = NULL;
+      svn_error_t *new_err = NULL;
 
-      svn_pool_clear(subpool);
 
-      ctx = apr_pcalloc(subpool, sizeof(*ctx));
-      ctx->pool = subpool;
+      svn_pool_clear(iterpool);
 
-      apr_hash_this(hi, &key, NULL, &val);
-      path = key;
-      token = val;
+      ctx = apr_pcalloc(iterpool, sizeof(*ctx));
+      ctx->pool = iterpool;
+
+      path = svn__apr_hash_index_key(hi);
+      token = svn__apr_hash_index_val(hi);
 
       if (force && (!token || token[0] == '\0'))
         {
           SVN_ERR(svn_ra_serf__get_lock(ra_session, &existing_lock, path,
-                                        subpool));
+                                        iterpool));
           token = existing_lock->token;
           if (!token)
             {
@@ -723,22 +725,25 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
               if (lock_func)
                 {
                   svn_error_t *err2;
-                  err2 = lock_func(lock_baton, path, FALSE, NULL, err, subpool);
+                  err2 = lock_func(lock_baton, path, FALSE, NULL, err,
+                                   iterpool);
                   svn_error_clear(err);
                   if (err2)
-                    return err2;
+                    return svn_error_trace(err2);
                 }
+              else
+                svn_error_clear(err);
               continue;
             }
         }
 
       unlock_ctx.force = force;
-      unlock_ctx.token = apr_pstrcat(subpool, "<", token, ">", (char *)NULL);
+      unlock_ctx.token = apr_pstrcat(iterpool, "<", token, ">", (char *)NULL);
 
       req_url = svn_path_url_add_component2(session->session_url.path, path,
-                                            subpool);
+                                            iterpool);
 
-      handler = apr_pcalloc(subpool, sizeof(*handler));
+      handler = apr_pcalloc(iterpool, sizeof(*handler));
 
       handler->method = "UNLOCK";
       handler->path = req_url;
@@ -752,7 +757,7 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
       handler->response_baton = ctx;
 
       svn_ra_serf__request_create(handler);
-      SVN_ERR(svn_ra_serf__context_run_wait(&ctx->done, session, subpool));
+      SVN_ERR(svn_ra_serf__context_run_wait(&ctx->done, session, iterpool));
 
       switch (ctx->status)
         {
@@ -760,23 +765,25 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
             break; /* OK */
           case 403:
             /* Api users expect this specific error code to detect failures */
-            lock_err = svn_error_createf(SVN_ERR_FS_LOCK_OWNER_MISMATCH, NULL,
-                                         _("Unlock request failed: %d %s"),
-                                         ctx->status, ctx->reason);
+            err = svn_error_createf(SVN_ERR_FS_LOCK_OWNER_MISMATCH, NULL,
+                                    _("Unlock request failed: %d %s"),
+                                    ctx->status, ctx->reason);
             break;
           default:
-            lock_err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
-                                   _("Unlock request failed: %d %s"),
-                                   ctx->status, ctx->reason);
+            err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+                                    _("Unlock request failed: %d %s"),
+                                    ctx->status, ctx->reason);
         }
 
       if (lock_func)
-        {
-          SVN_ERR(lock_func(lock_baton, path, FALSE, existing_lock,
-                            lock_err, subpool));
-          svn_error_clear(lock_err);
-        }
+        new_err = lock_func(lock_baton, path, FALSE, existing_lock, err,
+                            iterpool);
+
+      svn_error_clear(err);
+      SVN_ERR(new_err);
     }
 
+  svn_pool_destroy(iterpool);
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_serf/log.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_serf/log.c Mon Jul 30 06:39:28 2012
@@ -32,6 +32,7 @@
 #include "svn_pools.h"
 #include "svn_ra.h"
 #include "svn_dav.h"
+#include "svn_base64.h"
 #include "svn_xml.h"
 #include "svn_config.h"
 #include "svn_path.h"
@@ -67,9 +68,12 @@ typedef enum log_state_e {
 typedef struct log_info_t {
   apr_pool_t *pool;
 
-  /* The currently collected value as we build it up */
+  /* The currently collected value as we build it up, and its wire
+   * encoding (if any).
+   */
   const char *tmp;
   apr_size_t tmp_len;
+  const char *tmp_encoding;
 
   /* Temporary change path - ultimately inserted into changed_paths hash. */
   svn_log_changed_path2_t *tmp_path;
@@ -114,7 +118,8 @@ typedef struct log_context_t {
 static log_info_t *
 push_state(svn_ra_serf__xml_parser_t *parser,
            log_context_t *log_ctx,
-           log_state_e state)
+           log_state_e state,
+           const char **attrs)
 {
   svn_ra_serf__xml_push_state(parser, state);
 
@@ -152,6 +157,10 @@ push_state(svn_ra_serf__xml_parser_t *pa
     {
       log_info_t *info = parser->state->private;
 
+      info->tmp_encoding = svn_xml_get_attr_value("encoding", attrs);
+      if (info->tmp_encoding)
+        info->tmp_encoding = apr_pstrdup(info->pool, info->tmp_encoding);
+
       if (!info->log_entry->revprops)
         {
           info->log_entry->revprops = apr_hash_make(info->pool);
@@ -192,12 +201,12 @@ start_log(svn_ra_serf__xml_parser_t *par
   if (state == NONE &&
       strcmp(name.name, "log-report") == 0)
     {
-      push_state(parser, log_ctx, REPORT);
+      push_state(parser, log_ctx, REPORT, attrs);
     }
   else if (state == REPORT &&
            strcmp(name.name, "log-item") == 0)
     {
-      push_state(parser, log_ctx, ITEM);
+      push_state(parser, log_ctx, ITEM, attrs);
     }
   else if (state == ITEM)
     {
@@ -205,44 +214,43 @@ start_log(svn_ra_serf__xml_parser_t *par
 
       if (strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
         {
-          push_state(parser, log_ctx, VERSION);
+          push_state(parser, log_ctx, VERSION, attrs);
         }
       else if (strcmp(name.name, "creator-displayname") == 0)
         {
-          push_state(parser, log_ctx, CREATOR);
+          info = push_state(parser, log_ctx, CREATOR, attrs);
         }
       else if (strcmp(name.name, "date") == 0)
         {
-          push_state(parser, log_ctx, DATE);
+          info = push_state(parser, log_ctx, DATE, attrs);
         }
       else if (strcmp(name.name, "comment") == 0)
         {
-          push_state(parser, log_ctx, COMMENT);
+          info = push_state(parser, log_ctx, COMMENT, attrs);
         }
       else if (strcmp(name.name, "revprop") == 0)
         {
-          const char *revprop_name;
-          info = push_state(parser, log_ctx, REVPROP);
-          revprop_name = svn_xml_get_attr_value("name", attrs);
+          const char *revprop_name =
+            svn_xml_get_attr_value("name", attrs);
           if (revprop_name == NULL)
             return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                      _("Missing name attr in revprop element"));
-
+          info = push_state(parser, log_ctx, REVPROP, attrs);
           info->revprop_name = apr_pstrdup(info->pool, revprop_name);
         }
       else if (strcmp(name.name, "has-children") == 0)
         {
-          push_state(parser, log_ctx, HAS_CHILDREN);
+          push_state(parser, log_ctx, HAS_CHILDREN, attrs);
         }
       else if (strcmp(name.name, "subtractive-merge") == 0)
         {
-          push_state(parser, log_ctx, SUBTRACTIVE_MERGE);
+          push_state(parser, log_ctx, SUBTRACTIVE_MERGE, attrs);
         }
       else if (strcmp(name.name, "added-path") == 0)
         {
           const char *copy_path, *copy_rev_str;
 
-          info = push_state(parser, log_ctx, ADDED_PATH);
+          info = push_state(parser, log_ctx, ADDED_PATH, attrs);
           info->tmp_path->action = 'A';
 
           copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
@@ -266,7 +274,7 @@ start_log(svn_ra_serf__xml_parser_t *par
         {
           const char *copy_path, *copy_rev_str;
 
-          info = push_state(parser, log_ctx, REPLACED_PATH);
+          info = push_state(parser, log_ctx, REPLACED_PATH, attrs);
           info->tmp_path->action = 'R';
 
           copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
@@ -288,14 +296,14 @@ start_log(svn_ra_serf__xml_parser_t *par
         }
       else if (strcmp(name.name, "deleted-path") == 0)
         {
-          info = push_state(parser, log_ctx, DELETED_PATH);
+          info = push_state(parser, log_ctx, DELETED_PATH, attrs);
           info->tmp_path->action = 'D';
 
           SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
         }
       else if (strcmp(name.name, "modified-path") == 0)
         {
-          info = push_state(parser, log_ctx, MODIFIED_PATH);
+          info = push_state(parser, log_ctx, MODIFIED_PATH, attrs);
           info->tmp_path->action = 'M';
 
           SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
@@ -305,6 +313,39 @@ start_log(svn_ra_serf__xml_parser_t *par
   return SVN_NO_ERROR;
 }
 
+/*
+ * Set *DECODED_CDATA to a copy of current CDATA being tracked in INFO,
+ * decoded as necessary, and allocated from INFO->pool..
+ */
+static svn_error_t *
+maybe_decode_log_cdata(const svn_string_t **decoded_cdata,
+                       log_info_t *info)
+{
+  if (info->tmp_encoding)
+    {
+      svn_string_t in;
+      in.data = info->tmp;
+      in.len = info->tmp_len;
+
+      /* Check for a known encoding type.  This is easy -- there's
+         only one.  */
+      if (strcmp(info->tmp_encoding, "base64") != 0)
+        {
+          return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                                   _("Unsupported encoding '%s'"),
+                                   info->tmp_encoding);
+        }
+
+      *decoded_cdata = svn_base64_decode_string(&in, info->pool);
+    }
+  else
+    {
+      *decoded_cdata = svn_string_ncreate(info->tmp, info->tmp_len,
+                                          info->pool);
+    }
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 end_log(svn_ra_serf__xml_parser_t *parser,
         void *userData,
@@ -361,10 +402,10 @@ end_log(svn_ra_serf__xml_parser_t *parse
     {
       if (log_ctx->want_author)
         {
+          const svn_string_t *decoded_cdata;
+          SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
           apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
-                       APR_HASH_KEY_STRING,
-                       svn_string_ncreate(info->tmp, info->tmp_len,
-                                          info->pool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       info->tmp_len = 0;
       svn_ra_serf__xml_pop_state(parser);
@@ -374,10 +415,10 @@ end_log(svn_ra_serf__xml_parser_t *parse
     {
       if (log_ctx->want_date)
         {
+          const svn_string_t *decoded_cdata;
+          SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
           apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_DATE,
-                       APR_HASH_KEY_STRING,
-                       svn_string_ncreate(info->tmp, info->tmp_len,
-                                          info->pool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       info->tmp_len = 0;
       svn_ra_serf__xml_pop_state(parser);
@@ -387,19 +428,20 @@ end_log(svn_ra_serf__xml_parser_t *parse
     {
       if (log_ctx->want_message)
         {
+          const svn_string_t *decoded_cdata;
+          SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
           apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_LOG,
-                       APR_HASH_KEY_STRING,
-                       svn_string_ncreate(info->tmp, info->tmp_len,
-                                          info->pool));
+                       APR_HASH_KEY_STRING, decoded_cdata);
         }
       info->tmp_len = 0;
       svn_ra_serf__xml_pop_state(parser);
     }
   else if (state == REVPROP)
     {
+      const svn_string_t *decoded_cdata;
+      SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
       apr_hash_set(info->log_entry->revprops, info->revprop_name,
-                   APR_HASH_KEY_STRING,
-                   svn_string_ncreate(info->tmp, info->tmp_len, info->pool));
+                   APR_HASH_KEY_STRING, decoded_cdata);
       info->tmp_len = 0;
       svn_ra_serf__xml_pop_state(parser);
     }
@@ -562,6 +604,10 @@ create_log_body(serf_bucket_t **body_bkt
         }
     }
 
+  svn_ra_serf__add_tag_buckets(buckets,
+                               "S:encode-binary-props", NULL,
+                               alloc);
+
   svn_ra_serf__add_close_tag_buckets(buckets, alloc,
                                      "S:log-report");
 

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_serf/property.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_serf/property.c Mon Jul 30 06:39:28 2012
@@ -988,32 +988,33 @@ svn_ra_serf__get_baseline_info(const cha
      revision (if needed) with an OPTIONS request.  */
   if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
     {
-      basecoll_url = apr_psprintf(pool, "%s/%ld",
-                                  session->rev_root_stub, revision);
+      svn_revnum_t actual_revision;
 
-      if (latest_revnum)
+      if (SVN_IS_VALID_REVNUM(revision))
         {
-          if (SVN_IS_VALID_REVNUM(revision))
-            {
-              *latest_revnum = revision;
-            }
-          else
-           {
-              svn_ra_serf__options_context_t *opt_ctx;
+          actual_revision = revision;
+        }
+      else
+        {
+          svn_ra_serf__options_context_t *opt_ctx;
 
-              SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, session, conn,
+          SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, session, conn,
                                                   session->session_url.path,
                                                   pool));
-              SVN_ERR(svn_ra_serf__context_run_wait(
+          SVN_ERR(svn_ra_serf__context_run_wait(
                 svn_ra_serf__get_options_done_ptr(opt_ctx), session, pool));
 
-             *latest_revnum = svn_ra_serf__options_get_youngest_rev(opt_ctx);
-             if (! SVN_IS_VALID_REVNUM(*latest_revnum))
-               return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
-                                       _("The OPTIONS response did not include "
-                                         "the youngest revision"));
-          }
+          actual_revision = svn_ra_serf__options_get_youngest_rev(opt_ctx);
+          if (! SVN_IS_VALID_REVNUM(actual_revision))
+            return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
+                                    _("The OPTIONS response did not include "
+                                      "the youngest revision"));
         }
+
+      basecoll_url = apr_psprintf(pool, "%s/%ld",
+                                  session->rev_root_stub, actual_revision);
+      if (latest_revnum)
+        *latest_revnum = actual_revision;
     }
 
   /* Otherwise, we fall back to the old VCC_URL PROPFIND hunt.  */
@@ -1021,7 +1022,7 @@ svn_ra_serf__get_baseline_info(const cha
     {
       SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, conn, pool));
 
-      if (revision != SVN_INVALID_REVNUM)
+      if (SVN_IS_VALID_REVNUM(revision))
         {
           /* First check baseline information cache. */
           SVN_ERR(svn_ra_serf__blncache_get_bc_url(&basecoll_url,

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_serf/ra_serf.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_serf/ra_serf.h Mon Jul 30 06:39:28 2012
@@ -78,6 +78,7 @@ typedef struct svn_ra_serf__connection_t
 
   /* Are we using ssl */
   svn_boolean_t using_ssl;
+  int server_cert_failures; /* Collected cert failures in chain */
 
   /* Should we ask for compressed responses? */
   svn_boolean_t using_compression;
@@ -147,6 +148,9 @@ struct svn_ra_serf__session_t {
   svn_cancel_func_t cancel_func;
   void *cancel_baton;
 
+  /* Ev2 shim callbacks */
+  svn_delta_shim_callbacks_t *shim_callbacks;
+
   /* Error that we've received but not yet returned upstream. */
   svn_error_t *pending_error;
 
@@ -1453,6 +1457,11 @@ svn_ra_serf__error_on_status(int status_
                              const char *path,
                              const char *location);
 
+svn_error_t *
+svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session,
+                                    svn_delta_shim_callbacks_t *callbacks);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_serf/serf.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_serf/serf.c Mon Jul 30 06:39:28 2012
@@ -103,12 +103,11 @@ load_http_auth_types(apr_pool_t *pool, s
 
   if (http_auth_types)
     {
-      char *token, *last;
+      char *token;
       char *auth_types_list = apr_palloc(pool, strlen(http_auth_types) + 1);
       apr_collapse_spaces(auth_types_list, http_auth_types);
-      while ((token = apr_strtok(auth_types_list, ";", &last)) != NULL)
+      while ((token = svn_cstring_tokenize(";", &auth_types_list)) != NULL)
         {
-          auth_types_list = NULL;
           if (svn_cstring_casecmp("basic", token) == 0)
             *authn_types |= SERF_AUTHN_BASIC;
           else if (svn_cstring_casecmp("digest", token) == 0)
@@ -404,6 +403,7 @@ svn_ra_serf__open(svn_ra_session_t *sess
   serf_sess->conns[0]->last_status_code = -1;
 
   serf_sess->conns[0]->using_ssl = serf_sess->using_ssl;
+  serf_sess->conns[0]->server_cert_failures = 0;
   serf_sess->conns[0]->using_compression = serf_sess->using_compression;
   serf_sess->conns[0]->hostname = url.hostname;
   serf_sess->conns[0]->useragent = NULL;
@@ -1157,7 +1157,8 @@ static const svn_ra__vtable_t serf_vtabl
   svn_ra_serf__replay,
   svn_ra_serf__has_capability,
   svn_ra_serf__replay_range,
-  svn_ra_serf__get_deleted_rev
+  svn_ra_serf__get_deleted_rev,
+  svn_ra_serf__register_editor_shim_callbacks
 };
 
 svn_error_t *

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_serf/update.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_serf/update.c Mon Jul 30 06:39:28 2012
@@ -1691,7 +1691,9 @@ start_report(svn_ra_serf__xml_parser_t *
         }
       else
         {
-          SVN_ERR_MALFUNCTION();
+          return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                                   _("Unknown tag '%s' while at state %d"),
+                                   name.name, state);
         }
 
     }
@@ -1766,7 +1768,9 @@ start_report(svn_ra_serf__xml_parser_t *
         }
       else
         {
-          SVN_ERR_MALFUNCTION();
+          return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                                   _("Unknown tag '%s' while at state %d"),
+                                   name.name, state);
         }
     }
   else if (state == IGNORE_PROP_NAME)

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_serf/util.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_serf/util.c Mon Jul 30 06:39:28 2012
@@ -38,6 +38,7 @@
 #include "svn_private_config.h"
 #include "svn_string.h"
 #include "svn_xml.h"
+#include "../libsvn_ra/ra_loader.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_fspath.h"
 
@@ -271,6 +272,8 @@ ssl_server_cert(void *baton, int failure
   /* Implicitly approve any non-server certs. */
   if (serf_ssl_cert_depth(cert) > 0)
     {
+      if (failures)
+        conn->server_cert_failures |= ssl_convert_serf_failures(failures);
       return APR_SUCCESS;
     }
 
@@ -295,7 +298,8 @@ ssl_server_cert(void *baton, int failure
   cert_info.issuer_dname = convert_organisation_to_str(issuer, scratch_pool);
   cert_info.ascii_cert = serf_ssl_cert_export(cert, scratch_pool);
 
-  svn_failures = ssl_convert_serf_failures(failures);
+  svn_failures = (ssl_convert_serf_failures(failures)
+                  | conn->server_cert_failures);
 
   /* Try to find matching server name via subjectAltName first... */
   if (san) {
@@ -383,24 +387,26 @@ static svn_error_t *
 load_authorities(svn_ra_serf__connection_t *conn, const char *authorities,
                  apr_pool_t *pool)
 {
-  char *files, *file, *last;
-  files = apr_pstrdup(pool, authorities);
+  apr_array_header_t *files = svn_cstring_split(authorities, ";",
+                                                TRUE /* chop_whitespace */,
+                                                pool);
+  int i;
 
-  while ((file = apr_strtok(files, ";", &last)) != NULL)
+  for (i = 0; i < files->nelts; ++i)
     {
+      const char *file = APR_ARRAY_IDX(files, i, const char *);
       serf_ssl_certificate_t *ca_cert;
       apr_status_t status = serf_ssl_load_cert_file(&ca_cert, file, pool);
+
       if (status == APR_SUCCESS)
         status = serf_ssl_trust_cert(conn->ssl_context, ca_cert);
 
       if (status != APR_SUCCESS)
         {
-          return svn_error_createf
-            (SVN_ERR_BAD_CONFIG_VALUE, NULL,
+          return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
              _("Invalid config: unable to load certificate file '%s'"),
              svn_dirent_local_style(file, pool));
         }
-      files = NULL;
     }
 
   return SVN_NO_ERROR;
@@ -478,7 +484,7 @@ svn_ra_serf__conn_setup(apr_socket_t *so
 {
   svn_ra_serf__connection_t *conn = baton;
   svn_ra_serf__session_t *session = conn->session;
-  apr_status_t status = SVN_NO_ERROR;
+  apr_status_t status = APR_SUCCESS;
 
   svn_error_t *err = conn_setup(sock,
                                 read_bkt,
@@ -2461,3 +2467,13 @@ svn_ra_serf__error_on_status(int status_
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *ra_session,
+                                    svn_delta_shim_callbacks_t *callbacks)
+{
+  svn_ra_serf__session_t *session = ra_session->priv;
+
+  session->shim_callbacks = callbacks;
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_svn/client.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_svn/client.c Mon Jul 30 06:39:28 2012
@@ -1166,15 +1166,12 @@ static svn_error_t *ra_svn_get_dir(svn_r
 static svn_tristate_t
 optbool_to_tristate(apr_uint64_t v)
 {
-  switch (v)
-  {
-    case TRUE:
-      return svn_tristate_true;
-    case FALSE:
-      return svn_tristate_false;
-    default: /* Contains SVN_RA_SVN_UNSPECIFIED_NUMBER */
-      return svn_tristate_unknown;
-  }
+  if (v == TRUE)
+    return svn_tristate_true;
+  if (v == FALSE)
+    return svn_tristate_false;
+
+  return svn_tristate_unknown; /* Contains SVN_RA_SVN_UNSPECIFIED_NUMBER */
 }
 
 /* If REVISION is SVN_INVALID_REVNUM, no value is sent to the
@@ -2499,6 +2496,18 @@ ra_svn_get_deleted_rev(svn_ra_session_t 
   return svn_ra_svn_read_cmd_response(conn, pool, "r", revision_deleted);
 }
 
+static svn_error_t *
+ra_svn_register_editor_shim_callbacks(svn_ra_session_t *session,
+                                      svn_delta_shim_callbacks_t *callbacks)
+{
+  svn_ra_svn__session_baton_t *sess_baton = session->priv;
+  svn_ra_svn_conn_t *conn = sess_baton->conn;
+
+  conn->shim_callbacks = callbacks;
+
+  return SVN_NO_ERROR;
+}
+
 
 static const svn_ra__vtable_t ra_svn_vtable = {
   svn_ra_svn_version,
@@ -2535,7 +2544,8 @@ static const svn_ra__vtable_t ra_svn_vta
   ra_svn_replay,
   ra_svn_has_capability,
   ra_svn_replay_range,
-  ra_svn_get_deleted_rev
+  ra_svn_get_deleted_rev,
+  ra_svn_register_editor_shim_callbacks
 };
 
 svn_error_t *

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_svn/cyrus_auth.c Mon Jul 30 06:39:28 2012
@@ -186,12 +186,64 @@ svn_ra_svn__sasl_common_init(apr_pool_t 
   return SVN_NO_ERROR;
 }
 
+/* We are going to look at errno when we get SASL_FAIL but we don't
+   know for sure whether SASL always sets errno.  Clearing errno
+   before calling SASL functions helps in cases where SASL does
+   nothing to set errno. */
+#ifdef apr_set_os_error
+#define clear_sasl_errno() apr_set_os_error(APR_SUCCESS)
+#else
+#define clear_sasl_errno() (void)0
+#endif
+
+/* Sometimes SASL returns SASL_FAIL as RESULT and sets errno.
+ * SASL_FAIL translates to "generic error" which is quite unhelpful.
+ * Try to append a more informative error message based on errno so
+ * should be called before doing anything that may change errno. */
+static const char *
+get_sasl_errno_msg(int result, apr_pool_t *result_pool)
+{
+#ifdef apr_get_os_error
+  char buf[1024];
+
+  if (result == SASL_FAIL && apr_get_os_error() != 0)
+    return apr_psprintf(result_pool, ": %s",
+                        svn_strerror(apr_get_os_error(), buf, sizeof(buf)));
+#endif
+  return "";
+}
+
+/* Wrap an error message from SASL with a prefix that allows users
+ * to tell that the error message came from SASL.  Queries errno and
+ * so should be called before doing anything that may change errno. */
+static const char *
+get_sasl_error(sasl_conn_t *sasl_ctx, int result, apr_pool_t *result_pool)
+{
+  const char *sasl_errno_msg = get_sasl_errno_msg(result, result_pool);
+
+  return apr_psprintf(result_pool,
+                      _("SASL authentication error: %s%s"),
+                      sasl_errdetail(sasl_ctx), sasl_errno_msg);
+}
+
 static svn_error_t *sasl_init_cb(void *baton, apr_pool_t *pool)
 {
+  int result;
+
   SVN_ERR(svn_ra_svn__sasl_common_init(pool));
-  if (sasl_client_init(NULL) != SASL_OK)
-    return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                            _("Could not initialize the SASL library"));
+  clear_sasl_errno();
+  result = sasl_client_init(NULL);
+  if (result != SASL_OK)
+    {
+      const char *sasl_errno_msg = get_sasl_errno_msg(result, pool);
+
+      return svn_error_createf
+        (SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+         _("Could not initialized the SASL library: %s%s"),
+         sasl_errstring(result, NULL, NULL),
+         sasl_errno_msg);
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -338,16 +390,6 @@ get_password_cb(sasl_conn_t *conn, void 
   return SASL_FAIL;
 }
 
-/* Wrap an error message from SASL with a prefix that allows users
- * to tell that the error message came from SASL. */
-static const char *
-get_sasl_error(sasl_conn_t *sasl_ctx, apr_pool_t *result_pool)
-{
-  return apr_psprintf(result_pool,
-                      _("SASL authentication error: %s"),
-                      sasl_errdetail(sasl_ctx));
-}
-
 /* Create a new SASL context. */
 static svn_error_t *new_sasl_ctx(sasl_conn_t **sasl_ctx,
                                  svn_boolean_t is_tunneled,
@@ -360,14 +402,20 @@ static svn_error_t *new_sasl_ctx(sasl_co
   sasl_security_properties_t secprops;
   int result;
 
+  clear_sasl_errno();
   result = sasl_client_new(SVN_RA_SVN_SASL_NAME,
                            hostname, local_addrport, remote_addrport,
                            callbacks, SASL_SUCCESS_DATA,
                            sasl_ctx);
   if (result != SASL_OK)
-    return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                            sasl_errstring(result, NULL, NULL));
+    {
+      const char *sasl_errno_msg = get_sasl_errno_msg(result, pool);
 
+      return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+                               _("Could not create SASL context: %s%s"),
+                               sasl_errstring(result, NULL, NULL),
+                               sasl_errno_msg);
+    }
   svn_atomic_inc(&sasl_ctx_count);
   apr_pool_cleanup_register(pool, *sasl_ctx, sasl_dispose_cb,
                             apr_pool_cleanup_null);
@@ -378,11 +426,12 @@ static svn_error_t *new_sasl_ctx(sasl_co
          otherwise it will ignore EXTERNAL. The third parameter
          should be the username, but since SASL doesn't seem
          to use it on the client side, any non-empty string will do. */
+      clear_sasl_errno();
       result = sasl_setprop(*sasl_ctx,
                             SASL_AUTH_EXTERNAL, " ");
       if (result != SASL_OK)
         return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                                get_sasl_error(*sasl_ctx, pool));
+                                get_sasl_error(*sasl_ctx, result, pool));
     }
 
   /* Set security properties. */
@@ -410,6 +459,7 @@ static svn_error_t *try_auth(svn_ra_svn_
   do
     {
       again = FALSE;
+      clear_sasl_errno();
       result = sasl_client_start(sasl_ctx,
                                  mechstring,
                                  &client_interact,
@@ -428,7 +478,7 @@ static svn_error_t *try_auth(svn_ra_svn_
           case SASL_NOMEM:
             /* Fatal error.  Fail the authentication. */
             return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                                    get_sasl_error(sasl_ctx, pool));
+                                    get_sasl_error(sasl_ctx, result, pool));
           default:
             /* For anything else, delete the mech from the list
                and try again. */
@@ -480,6 +530,7 @@ static svn_error_t *try_auth(svn_ra_svn_
       if (strcmp(mech, "CRAM-MD5") != 0)
         in = svn_base64_decode_string(in, pool);
 
+      clear_sasl_errno();
       result = sasl_client_step(sasl_ctx,
                                 in->data,
                                 in->len,
@@ -489,7 +540,7 @@ static svn_error_t *try_auth(svn_ra_svn_
 
       if (result != SASL_OK && result != SASL_CONTINUE)
         return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                                get_sasl_error(sasl_ctx, pool));
+                                get_sasl_error(sasl_ctx, result, pool));
 
       /* If the server thinks we're done, then don't send any response. */
       if (strcmp(status, "success") == 0)
@@ -568,12 +619,13 @@ static svn_error_t *sasl_read_cb(void *b
           *len = 0;
           return SVN_NO_ERROR;
         }
+      clear_sasl_errno();
       result = sasl_decode(sasl_baton->ctx, buffer, len2,
                            &sasl_baton->read_buf,
                            &sasl_baton->read_len);
       if (result != SASL_OK)
         return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                                get_sasl_error(sasl_baton->ctx,
+                                get_sasl_error(sasl_baton->ctx, result,
                                                sasl_baton->scratch_pool));
     }
 
@@ -609,13 +661,14 @@ sasl_write_cb(void *baton, const char *b
     {
       /* Make sure we don't write too much. */
       *len = (*len > sasl_baton->maxsize) ? sasl_baton->maxsize : *len;
+      clear_sasl_errno();
       result = sasl_encode(sasl_baton->ctx, buffer, *len,
                            &sasl_baton->write_buf,
                            &sasl_baton->write_len);
 
       if (result != SASL_OK)
         return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                                get_sasl_error(sasl_baton->ctx,
+                                get_sasl_error(sasl_baton->ctx, result,
                                                sasl_baton->scratch_pool));
     }
 
@@ -669,10 +722,11 @@ svn_error_t *svn_ra_svn__enable_sasl_enc
       int result;
 
       /* Get the strength of the security layer. */
+      clear_sasl_errno();
       result = sasl_getprop(sasl_ctx, SASL_SSF, (void*) &ssfp);
       if (result != SASL_OK)
         return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                                get_sasl_error(sasl_ctx, pool));
+                                get_sasl_error(sasl_ctx, result, pool));
 
       if (*ssfp > 0)
         {
@@ -688,23 +742,25 @@ svn_error_t *svn_ra_svn__enable_sasl_enc
           sasl_baton->scratch_pool = conn->pool;
 
           /* Find out the maximum input size for sasl_encode. */
+          clear_sasl_errno();
           result = sasl_getprop(sasl_ctx, SASL_MAXOUTBUF, &maxsize);
           if (result != SASL_OK)
             return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                                    get_sasl_error(sasl_ctx, pool));
+                                    get_sasl_error(sasl_ctx, result, pool));
           sasl_baton->maxsize = *((const unsigned int *) maxsize);
 
           /* If there is any data left in the read buffer at this point,
              we need to decrypt it. */
           if (conn->read_end > conn->read_ptr)
             {
+              clear_sasl_errno();
               result = sasl_decode(sasl_ctx, conn->read_ptr,
                                    conn->read_end - conn->read_ptr,
                                    &sasl_baton->read_buf,
                                    &sasl_baton->read_len);
               if (result != SASL_OK)
                 return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                                        get_sasl_error(sasl_ctx, pool));
+                                        get_sasl_error(sasl_ctx, result, pool));
               conn->read_end = conn->read_ptr;
             }
 

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_svn/editorp.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_svn/editorp.c Mon Jul 30 06:39:28 2012
@@ -408,8 +408,6 @@ void svn_ra_svn_get_editor(const svn_del
 {
   svn_delta_editor_t *ra_svn_editor = svn_delta_default_editor(pool);
   ra_svn_edit_baton_t *eb;
-  svn_delta_shim_callbacks_t *shim_callbacks =
-                                    svn_delta_shim_callbacks_default(pool);
 
   eb = apr_palloc(pool, sizeof(*eb));
   eb->conn = conn;
@@ -439,7 +437,7 @@ void svn_ra_svn_get_editor(const svn_del
   *edit_baton = eb;
 
   svn_error_clear(svn_editor__insert_shims(editor, edit_baton, *editor,
-                                           *edit_baton, shim_callbacks,
+                                           *edit_baton, conn->shim_callbacks,
                                            pool, pool));
 }
 

Modified: subversion/branches/svn-bisect/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_ra_svn/ra_svn.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_ra_svn/ra_svn.h Mon Jul 30 06:39:28 2012
@@ -87,6 +87,7 @@ struct svn_ra_svn_conn_st {
   apr_hash_t *capabilities;
   int compression_level;
   char *remote_ip;
+  svn_delta_shim_callbacks_t *shim_callbacks;
   apr_pool_t *pool;
 };
 

Modified: subversion/branches/svn-bisect/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_repos/commit.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_repos/commit.c Mon Jul 30 06:39:28 2012
@@ -247,7 +247,7 @@ add_file_or_directory(const char *path,
          out-of-dateness error. */
       SVN_ERR(svn_fs_check_path(&kind, eb->txn_root, full_path, subpool));
       if ((kind != svn_node_none) && (! pb->was_copied))
-        return out_of_date(full_path, kind);
+        return svn_error_trace(out_of_date(full_path, kind));
 
       /* For now, require that the url come from the same repository
          that this commit is operating on. */
@@ -396,13 +396,13 @@ delete_entry(const char *path,
 
   /* If PATH doesn't exist in the txn, the working copy is out of date. */
   if (kind == svn_node_none)
-    return out_of_date(full_path, kind);
+    return svn_error_trace(out_of_date(full_path, kind));
 
   /* Now, make sure we're deleting the node we *think* we're
      deleting, else return an out-of-dateness error. */
   SVN_ERR(svn_fs_node_created_rev(&cr_rev, eb->txn_root, full_path, pool));
   if (SVN_IS_VALID_REVNUM(revision) && (revision < cr_rev))
-    return out_of_date(full_path, kind);
+    return svn_error_trace(out_of_date(full_path, kind));
 
   /* This routine is a mindless wrapper.  We call svn_fs_delete()
      because that will delete files and recursively delete
@@ -518,7 +518,7 @@ open_file(const char *path,
   /* If the node our caller has is an older revision number than the
      one in our transaction, return an out-of-dateness error. */
   if (SVN_IS_VALID_REVNUM(base_revision) && (base_revision < cr_rev))
-    return out_of_date(full_path, svn_node_file);
+    return svn_error_trace(out_of_date(full_path, svn_node_file));
 
   /* Build a new file baton */
   new_fb = apr_pcalloc(pool, sizeof(*new_fb));
@@ -602,7 +602,7 @@ change_dir_prop(void *dir_baton,
                                       eb->txn_root, db->path, pool));
 
       if (db->base_rev < created_rev)
-        return out_of_date(db->path, svn_node_dir);
+        return svn_error_trace(out_of_date(db->path, svn_node_dir));
     }
 
   return svn_repos_fs_change_node_prop(eb->txn_root, db->path,
@@ -786,16 +786,40 @@ static svn_error_t *
 prop_fetch_func(apr_hash_t **props,
                 void *baton,
                 const char *path,
+                svn_revnum_t base_revision,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
 {
   struct edit_baton *eb = baton;
   svn_fs_root_t *fs_root;
+  svn_error_t *err;
+
+  if (svn_path_is_url(path))
+    {
+      /* This is a copyfrom URL. */
+      path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
+      path = svn_fspath__canonicalize(path, scratch_pool);
+    }
+  else
+    {
+      /* This is a base-relative path. */
+      if (path[0] != '/')
+        /* Get an absolute path for use in the FS. */
+        path = svn_fspath__join(eb->base_path, path, scratch_pool);
+    }
 
   SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs,
                                svn_fs_txn_base_revision(eb->txn),
                                scratch_pool));
-  SVN_ERR(svn_fs_node_proplist(props, fs_root, path, result_pool));
+  err = svn_fs_node_proplist(props, fs_root, path, result_pool);
+  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
+    {
+      svn_error_clear(err);
+      *props = apr_hash_make(result_pool);
+      return SVN_NO_ERROR;
+    }
+  else if (err)
+    return svn_error_trace(err);
 
   return SVN_NO_ERROR;
 }
@@ -804,17 +828,91 @@ static svn_error_t *
 kind_fetch_func(svn_kind_t *kind,
                 void *baton,
                 const char *path,
+                svn_revnum_t base_revision,
                 apr_pool_t *scratch_pool)
 {
   struct edit_baton *eb = baton;
   svn_node_kind_t node_kind;
+  svn_fs_root_t *fs_root;
+
+  if (!SVN_IS_VALID_REVNUM(base_revision))
+    base_revision = svn_fs_txn_base_revision(eb->txn);
 
-  SVN_ERR(svn_fs_check_path(&node_kind, eb->txn_root, path, scratch_pool));
+  if (svn_path_is_url(path))
+    {
+      /* This is a copyfrom URL. */
+      path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
+      path = svn_fspath__canonicalize(path, scratch_pool);
+    }
+  else
+    {
+      /* This is a base-relative path. */
+      if (path[0] != '/')
+        /* Get an absolute path for use in the FS. */
+        path = svn_fspath__join(eb->base_path, path, scratch_pool);
+    }
+
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
+
+  SVN_ERR(svn_fs_check_path(&node_kind, fs_root, path, scratch_pool));
   *kind = svn__kind_from_node_kind(node_kind, FALSE);
 
   return SVN_NO_ERROR;
 } 
 
+static svn_error_t *
+fetch_base_func(const char **filename,
+                void *baton,
+                const char *path,
+                svn_revnum_t base_revision,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  struct edit_baton *eb = baton;
+  svn_stream_t *contents;
+  svn_stream_t *file_stream;
+  const char *tmp_filename;
+  svn_fs_root_t *fs_root;
+  svn_error_t *err;
+
+  if (!SVN_IS_VALID_REVNUM(base_revision))
+    base_revision = svn_fs_txn_base_revision(eb->txn);
+
+  if (svn_path_is_url(path))
+    {
+      /* This is a copyfrom URL. */
+      path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
+      path = svn_fspath__canonicalize(path, scratch_pool);
+    }
+  else
+    {
+      /* This is a base-relative path. */
+      if (path[0] != '/')
+        /* Get an absolute path for use in the FS. */
+        path = svn_fspath__join(eb->base_path, path, scratch_pool);
+    }
+
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
+
+  err = svn_fs_file_contents(&contents, fs_root, path, scratch_pool);
+  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
+    {
+      svn_error_clear(err);
+      *filename = NULL;
+      return SVN_NO_ERROR;
+    }
+  else if (err)
+    return svn_error_trace(err);
+  SVN_ERR(svn_stream_open_unique(&file_stream, &tmp_filename, NULL,
+                                 svn_io_file_del_on_pool_cleanup,
+                                 scratch_pool, scratch_pool));
+  SVN_ERR(svn_stream_copy3(contents, file_stream, NULL, NULL, scratch_pool));
+
+  *filename = apr_pstrdup(result_pool, tmp_filename);
+
+  return SVN_NO_ERROR;
+}
+
 
 
 /*** Public interfaces. ***/
@@ -890,9 +988,9 @@ svn_repos_get_commit_editor5(const svn_d
   *editor = e;
 
   shim_callbacks->fetch_props_func = prop_fetch_func;
-  shim_callbacks->fetch_props_baton = eb;
   shim_callbacks->fetch_kind_func = kind_fetch_func;
-  shim_callbacks->fetch_kind_baton = eb;
+  shim_callbacks->fetch_base_func = fetch_base_func;
+  shim_callbacks->fetch_baton = eb;
 
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
                                    shim_callbacks, pool, pool));



Mime
View raw message