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/05/17 00:04:00 UTC

svn commit: r1483586 [2/3] - in /subversion/branches/fsfs-format7: ./ build/ac-macros/ build/generator/ subversion/bindings/ctypes-python/test/ subversion/bindings/javahl/native/ subversion/bindings/swig/include/ subversion/bindings/swig/perl/libsvn_sw...

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c Thu May 16 22:03:58 2013
@@ -909,29 +909,38 @@ open_path(parent_path_t **parent_path_p,
   dag_node_t *here = NULL; /* The directory we're currently looking at.  */
   parent_path_t *parent_path; /* The path from HERE up to the root. */
   const char *rest; /* The portion of PATH we haven't traversed yet.  */
-  const char *path_so_far = "/";
   apr_pool_t *iterpool = svn_pool_create(pool);
 
+  /* path to the currently processed entry without trailing '/'.
+     We will reuse this across iterations by simply putting a NUL terminator
+     at the respective position and replacing that with a '/' in the next
+     iteration.  This is correct as we assert() PATH to be canonical. */
+  svn_stringbuf_t *path_so_far = svn_stringbuf_create(path, pool);
+
   /* callers often traverse the tree in some path-based order.  That means
      a sibling of PATH has been presently accessed.  Try to start the lookup
      directly at the parent node, if the caller did not requested the full
      parent chain. */
-  const char *directory = NULL;
   assert(svn_fs__is_canonical_abspath(path));
+  path_so_far->len = 0; /* "" */
   if (flags & open_path_node_only)
     {
-      directory = svn_dirent_dirname(path, pool);
+      const char *directory = svn_dirent_dirname(path, pool);
       if (directory[1] != 0) /* root nodes are covered anyway */
-        SVN_ERR(dag_node_cache_get(&here, root, directory, TRUE, pool));
+        {
+          SVN_ERR(dag_node_cache_get(&here, root, directory, TRUE, pool));
+          /* did the shortcut work? */
+          if (here)
+            {
+              apr_size_t dirname_len = strlen(directory);
+              path_so_far->len = dirname_len;
+              rest = path + dirname_len + 1;
+            }
+        }
     }
 
   /* did the shortcut work? */
-  if (here)
-    {
-      path_so_far = directory;
-      rest = path + strlen(directory) + 1;
-    }
-  else
+  if (!here)
     {
       /* Make a parent_path item for the root node, using its own current
          copy id.  */
@@ -939,6 +948,7 @@ open_path(parent_path_t **parent_path_p,
       rest = path + 1; /* skip the leading '/', it saves in iteration */
     }
 
+  path_so_far->data[path_so_far->len] = '\0';
   parent_path = make_parent_path(here, 0, 0, pool);
   parent_path->copy_inherit = copy_id_inherit_self;
 
@@ -958,8 +968,10 @@ open_path(parent_path_t **parent_path_p,
       /* Parse out the next entry from the path.  */
       entry = svn_fs__next_entry_name(&next, rest, pool);
 
-      /* Calculate the path traversed thus far. */
-      path_so_far = svn_fspath__join(path_so_far, entry, pool);
+      /* Update the path traversed thus far. */
+      path_so_far->data[path_so_far->len] = '/';
+      path_so_far->len += strlen(entry) + 1;
+      path_so_far->data[path_so_far->len] = '\0';
 
       if (*entry == '\0')
         {
@@ -982,7 +994,7 @@ open_path(parent_path_t **parent_path_p,
              element if we already know the lookup to fail for the
              complete path. */
           if (next || !(flags & open_path_uncached))
-            SVN_ERR(dag_node_cache_get(&cached_node, root, path_so_far,
+            SVN_ERR(dag_node_cache_get(&cached_node, root, path_so_far->data,
                                        TRUE, pool));
           if (cached_node)
             child = cached_node;
@@ -1036,7 +1048,8 @@ open_path(parent_path_t **parent_path_p,
 
           /* Cache the node we found (if it wasn't already cached). */
           if (! cached_node)
-            SVN_ERR(dag_node_cache_set(root, path_so_far, child, iterpool));
+            SVN_ERR(dag_node_cache_set(root, path_so_far->data, child,
+                                       iterpool));
         }
 
       /* Are we finished traversing the path?  */
@@ -1045,7 +1058,7 @@ open_path(parent_path_t **parent_path_p,
 
       /* The path isn't finished yet; we'd better be in a directory.  */
       if (svn_fs_fs__dag_node_kind(child) != svn_node_dir)
-        SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far),
+        SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far->data),
                   apr_psprintf(iterpool, _("Failure opening '%s'"), path));
 
       rest = next;
@@ -2250,7 +2263,7 @@ check_newline(const char *path, apr_pool
   if (c)
     return svn_error_createf(SVN_ERR_FS_PATH_SYNTAX, NULL,
        _("Invalid control character '0x%02x' in path '%s'"),
-       (unsigned char)*c, escape_newline(path, pool));
+       (unsigned char)*c, svn_path_illegal_path_escape(path, pool));
 
   return SVN_NO_ERROR;
 }
@@ -3791,7 +3804,8 @@ crawl_directory_dag_for_mergeinfo(svn_fs
           svn_error_t *err;
 
           SVN_ERR(svn_fs_fs__dag_get_proplist(&proplist, kid_dag, iterpool));
-          mergeinfo_string = svn_hash_gets(proplist, SVN_PROP_MERGEINFO);
+          mergeinfo_string = svn_hash_gets_fixed_key(proplist,
+                                                     SVN_PROP_MERGEINFO);
           if (!mergeinfo_string)
             {
               svn_string_t *idstr = svn_fs_fs__id_unparse(dirent->id, iterpool);
@@ -3909,7 +3923,7 @@ get_mergeinfo_for_path_internal(svn_merg
 
   SVN_ERR(svn_fs_fs__dag_get_proplist(&proplist, nearest_ancestor->node,
                                       scratch_pool));
-  mergeinfo_string = svn_hash_gets(proplist, SVN_PROP_MERGEINFO);
+  mergeinfo_string = svn_hash_gets_fixed_key(proplist, SVN_PROP_MERGEINFO);
   if (!mergeinfo_string)
     return svn_error_createf
       (SVN_ERR_FS_CORRUPT, NULL,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra/deprecated.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra/deprecated.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra/deprecated.c Thu May 16 22:03:58 2013
@@ -219,8 +219,8 @@ svn_error_t *svn_ra_get_commit_editor2(s
 {
   apr_hash_t *revprop_table = apr_hash_make(pool);
   if (log_msg)
-    svn_hash_sets(revprop_table, SVN_PROP_REVISION_LOG,
-                  svn_string_create(log_msg, pool));
+    svn_hash_sets_fixed_key(revprop_table, SVN_PROP_REVISION_LOG,
+                            svn_string_create(log_msg, pool));
   return svn_ra_get_commit_editor3(session, editor, edit_baton, revprop_table,
                                    commit_callback, commit_baton,
                                    lock_tokens, keep_locks, pool);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_local/ra_plugin.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_local/ra_plugin.c Thu May 16 22:03:58 2013
@@ -535,7 +535,8 @@ ignore_warnings(void *baton,
                 svn_error_t *err)
 {
 #ifdef SVN_DEBUG
-  SVN_DBG(("Ignoring FS warning %d\n", err ? err->apr_err : 0));
+  SVN_DBG(("Ignoring FS warning %s\n",
+           svn_error_symbolic_name(err ? err->apr_err : 0)));
 #endif
   return;
 }
@@ -760,10 +761,10 @@ svn_ra_local__get_commit_editor(svn_ra_s
 
   /* Copy the revprops table so we can add the username. */
   revprop_table = apr_hash_copy(pool, revprop_table);
-  svn_hash_sets(revprop_table, SVN_PROP_REVISION_AUTHOR,
-                svn_string_create(sess->username, pool));
-  svn_hash_sets(revprop_table, SVN_PROP_TXN_CLIENT_COMPAT_VERSION,
-                svn_string_create(SVN_VER_NUMBER, pool));
+  svn_hash_sets_fixed_key(revprop_table, SVN_PROP_REVISION_AUTHOR,
+                          svn_string_create(sess->username, pool));
+  svn_hash_sets_fixed_key(revprop_table, SVN_PROP_TXN_CLIENT_COMPAT_VERSION,
+                          svn_string_create(SVN_VER_NUMBER, pool));
 
   /* Get the repos commit-editor */
   return svn_repos_get_commit_editor5
@@ -1654,8 +1655,8 @@ svn_ra_local__get_commit_ev2(svn_editor_
 
   /* Copy the REVPROPS and insert the author/username.  */
   revprops = apr_hash_copy(scratch_pool, revprops);
-  svn_hash_sets(revprops, SVN_PROP_REVISION_AUTHOR,
-                svn_string_create(sess->username, scratch_pool));
+  svn_hash_sets_fixed_key(revprops, SVN_PROP_REVISION_AUTHOR,
+                          svn_string_create(sess->username, scratch_pool));
 
   return svn_error_trace(svn_repos__get_commit_ev2(
                            editor, sess->repos, NULL /* authz */,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/client.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/client.c Thu May 16 22:03:58 2013
@@ -974,8 +974,8 @@ static svn_error_t *ra_svn_commit(svn_ra
   ra_svn_commit_callback_baton_t *ccb;
   apr_hash_index_t *hi;
   apr_pool_t *iterpool;
-  const svn_string_t *log_msg = svn_hash_gets(revprop_table,
-                                              SVN_PROP_REVISION_LOG);
+  const svn_string_t *log_msg = svn_hash_gets_fixed_key(revprop_table,
+                                                        SVN_PROP_REVISION_LOG);
 
   /* If we're sending revprops other than svn:log, make sure the server won't
      silently ignore them. */
@@ -1624,14 +1624,14 @@ static svn_error_t *ra_svn_log(svn_ra_se
             {
               /* Caller requested all revprops; set author/date/log. */
               if (author)
-                svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
-                              author);
+                svn_hash_sets_fixed_key(log_entry->revprops,
+                                        SVN_PROP_REVISION_AUTHOR, author);
               if (date)
-                svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_DATE,
-                              date);
+                svn_hash_sets_fixed_key(log_entry->revprops,
+                                        SVN_PROP_REVISION_DATE, date);
               if (message)
-                svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_LOG,
-                              message);
+                svn_hash_sets_fixed_key(log_entry->revprops,
+                                        SVN_PROP_REVISION_LOG, message);
             }
           else
             {
@@ -1640,14 +1640,14 @@ static svn_error_t *ra_svn_log(svn_ra_se
                 {
                   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);
+                    svn_hash_sets_fixed_key(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);
+                    svn_hash_sets_fixed_key(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_hash_sets_fixed_key(log_entry->revprops,
+                                            SVN_PROP_REVISION_LOG, message);
                 }
             }
           SVN_ERR(receiver(receiver_baton, log_entry, iterpool));

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

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/delta.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/delta.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/delta.c Thu May 16 22:03:58 2013
@@ -497,7 +497,8 @@ delta_proplists(struct context *c,
                                            pool));
 
           /* Transmit the committed-date. */
-          committed_date = svn_hash_gets(r_props, SVN_PROP_REVISION_DATE);
+          committed_date = svn_hash_gets_fixed_key(r_props,
+                                                   SVN_PROP_REVISION_DATE);
           if (committed_date || source_path)
             {
               SVN_ERR(change_fn(c, object, SVN_PROP_ENTRY_COMMITTED_DATE,
@@ -505,7 +506,8 @@ delta_proplists(struct context *c,
             }
 
           /* Transmit the last-author. */
-          last_author = svn_hash_gets(r_props, SVN_PROP_REVISION_AUTHOR);
+          last_author = svn_hash_gets_fixed_key(r_props,
+                                                SVN_PROP_REVISION_AUTHOR);
           if (last_author || source_path)
             {
               SVN_ERR(change_fn(c, object, SVN_PROP_ENTRY_LAST_AUTHOR,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/deprecated.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/deprecated.c Thu May 16 22:03:58 2013
@@ -57,11 +57,11 @@ svn_repos_get_commit_editor4(const svn_d
 {
   apr_hash_t *revprop_table = apr_hash_make(pool);
   if (user)
-    svn_hash_sets(revprop_table, SVN_PROP_REVISION_AUTHOR,
-                  svn_string_create(user, pool));
+    svn_hash_sets_fixed_key(revprop_table, SVN_PROP_REVISION_AUTHOR,
+                            svn_string_create(user, pool));
   if (log_msg)
-    svn_hash_sets(revprop_table, SVN_PROP_REVISION_LOG,
-                  svn_string_create(log_msg, pool));
+    svn_hash_sets_fixed_key(revprop_table, SVN_PROP_REVISION_LOG,
+                            svn_string_create(log_msg, pool));
   return svn_repos_get_commit_editor5(editor, edit_baton, repos, txn,
                                       repos_url, base_path, revprop_table,
                                       commit_callback, commit_baton,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/dump.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/dump.c Thu May 16 22:03:58 2013
@@ -471,8 +471,8 @@ dump_node(struct edit_baton *eb,
          dumped. */
       if (!eb->verify && eb->notify_func && eb->oldest_dumped_rev > 1)
         {
-          svn_string_t *mergeinfo_str = svn_hash_gets(prophash,
-                                                      SVN_PROP_MERGEINFO);
+          svn_string_t *mergeinfo_str
+            = svn_hash_gets_fixed_key(prophash, SVN_PROP_MERGEINFO);
           if (mergeinfo_str)
             {
               svn_mergeinfo_t mergeinfo, old_mergeinfo;
@@ -1041,13 +1041,13 @@ write_revision_record(svn_stream_t *stre
   /* Run revision date properties through the time conversion to
      canonicalize them. */
   /* ### Remove this when it is no longer needed for sure. */
-  datevalue = svn_hash_gets(props, SVN_PROP_REVISION_DATE);
+  datevalue = svn_hash_gets_fixed_key(props, SVN_PROP_REVISION_DATE);
   if (datevalue)
     {
       SVN_ERR(svn_time_from_cstring(&timetemp, datevalue->data, pool));
       datevalue = svn_string_create(svn_time_to_cstring(timetemp, pool),
                                     pool);
-      svn_hash_sets(props, SVN_PROP_REVISION_DATE, datevalue);
+      svn_hash_sets_fixed_key(props, SVN_PROP_REVISION_DATE, datevalue);
     }
 
   encoded_prophash = svn_stringbuf_create_ensure(0, pool);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/fs-wrap.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/fs-wrap.c Thu May 16 22:03:58 2013
@@ -115,8 +115,9 @@ svn_repos_fs_begin_txn_for_commit2(svn_f
 {
   apr_array_header_t *revprops;
   const char *txn_name;
-  svn_string_t *author = svn_hash_gets(revprop_table, SVN_PROP_REVISION_AUTHOR);
   apr_hash_t *hooks_env;
+  svn_string_t *author = svn_hash_gets_fixed_key(revprop_table,
+                                                 SVN_PROP_REVISION_AUTHOR);
 
   /* Parse the hooks-env file (if any). */
   SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
@@ -153,11 +154,11 @@ svn_repos_fs_begin_txn_for_commit(svn_fs
 {
   apr_hash_t *revprop_table = apr_hash_make(pool);
   if (author)
-    svn_hash_sets(revprop_table, SVN_PROP_REVISION_AUTHOR,
-                  svn_string_create(author, pool));
+    svn_hash_sets_fixed_key(revprop_table, SVN_PROP_REVISION_AUTHOR,
+                            svn_string_create(author, pool));
   if (log_msg)
-    svn_hash_sets(revprop_table, SVN_PROP_REVISION_LOG,
-                  svn_string_create(log_msg, pool));
+    svn_hash_sets_fixed_key(revprop_table, SVN_PROP_REVISION_LOG,
+                            svn_string_create(log_msg, pool));
   return svn_repos_fs_begin_txn_for_commit2(txn_p, repos, rev, revprop_table,
                                             pool);
 }
@@ -409,10 +410,8 @@ svn_repos_fs_revision_prop(svn_string_t 
   else if (readability == svn_repos_revision_access_partial)
     {
       /* Only svn:author and svn:date are fetchable. */
-      if ((strncmp(propname, SVN_PROP_REVISION_AUTHOR,
-                   sizeof(SVN_PROP_REVISION_AUTHOR)-1) != 0)
-          && (strncmp(propname, SVN_PROP_REVISION_DATE,
-                      sizeof(SVN_PROP_REVISION_DATE)-1) != 0))
+      if ((strcmp(propname, SVN_PROP_REVISION_AUTHOR) != 0)
+          && (strcmp(propname, SVN_PROP_REVISION_DATE) != 0))
         *value_p = NULL;
 
       else
@@ -459,13 +458,13 @@ svn_repos_fs_revision_proplist(apr_hash_
 
       /* If they exist, we only copy svn:author and svn:date into the
          'real' hashtable being returned. */
-      value = svn_hash_gets(tmphash, SVN_PROP_REVISION_AUTHOR);
+      value = svn_hash_gets_fixed_key(tmphash, SVN_PROP_REVISION_AUTHOR);
       if (value)
-        svn_hash_sets(*table_p, SVN_PROP_REVISION_AUTHOR, value);
+        svn_hash_sets_fixed_key(*table_p, SVN_PROP_REVISION_AUTHOR, value);
 
-      value = svn_hash_gets(tmphash, SVN_PROP_REVISION_DATE);
+      value = svn_hash_gets_fixed_key(tmphash, SVN_PROP_REVISION_DATE);
       if (value)
-        svn_hash_sets(*table_p, SVN_PROP_REVISION_DATE, value);
+        svn_hash_sets_fixed_key(*table_p, SVN_PROP_REVISION_DATE, value);
     }
   else /* wholly readable revision */
     {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/log.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/log.c Thu May 16 22:03:58 2013
@@ -210,19 +210,16 @@ detect_changed(apr_hash_t **changed,
       /* NOTE:  Much of this loop is going to look quite similar to
          svn_repos_check_revision_access(), but we have to do more things
          here, so we'll live with the duplication. */
-      const void *key;
-      void *val;
       svn_fs_path_change2_t *change;
       const char *path;
+      apr_ssize_t path_len;
       char action;
       svn_log_changed_path2_t *item;
 
       svn_pool_clear(subpool);
 
       /* KEY will be the path, VAL the change. */
-      apr_hash_this(hi, &key, NULL, &val);
-      path = (const char *) key;
-      change = val;
+      apr_hash_this(hi, (const void **)&path, &path_len, (void **)&change);
 
       /* Skip path if unreadable. */
       if (authz_read_func)
@@ -311,11 +308,15 @@ detect_changed(apr_hash_t **changed,
 
       if ((action == 'A') || (action == 'R'))
         {
-          const char *copyfrom_path;
-          svn_revnum_t copyfrom_rev;
+          const char *copyfrom_path = change->copyfrom_path;
+          svn_revnum_t copyfrom_rev = change->copyfrom_rev;
 
-          SVN_ERR(svn_fs_copied_from(&copyfrom_rev, &copyfrom_path,
-                                     root, path, subpool));
+          /* the following is a potentially expensive operation since on FSFS
+             we will follow the DAG from ROOT to PATH and that requires
+             actually reading the directories along the way. */
+          if (!change->copyfrom_known)
+            SVN_ERR(svn_fs_copied_from(&copyfrom_rev, &copyfrom_path,
+                                      root, path, subpool));
 
           if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_rev))
             {
@@ -341,7 +342,9 @@ detect_changed(apr_hash_t **changed,
                 }
             }
         }
-      svn_hash_sets(*changed, apr_pstrdup(pool, path), item);
+
+      apr_hash_set(*changed, apr_pstrmemdup(pool, path, path_len), path_len,
+                   item);
     }
 
   svn_pool_destroy(subpool);
@@ -834,6 +837,11 @@ get_combined_mergeinfo_changes(svn_merge
         }
     }
 
+  /* In most revisions, there will be no mergeinfo change at all. */
+  if (   apr_hash_count(deleted_mergeinfo_catalog) == 0
+      && apr_hash_count(added_mergeinfo_catalog) == 0)
+    return SVN_NO_ERROR;
+  
   /* Check our PATHS for any changes to their inherited mergeinfo.
      (We deal with changes to mergeinfo directly *on* the paths in the
      following loop.)  */
@@ -1076,10 +1084,14 @@ fill_log_entry(svn_log_entry_t *log_entr
             {
               /* ... but we can only return author/date. */
               log_entry->revprops = svn_hash__make(pool);
-              svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
-                            svn_hash_gets(r_props, SVN_PROP_REVISION_AUTHOR));
-              svn_hash_sets(log_entry->revprops, SVN_PROP_REVISION_DATE,
-                            svn_hash_gets(r_props, SVN_PROP_REVISION_DATE));
+              svn_hash_sets_fixed_key(log_entry->revprops,
+                                      SVN_PROP_REVISION_AUTHOR,
+                            svn_hash_gets_fixed_key(r_props,
+                                                    SVN_PROP_REVISION_AUTHOR));
+              svn_hash_sets_fixed_key(log_entry->revprops,
+                                      SVN_PROP_REVISION_DATE,
+                            svn_hash_gets_fixed_key(r_props,
+                                                    SVN_PROP_REVISION_DATE));
             }
           else
             /* ... so return all we got. */
@@ -1087,21 +1099,47 @@ fill_log_entry(svn_log_entry_t *log_entr
         }
       else
         {
-          /* Requested only some revprops... */
           int i;
-          for (i = 0; i < revprops->nelts; i++)
+
+          /* Requested only some revprops... */
+          
+          /* often only the standard revprops got requested and delivered.
+             In that case, we can simply pass the hash on. */
+          if (revprops->nelts == apr_hash_count(r_props) && !censor_revprops)
             {
-              char *name = APR_ARRAY_IDX(revprops, i, char *);
-              svn_string_t *value = svn_hash_gets(r_props, name);
-              if (censor_revprops
-                  && !(strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0
-                       || strcmp(name, SVN_PROP_REVISION_DATE) == 0))
-                /* ... but we can only return author/date. */
-                continue;
-              if (log_entry->revprops == NULL)
-                log_entry->revprops = svn_hash__make(pool);
-              svn_hash_sets(log_entry->revprops, name, value);
+              log_entry->revprops = r_props;
+              for (i = 0; i < revprops->nelts; i++)
+                {
+                  const svn_string_t *name
+                    = APR_ARRAY_IDX(revprops, i, const svn_string_t *);
+                  if (!apr_hash_get(r_props, name->data, name->len))
+                    {
+                      /* hash does not match list of revprops we want */
+                      log_entry->revprops = NULL;
+                      break;
+                    }
+                }
             }
+
+          /* slow, revprop-by-revprop filtering */
+          if (log_entry->revprops == NULL)
+            for (i = 0; i < revprops->nelts; i++)
+              {
+                const svn_string_t *name
+                  = APR_ARRAY_IDX(revprops, i, const svn_string_t *);
+                svn_string_t *value
+                  = apr_hash_get(r_props, name->data, name->len);
+                if (censor_revprops
+                    && !(strncmp(name->data, SVN_PROP_REVISION_AUTHOR,
+                                 name->len) == 0
+                         || strncmp(name->data, SVN_PROP_REVISION_DATE,
+                                    name->len) == 0))
+                  /* ... but we can only return author/date. */
+                  continue;
+                if (log_entry->revprops == NULL)
+                  log_entry->revprops = svn_hash__make(pool);
+                apr_hash_set(log_entry->revprops, name->data, name->len, value);
+              }
         }
     }
 
@@ -1175,32 +1213,33 @@ send_log(svn_revnum_t rev,
       && apr_hash_count(log_target_history_as_mergeinfo))
     {
       apr_hash_index_t *hi;
-      apr_pool_t *subpool = svn_pool_create(pool);
+      apr_pool_t *iterpool = svn_pool_create(pool);
 
       /* REV was merged in, but it might already be part of the log target's
          natural history, so change our starting assumption. */
       found_rev_of_interest = FALSE;
 
       /* Look at each changed path in REV. */
-      for (hi = apr_hash_first(subpool, log_entry->changed_paths2);
+      for (hi = apr_hash_first(pool, log_entry->changed_paths2);
            hi;
            hi = apr_hash_next(hi))
         {
           svn_boolean_t path_is_in_history = FALSE;
           const char *changed_path = svn__apr_hash_index_key(hi);
           apr_hash_index_t *hi2;
-          apr_pool_t *inner_subpool = svn_pool_create(subpool);
+
+          apr_hash_this(hi, (const void**)&changed_path, NULL, NULL);
 
           /* Look at each path on the log target's mergeinfo. */
-          for (hi2 = apr_hash_first(inner_subpool,
+          for (hi2 = apr_hash_first(iterpool,
                                     log_target_history_as_mergeinfo);
                hi2;
                hi2 = apr_hash_next(hi2))
             {
-              const char *mergeinfo_path =
-                svn__apr_hash_index_key(hi2);
-              svn_rangelist_t *rangelist =
-                svn__apr_hash_index_val(hi2);
+              const char *mergeinfo_path;
+              svn_rangelist_t *rangelist;
+              apr_hash_this(hi2, (const void**)&mergeinfo_path, NULL,
+                                 (void **)&rangelist);
 
               /* Check whether CHANGED_PATH at revision REV is a child of
                  a (path, revision) tuple in LOG_TARGET_HISTORY_AS_MERGEINFO. */
@@ -1223,7 +1262,7 @@ send_log(svn_revnum_t rev,
               if (path_is_in_history)
                 break;
             }
-          svn_pool_destroy(inner_subpool);
+          svn_pool_clear(iterpool);
 
           if (!path_is_in_history)
             {
@@ -1234,7 +1273,7 @@ send_log(svn_revnum_t rev,
               break;
             }
         }
-      svn_pool_destroy(subpool);
+      svn_pool_destroy(iterpool);
     }
 
   /* If we only got changed paths the sake of detecting redundant merged
@@ -2243,6 +2282,19 @@ svn_repos_get_logs4(svn_repos_t *repos,
   svn_boolean_t descending_order;
   svn_mergeinfo_t paths_history_mergeinfo = NULL;
 
+  if (revprops)
+    {
+      int i;
+      apr_array_header_t *new_revprops
+        = apr_array_make(pool, revprops->nelts, sizeof(svn_string_t *));
+
+      for (i = 0; i < revprops->nelts; ++i)
+        APR_ARRAY_PUSH(new_revprops, svn_string_t *)
+          = svn_string_create(APR_ARRAY_IDX(revprops, i, const char *), pool);
+
+      revprops = new_revprops;
+    }
+  
   /* Setup log range. */
   SVN_ERR(svn_fs_youngest_rev(&head, fs, pool));
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/replay.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/replay.c Thu May 16 22:03:58 2013
@@ -704,31 +704,45 @@ path_driver_cb_func(void **dir_baton,
       /* Handle property modifications. */
       if (change->prop_mod || downgraded_copy)
         {
-          apr_array_header_t *prop_diffs;
-          apr_hash_t *old_props;
-          apr_hash_t *new_props;
-          int i;
-
-          if (source_root)
-            SVN_ERR(svn_fs_node_proplist(&old_props, source_root,
-                                         source_fspath, pool));
-          else
-            old_props = apr_hash_make(pool);
+          if (cb->compare_root)
+            {
+              apr_array_header_t *prop_diffs;
+              apr_hash_t *old_props;
+              apr_hash_t *new_props;
+              int i;
+
+              if (source_root)
+                SVN_ERR(svn_fs_node_proplist(&old_props, source_root,
+                                             source_fspath, pool));
+              else
+                old_props = apr_hash_make(pool);
 
-          SVN_ERR(svn_fs_node_proplist(&new_props, root, edit_path, pool));
+              SVN_ERR(svn_fs_node_proplist(&new_props, root, edit_path, pool));
 
-          SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, old_props,
-                                 pool));
+              SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, old_props,
+                                     pool));
 
-          for (i = 0; i < prop_diffs->nelts; ++i)
+              for (i = 0; i < prop_diffs->nelts; ++i)
+                {
+                  svn_prop_t *pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
+                   if (change->node_kind == svn_node_dir)
+                     SVN_ERR(editor->change_dir_prop(*dir_baton, pc->name,
+                                                     pc->value, pool));
+                   else if (change->node_kind == svn_node_file)
+                     SVN_ERR(editor->change_file_prop(file_baton, pc->name,
+                                                      pc->value, pool));
+                }
+            }
+          else
             {
-              svn_prop_t *pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
-               if (change->node_kind == svn_node_dir)
-                 SVN_ERR(editor->change_dir_prop(*dir_baton, pc->name,
-                                                 pc->value, pool));
-               else if (change->node_kind == svn_node_file)
-                 SVN_ERR(editor->change_file_prop(file_baton, pc->name,
-                                                  pc->value, pool));
+              /* Just do a dummy prop change to signal that there are *any*
+                 propmods. */
+              if (change->node_kind == svn_node_dir)
+                SVN_ERR(editor->change_dir_prop(*dir_baton, "", NULL,
+                                                pool));
+              else if (change->node_kind == svn_node_file)
+                SVN_ERR(editor->change_file_prop(file_baton, "", NULL,
+                                                 pool));
             }
         }
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/reporter.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/reporter.c Thu May 16 22:03:58 2013
@@ -487,10 +487,10 @@ get_revision_info(report_baton_t *b,
                                        scratch_pool));
 
       /* Extract the committed-date. */
-      cdate = svn_hash_gets(r_props, SVN_PROP_REVISION_DATE);
+      cdate = svn_hash_gets_fixed_key(r_props, SVN_PROP_REVISION_DATE);
 
       /* Extract the last-author. */
-      author = svn_hash_gets(r_props, SVN_PROP_REVISION_AUTHOR);
+      author = svn_hash_gets_fixed_key(r_props, SVN_PROP_REVISION_AUTHOR);
 
       /* Create a result object */
       info = apr_palloc(b->pool, sizeof(*info));

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/rev_hunt.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/rev_hunt.c Thu May 16 22:03:58 2013
@@ -171,12 +171,8 @@ svn_repos_get_committed_info(svn_revnum_
   SVN_ERR(svn_fs_revision_proplist(&revprops, fs, *committed_rev, pool));
 
   /* Extract date and author from these revprops. */
-  committed_date_s = apr_hash_get(revprops,
-                                  SVN_PROP_REVISION_DATE,
-                                  sizeof(SVN_PROP_REVISION_DATE)-1);
-  last_author_s = apr_hash_get(revprops,
-                               SVN_PROP_REVISION_AUTHOR,
-                               sizeof(SVN_PROP_REVISION_AUTHOR)-1);
+  committed_date_s = svn_hash_gets_fixed_key(revprops, SVN_PROP_REVISION_DATE);
+  last_author_s = svn_hash_gets_fixed_key(revprops, SVN_PROP_REVISION_AUTHOR);
 
   *committed_date = committed_date_s ? committed_date_s->data : NULL;
   *last_author = last_author_s ? last_author_s->data : NULL;

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/cache-inprocess.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/cache-inprocess.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/cache-inprocess.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/cache-inprocess.c Thu May 16 22:03:58 2013
@@ -190,7 +190,6 @@ inprocess_cache_get_internal(char **buff
 {
   struct cache_entry *entry = apr_hash_get(cache->hash, key, cache->klen);
 
-  *buffer = NULL;
   if (entry)
     {
       SVN_ERR(move_page_to_front(cache, entry->page));
@@ -201,6 +200,11 @@ inprocess_cache_get_internal(char **buff
 
       *size = entry->size;
     }
+  else
+    {
+      *buffer = NULL;
+      *size = 0;
+    }
 
   return SVN_NO_ERROR;
 }
@@ -213,25 +217,33 @@ inprocess_cache_get(void **value_p,
                     apr_pool_t *result_pool)
 {
   inprocess_cache_t *cache = cache_void;
-  char* buffer = NULL;
-  apr_size_t size = 0;
 
   if (key)
-    SVN_MUTEX__WITH_LOCK(cache->mutex,
-                         inprocess_cache_get_internal(&buffer,
-                                                      &size,
-                                                      cache,
-                                                      key,
-                                                      result_pool));
+    {
+      char* buffer;
+      apr_size_t size;
 
-  /* deserialize the buffer content. Usually, this will directly
-     modify the buffer content directly.
-   */
-  *value_p = NULL;
-  *found = buffer != NULL;
-  return buffer && size
-    ? cache->deserialize_func(value_p, buffer, size, result_pool)
-    : SVN_NO_ERROR;
+      SVN_MUTEX__WITH_LOCK(cache->mutex,
+                           inprocess_cache_get_internal(&buffer,
+                                                        &size,
+                                                        cache,
+                                                        key,
+                                                        result_pool));
+      /* deserialize the buffer content. Usually, this will directly
+         modify the buffer content directly. */
+      *found = (buffer != NULL);
+      if (!buffer || !size)
+        *value_p = NULL;
+      else
+        return cache->deserialize_func(value_p, buffer, size, result_pool);
+    }
+  else
+    {
+      *value_p = NULL;
+      *found = FALSE;
+    }
+
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t *

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/cmdline.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/cmdline.c Thu May 16 22:03:58 2013
@@ -236,7 +236,7 @@ svn_cmdline_init(const char *progname, F
   /* Create a pool for use by the UTF-8 routines.  It will be cleaned
      up by APR at exit time. */
   pool = svn_pool_create(NULL);
-  svn_utf_initialize2(pool, FALSE);
+  svn_utf_initialize2(FALSE, pool);
 
   if ((err = svn_nls_init()))
     {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/compat.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/compat.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/compat.c Thu May 16 22:03:58 2013
@@ -76,9 +76,9 @@ svn_compat_log_revprops_clear(apr_hash_t
 {
   if (revprops)
     {
-      svn_hash_sets(revprops, SVN_PROP_REVISION_AUTHOR, NULL);
-      svn_hash_sets(revprops, SVN_PROP_REVISION_DATE, NULL);
-      svn_hash_sets(revprops, SVN_PROP_REVISION_LOG, NULL);
+      svn_hash_sets_fixed_key(revprops, SVN_PROP_REVISION_AUTHOR, NULL);
+      svn_hash_sets_fixed_key(revprops, SVN_PROP_REVISION_DATE, NULL);
+      svn_hash_sets_fixed_key(revprops, SVN_PROP_REVISION_LOG, NULL);
     }
 }
 
@@ -103,11 +103,14 @@ svn_compat_log_revprops_out(const char *
   *author = *date = *message = NULL;
   if (revprops)
     {
-      if ((author_s = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR)))
+      if ((author_s = svn_hash_gets_fixed_key(revprops,
+                                              SVN_PROP_REVISION_AUTHOR)))
         *author = author_s->data;
-      if ((date_s = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE)))
+      if ((date_s = svn_hash_gets_fixed_key(revprops,
+                                            SVN_PROP_REVISION_DATE)))
         *date = date_s->data;
-      if ((message_s = svn_hash_gets(revprops, SVN_PROP_REVISION_LOG)))
+      if ((message_s = svn_hash_gets_fixed_key(revprops,
+                                               SVN_PROP_REVISION_LOG)))
         *message = message_s->data;
     }
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/deprecated.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/deprecated.c Thu May 16 22:03:58 2013
@@ -1255,7 +1255,7 @@ svn_xml_make_header(svn_stringbuf_t **st
 void
 svn_utf_initialize(apr_pool_t *pool)
 {
-  svn_utf_initialize2(pool, FALSE);
+  svn_utf_initialize2(FALSE, pool);
 }
 
 svn_error_t *

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/error.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/error.c Thu May 16 22:03:58 2013
@@ -771,6 +771,12 @@ svn_error_set_malfunction_handler(svn_er
   return old_malfunction_handler;
 }
 
+svn_error_malfunction_handler_t
+svn_error_get_malfunction_handler(void)
+{
+  return malfunction_handler;
+}
+
 /* Note: Although this is a "__" function, it is in the public ABI, so
  * we can never remove it or change its signature. */
 svn_error_t *

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/hash.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/hash.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/hash.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/hash.c Thu May 16 22:03:58 2013
@@ -576,20 +576,16 @@ svn_hash__get_bool(apr_hash_t *hash, con
 
 /*** Optimized hash function ***/
 
-/* Optimized version of apr_hashfunc_default in APR 1.4.5 and earlier.
- * It assumes that the CPU has 32-bit multiplications with high throughput
- * of at least 1 operation every 3 cycles. Latency is not an issue. Another
- * optimization is a mildly unrolled main loop and breaking the dependency
- * chain within the loop.
- *
- * Note that most CPUs including Intel Atom, VIA Nano, ARM feature the
- * assumed pipelined multiplication circuitry. They can do one MUL every
- * or every other cycle.
- *
- * The performance is ultimately limited by the fact that most CPUs can
- * do only one LOAD and only one BRANCH operation per cycle. The best we
- * can do is to process one character per cycle - provided the processor
- * is wide enough to do 1 LOAD, COMPARE, BRANCH, MUL and ADD per cycle.
+/* apr_hashfunc_t optimized for the key that we use in SVN: paths and 
+ * property names.  Its primary goal is speed for keys of known length.
+ * 
+ * Since strings tend to spawn large value spaces (usually differ in many
+ * bits with differences spanning a larger section of the key), we can be
+ * quite sloppy extracting a hash value.  The more keys there are in a
+ * hash container, the more bits of the value returned by this function
+ * will be used.  For a small number of string keys, choosing bits from any 
+ * any fix location close to the tail of those keys would usually be good
+ * enough to prevent high collision rates.
  */
 static unsigned int
 hashfunc_compatible(const char *char_key, apr_ssize_t *klen)
@@ -600,37 +596,29 @@ hashfunc_compatible(const char *char_key
     apr_ssize_t i;
 
     if (*klen == APR_HASH_KEY_STRING)
+      *klen = strlen(char_key);
+
+#if SVN_UNALIGNED_ACCESS_IS_OK
+    for (p = key, i = *klen; i >= 4; i-=4, p+=4)
       {
-        for (p = key; ; p+=4)
-          {
-            unsigned int new_hash = hash * 33 * 33 * 33 * 33;
-            if (!p[0]) break;
-            new_hash += p[0] * 33 * 33 * 33;
-            if (!p[1]) break;
-            new_hash += p[1] * 33 * 33;
-            if (!p[2]) break;
-            new_hash += p[2] * 33;
-            if (!p[3]) break;
-            hash = new_hash + p[3];
-          }
-        for (; *p; p++)
-            hash = hash * 33 + *p;
+        apr_uint32_t chunk = *(apr_uint32_t *)p;
 
-        *klen = p - key;
+        /* the ">> 17" part gives upper bits in the chunk a chance to make
+           some impact as well */
+        hash = hash * 33 * 33 * 33 * 33 + chunk + (chunk >> 17);
       }
-    else
+#else
+    for (p = key, i = *klen; i >= 4; i-=4, p+=4)
       {
-        for (p = key, i = *klen; i >= 4; i-=4, p+=4)
-          {
-            hash = hash * 33 * 33 * 33 * 33
-                 + p[0] * 33 * 33 * 33
-                 + p[1] * 33 * 33
-                 + p[2] * 33
-                 + p[3];
-          }
-        for (; i; i--, p++)
-            hash = hash * 33 + *p;
+        hash = hash * 33 * 33 * 33 * 33
+              + p[0] * 33 * 33 * 33
+              + p[1] * 33 * 33
+              + p[2] * 33
+              + p[3];
       }
+#endif
+    for (; i; i--, p++)
+        hash = hash * 33 + *p;
 
     return hash;
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/mergeinfo.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/mergeinfo.c Thu May 16 22:03:58 2013
@@ -611,6 +611,23 @@ svn_rangelist__parse(svn_rangelist_t **r
   return SVN_NO_ERROR;
 }
 
+/* Return TRUE, if all ranges in RANGELIST are in ascending order and do
+ * not overlap.  If this returns FALSE, you probaly want to qsort() the
+ * ranges and then call svn_rangelist__combine_adjacent_ranges().
+ */
+static svn_boolean_t
+is_rangelist_normalized(svn_rangelist_t *rangelist)
+{
+  int i;
+  svn_merge_range_t **ranges = (svn_merge_range_t **)rangelist->elts;
+
+  for (i = 0; i < rangelist->nelts-1; ++i)
+    if (ranges[i]->end >= ranges[i+1]->start)
+      return FALSE;
+
+  return TRUE;
+}
+
 svn_error_t *
 svn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist,
                                        apr_pool_t *scratch_pool)
@@ -692,9 +709,11 @@ parse_revision_line(const char **input, 
   if (*input != end)
     *input = *input + 1;
 
-  /* Sort the rangelist, combine adjacent ranges into single ranges,
-     and make sure there are no overlapping ranges. */
-  if (rangelist->nelts > 1)
+  /* Sort the rangelist, combine adjacent ranges into single ranges, and
+     make sure there are no overlapping ranges.  Luckily, most data in
+     svn:mergeinfo will already be in normalized form and we can skip this.
+   */
+  if (! is_rangelist_normalized(rangelist))
     {
       qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size,
             svn_sort_compare_ranges);
@@ -2223,16 +2242,19 @@ svn_rangelist_dup(const svn_rangelist_t 
 
   /* allocate target range buffer with a single operation */
   svn_merge_range_t *copy = apr_palloc(pool, sizeof(*copy) * rangelist->nelts);
+
+  /* for efficiency, directly address source and target reference buffers */
+  svn_merge_range_t **source = (svn_merge_range_t **)(rangelist->elts);
+  svn_merge_range_t **target = (svn_merge_range_t **)(new_rl->elts);
   int i;
 
-  /* fill it iteratively and link it into the range list */
+  /* copy ranges iteratively and link them into the target range list */
   for (i = 0; i < rangelist->nelts; i++)
     {
-      memcpy(copy + i,
-             APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *),
-             sizeof(*copy));
-      APR_ARRAY_PUSH(new_rl, svn_merge_range_t *) = copy + i;
+      copy[i] = *source[i];
+      target[i] = &copy[i];
     }
+  new_rl->nelts = rangelist->nelts;
 
   return new_rl;
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/nls.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/nls.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/nls.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/nls.c Thu May 16 22:03:58 2013
@@ -56,7 +56,6 @@ svn_nls_init(void)
       char* utf8_path;
       const char* internal_path;
       apr_pool_t* pool;
-      apr_status_t apr_err;
       apr_size_t inwords, outbytes, outlength;
 
       apr_pool_create(&pool, 0);
@@ -99,10 +98,10 @@ svn_nls_init(void)
 
           if (outbytes == 0)
             {
-              err = svn_error_createf(apr_err, NULL,
-                                      _("Can't convert module path "
-                                        "to UTF-8 from UCS-2: '%s'"),
-                                      ucs2_path);
+              err = svn_error_wrap_apr(apr_get_os_error(),
+                                       _("Can't convert module path "
+                                         "to UTF-8 from UCS-2: '%s'"),
+                                       ucs2_path);
             }
           else
             {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/path.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/path.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/path.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/path.c Thu May 16 22:03:58 2013
@@ -1164,11 +1164,8 @@ svn_path_cstring_to_utf8(const char **pa
 }
 
 
-/* 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)
+const char *
+svn_path_illegal_path_escape(const char *path, apr_pool_t *pool)
 {
   svn_stringbuf_t *retstr;
   apr_size_t i, copied = 0;
@@ -1194,7 +1191,7 @@ illegal_path_escape(const char *path, ap
                                   i - copied);
 
       /* Make sure buffer is big enough for '\' 'N' 'N' 'N' (and NUL) */
-      svn_stringbuf_ensure(retstr, retstr->len + 4);
+      svn_stringbuf_ensure(retstr, retstr->len + 5);
       /*### 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) */
@@ -1228,11 +1225,11 @@ svn_path_check_valid(const char *path, a
     {
       if (svn_ctype_iscntrl(*c))
         {
-          return svn_error_createf
-            (SVN_ERR_FS_PATH_SYNTAX, NULL,
+          return svn_error_createf(SVN_ERR_FS_PATH_SYNTAX, NULL,
              _("Invalid control character '0x%02x' in path '%s'"),
              (unsigned char)*c,
-             illegal_path_escape(svn_dirent_local_style(path, pool), pool));
+             svn_path_illegal_path_escape(svn_dirent_local_style(path, pool),
+                                          pool));
         }
     }
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/string.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/string.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/string.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/string.c Thu May 16 22:03:58 2013
@@ -1038,6 +1038,36 @@ svn__strtoff(apr_off_t *offset, const ch
 #endif
 }
 
+unsigned long
+svn__strtoul(const char *buffer, char **end)
+{
+  unsigned long result = 0;
+
+  /* this loop will execute in just 2 CPU cycles, confirmed by measurement:
+     7 macro-ops (max 4 / cycle => 2 cycles)
+       1 load (max 1 / cycle)
+       1 jumps (compare + conditional jump == 1 macro op; max 1 / cycle)
+       2 arithmetic ops (subtract, increment; max 3 / cycle)
+       2 scale-and-add AGU ops (max 3 / cycle)
+       1 compiler-generated move operation
+     dependency chain: temp = result * 4 + result; result = temp * 2 + c
+                       (2 ops with latency 1 => 2 cycles)
+   */
+  while (1)
+    {
+      unsigned long c = *buffer - '0';
+      if (c > 9)
+        break;
+
+      result = result * 10 + c;
+      ++buffer;
+    }
+
+  *end = (char *)buffer;
+  return result;
+}
+
+
 /* "Precalculated" itoa values for 2 places (including leading zeros).
  * For maximum performance, make sure all table entries are word-aligned.
  */

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/types.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/types.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/types.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/types.c Thu May 16 22:03:58 2013
@@ -31,6 +31,9 @@
 #include "svn_props.h"
 #include "svn_private_config.h"
 
+#include "private/svn_dep_compat.h"
+#include "private/svn_string_private.h"
+
 svn_error_t *
 svn_revnum_parse(svn_revnum_t *rev,
                  const char *str,
@@ -38,28 +41,37 @@ svn_revnum_parse(svn_revnum_t *rev,
 {
   char *end;
 
-  svn_revnum_t result = strtol(str, &end, 10);
+  svn_revnum_t result = (svn_revnum_t)svn__strtoul(str, &end);
 
   if (endptr)
-    *endptr = end;
+    *endptr = str;
 
   if (str == end)
-    return svn_error_createf(SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
-                             _("Invalid revision number found parsing '%s'"),
-                             str);
-
-  if (result < 0)
+    return svn_error_createf
+              (SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
+               *str == '-' ? _("Negative revision number found parsing '%s'")
+                           : _("Invalid revision number found parsing '%s'"),
+               str);
+
+  /* a revision number with more than 9 digits is suspicious.
+     Have a closer look at those. */
+  if (str + 10 <= end)
     {
-      /* The end pointer from strtol() is valid, but a negative revision
-         number is invalid, so move the end pointer back to the
-         beginning of the string. */
-      if (endptr)
-        *endptr = str;
-
-      return svn_error_createf(SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
-                               _("Negative revision number found parsing '%s'"),
-                               str);
+      /* we support 32 bit revision numbers only. check for overflows */
+      if (str + 10 < end)
+        return svn_error_createf
+                  (SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
+                  _("Revision number longer than 10 digits '%s'"), str);
+        
+      /* we support 32 bit revision numbers only. check for overflows */
+      if (*str > '2' || (apr_uint32_t)result > APR_INT32_MAX)
+        return svn_error_createf
+                  (SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
+                  _("Revision number too large or not normalized '%s'"), str);
     }
+  
+  if (endptr)
+    *endptr = end;
 
   *rev = result;
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/utf.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/utf.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/utf.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/utf.c Thu May 16 22:03:58 2013
@@ -121,8 +121,8 @@ xlate_handle_node_cleanup(void *arg)
 }
 
 void
-svn_utf_initialize2(apr_pool_t *pool,
-                    svn_boolean_t assume_native_utf8)
+svn_utf_initialize2(svn_boolean_t assume_native_utf8,
+                    apr_pool_t *pool)
 {
   if (!xlate_handle_hash)
     {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/utf8proc.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/utf8proc.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/utf8proc.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/utf8proc.c Thu May 16 22:03:58 2013
@@ -156,7 +156,7 @@ encode_ucs4(svn_membuf_t *buffer, apr_in
   utf8len = utf8proc_encode_char(ucs4chr, ((uint8_t*)buffer->data + *length));
   if (!utf8len)
     return svn_error_createf(SVN_ERR_UTF8PROC_ERROR, NULL,
-                             "Invalid Unicode character U+%04lX",
+                             _("Invalid Unicode character U+%04lX"),
                              (long)ucs4chr);
   *length += utf8len;
   return SVN_NO_ERROR;
@@ -196,11 +196,11 @@ svn_utf__glob(svn_boolean_t *match,
   apr_size_t patternbuf_len;
   apr_size_t tempbuf_len;
 
-  /* If we're in LIKE mode, we don't do custom escape chars. */
+  /* If we're in GLOB mode, we don't do custom escape chars. */
   if (escape && !sql_like)
     return svn_error_create(SVN_ERR_UTF8_GLOB, NULL,
-                            "The GLOB operator does not allow"
-                            " a custom escape character");
+                            _("Cannot use a custom escape token"
+                              " in glob matching mode"));
 
   /* Convert the patern to NFD UTF-8. We can't use the UCS-4 result
      because apr_fnmatch can't handle it.*/
@@ -228,12 +228,12 @@ svn_utf__glob(svn_boolean_t *match,
           if (result < 0)
             return svn_error_create(SVN_ERR_UTF8PROC_ERROR, NULL,
                                     gettext(utf8proc_errmsg(result)));
-          if (result > 1)
+          if (result == 0 || result > 1)
             return svn_error_create(SVN_ERR_UTF8_GLOB, NULL,
-                                    "The ESCAPE parameter is too long");
+                                    _("Escape token must be one character"));
           if ((ucs4esc & 0xFF) != ucs4esc)
             return svn_error_createf(SVN_ERR_UTF8_GLOB, NULL,
-                                     "Invalid ESCAPE character U+%04lX",
+                                     _("Invalid escape character U+%04lX"),
                                      (long)ucs4esc);
         }
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/conflicts.c Thu May 16 22:03:58 2013
@@ -159,16 +159,16 @@ conflict__read_location(svn_wc_conflict_
     }
   c = c->next;
 
-  repos_root_url = apr_pstrmemdup(scratch_pool, c->data, c->len);
+  repos_root_url = apr_pstrmemdup(result_pool, c->data, c->len);
   c = c->next;
 
   if (c->is_atom)
-    repos_uuid = apr_pstrmemdup(scratch_pool, c->data, c->len);
+    repos_uuid = apr_pstrmemdup(result_pool, c->data, c->len);
   else
     repos_uuid = NULL;
   c = c->next;
 
-  repos_relpath = apr_pstrmemdup(scratch_pool, c->data, c->len);
+  repos_relpath = apr_pstrmemdup(result_pool, c->data, c->len);
   c = c->next;
 
   SVN_ERR(svn_skel__parse_int(&v, c, scratch_pool));
@@ -2298,7 +2298,7 @@ svn_wc__read_conflicts(const apr_array_h
   SVN_ERR(svn_wc__conflict_read_info(&operation, &locations, &text_conflicted,
                                      &prop_conflicted, &tree_conflicted,
                                      db, local_abspath, conflict_skel,
-                                     scratch_pool, scratch_pool));
+                                     result_pool, scratch_pool));
 
   cflcts = apr_array_make(result_pool, 4,
                           sizeof(svn_wc_conflict_description2_t*));

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/diff_editor.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/diff_editor.c Thu May 16 22:03:58 2013
@@ -2362,9 +2362,9 @@ wrap_ensure_empty_file(wc_diff_wrap_bato
     return SVN_NO_ERROR;
 
   /* Create a unique file in the tempdir */
-  SVN_ERR(svn_io_open_uniquely_named(NULL, &wb->empty_file, NULL, NULL, NULL,
-                                     svn_io_file_del_on_pool_cleanup,
-                                     wb->result_pool, scratch_pool));
+  SVN_ERR(svn_io_open_unique_file3(NULL, &wb->empty_file, NULL,
+                                   svn_io_file_del_on_pool_cleanup,
+                                   wb->result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/diff_local.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/diff_local.c Thu May 16 22:03:58 2013
@@ -201,6 +201,15 @@ diff_status_callback(void *baton,
       case svn_wc_status_ignored:
         return SVN_NO_ERROR; /* No diff */
 
+      case svn_wc_status_conflicted:
+        if (status->text_status == svn_wc_status_none
+            && status->prop_status == svn_wc_status_none)
+          {
+            /* Node is an actual only node describing a tree conflict */
+            return SVN_NO_ERROR;
+          }
+        break;
+
       default:
         break; /* Go check other conditions */
     }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/entries.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/entries.c Thu May 16 22:03:58 2013
@@ -1565,7 +1565,9 @@ insert_actual_node(svn_sqlite__db_t *sdb
                                 actual_node->conflict_new,
                                 actual_node->prop_reject,
                                 actual_node->tree_conflict_data,
-                                strlen(actual_node->tree_conflict_data),
+                                actual_node->tree_conflict_data
+                                    ? strlen(actual_node->tree_conflict_data)
+                                    : 0,
                                 scratch_pool, scratch_pool));
 
   if (conflict_data)

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/props.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/props.c Thu May 16 22:03:58 2013
@@ -81,12 +81,10 @@ append_prop_conflict(svn_stream_t *strea
   /* TODO:  someday, perhaps prefix each conflict_description with a
      timestamp or something? */
   const svn_string_t *conflict_desc;
-  const char *native_text;
 
   SVN_ERR(prop_conflict_from_skel(&conflict_desc, prop_skel, pool, pool));
-  native_text = svn_utf_cstring_from_utf8_fuzzy(conflict_desc->data, pool);
 
-  return svn_stream_puts(stream, native_text);
+  return svn_stream_puts(stream, conflict_desc->data);
 }
 
 /*---------------------------------------------------------------------*/
@@ -614,12 +612,26 @@ prop_conflict_from_skel(const svn_string
           const char *mine_marker = _("<<<<<<< (local property value)");
           const char *incoming_marker = _(">>>>>>> (incoming property value)");
           const char *separator = "=======";
+          svn_string_t *original_ascii =
+            svn_string_create(svn_utf_cstring_from_utf8_fuzzy(original->data,
+                                                              scratch_pool),
+                              scratch_pool);
+          svn_string_t *mine_ascii =
+            svn_string_create(svn_utf_cstring_from_utf8_fuzzy(mine->data,
+                                                              scratch_pool),
+                              scratch_pool);
+          svn_string_t *incoming_ascii =
+            svn_string_create(svn_utf_cstring_from_utf8_fuzzy(incoming->data,
+                                                              scratch_pool),
+                              scratch_pool);
 
           style = svn_diff_conflict_display_modified_latest;
           stream = svn_stream_from_stringbuf(buf, scratch_pool);
           SVN_ERR(svn_stream_skip(stream, buf->len));
           SVN_ERR(svn_diff_mem_string_output_merge2(stream, diff,
-                                                    original, mine, incoming,
+                                                    original_ascii,
+                                                    mine_ascii,
+                                                    incoming_ascii,
                                                     NULL, mine_marker,
                                                     incoming_marker, separator,
                                                     style, scratch_pool));

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/status.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/status.c Thu May 16 22:03:58 2013
@@ -995,12 +995,12 @@ collect_ignore_patterns(apr_array_header
     {
       const svn_string_t *value;
 
-      value = svn_hash_gets(props, SVN_PROP_IGNORE);
+      value = svn_hash_gets_fixed_key(props, SVN_PROP_IGNORE);
       if (value)
         svn_cstring_split_append(*patterns, value->data, "\n\r", FALSE,
                                  result_pool);
 
-      value = svn_hash_gets(props, SVN_PROP_INHERITABLE_IGNORES);
+      value = svn_hash_gets_fixed_key(props, SVN_PROP_INHERITABLE_IGNORES);
       if (value)
         svn_cstring_split_append(*patterns, value->data, "\n\r", FALSE,
                                  result_pool);

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/activity.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/activity.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/activity.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/activity.c Thu May 16 22:03:58 2013
@@ -255,9 +255,9 @@ dav_svn__create_txn(const dav_svn_repos 
 
   if (repos->username)
     {
-      svn_hash_sets(revprops,
-                    SVN_PROP_REVISION_AUTHOR,
-                    svn_string_create(repos->username, pool));
+      svn_hash_sets_fixed_key(revprops,
+                              SVN_PROP_REVISION_AUTHOR,
+                              svn_string_create(repos->username, pool));
     }
 
   serr = svn_fs_youngest_rev(&rev, repos->fs, pool);

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/lock.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/lock.c Thu May 16 22:03:58 2013
@@ -680,9 +680,10 @@ append_locks(dav_lockdb *lockdb,
       svn_fs_root_t *txn_root;
       const char *conflict_msg;
       apr_hash_t *revprop_table = apr_hash_make(resource->pool);
-      svn_hash_sets(revprop_table,
-                    SVN_PROP_REVISION_AUTHOR,
-                    svn_string_create(repos->username, resource->pool));
+      svn_hash_sets_fixed_key(revprop_table,
+                              SVN_PROP_REVISION_AUTHOR,
+                              svn_string_create(repos->username,
+                                                resource->pool));
 
       if (resource->info->repos->is_svn_client)
         return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED,

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/mod_dav_svn.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/mod_dav_svn.c Thu May 16 22:03:58 2013
@@ -137,7 +137,7 @@ init(apr_pool_t *p, apr_pool_t *plog, ap
 
   /* This returns void, so we can't check for error. */
   conf = ap_get_module_config(s->module_config, &dav_svn_module);
-  svn_utf_initialize2(p, conf->use_utf8);
+  svn_utf_initialize2(conf->use_utf8, p);
 
   return OK;
 }

Modified: subversion/branches/fsfs-format7/subversion/svndumpfilter/svndumpfilter.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/svndumpfilter/svndumpfilter.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/svndumpfilter/svndumpfilter.c (original)
+++ subversion/branches/fsfs-format7/subversion/svndumpfilter/svndumpfilter.c Thu May 16 22:03:58 2013
@@ -399,11 +399,12 @@ output_revision(struct revision_baton_t 
       apr_hash_t *old_props = rb->props;
       rb->has_props = TRUE;
       rb->props = apr_hash_make(hash_pool);
-      svn_hash_sets(rb->props, SVN_PROP_REVISION_DATE,
-                    svn_hash_gets(old_props, SVN_PROP_REVISION_DATE));
-      svn_hash_sets(rb->props, SVN_PROP_REVISION_LOG,
-                    svn_string_create(_("This is an empty revision for "
-                                        "padding."), hash_pool));
+      svn_hash_sets_fixed_key(rb->props, SVN_PROP_REVISION_DATE,
+                              svn_hash_gets_fixed_key(old_props,
+                                                      SVN_PROP_REVISION_DATE));
+      svn_hash_sets_fixed_key(rb->props, SVN_PROP_REVISION_LOG,
+                              svn_string_create(_("This is an empty revision "
+                                                  "for padding."), hash_pool));
     }
 
   /* Now, "rasterize" the props to a string, and append the property

Modified: subversion/branches/fsfs-format7/subversion/svnmucc/svnmucc.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/svnmucc/svnmucc.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/svnmucc/svnmucc.c (original)
+++ subversion/branches/fsfs-format7/subversion/svnmucc/svnmucc.c Thu May 16 22:03:58 2013
@@ -751,7 +751,7 @@ execute(const apr_array_header_t *action
                                             "svnmucc: ", "--config-option"));
   cfg_config = svn_hash_gets(config, SVN_CONFIG_CATEGORY_CONFIG);
 
-  if (! svn_hash_gets(revprops, SVN_PROP_REVISION_LOG))
+  if (! svn_hash_gets_fixed_key(revprops, SVN_PROP_REVISION_LOG))
     {
       svn_string_t *msg = svn_string_create("", pool);
 
@@ -770,7 +770,7 @@ execute(const apr_array_header_t *action
                       TRUE, NULL, apr_hash_pool_get(revprops)));
         }
 
-      svn_hash_sets(revprops, SVN_PROP_REVISION_LOG, msg);
+      svn_hash_sets_fixed_key(revprops, SVN_PROP_REVISION_LOG, msg);
     }
 
   SVN_ERR(create_ra_callbacks(&ra_callbacks, username, password, config_dir,
@@ -1028,13 +1028,13 @@ sanitize_log_sources(apr_hash_t *revprop
         return mutually_exclusive_logs_error();
 
       SVN_ERR(svn_utf_cstring_to_utf8(&message, filedata->data, hash_pool));
-      svn_hash_sets(revprops, SVN_PROP_REVISION_LOG,
-                    svn_stringbuf__morph_into_string(filedata));
+      svn_hash_sets_fixed_key(revprops, SVN_PROP_REVISION_LOG,
+                              svn_stringbuf__morph_into_string(filedata));
     }
   else if (message)
     {
-      svn_hash_sets(revprops, SVN_PROP_REVISION_LOG,
-                    svn_string_create(message, hash_pool));
+      svn_hash_sets_fixed_key(revprops, SVN_PROP_REVISION_LOG,
+                              svn_string_create(message, hash_pool));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/fsfs-format7/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/svnrdump/load_editor.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/fsfs-format7/subversion/svnrdump/load_editor.c Thu May 16 22:03:58 2013
@@ -635,8 +635,10 @@ new_node_record(void **node_baton,
          commit_editor. We'll set them separately using the RA API
          after closing the editor (see close_revision). */
 
-      svn_hash_sets(rb->revprop_table, SVN_PROP_REVISION_AUTHOR, NULL);
-      svn_hash_sets(rb->revprop_table, SVN_PROP_REVISION_DATE, NULL);
+      svn_hash_sets_fixed_key(rb->revprop_table,
+                              SVN_PROP_REVISION_AUTHOR, NULL);
+      svn_hash_sets_fixed_key(rb->revprop_table,
+                              SVN_PROP_REVISION_DATE, NULL);
 
       SVN_ERR(svn_ra__register_editor_shim_callbacks(rb->pb->session,
                                     get_shim_callbacks(rb, rb->pool)));

Modified: subversion/branches/fsfs-format7/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/svnserve/serve.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/svnserve/serve.c (original)
+++ subversion/branches/fsfs-format7/subversion/svnserve/serve.c Thu May 16 22:03:58 2013
@@ -1446,14 +1446,14 @@ static svn_error_t *commit(svn_ra_svn_co
   else
     {
       revprop_table = apr_hash_make(pool);
-      svn_hash_sets(revprop_table, SVN_PROP_REVISION_LOG,
-                    svn_string_create(log_msg, pool));
+      svn_hash_sets_fixed_key(revprop_table, SVN_PROP_REVISION_LOG,
+                              svn_string_create(log_msg, pool));
     }
 
   /* Get author from the baton, making sure clients can't circumvent
      the authentication via the revision props. */
-  svn_hash_sets(revprop_table, SVN_PROP_REVISION_AUTHOR,
-                b->user ? svn_string_create(b->user, pool) : NULL);
+  svn_hash_sets_fixed_key(revprop_table, SVN_PROP_REVISION_AUTHOR,
+                          b->user ? svn_string_create(b->user, pool) : NULL);
 
   ccb.pool = pool;
   ccb.new_rev = &new_rev;

Modified: subversion/branches/fsfs-format7/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/svnserve/svnserve.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/svnserve/svnserve.c (original)
+++ subversion/branches/fsfs-format7/subversion/svnserve/svnserve.c Thu May 16 22:03:58 2013
@@ -1043,7 +1043,9 @@ int main(int argc, const char *argv[])
                                          connection_pool) == APR_CHILD_DONE)
             ;
         }
-      if (APR_STATUS_IS_EINTR(status))
+      if (APR_STATUS_IS_EINTR(status)
+          || APR_STATUS_IS_ECONNABORTED(status)
+          || APR_STATUS_IS_ECONNRESET(status))
         {
           svn_pool_destroy(connection_pool);
           continue;

Modified: subversion/branches/fsfs-format7/subversion/svnsync/svnsync.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/svnsync/svnsync.c?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/svnsync/svnsync.c (original)
+++ subversion/branches/fsfs-format7/subversion/svnsync/svnsync.c Thu May 16 22:03:58 2013
@@ -1235,9 +1235,9 @@ replay_rev_started(svn_revnum_t revision
      have to set it to at least the empty string. If there's a svn:log
      property on this revision, we will write the actual value in the
      replay_rev_finished callback. */
-  if (! svn_hash_gets(filtered, SVN_PROP_REVISION_LOG))
-    svn_hash_sets(filtered, SVN_PROP_REVISION_LOG,
-                  svn_string_create_empty(pool));
+  if (! svn_hash_gets_fixed_key(filtered, SVN_PROP_REVISION_LOG))
+    svn_hash_sets_fixed_key(filtered, SVN_PROP_REVISION_LOG,
+                            svn_string_create_empty(pool));
 
   /* If necessary, normalize encoding and line ending style. Add the number
      of properties that required EOL normalization to the overall count

Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/diff_tests.py?rev=1483586&r1=1483585&r2=1483586&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/diff_tests.py Thu May 16 22:03:58 2013
@@ -32,7 +32,7 @@ logger = logging.getLogger()
 
 # Our testing module
 import svntest
-from svntest import err
+from svntest import err, wc
 
 from prop_tests import binary_mime_type_on_text_file_warning
 
@@ -4506,6 +4506,80 @@ def diff_dir_replaced_by_dir(sbox):
   svntest.actions.run_and_verify_svn(None, expected_output, [],
                                      'diff', '--summarize', wc_dir)
 
+
+@Issue(4366)
+def diff_repos_empty_file_addition(sbox):
+  "repos diff of rev which adds empty file"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Add and commit an empty file.
+  svntest.main.file_append(sbox.ospath('newfile'), "")
+  svntest.main.run_svn(None, 'add', sbox.ospath('newfile'))
+  expected_output = svntest.wc.State(sbox.wc_dir, {
+    'newfile': Item(verb='Adding'),
+    })
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+  expected_status.add({
+    'newfile' : Item(status='  ', wc_rev=2),
+    })
+  svntest.actions.run_and_verify_commit(sbox.wc_dir, expected_output,
+                                        expected_status, None, sbox.wc_dir)
+
+  # Now diff the revision that added the empty file.
+  expected_output = [
+    'Index: newfile\n',
+    '===================================================================\n',
+    ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'diff', '-c', '2', sbox.repo_url)
+
+def diff_missing_tree_conflict_victim(sbox):
+  "diff with missing tree-conflict victim in wc"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Produce an 'incoming edit vs. local missing' tree conflict:
+  # r2: edit iota and commit the change
+  svntest.main.file_append(sbox.ospath('iota'), "This is a change to iota.\n")
+  sbox.simple_propset('k', 'v', 'A/C')
+  sbox.simple_commit()
+  # now remove iota
+  sbox.simple_rm('iota', 'A/C')
+  sbox.simple_commit()
+  # update to avoid mixed-rev wc warning
+  sbox.simple_update()
+  # merge r2 into wc and verify that a tree conflict is flagged on iota
+  expected_output = wc.State(wc_dir, {
+      'iota' : Item(status='  ', treeconflict='C'),
+      'A/C' : Item(status='  ', treeconflict='C')
+  })
+  expected_mergeinfo_output = wc.State(wc_dir, {})
+  expected_elision_output = wc.State(wc_dir, {})
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('iota','A/C')
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+  expected_status.tweak('iota', 'A/C',
+                        status='! ', treeconflict='C', wc_rev=None)
+  expected_skip = wc.State('', { })
+  svntest.actions.run_and_verify_merge(wc_dir, '1', '2',
+                                       sbox.repo_url, None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, None, None, None, None, None,
+                                       False, '--ignore-ancestry', wc_dir)
+
+  # 'svn diff' should show no change for the working copy
+  # This currently fails because svn errors out with a 'node not found' error
+  expected_output = [ ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff', wc_dir)
+
 ########################################################################
 #Run the tests
 
@@ -4584,6 +4658,8 @@ test_list = [ None,
               local_tree_replace,
               diff_dir_replaced_by_file,
               diff_dir_replaced_by_dir,
+              diff_repos_empty_file_addition,
+              diff_missing_tree_conflict_victim,
               ]
 
 if __name__ == '__main__':