subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From julianf...@apache.org
Subject svn commit: r1489602 [2/3] - in /subversion/branches/move-tracking-1: ./ build/generator/ contrib/hook-scripts/ notes/ subversion/bindings/swig/perl/libsvn_swig_perl/ subversion/bindings/swig/perl/native/ subversion/bindings/swig/ruby/test/ subversion/...
Date Tue, 04 Jun 2013 20:56:33 GMT
Modified: subversion/branches/move-tracking-1/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_ra_svn/client.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_ra_svn/client.c Tue Jun  4 20:56:23 2013
@@ -50,6 +50,7 @@
 #include "svn_private_config.h"
 
 #include "private/svn_fspath.h"
+#include "private/svn_subr_private.h"
 
 #include "../libsvn_ra/ra_loader.h"
 
@@ -1095,7 +1096,7 @@ parse_iproplist(apr_array_header_t **inh
       new_iprop->path_or_url = svn_path_url_add_component2(repos_root_url,
                                                            parent_rel_path,
                                                            result_pool);
-      new_iprop->prop_hash = apr_hash_make(result_pool);
+      new_iprop->prop_hash = svn_hash__make(result_pool);
       for (hi = apr_hash_first(iterpool, iprops);
            hi;
            hi = apr_hash_next(hi))
@@ -1234,7 +1235,7 @@ static svn_error_t *ra_svn_get_dir(svn_r
     return SVN_NO_ERROR;
 
   /* Interpret the directory list. */
-  *dirents = apr_hash_make(pool);
+  *dirents = svn_hash__make(pool);
   for (i = 0; i < dirlist->nelts; i++)
     {
       const char *name, *kind, *cdate, *cauthor;
@@ -1322,7 +1323,7 @@ static svn_error_t *ra_svn_get_mergeinfo
   *catalog = NULL;
   if (mergeinfo_tuple->nelts > 0)
     {
-      *catalog = apr_hash_make(pool);
+      *catalog = svn_hash__make(pool);
       for (i = 0; i < mergeinfo_tuple->nelts; i++)
         {
           svn_mergeinfo_t for_path;
@@ -1475,6 +1476,9 @@ static svn_error_t *ra_svn_log(svn_ra_se
   const char *path;
   char *name;
   svn_boolean_t want_custom_revprops;
+  svn_boolean_t want_author = FALSE;
+  svn_boolean_t want_message = FALSE;
+  svn_boolean_t want_date = FALSE;
 
   SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w((!", "log"));
   if (paths)
@@ -1497,10 +1501,14 @@ static svn_error_t *ra_svn_log(svn_ra_se
         {
           name = APR_ARRAY_IDX(revprops, i, char *);
           SVN_ERR(svn_ra_svn__write_cstring(conn, pool, name));
-          if (!want_custom_revprops
-              && strcmp(name, SVN_PROP_REVISION_AUTHOR) != 0
-              && strcmp(name, SVN_PROP_REVISION_DATE) != 0
-              && strcmp(name, SVN_PROP_REVISION_LOG) != 0)
+
+          if (strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
+            want_author = TRUE;
+          else if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
+            want_date = TRUE;
+          else if (strcmp(name, SVN_PROP_REVISION_LOG) == 0)
+            want_message = TRUE;
+          else
             want_custom_revprops = TRUE;
         }
       SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!))"));
@@ -1508,6 +1516,10 @@ static svn_error_t *ra_svn_log(svn_ra_se
   else
     {
       SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!w())", "all-revprops"));
+
+      want_author = TRUE;
+      want_date = TRUE;
+      want_message = TRUE;
       want_custom_revprops = TRUE;
     }
 
@@ -1571,11 +1583,12 @@ static svn_error_t *ra_svn_log(svn_ra_se
       if (cplist->nelts > 0)
         {
           /* Interpret the changed-paths list. */
-          cphash = apr_hash_make(iterpool);
+          cphash = svn_hash__make(iterpool);
           for (i = 0; i < cplist->nelts; i++)
             {
               svn_log_changed_path2_t *change;
-              const char *copy_path, *action, *cpath, *kind_str;
+              svn_string_t *cpath;
+              const char *copy_path, *action, *kind_str;
               apr_uint64_t text_mods, prop_mods;
               svn_revnum_t copy_rev;
               svn_ra_svn_item_t *elt = &APR_ARRAY_IDX(cplist, i,
@@ -1585,13 +1598,19 @@ static svn_error_t *ra_svn_log(svn_ra_se
                 return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                         _("Changed-path entry not a list"));
               SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, iterpool,
-                                              "cw(?cr)?(?c?BB)",
+                                              "sw(?cr)?(?c?BB)",
                                               &cpath, &action, &copy_path,
                                               &copy_rev, &kind_str,
                                               &text_mods, &prop_mods));
-              cpath = svn_fspath__canonicalize(cpath, iterpool);
-              if (copy_path)
+
+              if (!svn_fspath__is_canonical(cpath->data))
+                {
+                  cpath->data = svn_fspath__canonicalize(cpath->data, iterpool);
+                  cpath->len = strlen(cpath->data);
+                }
+              if (copy_path && !svn_fspath__is_canonical(copy_path))
                 copy_path = svn_fspath__canonicalize(copy_path, iterpool);
+
               change = svn_log_changed_path2_create(iterpool);
               change->action = *action;
               change->copyfrom_path = copy_path;
@@ -1599,7 +1618,7 @@ static svn_error_t *ra_svn_log(svn_ra_se
               change->node_kind = svn_node_kind_from_word(kind_str);
               change->text_modified = optbool_to_tristate(text_mods);
               change->props_modified = optbool_to_tristate(prop_mods);
-              svn_hash_sets(cphash, cpath, change);
+              apr_hash_set(cphash, cpath->data, cpath->len, change);
             }
         }
       else
@@ -1619,37 +1638,18 @@ static svn_error_t *ra_svn_log(svn_ra_se
             SVN_ERR(svn_ra_svn__parse_proplist(rplist, iterpool,
                                                &log_entry->revprops));
           if (log_entry->revprops == NULL)
-            log_entry->revprops = apr_hash_make(iterpool);
-          if (revprops == NULL)
-            {
-              /* Caller requested all revprops; set author/date/log. */
-              if (author)
-                svn_hash_sets(log_entry->revprops,
-                              SVN_PROP_REVISION_AUTHOR, author);
-              if (date)
-                svn_hash_sets(log_entry->revprops,
-                              SVN_PROP_REVISION_DATE, date);
-              if (message)
-                svn_hash_sets(log_entry->revprops,
-                              SVN_PROP_REVISION_LOG, message);
-            }
-          else
-            {
-              /* Caller requested some; maybe set author/date/log. */
-              for (i = 0; i < revprops->nelts; i++)
-                {
-                  name = APR_ARRAY_IDX(revprops, i, char *);
-                  if (author && strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
-                    svn_hash_sets(log_entry->revprops,
-                                  SVN_PROP_REVISION_AUTHOR, author);
-                  if (date && strcmp(name, SVN_PROP_REVISION_DATE) == 0)
-                    svn_hash_sets(log_entry->revprops,
-                                  SVN_PROP_REVISION_DATE, date);
-                  if (message && strcmp(name, SVN_PROP_REVISION_LOG) == 0)
-                    svn_hash_sets(log_entry->revprops,
-                                  SVN_PROP_REVISION_LOG, message);
-                }
-            }
+            log_entry->revprops = svn_hash__make(iterpool);
+
+          if (author && want_author)
+            svn_hash_sets(log_entry->revprops,
+                          SVN_PROP_REVISION_AUTHOR, author);
+          if (date && want_date)
+            svn_hash_sets(log_entry->revprops,
+                          SVN_PROP_REVISION_DATE, date);
+          if (message && want_message)
+            svn_hash_sets(log_entry->revprops,
+                          SVN_PROP_REVISION_LOG, message);
+
           SVN_ERR(receiver(receiver_baton, log_entry, iterpool));
           if (log_entry->has_children)
             {

Modified: subversion/branches/move-tracking-1/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_ra_svn/marshal.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_ra_svn/marshal.c Tue Jun  4 20:56:23 2013
@@ -47,6 +47,7 @@
 #include "private/svn_string_private.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_error_private.h"
+#include "private/svn_subr_private.h"
 
 #define svn_iswhitespace(c) ((c) == ' ' || (c) == '\n')
 
@@ -56,6 +57,19 @@
 
 #define SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD (0x100000)
 
+/* We don't use "words" longer than this in our protocol.  The longest word
+ * we are currently using is only about 16 chars long but we leave room for
+ * longer future capability and command names.
+ */
+#define MAX_WORD_LENGTH 31
+
+/* The generic parsers will use the following value to limit the recursion
+ * depth to some reasonable value.  The current protocol implementation
+ * actually uses only maximum item nesting level of around 5.  So, there is
+ * plenty of headroom here.
+ */
+#define ITEM_NESTING_LIMIT 64
+
 /* Return the APR socket timeout to be used for the connection depending
  * on whether there is a blockage handler or zero copy has been activated. */
 static apr_interval_time_t
@@ -511,21 +525,32 @@ svn_ra_svn__write_number(svn_ra_svn_conn
   return write_number(conn, pool, number, ' ');
 }
 
-svn_error_t *
-svn_ra_svn__write_string(svn_ra_svn_conn_t *conn,
-                         apr_pool_t *pool,
-                         const svn_string_t *str)
+static svn_error_t *
+svn_ra_svn__write_ncstring(svn_ra_svn_conn_t *conn,
+                           apr_pool_t *pool,
+                           const char *s,
+                           apr_size_t len)
 {
-  if (str->len < 10)
+  if (len < 10)
     {
-      SVN_ERR(writebuf_writechar(conn, pool, (char)(str->len + '0')));
+      SVN_ERR(writebuf_writechar(conn, pool, (char)(len + '0')));
       SVN_ERR(writebuf_writechar(conn, pool, ':'));
     }
   else
-    SVN_ERR(write_number(conn, pool, str->len, ':'));
+    SVN_ERR(write_number(conn, pool, len, ':'));
 
-  SVN_ERR(writebuf_write(conn, pool, str->data, str->len));
+  SVN_ERR(writebuf_write(conn, pool, s, len));
   SVN_ERR(writebuf_writechar(conn, pool, ' '));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_string(svn_ra_svn_conn_t *conn,
+                         apr_pool_t *pool,
+                         const svn_string_t *str)
+{
+  svn_ra_svn__write_ncstring(conn, pool, str->data, str->len);
   return SVN_NO_ERROR;
 }
 
@@ -534,19 +559,7 @@ svn_ra_svn__write_cstring(svn_ra_svn_con
                           apr_pool_t *pool,
                           const char *s)
 {
-  apr_size_t len = strlen(s);
-
-  if (len < 10)
-    {
-      SVN_ERR(writebuf_writechar(conn, pool, (char)(len + '0')));
-      SVN_ERR(writebuf_writechar(conn, pool, ':'));
-    }
-  else
-    SVN_ERR(write_number(conn, pool, len, ':'));
-
-  SVN_ERR(writebuf_write(conn, pool, s, len));
-  SVN_ERR(writebuf_writechar(conn, pool, ' '));
-
+  svn_ra_svn__write_ncstring(conn, pool, s, strlen(s));
   return SVN_NO_ERROR;
 }
 
@@ -562,31 +575,45 @@ svn_ra_svn__write_word(svn_ra_svn_conn_t
 }
 
 svn_error_t *
+svn_ra_svn__write_boolean(svn_ra_svn_conn_t *conn,
+                          apr_pool_t *pool,
+                          svn_boolean_t value)
+{
+  if (value)
+    SVN_ERR(writebuf_write_short_string(conn, pool, "true ", 5));
+  else
+    SVN_ERR(writebuf_write_short_string(conn, pool, "false ", 6));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_ra_svn__write_proplist(svn_ra_svn_conn_t *conn,
                            apr_pool_t *pool,
                            apr_hash_t *props)
 {
-  apr_pool_t *iterpool;
   apr_hash_index_t *hi;
-  const void *key;
-  void *val;
   const char *propname;
   svn_string_t *propval;
+  apr_size_t len;
 
+  /* One might use an iterpool here but that would only be used when the
+     send buffer gets flushed and only by the CONN's progress callback.
+     That should happen at most once for typical prop lists and even then
+     use only a few bytes at best.
+   */
   if (props)
-    {
-      iterpool = svn_pool_create(pool);
-      for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
-        {
-          svn_pool_clear(iterpool);
-          apr_hash_this(hi, &key, NULL, &val);
-          propname = key;
-          propval = val;
-          SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "cs",
-                                          propname, propval));
-        }
-      svn_pool_destroy(iterpool);
-    }
+    for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
+      {
+        apr_hash_this(hi, (const void **)&propname, 
+                          (apr_ssize_t *)&len,
+                          (void **)&propval);
+
+        SVN_ERR(svn_ra_svn__start_list(conn, pool));
+        SVN_ERR(svn_ra_svn__write_ncstring(conn, pool, propname, len));
+        SVN_ERR(svn_ra_svn__write_string(conn, pool, propval));
+        SVN_ERR(svn_ra_svn__end_list(conn, pool));
+      }
 
   return SVN_NO_ERROR;
 }
@@ -704,8 +731,7 @@ vwrite_tuple_number(svn_ra_svn_conn_t *c
 static svn_error_t *
 vwrite_tuple_boolean(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
 {
-  const char *cstr = va_arg(*ap, svn_boolean_t) ? "true" : "false";
-  return svn_ra_svn__write_word(conn, pool, cstr);
+  return svn_ra_svn__write_boolean(conn, pool, va_arg(*ap, svn_boolean_t));
 }
 
 static svn_error_t *
@@ -780,8 +806,7 @@ write_tuple_boolean(svn_ra_svn_conn_t *c
                     apr_pool_t *pool,
                     svn_boolean_t value)
 {
-  const char *cstr = value ? "true" : "false";
-  return svn_ra_svn__write_word(conn, pool, cstr);
+  return svn_ra_svn__write_boolean(conn, pool, value);
 }
 
 static svn_error_t *
@@ -929,7 +954,6 @@ svn_ra_svn__write_tuple(svn_ra_svn_conn_
 static svn_error_t *read_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                 svn_ra_svn_item_t *item, apr_uint64_t len64)
 {
-  svn_stringbuf_t *stringbuf;
   apr_size_t len = (apr_size_t)len64;
   apr_size_t readbuf_len;
   char *dest;
@@ -940,51 +964,53 @@ static svn_error_t *read_string(svn_ra_s
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                             _("String length larger than maximum"));
 
-  /* Read the string in chunks.  The chunk size is large enough to avoid
-   * re-allocation in typical cases, and small enough to ensure we do not
-   * pre-allocate an unreasonable amount of memory if (perhaps due to
-   * network data corruption or a DOS attack), we receive a bogus claim that
-   * a very long string is going to follow.  In that case, we start small
-   * and wait for all that data to actually show up.  This does not fully
-   * prevent DOS attacks but makes them harder (you have to actually send
-   * gigabytes of data). */
-  readbuf_len = len < SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD
-                    ? len
-                    : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
-  stringbuf = svn_stringbuf_create_ensure(readbuf_len, pool);
-  dest = stringbuf->data;
-
-  /* Read remaining string data directly into the string structure.
-   * Do it iteratively, if necessary.  */
-  while (readbuf_len)
-    {
-      SVN_ERR(readbuf_read(conn, pool, dest, readbuf_len));
-
-      stringbuf->len += readbuf_len;
-      len -= readbuf_len;
-
-      /* Early exit. In most cases, strings can be read in the first
-       * iteration. */
-      if (len == 0)
-        break;
-
-      /* Prepare next iteration: determine length of chunk to read
-       * and re-alloc the string buffer. */
-      readbuf_len
-        = len < SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD
-              ? len
-              : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
-
-      svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len);
-      dest = stringbuf->data + stringbuf->len;
-    }
-
-  /* zero-terminate the string */
-  stringbuf->data[stringbuf->len] = '\0';
-
-  /* Return the string properly wrapped into an RA_SVN item. */
-  item->kind = SVN_RA_SVN_STRING;
-  item->u.string = svn_stringbuf__morph_into_string(stringbuf);
+  /* Shorter strings can be copied directly from the read buffer. */
+  if (conn->read_ptr + len <= conn->read_end)
+    {
+      item->kind = SVN_RA_SVN_STRING;
+      item->u.string = svn_string_ncreate(conn->read_ptr, len, pool);
+      conn->read_ptr += len;
+    }
+  else
+    {
+      /* Read the string in chunks.  The chunk size is large enough to avoid
+       * re-allocation in typical cases, and small enough to ensure we do
+       * not pre-allocate an unreasonable amount of memory if (perhaps due
+       * to network data corruption or a DOS attack), we receive a bogus
+       * claim that a very long string is going to follow.  In that case, we
+       * start small and wait for all that data to actually show up.  This
+       * does not fully prevent DOS attacks but makes them harder (you have
+       * to actually send gigabytes of data). */
+      svn_stringbuf_t *stringbuf = svn_stringbuf_create_empty(pool);
+
+      /* Read string data directly into the string structure.
+       * Do it iteratively.  */
+      do      
+        {
+          /* Determine length of chunk to read and re-alloc the buffer. */
+          readbuf_len
+            = len < SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD
+                  ? len
+                  : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
+
+          svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len);
+          dest = stringbuf->data + stringbuf->len;
+
+          /* read data & update length info */
+          SVN_ERR(readbuf_read(conn, pool, dest, readbuf_len));
+
+          stringbuf->len += readbuf_len;
+          len -= readbuf_len;
+        }
+      while (len);
+      
+      /* zero-terminate the string */
+      stringbuf->data[stringbuf->len] = '\0';
+
+      /* Return the string properly wrapped into an RA_SVN item. */
+      item->kind = SVN_RA_SVN_STRING;
+      item->u.string = svn_stringbuf__morph_into_string(stringbuf);
+    }
 
   return SVN_NO_ERROR;
 }
@@ -1002,9 +1028,9 @@ static svn_error_t *read_item(svn_ra_svn
   svn_stringbuf_t *str;
   svn_ra_svn_item_t *listitem;
 
-  if (++level >= 64)
+  if (++level >= ITEM_NESTING_LIMIT)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
-                            _("Too many nested items"));
+                            _("Items are nested too deeply"));
 
 
   /* Determine the item type and read it in.  Make sure that c is the
@@ -1022,7 +1048,8 @@ static svn_error_t *read_item(svn_ra_svn
             break;
           val = val * 10 + (c - '0');
           /* val wrapped past maximum value? */
-          if (prev_val >= (APR_UINT64_MAX / 10) && (val / 10) != prev_val)
+          if ((prev_val >= (APR_UINT64_MAX / 10))
+              && (val < APR_UINT64_MAX - 10))
             return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                     _("Number is larger than maximum"));
         }
@@ -1041,31 +1068,72 @@ static svn_error_t *read_item(svn_ra_svn
     }
   else if (svn_ctype_isalpha(c))
     {
-      /* It's a word. */
-      str = svn_stringbuf_create_ensure(16, pool);
-      svn_stringbuf_appendbyte(str, c);
+      /* It's a word.  Read it into a buffer of limited size. */
+      char *buffer = apr_palloc(pool, MAX_WORD_LENGTH + 1);
+      char *end = buffer + MAX_WORD_LENGTH;
+      char *p = buffer + 1;
+
+      buffer[0] = c;
       while (1)
         {
-          SVN_ERR(readbuf_getchar(conn, pool, &c));
-          if (!svn_ctype_isalnum(c) && c != '-')
+          SVN_ERR(readbuf_getchar(conn, pool, p));
+          if (!svn_ctype_isalnum(*p) && *p != '-')
             break;
-          svn_stringbuf_appendbyte(str, c);
+
+          if (++p == end)
+            return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+                                    _("Word is too long"));
         }
+
+      c = *p;
+      *p = '\0';
+
       item->kind = SVN_RA_SVN_WORD;
-      item->u.word = str->data;
+      item->u.word = buffer;
     }
   else if (c == '(')
     {
-      /* Read in the list items. */
+      /* Allocate an APR array with room for (initially) 4 items.
+       * We do this manually because lists are the most frequent protocol
+       * element, often used to frame a single, optional value.  We save
+       * about 20% of total protocol handling time. */
+      char *buffer = apr_palloc(pool, sizeof(apr_array_header_t)
+                                      + 4 * sizeof(svn_ra_svn_item_t));
+      svn_ra_svn_item_t *data
+        = (svn_ra_svn_item_t *)(buffer + sizeof(apr_array_header_t));
+
       item->kind = SVN_RA_SVN_LIST;
-      item->u.list = apr_array_make(pool, 4, sizeof(svn_ra_svn_item_t));
+      item->u.list = (apr_array_header_t *)buffer;
+      item->u.list->elts = (char *)data;
+      item->u.list->pool = pool;
+      item->u.list->elt_size = sizeof(*data);
+      item->u.list->nelts = 0; 
+      item->u.list->nalloc = 4;
+
+      listitem = data;
+
+      /* Read in the list items. */
       while (1)
         {
           SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));
           if (c == ')')
             break;
-          listitem = apr_array_push(item->u.list);
+
+          /* increase array capacity if necessary */
+          if (item->u.list->nelts == item->u.list->nalloc)
+            {
+              data = apr_palloc(pool, 2 * item->u.list->nelts * sizeof(*data));
+              memcpy(data, item->u.list->elts, item->u.list->nelts * sizeof(*data));
+              item->u.list->elts = (char *)data;
+              item->u.list->nalloc *= 2;
+              listitem = data + item->u.list->nelts;
+            }
+
+          /* read next protocol item */
           SVN_ERR(read_item(conn, pool, listitem, c, level));
+
+          listitem++; 
+          item->u.list->nelts++;
         }
       SVN_ERR(readbuf_getchar(conn, pool, &c));
     }
@@ -1202,14 +1270,15 @@ static svn_error_t *vparse_tuple(const a
       if (**fmt == '?')
         (*fmt)++;
       elt = &APR_ARRAY_IDX(items, count, svn_ra_svn_item_t);
-      if (**fmt == 'n' && elt->kind == SVN_RA_SVN_NUMBER)
-        *va_arg(*ap, apr_uint64_t *) = elt->u.number;
-      else if (**fmt == 'r' && elt->kind == SVN_RA_SVN_NUMBER)
-        *va_arg(*ap, svn_revnum_t *) = (svn_revnum_t) elt->u.number;
-      else if (**fmt == 's' && elt->kind == SVN_RA_SVN_STRING)
-        *va_arg(*ap, svn_string_t **) = elt->u.string;
+      if (**fmt == '(' && elt->kind == SVN_RA_SVN_LIST)
+        {
+          (*fmt)++;
+          SVN_ERR(vparse_tuple(elt->u.list, pool, fmt, ap));
+        }
       else if (**fmt == 'c' && elt->kind == SVN_RA_SVN_STRING)
         *va_arg(*ap, const char **) = elt->u.string->data;
+      else if (**fmt == 's' && elt->kind == SVN_RA_SVN_STRING)
+        *va_arg(*ap, svn_string_t **) = elt->u.string;
       else if (**fmt == 'w' && elt->kind == SVN_RA_SVN_WORD)
         *va_arg(*ap, const char **) = elt->u.word;
       else if (**fmt == 'b' && elt->kind == SVN_RA_SVN_WORD)
@@ -1221,6 +1290,10 @@ static svn_error_t *vparse_tuple(const a
           else
             break;
         }
+      else if (**fmt == 'n' && elt->kind == SVN_RA_SVN_NUMBER)
+        *va_arg(*ap, apr_uint64_t *) = elt->u.number;
+      else if (**fmt == 'r' && elt->kind == SVN_RA_SVN_NUMBER)
+        *va_arg(*ap, svn_revnum_t *) = (svn_revnum_t) elt->u.number;
       else if (**fmt == 'B' && elt->kind == SVN_RA_SVN_WORD)
         {
           if (strcmp(elt->u.word, "true") == 0)
@@ -1241,11 +1314,6 @@ static svn_error_t *vparse_tuple(const a
         }
       else if (**fmt == 'l' && elt->kind == SVN_RA_SVN_LIST)
         *va_arg(*ap, apr_array_header_t **) = elt->u.list;
-      else if (**fmt == '(' && elt->kind == SVN_RA_SVN_LIST)
-        {
-          (*fmt)++;
-          SVN_ERR(vparse_tuple(elt->u.list, pool, fmt, ap));
-        }
       else if (**fmt == ')')
         return SVN_NO_ERROR;
       else
@@ -1354,7 +1422,7 @@ svn_ra_svn__parse_proplist(const apr_arr
   svn_ra_svn_item_t *elt;
   int i;
 
-  *props = apr_hash_make(pool);
+  *props = svn_hash__make(pool);
   for (i = 0; i < list->nelts; i++)
     {
       elt = &APR_ARRAY_IDX(list, i, svn_ra_svn_item_t);
@@ -2299,3 +2367,59 @@ svn_error_t *svn_ra_svn__write_cmd_failu
     }
   return writebuf_write_short_string(conn, pool, ") ) ", 4);
 }
+
+svn_error_t *
+svn_ra_svn__write_data_log_changed_path(svn_ra_svn_conn_t *conn,
+                                        apr_pool_t *pool,
+                                        const char *path,
+                                        char action,
+                                        const char *copyfrom_path,
+                                        svn_revnum_t copyfrom_rev,
+                                        svn_node_kind_t node_kind,
+                                        svn_boolean_t text_modified,
+                                        svn_boolean_t props_modified)
+{
+  SVN_ERR(write_tuple_start_list(conn, pool));
+
+  SVN_ERR(write_tuple_cstring(conn, pool, path));
+  SVN_ERR(writebuf_writechar(conn, pool, action));
+  SVN_ERR(writebuf_writechar(conn, pool, ' '));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_cstring_opt(conn, pool, copyfrom_path));
+  SVN_ERR(write_tuple_revision_opt(conn, pool, copyfrom_rev));
+  SVN_ERR(write_tuple_end_list(conn, pool));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_cstring(conn, pool, svn_node_kind_to_word(node_kind)));
+  SVN_ERR(write_tuple_boolean(conn, pool, text_modified));
+  SVN_ERR(write_tuple_boolean(conn, pool, props_modified));
+
+  return writebuf_write_short_string(conn, pool, ") ) ", 4);
+}
+
+svn_error_t *
+svn_ra_svn__write_data_log_entry(svn_ra_svn_conn_t *conn,
+                                 apr_pool_t *pool,
+                                 svn_revnum_t revision,
+                                 const svn_string_t *author,
+                                 const svn_string_t *date,
+                                 const svn_string_t *message,
+                                 svn_boolean_t has_children,
+                                 svn_boolean_t invalid_revnum,
+                                 int revprop_count)
+{
+  SVN_ERR(write_tuple_revision(conn, pool, revision));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_string_opt(conn, pool, author));
+  SVN_ERR(write_tuple_end_list(conn, pool));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_string_opt(conn, pool, date));
+  SVN_ERR(write_tuple_end_list(conn, pool));
+  SVN_ERR(write_tuple_start_list(conn, pool));
+  SVN_ERR(write_tuple_string_opt(conn, pool, message));
+  SVN_ERR(write_tuple_end_list(conn, pool));
+  SVN_ERR(write_tuple_boolean(conn, pool, has_children));
+  SVN_ERR(write_tuple_boolean(conn, pool, invalid_revnum));
+  SVN_ERR(svn_ra_svn__write_number(conn, pool, revprop_count));
+  
+  return SVN_NO_ERROR;
+}

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

Modified: subversion/branches/move-tracking-1/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_repos/reporter.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_repos/reporter.c Tue Jun  4 20:56:23 2013
@@ -1140,12 +1140,9 @@ delta_dirs(report_baton_t *b, svn_revnum
            svn_boolean_t start_empty, svn_depth_t wc_depth,
            svn_depth_t requested_depth, apr_pool_t *pool)
 {
-  svn_fs_root_t *s_root;
   apr_hash_t *s_entries = NULL, *t_entries;
   apr_hash_index_t *hi;
   apr_pool_t *subpool;
-  const char *name, *s_fullpath, *t_fullpath, *e_fullpath;
-  path_info_t *info;
 
   /* Compare the property lists.  If we're starting empty, pass a NULL
      source path so that we add all the properties.
@@ -1160,6 +1157,8 @@ delta_dirs(report_baton_t *b, svn_revnum
       /* Get the list of entries in each of source and target. */
       if (s_path && !start_empty)
         {
+          svn_fs_root_t *s_root;
+
           SVN_ERR(get_source_root(b, &s_root, s_rev));
           SVN_ERR(svn_fs_dir_entries(&s_entries, s_root, s_path, pool));
         }
@@ -1170,6 +1169,8 @@ delta_dirs(report_baton_t *b, svn_revnum
 
       while (1)
         {
+          path_info_t *info;
+          const char *name, *s_fullpath, *t_fullpath, *e_fullpath;
           const svn_fs_dirent_t *s_entry, *t_entry;
 
           svn_pool_clear(subpool);
@@ -1197,10 +1198,9 @@ delta_dirs(report_baton_t *b, svn_revnum
           t_fullpath = svn_fspath__join(t_path, name, subpool);
           t_entry = svn_hash_gets(t_entries, name);
           s_fullpath = s_path ? svn_fspath__join(s_path, name, subpool) : NULL;
-          s_entry = s_entries ?
-            svn_hash_gets(s_entries, name) : NULL;
+          s_entry = s_entries ? svn_hash_gets(s_entries, name) : NULL;
 
-          /* The only special cases here are
+          /* The only special cases where we don't process the entry are
 
              - When requested_depth is files but the reported path is
              a directory.  This is technically a client error, but we
@@ -1208,10 +1208,10 @@ delta_dirs(report_baton_t *b, svn_revnum
 
              - When the reported depth is svn_depth_exclude.
           */
-          if ((! info || info->depth != svn_depth_exclude)
-              && (requested_depth != svn_depth_files
-                  || ((! t_entry || t_entry->kind != svn_node_dir)
-                      && (! s_entry || s_entry->kind != svn_node_dir))))
+          if (! ((requested_depth == svn_depth_files
+                  && ((t_entry && t_entry->kind == svn_node_dir)
+                      || (s_entry && s_entry->kind == svn_node_dir)))
+                 || (info && info->depth == svn_depth_exclude)))
             SVN_ERR(update_entry(b, s_rev, s_fullpath, s_entry, t_fullpath,
                                  t_entry, dir_baton, e_fullpath, info,
                                  info ? info->depth
@@ -1240,13 +1240,13 @@ delta_dirs(report_baton_t *b, svn_revnum
                hi;
                hi = apr_hash_next(hi))
             {
-              const svn_fs_dirent_t *s_entry;
+              const svn_fs_dirent_t *s_entry = svn__apr_hash_index_val(hi);
 
               svn_pool_clear(subpool);
-              s_entry = svn__apr_hash_index_val(hi);
 
               if (svn_hash_gets(t_entries, s_entry->name) == NULL)
                 {
+                  const char *e_fullpath;
                   svn_revnum_t deleted_rev;
 
                   if (s_entry->kind == svn_node_file
@@ -1277,10 +1277,11 @@ delta_dirs(report_baton_t *b, svn_revnum
       /* Loop over the dirents in the target. */
       for (hi = apr_hash_first(pool, t_entries); hi; hi = apr_hash_next(hi))
         {
-          const svn_fs_dirent_t *s_entry, *t_entry;
+          const svn_fs_dirent_t *t_entry = svn__apr_hash_index_val(hi);
+          const svn_fs_dirent_t *s_entry;
+          const char *s_fullpath, *t_fullpath, *e_fullpath;
 
           svn_pool_clear(subpool);
-          t_entry = svn__apr_hash_index_val(hi);
 
           if (is_depth_upgrade(wc_depth, requested_depth, t_entry->kind))
             {
@@ -1301,11 +1302,9 @@ delta_dirs(report_baton_t *b, svn_revnum
                       || requested_depth == svn_depth_files))
                 continue;
 
-              /* Look for an entry with the same name
-                 in the source dirents. */
+              /* Look for an entry with the same name in the source dirents. */
               s_entry = s_entries ?
-                  svn_hash_gets(s_entries, t_entry->name)
-                  : NULL;
+                  svn_hash_gets(s_entries, t_entry->name) : NULL;
               s_fullpath = s_entry ?
                   svn_fspath__join(s_path, t_entry->name, subpool) : NULL;
             }
@@ -1321,8 +1320,6 @@ delta_dirs(report_baton_t *b, svn_revnum
                                subpool));
         }
 
-
-      /* Destroy iteration subpool. */
       svn_pool_destroy(subpool);
     }
   return SVN_NO_ERROR;

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/adler32.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/adler32.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/adler32.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/adler32.c Tue Jun  4 20:56:23 2013
@@ -57,7 +57,7 @@ svn__adler32(apr_uint32_t checksum, cons
    */
   if (len >= 80)
     {
-      /* Larger buffers can be effiently handled by Marc Adler's
+      /* Larger buffers can be efficiently handled by Marc Adler's
        * optimized code. Also, new zlib versions will come with
        * SIMD code for x86 and x64.
        */
@@ -76,16 +76,16 @@ svn__adler32(apr_uint32_t checksum, cons
        * (approx. one clock tick per byte + 2 ticks loop overhead)
        */
       for (; len >= 8; len -= 8, input += 8)
-      {
-        s1 += input[0]; s2 += s1;
-        s1 += input[1]; s2 += s1;
-        s1 += input[2]; s2 += s1;
-        s1 += input[3]; s2 += s1;
-        s1 += input[4]; s2 += s1;
-        s1 += input[5]; s2 += s1;
-        s1 += input[6]; s2 += s1;
-        s1 += input[7]; s2 += s1;
-      }
+        {
+          s1 += input[0]; s2 += s1;
+          s1 += input[1]; s2 += s1;
+          s1 += input[2]; s2 += s1;
+          s1 += input[3]; s2 += s1;
+          s1 += input[4]; s2 += s1;
+          s1 += input[5]; s2 += s1;
+          s1 += input[6]; s2 += s1;
+          s1 += input[7]; s2 += s1;
+        }
 
       /* Adler-32 calculation as a simple two ticks per iteration loop.
        */

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/auth.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/auth.c Tue Jun  4 20:56:23 2013
@@ -251,7 +251,9 @@ svn_auth_first_credentials(void **creden
     }
 
   if (! creds)
-    *state = NULL;
+    {
+      *state = NULL;
+    }
   else
     {
       /* Build an abstract iteration state. */
@@ -305,10 +307,12 @@ svn_auth_next_credentials(void **credent
         }
       else if (provider->vtable->next_credentials)
         {
-          SVN_ERR(provider->vtable->next_credentials(
-                      &creds, state->provider_iter_baton,
-                      provider->provider_baton, auth_baton->parameters,
-                      state->realmstring, auth_baton->pool));
+          SVN_ERR(provider->vtable->next_credentials(&creds,
+                                                     state->provider_iter_baton,
+                                                     provider->provider_baton,
+                                                     auth_baton->parameters,
+                                                     state->realmstring,
+                                                     auth_baton->pool));
         }
 
       if (creds != NULL)
@@ -374,12 +378,11 @@ svn_auth_save_credentials(svn_auth_iters
       provider = APR_ARRAY_IDX(state->table->providers, i,
                                svn_auth_provider_object_t *);
       if (provider->vtable->save_credentials)
-        SVN_ERR(provider->vtable->save_credentials
-                (&save_succeeded, creds,
-                 provider->provider_baton,
-                 auth_baton->parameters,
-                 state->realmstring,
-                 pool));
+        SVN_ERR(provider->vtable->save_credentials(&save_succeeded, creds,
+                                                   provider->provider_baton,
+                                                   auth_baton->parameters,
+                                                   state->realmstring,
+                                                   pool));
 
       if (save_succeeded)
         break;

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/compat.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/compat.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/compat.c Tue Jun  4 20:56:23 2013
@@ -95,23 +95,33 @@ svn_compat_log_revprops_in(apr_pool_t *p
 }
 
 void
-svn_compat_log_revprops_out(const char **author, const char **date,
-                            const char **message, apr_hash_t *revprops)
+svn_compat_log_revprops_out_string(const svn_string_t **author,
+                                   const svn_string_t **date,
+                                   const svn_string_t **message,
+                                   apr_hash_t *revprops)
 {
-  svn_string_t *author_s, *date_s,  *message_s;
-
   *author = *date = *message = NULL;
   if (revprops)
     {
-      if ((author_s = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR)))
-        *author = author_s->data;
-      if ((date_s = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE)))
-        *date = date_s->data;
-      if ((message_s = svn_hash_gets(revprops, SVN_PROP_REVISION_LOG)))
-        *message = message_s->data;
+      *author = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);
+      *date = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE);
+      *message = svn_hash_gets(revprops, SVN_PROP_REVISION_LOG);
     }
 }
 
+void
+svn_compat_log_revprops_out(const char **author, const char **date,
+                            const char **message, apr_hash_t *revprops)
+{
+  const svn_string_t *author_s, *date_s,  *message_s;
+  svn_compat_log_revprops_out_string(&author_s, &date_s,  &message_s,
+                                     revprops);
+
+  *author = author_s ? author_s->data : NULL;
+  *date = date_s ? date_s->data : NULL;
+  *message = message_s ? message_s->data : NULL;
+}
+
 /* Baton for use with svn_compat_wrap_log_receiver */
 struct log_wrapper_baton {
   void *baton;

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/config_file.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/config_file.c Tue Jun  4 20:56:23 2013
@@ -401,10 +401,13 @@ svn_config__parse_file(svn_config_t *cfg
                        svn_boolean_t must_exist, apr_pool_t *result_pool)
 {
   svn_error_t *err = SVN_NO_ERROR;
+  apr_file_t *apr_file;
   svn_stream_t *stream;
   apr_pool_t *scratch_pool = svn_pool_create(result_pool);
 
-  err = svn_stream_open_readonly(&stream, file, scratch_pool, scratch_pool);
+  /* Use unbuffered IO since we use our own buffering. */
+  err = svn_io_file_open(&apr_file, file, APR_READ, APR_OS_DEFAULT,
+                         scratch_pool);
 
   if (! must_exist && err && APR_STATUS_IS_ENOENT(err->apr_err))
     {
@@ -415,6 +418,7 @@ svn_config__parse_file(svn_config_t *cfg
   else
     SVN_ERR(err);
 
+  stream = svn_stream_from_aprfile2(apr_file, FALSE, scratch_pool);
   err = svn_config__parse_stream(cfg, stream, result_pool, scratch_pool);
 
   if (err != SVN_NO_ERROR)

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/dirent_uri.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/dirent_uri.c Tue Jun  4 20:56:23 2013
@@ -1688,7 +1688,8 @@ svn_dirent_is_canonical(const char *dire
 static svn_boolean_t
 relpath_is_canonical(const char *relpath)
 {
-  const char *ptr = relpath, *seg = relpath;
+  const char *ptr = relpath;
+  apr_size_t i, len;
 
   /* RELPATH is canonical if it has:
    *  - no '.' segments
@@ -1696,36 +1697,32 @@ relpath_is_canonical(const char *relpath
    *  - no '//'
    */
 
-  if (*relpath == '\0')
-    return TRUE;
-
+  /* invalid beginnings */
   if (*ptr == '/')
     return FALSE;
 
-  /* Now validate the rest of the path. */
-  while(1)
-    {
-      apr_size_t seglen = ptr - seg;
-
-      if (seglen == 1 && *seg == '.')
-        return FALSE;  /*  /./   */
-
-      if (*ptr == '/' && *(ptr+1) == '/')
-        return FALSE;  /*  //    */
-
-      if (! *ptr && *(ptr - 1) == '/')
-        return FALSE;  /* foo/  */
+  if (ptr[0] == '.' && (ptr[1] == '/' || ptr[1] == '\0'))
+    return FALSE;
 
-      if (! *ptr)
-        break;
+  /* valid special cases */
+  len = strlen(ptr);
+  if (len < 2)
+    return TRUE;
 
-      if (*ptr == '/')
-        ptr++;
-      seg = ptr;
+  /* invalid endings */
+  if (ptr[len-1] == '/' || (ptr[len-1] == '.' && ptr[len-2] == '/'))
+    return FALSE;
 
-      while (*ptr && (*ptr != '/'))
-        ptr++;
-    }
+  /* Now validate the rest of the path. */
+  for (i = 0; i < len - 1; ++i)
+    if (ptr[i] == '/' && ptr[i+1] <= '/') /* '.' and '/' have smaller UTF-8
+                                             codes than most other chars */
+      {
+        if (ptr[i+1] == '/')
+          return FALSE;  /*  //   */
+        if (ptr[i+1] == '.' && ptr[i+2] == '/')
+          return FALSE;  /*  /./  */
+      }
 
   return TRUE;
 }

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/eol.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/eol.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/eol.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/eol.c Tue Jun  4 20:56:23 2013
@@ -30,14 +30,12 @@
 #include "private/svn_eol_private.h"
 #include "private/svn_dep_compat.h"
 
-/* Machine-word-sized masks used in svn_eol__find_eol_start.
- */
 char *
 svn_eol__find_eol_start(char *buf, apr_size_t len)
 {
 #if !SVN_UNALIGNED_ACCESS_IS_OK
 
-  /* On some systems, we need to make sure that buf is properly aligned
+  /* On some systems, we need to make sure that BUF is properly aligned
    * for chunky data access. This overhead is still justified because
    * only lines tend to be tens of chars long.
    */
@@ -62,8 +60,8 @@ svn_eol__find_eol_start(char *buf, apr_s
     apr_uintptr_t r_test = chunk ^ SVN__R_MASK;
     apr_uintptr_t n_test = chunk ^ SVN__N_MASK;
 
-    /* A byte in SVN__R_TEST can by < 0x80, iff it has been \0 before
-     * (i.e. \r in *BUF). Dito for SVN__N_TEST. */
+    /* A byte in SVN__R_TEST can only be < 0x80, iff it has been \0 before
+     * (i.e. \r in *BUF). Ditto for SVN__N_TEST. */
     r_test |= (r_test & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
     n_test |= (n_test & SVN__LOWER_7BITS_SET) + SVN__LOWER_7BITS_SET;
 

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/io.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/io.c Tue Jun  4 20:56:23 2013
@@ -2804,10 +2804,23 @@ svn_io_wait_for_cmd(apr_proc_t *cmd_proc
 
   if (exitwhy)
     *exitwhy = exitwhy_val;
+  else if (APR_PROC_CHECK_SIGNALED(exitwhy_val)
+           && APR_PROC_CHECK_CORE_DUMP(exitwhy_val))
+    return svn_error_createf
+      (SVN_ERR_EXTERNAL_PROGRAM, NULL,
+       _("Process '%s' failed (exitwhy %d, signal %d, core dumped)"),
+       cmd, exitwhy_val, exitcode_val);
+  else if (APR_PROC_CHECK_SIGNALED(exitwhy_val))
+    return svn_error_createf
+      (SVN_ERR_EXTERNAL_PROGRAM, NULL,
+       _("Process '%s' failed (exitwhy %d, signal %d)"),
+       cmd, exitwhy_val, exitcode_val);
   else if (! APR_PROC_CHECK_EXIT(exitwhy_val))
+    /* Don't really know what happened here. */
     return svn_error_createf
       (SVN_ERR_EXTERNAL_PROGRAM, NULL,
-       _("Process '%s' failed (exitwhy %d)"), cmd, exitwhy_val);
+       _("Process '%s' failed (exitwhy %d, exitcode %d)"),
+       cmd, exitwhy_val, exitcode_val);
 
   if (exitcode)
     *exitcode = exitcode_val;

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/ssl_client_cert_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/ssl_client_cert_providers.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/ssl_client_cert_providers.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/ssl_client_cert_providers.c Tue Jun  4 20:56:23 2013
@@ -79,13 +79,12 @@ ssl_client_cert_file_first_credentials(v
 }
 
 
-static const svn_auth_provider_t ssl_client_cert_file_provider =
-  {
-    SVN_AUTH_CRED_SSL_CLIENT_CERT,
-    ssl_client_cert_file_first_credentials,
-    NULL,
-    NULL
-  };
+static const svn_auth_provider_t ssl_client_cert_file_provider = {
+  SVN_AUTH_CRED_SSL_CLIENT_CERT,
+  ssl_client_cert_file_first_credentials,
+  NULL,
+  NULL
+};
 
 
 /*** Public API to SSL file providers. ***/

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/ssl_server_trust_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/ssl_server_trust_providers.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/ssl_server_trust_providers.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/ssl_server_trust_providers.c Tue Jun  4 20:56:23 2013
@@ -149,9 +149,9 @@ ssl_server_trust_file_save_credentials(s
 
 static const svn_auth_provider_t ssl_server_trust_file_provider = {
   SVN_AUTH_CRED_SSL_SERVER_TRUST,
-  &ssl_server_trust_file_first_credentials,
+  ssl_server_trust_file_first_credentials,
   NULL,
-  &ssl_server_trust_file_save_credentials,
+  ssl_server_trust_file_save_credentials,
 };
 
 

Modified: subversion/branches/move-tracking-1/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_subr/subst.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_subr/subst.c Tue Jun  4 20:56:23 2013
@@ -50,6 +50,7 @@
 #include "svn_private_config.h"
 
 #include "private/svn_string_private.h"
+#include "private/svn_eol_private.h"
 
 /**
  * The textual elements of a detranslated special file.  One of these
@@ -297,14 +298,23 @@ build_keywords(apr_hash_t **kw,
   for (i = 0; i < keyword_tokens->nelts; ++i)
     {
       const char *keyword = APR_ARRAY_IDX(keyword_tokens, i, const char *);
-      apr_array_header_t *custom_keyword_tokens = NULL;
+      const char *custom_fmt = NULL;
 
       if (expand_custom_keywords)
-        custom_keyword_tokens = svn_cstring_split(keyword, "=",
-                                                  TRUE /* chop */, pool);
-      if (expand_custom_keywords && custom_keyword_tokens->nelts == 2)
         {
-          const char *custom_fmt;
+          char *sep;
+
+          /* Check if there is a custom keyword definition, started by '='. */
+          sep = strchr(keyword, '=');
+          if (sep)
+            {
+              *sep = '\0'; /* Split keyword's name from custom format. */
+              custom_fmt = sep + 1;
+            }
+        }
+
+      if (custom_fmt)
+        {
           svn_string_t *custom_val;
 
           /* Custom keywords must be allowed to match the name of an
@@ -312,9 +322,6 @@ build_keywords(apr_hash_t **kw,
            * in case new fixed keywords are added to Subversion which
            * happen to match a custom keyword defined somewhere.
            * There is only one global namespace for keyword names. */
-
-          keyword = APR_ARRAY_IDX(custom_keyword_tokens, 0, const char*);
-          custom_fmt = APR_ARRAY_IDX(custom_keyword_tokens, 1, const char*);
           custom_val = keyword_printf(custom_fmt, rev, url, repos_root_url,
                                       date, author, pool);
           svn_hash_sets(*kw, keyword, custom_val);
@@ -1116,28 +1123,42 @@ translate_chunk(svn_stream_t *dst,
               /* skip current EOL */
               len += b->eol_str_len;
 
-              /* Check 4 bytes at once to allow for efficient pipelining
-                 and to reduce loop condition overhead. */
-              while ((p + len + 4) <= end)
+              if (b->keywords)
                 {
-                  if (interesting[(unsigned char)p[len]]
-                      || interesting[(unsigned char)p[len+1]]
-                      || interesting[(unsigned char)p[len+2]]
-                      || interesting[(unsigned char)p[len+3]])
-                    break;
-
-                  len += 4;
+                  /* Check 4 bytes at once to allow for efficient pipelining
+                    and to reduce loop condition overhead. */
+                  while ((p + len + 4) <= end)
+                    {
+                      if (interesting[(unsigned char)p[len]]
+                          || interesting[(unsigned char)p[len+1]]
+                          || interesting[(unsigned char)p[len+2]]
+                          || interesting[(unsigned char)p[len+3]])
+                        break;
+
+                      len += 4;
+                    }
+
+                  /* Found an interesting char or EOF in the next 4 bytes.
+                     Find its exact position. */
+                  while ((p + len) < end
+                         && !interesting[(unsigned char)p[len]])
+                    ++len;
+                }
+              else
+                {
+                  /* use our optimized sub-routine to find the next EOL */
+                  const char *start = p + len;
+                  const char *eol
+                    = svn_eol__find_eol_start((char *)start, end - start);
+                  
+                  /* EOL will be NULL if we did not find a line ending */
+                  len += (eol ? eol : end) - start;
                 }
-
-               /* Found an interesting char or EOF in the next 4 bytes.
-                  Find its exact position. */
-               while ((p + len) < end && !interesting[(unsigned char)p[len]])
-                 ++len;
             }
           while (b->nl_translation_skippable ==
                    svn_tristate_true &&       /* can potentially skip EOLs */
                  p + len + 2 < end &&         /* not too close to EOF */
-                 eol_unchanged (b, p + len)); /* EOL format already ok */
+                 eol_unchanged(b, p + len));  /* EOL format already ok */
 
           while ((p + len) < end && !interesting[(unsigned char)p[len]])
             len++;

Modified: subversion/branches/move-tracking-1/subversion/libsvn_wc/tree_conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_wc/tree_conflicts.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_wc/tree_conflicts.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_wc/tree_conflicts.c Tue Jun  4 20:56:23 2013
@@ -506,6 +506,8 @@ svn_wc__get_tree_conflict(const svn_wc_c
           return SVN_NO_ERROR;
         }
     }
+
+  *tree_conflict = NULL;
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/move-tracking-1/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/libsvn_wc/update_editor.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/move-tracking-1/subversion/libsvn_wc/update_editor.c Tue Jun  4 20:56:23 2013
@@ -1706,7 +1706,7 @@ delete_entry(const char *path,
   const char *base = svn_relpath_basename(path, NULL);
   const char *local_abspath;
   const char *repos_relpath;
-  svn_node_kind_t kind, base_kind;
+  svn_node_kind_t kind;
   svn_revnum_t old_revision;
   svn_boolean_t conflicted;
   svn_boolean_t have_work;
@@ -1735,6 +1735,7 @@ delete_entry(const char *path,
   {
     svn_boolean_t is_root;
 
+
     SVN_ERR(svn_wc__db_is_wcroot(&is_root, eb->db, local_abspath,
                                  scratch_pool));
 
@@ -1762,10 +1763,9 @@ delete_entry(const char *path,
   if (!have_work)
     {
       base_status = status;
-      base_kind = kind;
     }
   else
-    SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, &old_revision,
+    SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, &old_revision,
                                      &repos_relpath,
                                      NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                      NULL, NULL, NULL, NULL, NULL,
@@ -1836,9 +1836,7 @@ delete_entry(const char *path,
     {
       SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
                                   status, TRUE,
-                                  (kind == svn_node_dir)
-                                        ? svn_node_dir
-                                        : svn_node_file,
+                                  kind,
                                   svn_wc_conflict_action_delete,
                                   pb->pool, scratch_pool));
     }

Modified: subversion/branches/move-tracking-1/subversion/mod_dav_svn/activity.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/mod_dav_svn/activity.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/mod_dav_svn/activity.c (original)
+++ subversion/branches/move-tracking-1/subversion/mod_dav_svn/activity.c Tue Jun  4 20:56:23 2013
@@ -193,7 +193,6 @@ dav_svn__store_activity(const dav_svn_re
                         const char *txn_name)
 {
   const char *final_path;
-  const char *tmp_path;
   const char *activity_contents;
   svn_error_t *err;
 

Modified: subversion/branches/move-tracking-1/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/mod_dav_svn/lock.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/move-tracking-1/subversion/mod_dav_svn/lock.c Tue Jun  4 20:56:23 2013
@@ -647,7 +647,7 @@ append_locks(dav_lockdb *lockdb,
 
   /* We don't allow anonymous locks */
   if (! repos->username)
-    return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,
+    return dav_svn__new_error(resource->pool, HTTP_NOT_IMPLEMENTED,
                               DAV_ERR_LOCK_SAVE_LOCK,
                               "Anonymous lock creation is not allowed.");
 
@@ -776,7 +776,7 @@ append_locks(dav_lockdb *lockdb,
   if (serr && serr->apr_err == SVN_ERR_FS_NO_USER)
     {
       svn_error_clear(serr);
-      return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,
+      return dav_svn__new_error(resource->pool, HTTP_NOT_IMPLEMENTED,
                                 DAV_ERR_LOCK_SAVE_LOCK,
                                 "Anonymous lock creation is not allowed.");
     }
@@ -886,7 +886,7 @@ remove_lock(dav_lockdb *lockdb,
       if (serr && serr->apr_err == SVN_ERR_FS_NO_USER)
         {
           svn_error_clear(serr);
-          return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,
+          return dav_svn__new_error(resource->pool, HTTP_NOT_IMPLEMENTED,
                                     DAV_ERR_LOCK_SAVE_LOCK,
                                     "Anonymous lock removal is not allowed.");
         }
@@ -953,7 +953,7 @@ refresh_locks(dav_lockdb *lockdb,
      current lock on the incoming resource? */
   if ((! slock)
       || (strcmp(token->uuid_str, slock->token) != 0))
-    return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,
+    return dav_svn__new_error(resource->pool, HTTP_PRECONDITION_FAILED,
                               DAV_ERR_LOCK_SAVE_LOCK,
                               "Lock refresh request doesn't match existing "
                               "lock.");
@@ -974,7 +974,7 @@ refresh_locks(dav_lockdb *lockdb,
   if (serr && serr->apr_err == SVN_ERR_FS_NO_USER)
     {
       svn_error_clear(serr);
-      return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,
+      return dav_svn__new_error(resource->pool, HTTP_NOT_IMPLEMENTED,
                                 DAV_ERR_LOCK_SAVE_LOCK,
                                 "Anonymous lock refreshing is not allowed.");
     }

Modified: subversion/branches/move-tracking-1/subversion/svn/file-merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/svn/file-merge.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/svn/file-merge.c (original)
+++ subversion/branches/move-tracking-1/subversion/svn/file-merge.c Tue Jun  4 20:56:23 2013
@@ -853,13 +853,20 @@ svn_cl__merge_file(const char *base_path
   const char *merged_file_name;
   struct file_merge_baton fmb;
   svn_boolean_t executable;
+  const char *merged_path_local_style;
+  const char *merged_rel_path;
+  const char *wc_path_local_style;
+  const char *wc_rel_path = svn_dirent_skip_ancestor(path_prefix, wc_path);
+
+  /* PATH_PREFIX may not be an ancestor of WC_PATH, just use the
+     full WC_PATH in that case. */
+  if (wc_rel_path)
+    wc_path_local_style = svn_dirent_local_style(wc_rel_path, scratch_pool);
+  else
+    wc_path_local_style = svn_dirent_local_style(wc_path, scratch_pool);
 
-
-  SVN_ERR(svn_cmdline_printf(
-            scratch_pool, _("Merging '%s'.\n"),
-            svn_dirent_local_style(svn_dirent_skip_ancestor(path_prefix,
-                                                            wc_path),
-                                   scratch_pool)));
+  SVN_ERR(svn_cmdline_printf(scratch_pool, _("Merging '%s'.\n"),
+                             wc_path_local_style));
 
   SVN_ERR(svn_io_file_open(&original_file, base_path,
                            APR_READ | APR_BUFFERED,
@@ -905,29 +912,30 @@ svn_cl__merge_file(const char *base_path
   if (fmb.abort_merge)
     {
       SVN_ERR(svn_io_remove_file2(merged_file_name, TRUE, scratch_pool));
-      SVN_ERR(svn_cmdline_printf(
-                scratch_pool, _("Merge of '%s' aborted.\n"),
-                svn_dirent_local_style(svn_dirent_skip_ancestor(path_prefix,
-                                                                wc_path),
-                                       scratch_pool)));
-
+      SVN_ERR(svn_cmdline_printf(scratch_pool, _("Merge of '%s' aborted.\n"),
+                                 wc_path_local_style));
       return SVN_NO_ERROR;
     }
 
   SVN_ERR(svn_io_is_file_executable(&executable, merged_path, scratch_pool));
+
+  merged_rel_path = svn_dirent_skip_ancestor(path_prefix, merged_path);
+  if (merged_rel_path)
+    merged_path_local_style = svn_dirent_local_style(merged_rel_path,
+                                                     scratch_pool);
+  else
+    merged_path_local_style = svn_dirent_local_style(merged_path,
+                                                     scratch_pool);
+
   SVN_ERR_W(svn_io_copy_file(merged_file_name, merged_path, FALSE,
                              scratch_pool),
             apr_psprintf(scratch_pool,
                          _("Could not write merged result to '%s', saved "
                            "instead at '%s'.\n'%s' remains in conflict.\n"),
-                         svn_dirent_local_style(
-                           svn_dirent_skip_ancestor(path_prefix, merged_path),
-                           scratch_pool),
+                         merged_path_local_style,
                          svn_dirent_local_style(merged_file_name,
                                                 scratch_pool),
-                         svn_dirent_local_style(
-                           svn_dirent_skip_ancestor(path_prefix, wc_path),
-                           scratch_pool)));
+                         wc_path_local_style));
   SVN_ERR(svn_io_set_file_executable(merged_path, executable, FALSE,
                                      scratch_pool));
   SVN_ERR(svn_io_remove_file2(merged_file_name, TRUE, scratch_pool));
@@ -941,15 +949,11 @@ svn_cl__merge_file(const char *base_path
     SVN_ERR(svn_cmdline_printf(
               scratch_pool,
               _("Merge of '%s' completed (remains in conflict).\n"),
-              svn_dirent_local_style(svn_dirent_skip_ancestor(path_prefix,
-                                                              wc_path),
-                                     scratch_pool)));
+              wc_path_local_style));
   else
     SVN_ERR(svn_cmdline_printf(
               scratch_pool, _("Merge of '%s' completed.\n"),
-              svn_dirent_local_style(svn_dirent_skip_ancestor(path_prefix,
-                                                              wc_path),
-                                     scratch_pool)));
+              wc_path_local_style));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-1/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/svnadmin/svnadmin.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/move-tracking-1/subversion/svnadmin/svnadmin.c Tue Jun  4 20:56:23 2013
@@ -620,6 +620,17 @@ parse_args(apr_array_header_t **args,
 }
 
 
+/* This implements 'svn_error_malfunction_handler_t. */
+static svn_error_t *
+crashtest_malfunction_handler(svn_boolean_t can_return,
+                              const char *file,
+                              int line,
+                              const char *expr)
+{
+  abort();
+  return SVN_NO_ERROR; /* Not reached. */
+}
+
 /* This implements `svn_opt_subcommand_t'. */
 static svn_error_t *
 subcommand_crashtest(apr_getopt_t *os, void *baton, apr_pool_t *pool)
@@ -627,7 +638,14 @@ subcommand_crashtest(apr_getopt_t *os, v
   struct svnadmin_opt_state *opt_state = baton;
   svn_repos_t *repos;
 
+  (void)svn_error_set_malfunction_handler(crashtest_malfunction_handler);
   SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+  SVN_ERR(svn_cmdline_printf(pool,
+                             _("Successfully opened repository '%s'.\n"
+                               "Will now crash to simulate a crashing "
+                               "server process.\n"),
+                             svn_dirent_local_style(opt_state->repository_path,
+                                                    pool)));
   SVN_ERR_MALFUNCTION();
 
   /* merely silence a compiler warning (this will never be executed) */
@@ -753,6 +771,39 @@ subcommand_deltify(apr_getopt_t *os, voi
   return SVN_NO_ERROR;
 }
 
+static void
+cmdline_stream_printf(svn_stream_t *stream,
+                      apr_pool_t *pool,
+                      const char *fmt,
+                      ...)
+  __attribute__((format(printf, 3, 4)));
+
+static void
+cmdline_stream_printf(svn_stream_t *stream,
+                      apr_pool_t *pool,
+                      const char *fmt,
+                      ...)
+{
+  const char *message;
+  va_list ap;
+  svn_error_t *err;
+  const char *out;
+
+  va_start(ap, fmt);
+  message = apr_pvsprintf(pool, fmt, ap);
+  va_end(ap);
+
+  err = svn_cmdline_cstring_from_utf8(&out, message, pool);
+
+  if (err)
+    {
+      svn_error_clear(err);
+      out = svn_cmdline_cstring_from_utf8_fuzzy(message, pool);
+    }
+
+  svn_error_clear(svn_stream_puts(stream, out));
+}
+
 
 /* Implementation of svn_repos_notify_func_t to wrap the output to a
    response stream for svn_repos_dump_fs2() and svn_repos_verify_fs() */
@@ -762,36 +813,35 @@ repos_notify_handler(void *baton,
                      apr_pool_t *scratch_pool)
 {
   svn_stream_t *feedback_stream = baton;
-  apr_size_t len;
 
   switch (notify->action)
   {
     case svn_repos_notify_warning:
-      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                        "WARNING 0x%04x: %s\n", notify->warning,
-                                        notify->warning_str));
+      cmdline_stream_printf(feedback_stream, scratch_pool,
+                            "WARNING 0x%04x: %s\n", notify->warning,
+                            notify->warning_str);
       return;
 
     case svn_repos_notify_dump_rev_end:
-      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                        _("* Dumped revision %ld.\n"),
-                                        notify->revision));
+      cmdline_stream_printf(feedback_stream, scratch_pool,
+                            _("* Dumped revision %ld.\n"),
+                            notify->revision);
       return;
 
     case svn_repos_notify_verify_rev_end:
-      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                        _("* Verified revision %ld.\n"),
-                                        notify->revision));
+      cmdline_stream_printf(feedback_stream, scratch_pool,
+                            _("* Verified revision %ld.\n"),
+                            notify->revision);
       return;
 
     case svn_repos_notify_verify_rev_structure:
       if (notify->revision == SVN_INVALID_REVNUM)
-        svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                _("* Verifying repository metadata ...\n")));
+        cmdline_stream_printf(feedback_stream, scratch_pool,
+                              _("* Verifying repository metadata ...\n"));
       else
-        svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                        _("* Verifying metadata at revision %ld ...\n"),
-                        notify->revision));
+        cmdline_stream_printf(feedback_stream, scratch_pool,
+                              _("* Verifying metadata at revision %ld ...\n"),
+                              notify->revision);
       return;
 
     case svn_repos_notify_pack_shard_start:
@@ -799,14 +849,14 @@ repos_notify_handler(void *baton,
         const char *shardstr = apr_psprintf(scratch_pool,
                                             "%" APR_INT64_T_FMT,
                                             notify->shard);
-        svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                          _("Packing revisions in shard %s..."),
-                                          shardstr));
+        cmdline_stream_printf(feedback_stream, scratch_pool,
+                              _("Packing revisions in shard %s..."),
+                              shardstr);
       }
       return;
 
     case svn_repos_notify_pack_shard_end:
-      svn_error_clear(svn_stream_puts(feedback_stream, _("done.\n")));
+      cmdline_stream_printf(feedback_stream, scratch_pool, _("done.\n"));
       return;
 
     case svn_repos_notify_pack_shard_start_revprop:
@@ -814,30 +864,30 @@ repos_notify_handler(void *baton,
         const char *shardstr = apr_psprintf(scratch_pool,
                                             "%" APR_INT64_T_FMT,
                                             notify->shard);
-        svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                          _("Packing revprops in shard %s..."),
-                                          shardstr));
+        cmdline_stream_printf(feedback_stream, scratch_pool,
+                              _("Packing revprops in shard %s..."),
+                              shardstr);
       }
       return;
 
     case svn_repos_notify_pack_shard_end_revprop:
-      svn_error_clear(svn_stream_puts(feedback_stream, _("done.\n")));
+      cmdline_stream_printf(feedback_stream, scratch_pool, _("done.\n"));
       return;
 
     case svn_repos_notify_load_txn_committed:
       if (notify->old_revision == SVN_INVALID_REVNUM)
         {
-          svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                            _("\n------- Committed revision %ld >>>\n\n"),
-                            notify->new_revision));
+          cmdline_stream_printf(feedback_stream, scratch_pool,
+                                _("\n------- Committed revision %ld >>>\n\n"),
+                                notify->new_revision);
         }
       else
         {
-          svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                            _("\n------- Committed new rev %ld"
-                              " (loaded from original rev %ld"
-                              ") >>>\n\n"), notify->new_revision,
-                              notify->old_revision));
+          cmdline_stream_printf(feedback_stream, scratch_pool,
+                                _("\n------- Committed new rev %ld"
+                                  " (loaded from original rev %ld"
+                                  ") >>>\n\n"), notify->new_revision,
+                                notify->old_revision);
         }
       return;
 
@@ -846,27 +896,27 @@ repos_notify_handler(void *baton,
         switch (notify->node_action)
         {
           case svn_node_action_change:
-            svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+            cmdline_stream_printf(feedback_stream, scratch_pool,
                                   _("     * editing path : %s ..."),
-                                  notify->path));
+                                  notify->path);
             break;
 
           case svn_node_action_delete:
-            svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+            cmdline_stream_printf(feedback_stream, scratch_pool,
                                   _("     * deleting path : %s ..."),
-                                  notify->path));
+                                  notify->path);
             break;
 
           case svn_node_action_add:
-            svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+            cmdline_stream_printf(feedback_stream, scratch_pool,
                                   _("     * adding path : %s ..."),
-                                  notify->path));
+                                  notify->path);
             break;
 
           case svn_node_action_replace:
-            svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+            cmdline_stream_printf(feedback_stream, scratch_pool,
                                   _("     * replacing path : %s ..."),
-                                  notify->path));
+                                  notify->path);
             break;
 
         }
@@ -874,32 +924,30 @@ repos_notify_handler(void *baton,
       return;
 
     case svn_repos_notify_load_node_done:
-      len = 7;
-      svn_error_clear(svn_stream_write(feedback_stream, _(" done.\n"), &len));
+      cmdline_stream_printf(feedback_stream, scratch_pool, _(" done.\n"));
       return;
 
     case svn_repos_notify_load_copied_node:
-      len = 9;
-      svn_error_clear(svn_stream_write(feedback_stream, "COPIED...", &len));
+      cmdline_stream_printf(feedback_stream, scratch_pool, "COPIED...");
       return;
 
     case svn_repos_notify_load_txn_start:
-      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                _("<<< Started new transaction, based on "
-                                  "original revision %ld\n"),
-                                notify->old_revision));
+      cmdline_stream_printf(feedback_stream, scratch_pool,
+                            _("<<< Started new transaction, based on "
+                              "original revision %ld\n"),
+                            notify->old_revision);
       return;
 
     case svn_repos_notify_load_skipped_rev:
-      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                _("<<< Skipped original revision %ld\n"),
-                                notify->old_revision));
+      cmdline_stream_printf(feedback_stream, scratch_pool,
+                            _("<<< Skipped original revision %ld\n"),
+                            notify->old_revision);
       return;
 
     case svn_repos_notify_load_normalized_mergeinfo:
-      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                                _(" removing '\\r' from %s ..."),
-                                SVN_PROP_MERGEINFO));
+      cmdline_stream_printf(feedback_stream, scratch_pool,
+                            _(" removing '\\r' from %s ..."),
+                            SVN_PROP_MERGEINFO);
       return;
 
     case svn_repos_notify_mutex_acquired:
@@ -908,17 +956,17 @@ repos_notify_handler(void *baton,
       return;
 
     case svn_repos_notify_recover_start:
-      svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
-                             _("Repository lock acquired.\n"
-                               "Please wait; recovering the"
-                               " repository may take some time...\n")));
+      cmdline_stream_printf(feedback_stream, scratch_pool,
+                            _("Repository lock acquired.\n"
+                              "Please wait; recovering the"
+                              " repository may take some time...\n"));
       return;
 
     case svn_repos_notify_upgrade_start:
-      svn_error_clear(svn_stream_puts(feedback_stream,
-                             _("Repository lock acquired.\n"
-                               "Please wait; upgrading the"
-                               " repository may take some time...\n")));
+      cmdline_stream_printf(feedback_stream, scratch_pool,
+                            _("Repository lock acquired.\n"
+                              "Please wait; upgrading the"
+                              " repository may take some time...\n"));
       return;
 
     default:

Modified: subversion/branches/move-tracking-1/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/svnserve/serve.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/svnserve/serve.c (original)
+++ subversion/branches/move-tracking-1/subversion/svnserve/serve.c Tue Jun  4 20:56:23 2013
@@ -2090,8 +2090,7 @@ static svn_error_t *log_receiver(void *b
   svn_ra_svn_conn_t *conn = b->conn;
   apr_hash_index_t *h;
   svn_boolean_t invalid_revnum = FALSE;
-  char action[2];
-  const char *author, *date, *message;
+  const svn_string_t *author, *date, *message;
   apr_uint64_t revprop_count;
 
   if (log_entry->revision == SVN_INVALID_REVNUM)
@@ -2108,7 +2107,19 @@ static svn_error_t *log_receiver(void *b
       b->stack_depth--;
     }
 
-  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "(!"));
+  svn_compat_log_revprops_out_string(&author, &date, &message,
+                                     log_entry->revprops);
+  svn_compat_log_revprops_clear(log_entry->revprops);
+  if (log_entry->revprops)
+    revprop_count = apr_hash_count(log_entry->revprops);
+  else
+    revprop_count = 0;
+
+  /* send LOG_ENTRY */
+  SVN_ERR(svn_ra_svn__start_list(conn, pool));
+
+  /* send LOG_ENTRY->CHANGED_PATHS2 */
+  SVN_ERR(svn_ra_svn__start_list(conn, pool));
   if (log_entry->changed_paths2)
     {
       for (h = apr_hash_first(pool, log_entry->changed_paths2); h;
@@ -2117,34 +2128,36 @@ static svn_error_t *log_receiver(void *b
           const char *path = svn__apr_hash_index_key(h);
           svn_log_changed_path2_t *change = svn__apr_hash_index_val(h);
 
-          action[0] = change->action;
-          action[1] = '\0';
-          SVN_ERR(svn_ra_svn__write_tuple(
-                      conn, pool, "cw(?cr)(cbb)",
+          SVN_ERR(svn_ra_svn__write_data_log_changed_path(
+                      conn, pool,
                       path,
-                      action,
+                      change->action,
                       change->copyfrom_path,
                       change->copyfrom_rev,
-                      svn_node_kind_to_word(change->node_kind),
+                      change->node_kind,
                       /* text_modified and props_modified are never unknown */
                       change->text_modified  == svn_tristate_true,
                       change->props_modified == svn_tristate_true));
         }
     }
-  svn_compat_log_revprops_out(&author, &date, &message, log_entry->revprops);
-  svn_compat_log_revprops_clear(log_entry->revprops);
-  if (log_entry->revprops)
-    revprop_count = apr_hash_count(log_entry->revprops);
-  else
-    revprop_count = 0;
-  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)r(?c)(?c)(?c)bbn(!",
-                                  log_entry->revision,
-                                  author, date, message,
-                                  log_entry->has_children,
-                                  invalid_revnum, revprop_count));
-  SVN_ERR(svn_ra_svn__write_proplist(conn, pool, log_entry->revprops));
-  SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "!)b",
-                                  log_entry->subtractive_merge));
+  SVN_ERR(svn_ra_svn__end_list(conn, pool));
+  
+  /* send LOG_ENTRY main members */
+  SVN_ERR(svn_ra_svn__write_data_log_entry(conn, pool,
+                                           log_entry->revision,
+                                           author, date, message,
+                                           log_entry->has_children,
+                                           invalid_revnum, revprop_count));
+
+  /* send LOG_ENTRY->REVPROPS */
+  SVN_ERR(svn_ra_svn__start_list(conn, pool));
+  if (revprop_count)
+    SVN_ERR(svn_ra_svn__write_proplist(conn, pool, log_entry->revprops));
+  SVN_ERR(svn_ra_svn__end_list(conn, pool));
+
+  /* send LOG_ENTRY members that were added in later SVN releases */
+  SVN_ERR(svn_ra_svn__write_boolean(conn, pool, log_entry->subtractive_merge));
+  SVN_ERR(svn_ra_svn__end_list(conn, pool));
 
   if (log_entry->has_children)
     b->stack_depth++;

Modified: subversion/branches/move-tracking-1/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/tests/cmdline/lock_tests.py?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/move-tracking-1/subversion/tests/cmdline/lock_tests.py Tue Jun  4 20:56:23 2013
@@ -1815,6 +1815,31 @@ def lock_unlock_deleted(sbox):
   expected_status.tweak('A/mu', writelocked=None)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
+@Issue(4369)
+def commit_stolen_lock(sbox):
+  "commit with a stolen lock"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_append('A/mu', 'zig-zag')
+  sbox.simple_lock('A/mu')
+
+  expected_output = '\'mu\' locked by user \'jrandom\'.'
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'lock', '--force',
+                                     sbox.repo_url + '/A/mu')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/mu', status='M ', writelocked='T')
+  err_re = "(.*E160037: Cannot verify lock on path '/A/mu')|" + \
+           "(.*E160038: '/.*/A/mu': no lock token available)"
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        [],
+                                        expected_status,
+                                        err_re,
+                                        wc_dir)
+
 ########################################################################
 # Run the tests
 
@@ -1866,6 +1891,7 @@ test_list = [ None,
               lock_multi_wc,
               locks_stick_over_switch,
               lock_unlock_deleted,
+              commit_stolen_lock,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-1/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/tests/cmdline/svntest/sandbox.py?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/move-tracking-1/subversion/tests/cmdline/svntest/sandbox.py Tue Jun  4 20:56:23 2013
@@ -362,6 +362,13 @@ class Sandbox:
        DEST is a relpath relative to the WC."""
     open(self.ospath(dest), truncate and 'w' or 'a').write(contents)
 
+  def simple_lock(self, *targets):
+    """Lock TARGETS in the WC.
+       TARGETS are relpaths relative to the WC."""
+    assert len(targets) > 0
+    targets = self.ospaths(targets)
+    svntest.main.run_svn(False, 'lock', *targets)
+
 
 def is_url(target):
   return (target.startswith('^/')

Modified: subversion/branches/move-tracking-1/subversion/tests/libsvn_diff/diff-diff3-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/tests/libsvn_diff/diff-diff3-test.c (original)
+++ subversion/branches/move-tracking-1/subversion/tests/libsvn_diff/diff-diff3-test.c Tue Jun  4 20:56:23 2013
@@ -2947,7 +2947,7 @@ struct svn_test_descriptor_t test_funcs[
     SVN_TEST_PASS2(test_identical_suffix,
                    "identical suffix starts at the boundary of a chunk"),
     SVN_TEST_PASS2(test_token_compare,
-                   "compare tokes at the chunk boundary"),
+                   "compare tokens at the chunk boundary"),
     SVN_TEST_PASS2(two_way_issue_3362_v1,
                    "2-way issue #3362 test v1"),
     SVN_TEST_PASS2(two_way_issue_3362_v2,

Modified: subversion/branches/move-tracking-1/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/tests/libsvn_fs/fs-test.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/move-tracking-1/subversion/tests/libsvn_fs/fs-test.c Tue Jun  4 20:56:23 2013
@@ -3755,6 +3755,17 @@ small_file_integrity(const svn_test_opts
 
 
 static svn_error_t *
+almostmedium_file_integrity(const svn_test_opts_t *opts,
+                            apr_pool_t *pool)
+{
+  apr_uint32_t seed = (apr_uint32_t) apr_time_now();
+
+  return file_integrity_helper(SVN_DELTA_WINDOW_SIZE - 1, &seed, opts,
+                               "test-repo-almostmedium-file-integrity", pool);
+}
+
+
+static svn_error_t *
 medium_file_integrity(const svn_test_opts_t *opts,
                       apr_pool_t *pool)
 {
@@ -5055,6 +5066,8 @@ struct svn_test_descriptor_t test_funcs[
                        "check old revisions"),
     SVN_TEST_OPTS_PASS(check_all_revisions,
                        "after each commit, check all revisions"),
+    SVN_TEST_OPTS_PASS(almostmedium_file_integrity,
+                       "create and modify almostmedium file"),
     SVN_TEST_OPTS_PASS(medium_file_integrity,
                        "create and modify medium file"),
     SVN_TEST_OPTS_PASS(large_file_integrity,

Modified: subversion/branches/move-tracking-1/subversion/tests/libsvn_subr/subst_translate-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/tests/libsvn_subr/subst_translate-test.c?rev=1489602&r1=1489601&r2=1489602&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/tests/libsvn_subr/subst_translate-test.c (original)
+++ subversion/branches/move-tracking-1/subversion/tests/libsvn_subr/subst_translate-test.c Tue Jun  4 20:56:23 2013
@@ -269,6 +269,10 @@ test_svn_subst_build_keywords3(apr_pool_
        "trunk/foo.txt stsp foo.txt %",
        "1234", "http://svn.example.com/repos/trunk/foo.txt",
        "http://svn.example.com/repos", "stsp"},
+      {"FOO", "FOO=author%_=%_%a",
+       "author = stsp",
+       "1234", "http://svn.example.com/repos/trunk/foo.txt",
+       "http://svn.example.com/repos", "stsp"},
       {"MyKeyword", "MyKeyword=%r%_%u%_%_%a",
        "4567 http://svn.example.com/svn/branches/myfile  jrandom",
        "4567", "http://svn.example.com/svn/branches/myfile",
@@ -295,6 +299,7 @@ test_svn_subst_build_keywords3(apr_pool_
                                         t->rev, t->url, t->repos_root_url,
                                         0 /* date */, t->author, pool));
       expanded_keyword = svn_hash_gets(kw, t->keyword_name);
+      SVN_TEST_ASSERT(expanded_keyword != NULL);
       SVN_TEST_STRING_ASSERT(expanded_keyword->data, t->expanded_keyword);
     }
 



Mime
View raw message