subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From br...@apache.org
Subject svn commit: r1692665 [2/3] - in /subversion/branches/1.7.x-r1542765: ./ build/ac-macros/ build/generator/ build/generator/templates/ subversion/bindings/javahl/native/ subversion/bindings/swig/include/ subversion/include/ subversion/include/private/ su...
Date Sat, 25 Jul 2015 21:43:58 GMT
Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_client/copy.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_client/copy.c Sat Jul 25 21:43:57 2015
@@ -374,6 +374,8 @@ do_wc_to_wc_moves(const apr_array_header
     {
       const char *src_parent_abspath;
       struct do_wc_to_wc_moves_with_locks_baton baton;
+      const char *src_wcroot_abspath;
+      const char *dst_wcroot_abspath;
 
       svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                     svn_client__copy_pair_t *);
@@ -386,6 +388,13 @@ do_wc_to_wc_moves(const apr_array_header
       src_parent_abspath = svn_dirent_dirname(pair->src_abspath_or_url,
                                               iterpool);
 
+      SVN_ERR(svn_wc__get_wc_root(&src_wcroot_abspath,
+                                 ctx->wc_ctx, src_parent_abspath,
+                                 iterpool, iterpool));
+      SVN_ERR(svn_wc__get_wc_root(&dst_wcroot_abspath,
+                                 ctx->wc_ctx, pair->dst_parent_abspath,
+                                 iterpool, iterpool));
+
       /* We now need to lock the right combination of batons.
          Four cases:
            1) src_parent == dst_parent
@@ -394,14 +403,18 @@ do_wc_to_wc_moves(const apr_array_header
            4) src_parent and dst_parent are disjoint
          We can handle 1) as either 2) or 3) */
       if (strcmp(src_parent_abspath, pair->dst_parent_abspath) == 0
-          || svn_dirent_is_child(src_parent_abspath, pair->dst_parent_abspath,
-                                 iterpool))
+          || (svn_dirent_is_child(src_parent_abspath, pair->dst_parent_abspath,
+                                  NULL)
+              && !svn_dirent_is_child(src_parent_abspath, dst_wcroot_abspath,
+                                      NULL)))
         {
           baton.lock_src = TRUE;
           baton.lock_dst = FALSE;
         }
-      else if (svn_dirent_is_child(pair->dst_parent_abspath, src_parent_abspath,
-                                   iterpool))
+      else if (svn_dirent_is_child(pair->dst_parent_abspath,
+                                   src_parent_abspath, NULL)
+               && !svn_dirent_is_child(pair->dst_parent_abspath,
+                                       src_wcroot_abspath, NULL))
         {
           baton.lock_src = FALSE;
           baton.lock_dst = TRUE;
@@ -979,7 +992,10 @@ repos_to_repos_copy(const apr_array_head
                                 pair->src_abspath_or_url, pool) != NULL))
         {
           info->resurrection = TRUE;
-          top_url = svn_uri_dirname(top_url, pool);
+          top_url = svn_uri_get_longest_ancestor(
+                            top_url,
+                            svn_uri_dirname(pair->dst_abspath_or_url, pool),
+                            pool);
           SVN_ERR(svn_ra_reparent(ra_session, top_url, pool));
         }
     }

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_client/delete.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_client/delete.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_client/delete.c Sat Jul 25 21:43:57 2015
@@ -143,7 +143,7 @@ path_driver_cb_func(void **dir_baton,
 
 static svn_error_t *
 single_repos_delete(svn_ra_session_t *ra_session,
-                    const char *repos_root,
+                    const char *base_uri,
                     const apr_array_header_t *relpaths,
                     const apr_hash_t *revprop_table,
                     svn_commit_callback2_t commit_callback,
@@ -171,7 +171,7 @@ single_repos_delete(svn_ra_session_t *ra
           const char *relpath = APR_ARRAY_IDX(relpaths, i, const char *);
 
           item = svn_client_commit_item3_create(pool);
-          item->url = svn_path_url_add_component2(repos_root, relpath, pool);
+          item->url = svn_path_url_add_component2(base_uri, relpath, pool);
           item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE;
           APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
         }
@@ -311,7 +311,6 @@ delete_urls_multi_repos(const apr_array_
   iterpool = svn_pool_create(pool);
   for (hi = apr_hash_first(pool, deletables); hi; hi = apr_hash_next(hi))
     {
-      const char *repos_root = svn__apr_hash_index_key(hi);
       struct repos_deletables_t *repos_deletables = svn__apr_hash_index_val(hi);
       const char *base_uri;
       apr_array_header_t *target_relpaths;
@@ -348,7 +347,7 @@ delete_urls_multi_repos(const apr_array_
         }
           
       SVN_ERR(svn_ra_reparent(repos_deletables->ra_session, base_uri, pool));
-      SVN_ERR(single_repos_delete(repos_deletables->ra_session, repos_root,
+      SVN_ERR(single_repos_delete(repos_deletables->ra_session, base_uri,
                                   target_relpaths,
                                   revprop_table, commit_callback,
                                   commit_baton, ctx, iterpool));

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_client/externals.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_client/externals.c Sat Jul 25 21:43:57 2015
@@ -464,7 +464,10 @@ switch_file_external(const char *local_a
        ### information into the wrong working copy */
     const char *definition_abspath = svn_dirent_dirname(local_abspath,subpool);
 
-    /* Open an RA session to 'source' URL */
+    /* ### Why do we open a new session?  RA_SESSION is a valid
+       ### session -- the caller used it to call svn_ra_check_path on
+       ### this very URL, the caller also did the resolving and
+       ### reparenting that is repeated here. */
     SVN_ERR(svn_client__ra_session_from_path(&ra_session, &revnum,
                                              &switch_rev_url,
                                              url, dir_abspath,
@@ -497,7 +500,7 @@ switch_file_external(const char *local_a
     /* Tell RA to do an update of URL+TARGET to REVISION; if we pass an
      invalid revnum, that means RA will use the latest revision. */
   SVN_ERR(svn_ra_do_switch2(ra_session, &reporter, &report_baton, revnum,
-                            target, svn_depth_unknown, url,
+                            target, svn_depth_unknown, switch_rev_url,
                             switch_editor, switch_baton, subpool));
 
   SVN_ERR(svn_wc__crawl_file_external(ctx->wc_ctx, local_abspath,

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_client/patch.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_client/patch.c Sat Jul 25 21:43:57 2015
@@ -1858,6 +1858,56 @@ send_patch_notification(const patch_targ
   return SVN_NO_ERROR;
 }
 
+static void
+svn_sort__array(apr_array_header_t *array,
+                int (*comparison_func)(const void *,
+                                       const void *))
+{
+  qsort(array->elts, array->nelts, array->elt_size, comparison_func);
+}
+
+/* Implements the callback for svn_sort__array.  Puts hunks that match
+   before hunks that do not match, puts hunks that match in order
+   based on postion matched, puts hunks that do not match in order
+   based on original position. */
+static int
+sort_matched_hunks(const void *a, const void *b)
+{
+  const hunk_info_t *item1 = *((const hunk_info_t * const *)a);
+  const hunk_info_t *item2 = *((const hunk_info_t * const *)b);
+  svn_boolean_t matched1 = !item1->rejected && !item1->already_applied;
+  svn_boolean_t matched2 = !item2->rejected && !item2->already_applied;
+  svn_linenum_t original1, original2;
+
+  if (matched1 && matched2)
+    {
+      /* Both match so use order matched in file. */
+      if (item1->matched_line > item2->matched_line)
+        return 1;
+      else if (item1->matched_line == item2->matched_line)
+        return 0;
+      else
+        return -1;
+    }
+  else if (matched2)
+    /* Only second matches, put it before first. */
+    return 1;
+  else if (matched1)
+    /* Only first matches, put it before second. */
+    return -1;
+
+  /* Neither matches, sort by original_start. */
+  original1 = svn_diff_hunk_get_original_start(item1->hunk);
+  original2 = svn_diff_hunk_get_original_start(item2->hunk);
+  if (original1 > original2)
+    return 1;
+  else if (original1 == original2)
+    return 0;
+  else
+    return -1;
+}
+
+
 /* Apply a PATCH to a working copy at ABS_WC_PATH and put the result
  * into temporary files, to be installed in the working copy later.
  * Return information about the patch target in *PATCH_TARGET, allocated
@@ -1939,6 +1989,10 @@ apply_one_patch(patch_target_t **patch_t
       APR_ARRAY_PUSH(target->content->hunks, hunk_info_t *) = hi;
     }
 
+  /* Hunks are applied in the order determined by the matched line and
+     this may be different from the order of the original lines. */
+  svn_sort__array(target->content->hunks, sort_matched_hunks);
+
   /* Apply or reject hunks. */
   for (i = 0; i < target->content->hunks->nelts; i++)
     {

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_delta/svndiff.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_delta/svndiff.c Sat Jul 25 21:43:57 2015
@@ -647,7 +647,13 @@ decode_window(svn_txdelta_window_t *wind
     }
   else
     {
-      new_data->data = (const char *) insend;
+      /* Copy the data because an svn_string_t must have the invariant
+         data[len]=='\0'. */
+      char *buf = apr_palloc(pool, newlen + 1);
+
+      memcpy(buf, insend, newlen);
+      buf[newlen] = '\0';
+      new_data->data = buf;
       new_data->len = newlen;
     }
 

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_diff/diff_file.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_diff/diff_file.c Sat Jul 25 21:43:57 2015
@@ -556,6 +556,13 @@ find_identical_suffix(apr_off_t *suffix_
       file_for_suffix[i].chunk =
         (int) offset_to_chunk(file_for_suffix[i].size); /* last chunk */
       length[i] = offset_in_chunk(file_for_suffix[i].size);
+      if (length[i] == 0)
+        {
+          /* last chunk is an empty chunk -> start at next-to-last chunk */
+          file_for_suffix[i].chunk = file_for_suffix[i].chunk - 1;
+          length[i] = CHUNK_SIZE;
+        }
+
       if (file_for_suffix[i].chunk == file[i].chunk)
         {
           /* Prefix ended in last chunk, so we can reuse the prefix buffer */

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_fs_fs/fs_fs.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_fs_fs/fs_fs.c Sat Jul 25 21:43:57 2015
@@ -6958,10 +6958,13 @@ recover_find_max_ids(svn_fs_t *fs, svn_r
                               "representation"));
 
   /* Now create a stream that's allowed to read only as much data as is
-     stored in the representation. */
+     stored in the representation.  Note that this is a directory, i.e. 
+     represented using the hash format on disk and can never have 0 length. */
   baton.file = rev_file;
   baton.pool = pool;
-  baton.remaining = data_rep->expanded_size;
+  baton.remaining = data_rep->expanded_size
+                  ? data_rep->expanded_size
+                  : data_rep->size;
   stream = svn_stream_create(&baton, pool);
   svn_stream_set_read(stream, read_handler_recover);
 

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_ra_serf/util.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_ra_serf/util.c Sat Jul 25 21:43:57 2015
@@ -28,7 +28,6 @@
 #define APR_WANT_STRFUNC
 #include <apr.h>
 #include <apr_want.h>
-#include <apr_fnmatch.h>
 
 #include <serf.h>
 #include <serf_bucket_types.h>
@@ -40,6 +39,7 @@
 #include "svn_xml.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_fspath.h"
+#include "private/svn_cert.h"
 
 #include "ra_serf.h"
 
@@ -202,7 +202,10 @@ ssl_server_cert(void *baton, int failure
   apr_hash_t *issuer, *subject, *serf_cert;
   apr_array_header_t *san;
   void *creds;
-  int found_matching_hostname = 0;
+  svn_boolean_t found_matching_hostname = FALSE;
+  svn_boolean_t found_san_entry = FALSE;
+  svn_string_t *actual_hostname =
+      svn_string_create(conn->hostname, scratch_pool);
 
   /* Implicitly approve any non-server certs. */
   if (serf_ssl_cert_depth(cert) > 0)
@@ -237,30 +240,42 @@ ssl_server_cert(void *baton, int failure
                   | conn->server_cert_failures);
 
   /* Try to find matching server name via subjectAltName first... */
-  if (san) {
+  if (san)
+    {
       int i;
-      for (i = 0; i < san->nelts; i++) {
+      found_san_entry = san->nelts > 0;
+      for (i = 0; i < san->nelts; i++)
+        {
           char *s = APR_ARRAY_IDX(san, i, char*);
-          if (apr_fnmatch(s, conn->hostname,
-                          APR_FNM_PERIOD | APR_FNM_CASE_BLIND) == APR_SUCCESS)
+          svn_string_t *cert_hostname = svn_string_create(s, scratch_pool);
+
+          if (svn_cert__match_dns_identity(cert_hostname, actual_hostname))
             {
-              found_matching_hostname = 1;
+              found_matching_hostname = TRUE;
               cert_info.hostname = s;
               break;
             }
-      }
-  }
+        }
+    }
 
-  /* Match server certificate CN with the hostname of the server */
-  if (!found_matching_hostname && cert_info.hostname)
+  /* Match server certificate CN with the hostname of the server iff
+   * we didn't find any subjectAltName fields and try to match them.
+   * Per RFC 2818 they are authoritative if present and CommonName
+   * should be ignored. */
+  if (!found_matching_hostname && !found_san_entry && cert_info.hostname)
     {
-      if (apr_fnmatch(cert_info.hostname, conn->hostname,
-                      APR_FNM_PERIOD | APR_FNM_CASE_BLIND) == APR_FNM_NOMATCH)
+      svn_string_t *cert_hostname = svn_string_create(cert_info.hostname,
+                                                      scratch_pool);
+
+      if (svn_cert__match_dns_identity(cert_hostname, actual_hostname))
         {
-          svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
+          found_matching_hostname = TRUE;
         }
     }
 
+  if (!found_matching_hostname)
+    svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
+
   svn_auth_set_parameter(conn->session->wc_callbacks->auth_baton,
                          SVN_AUTH_PARAM_SSL_SERVER_FAILURES,
                          &svn_failures);

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_repos/dump.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_repos/dump.c Sat Jul 25 21:43:57 2015
@@ -212,6 +212,48 @@ make_dir_baton(const char *path,
   return new_db;
 }
 
+/* If the mergeinfo in MERGEINFO_STR refers to any revisions older than
+ * OLDEST_DUMPED_REV, issue a warning and set *FOUND_OLD_MERGEINFO to TRUE,
+ * otherwise leave *FOUND_OLD_MERGEINFO unchanged.
+ */
+static svn_error_t *
+verify_mergeinfo_revisions(svn_boolean_t *found_old_mergeinfo,
+                           const char *mergeinfo_str,
+                           svn_revnum_t oldest_dumped_rev,
+                           svn_repos_notify_func_t notify_func,
+                           void *notify_baton,
+                           apr_pool_t *pool)
+{
+  svn_mergeinfo_t mergeinfo, old_mergeinfo;
+
+  SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_str, pool));
+  SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
+            &old_mergeinfo, mergeinfo,
+            oldest_dumped_rev - 1, 0,
+            TRUE, pool, pool));
+
+  if (apr_hash_count(old_mergeinfo))
+    {
+      svn_repos_notify_t *notify =
+        svn_repos_notify_create(svn_repos_notify_warning, pool);
+
+      notify->warning = svn_repos_notify_warning_found_old_mergeinfo;
+      notify->warning_str = apr_psprintf(
+        pool,
+        _("Mergeinfo referencing revision(s) prior "
+          "to the oldest dumped revision (r%ld). "
+          "Loading this dump may result in invalid "
+          "mergeinfo."),
+        oldest_dumped_rev);
+
+      if (found_old_mergeinfo)
+        *found_old_mergeinfo = TRUE;
+      notify_func(notify_baton, notify, pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 
 /* This helper is the main "meat" of the editor -- it does all the
    work of writing a node record.
@@ -473,31 +515,13 @@ dump_node(struct edit_baton *eb,
                                                      APR_HASH_KEY_STRING);
           if (mergeinfo_str)
             {
-              svn_mergeinfo_t mergeinfo, old_mergeinfo;
-
-              SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_str->data,
-                                          pool));
-              SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
-                &old_mergeinfo, mergeinfo,
-                eb->oldest_dumped_rev - 1, 0,
-                TRUE, pool, pool));
-              if (apr_hash_count(old_mergeinfo))
-                {
-                  svn_repos_notify_t *notify =
-                    svn_repos_notify_create(svn_repos_notify_warning, pool);
-
-                  notify->warning = svn_repos_notify_warning_found_old_mergeinfo;
-                  notify->warning_str = apr_psprintf(
-                    pool,
-                    _("Mergeinfo referencing revision(s) prior "
-                      "to the oldest dumped revision (r%ld). "
-                      "Loading this dump may result in invalid "
-                      "mergeinfo."),
-                    eb->oldest_dumped_rev);
-
-                  eb->found_old_mergeinfo = TRUE;
-                  eb->notify_func(eb->notify_baton, notify, pool);
-                }
+              /* An error in verifying the mergeinfo must not prevent dumping
+                 the data. Ignore any such error. */
+              svn_error_clear(verify_mergeinfo_revisions(
+                                &eb->found_old_mergeinfo,
+                                mergeinfo_str->data, eb->oldest_dumped_rev,
+                                eb->notify_func, eb->notify_baton,
+                                pool));
             }
         }
 

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/config.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/config.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/config.c Sat Jul 25 21:43:57 2015
@@ -447,14 +447,15 @@ make_string_from_option(const char **val
       expand_option_value(cfg, section, opt->value, &opt->x_value, tmp_pool);
       opt->expanded = TRUE;
 
-      if (!x_pool)
+      if (x_pool != cfg->x_pool)
         {
           /* Grab the fully expanded value from tmp_pool before its
              disappearing act. */
           if (opt->x_value)
             opt->x_value = apr_pstrmemdup(cfg->x_pool, opt->x_value,
                                           strlen(opt->x_value));
-          svn_pool_destroy(tmp_pool);
+          if (!x_pool)
+            svn_pool_destroy(tmp_pool);
         }
     }
 

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/config_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/config_auth.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/config_auth.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/config_auth.c Sat Jul 25 21:43:57 2015
@@ -90,6 +90,7 @@ svn_config_read_auth_data(apr_hash_t **h
   if (kind == svn_node_file)
     {
       svn_stream_t *stream;
+      svn_string_t *stored_realm;
 
       SVN_ERR_W(svn_stream_open_readonly(&stream, auth_path, pool, pool),
                 _("Unable to open auth file for reading"));
@@ -100,6 +101,12 @@ svn_config_read_auth_data(apr_hash_t **h
                 apr_psprintf(pool, _("Error parsing '%s'"),
                              svn_dirent_local_style(auth_path, pool)));
 
+      stored_realm = apr_hash_get(*hash, SVN_CONFIG_REALMSTRING_KEY,
+                                  APR_HASH_KEY_STRING);
+
+      if (!stored_realm || strcmp(stored_realm->data, realmstring) != 0)
+        *hash = NULL; /* Hash collision, or somebody tampering with storage */
+
       SVN_ERR(svn_stream_close(stream));
     }
 

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/dirent_uri.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/dirent_uri.c Sat Jul 25 21:43:57 2015
@@ -38,6 +38,7 @@
 
 #include "dirent_uri.h"
 #include "private/svn_fspath.h"
+#include "private/svn_cert.h"
 
 /* The canonical empty path.  Can this be changed?  Well, change the empty
    test below and the path library will work, not so sure about the fs/wc
@@ -2631,3 +2632,81 @@ svn_urlpath__canonicalize(const char *ur
     }
   return uri;
 }
+
+
+/* -------------- The cert API (see private/svn_cert.h) ------------- */
+
+svn_boolean_t
+svn_cert__match_dns_identity(svn_string_t *pattern, svn_string_t *hostname)
+{
+  apr_size_t pattern_pos = 0, hostname_pos = 0;
+
+  /* support leading wildcards that composed of the only character in the
+   * left-most label. */
+  if (pattern->len >= 2 &&
+      pattern->data[pattern_pos] == '*' &&
+      pattern->data[pattern_pos + 1] == '.')
+    {
+      while (hostname_pos < hostname->len &&
+             hostname->data[hostname_pos] != '.')
+        {
+          hostname_pos++;
+        }
+      /* Assume that the wildcard must match something.  Rule 2 says
+       * that *.example.com should not match example.com.  If the wildcard
+       * ends up not matching anything then it matches .example.com which
+       * seems to be essentially the same as just example.com */
+      if (hostname_pos == 0)
+        return FALSE;
+
+      pattern_pos++;
+    }
+
+  while (pattern_pos < pattern->len && hostname_pos < hostname->len)
+    {
+      char pattern_c = pattern->data[pattern_pos];
+      char hostname_c = hostname->data[hostname_pos];
+
+      /* fold case as described in RFC 4343.
+       * Note: We actually convert to lowercase, since our URI
+       * canonicalization code converts to lowercase and generally
+       * most certs are issued with lowercase DNS names, meaning
+       * this avoids the fold operation in most cases.  The RFC
+       * suggests the opposite transformation, but doesn't require
+       * any specific implementation in any case.  It is critical
+       * that this folding be locale independent so you can't use
+       * tolower(). */
+      pattern_c = canonicalize_to_lower(pattern_c);
+      hostname_c = canonicalize_to_lower(hostname_c);
+
+      if (pattern_c != hostname_c)
+        {
+          /* doesn't match */
+          return FALSE;
+        }
+      else
+        {
+          /* characters match so skip both */
+          pattern_pos++;
+          hostname_pos++;
+        }
+    }
+
+  /* ignore a trailing period on the hostname since this has no effect on the
+   * security of the matching.  See the following for the long explanation as
+   * to why:
+   * https://bugzilla.mozilla.org/show_bug.cgi?id=134402#c28
+   */
+  if (pattern_pos == pattern->len &&
+      hostname_pos == hostname->len - 1 &&
+      hostname->data[hostname_pos] == '.')
+    hostname_pos++;
+
+  if (pattern_pos != pattern->len || hostname_pos != hostname->len)
+    {
+      /* end didn't match */
+      return FALSE;
+    }
+
+  return TRUE;
+}

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/error.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/error.c Sat Jul 25 21:43:57 2015
@@ -249,6 +249,8 @@ svn_error_compose(svn_error_t *chain, sv
       *chain = *new_err;
       if (chain->message)
         chain->message = apr_pstrdup(pool, new_err->message);
+      if (chain->file)
+        chain->file = apr_pstrdup(pool, new_err->file);
       chain->pool = pool;
 #if defined(SVN_DEBUG)
       if (! new_err->child)
@@ -318,6 +320,8 @@ svn_error_dup(svn_error_t *err)
       tmp_err->pool = pool;
       if (tmp_err->message)
         tmp_err->message = apr_pstrdup(pool, tmp_err->message);
+      if (tmp_err->file)
+        tmp_err->file = apr_pstrdup(pool, tmp_err->file);
     }
 
 #if defined(SVN_DEBUG)

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/opt.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_subr/opt.c Sat Jul 25 21:43:57 2015
@@ -1088,7 +1088,7 @@ svn_opt__print_version_info(const char *
                                      "   compiled %s, %s\n\n"), pgm_name,
                              SVN_VERSION, __DATE__, __TIME__));
   SVN_ERR(svn_cmdline_fputs(
-             _("Copyright (C) 2014 The Apache Software Foundation.\n"
+             _("Copyright (C) 2015 The Apache Software Foundation.\n"
                "This software consists of contributions made by many "
                "people; see the NOTICE\n"
                "file for more information.\n"

Modified: subversion/branches/1.7.x-r1542765/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/libsvn_wc/wc_db.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/libsvn_wc/wc_db.c Sat Jul 25 21:43:57 2015
@@ -3318,8 +3318,9 @@ get_info_for_copy(apr_int64_t *copyfrom_
                   svn_wc__db_kind_t *kind,
                   svn_boolean_t *op_root,
                   svn_boolean_t *have_work,
-                  svn_wc__db_wcroot_t *wcroot,
+                  svn_wc__db_wcroot_t *src_wcroot,
                   const char *local_relpath,
+                  svn_wc__db_wcroot_t *dst_wcroot,
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
 {
@@ -3332,7 +3333,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
                     NULL /* have_base */,
                     NULL /* have_more_work */,
                     have_work,
-                    wcroot, local_relpath, result_pool, scratch_pool));
+                    src_wcroot, local_relpath, result_pool, scratch_pool));
 
   if (*status == svn_wc__db_status_excluded)
     {
@@ -3349,7 +3350,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
                                 &parent_status,
                                 &parent_kind,
                                 NULL, &parent_have_work,
-                                wcroot, parent_relpath,
+                                src_wcroot, parent_relpath, dst_wcroot,
                                 scratch_pool, scratch_pool));
       if (*copyfrom_relpath)
         *copyfrom_relpath = svn_relpath_join(*copyfrom_relpath, base_name,
@@ -3362,7 +3363,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
       SVN_ERR(scan_addition(NULL, &op_root_relpath,
                             NULL, NULL, /* repos_* */
                             copyfrom_relpath, copyfrom_id, copyfrom_rev,
-                            wcroot, local_relpath,
+                            src_wcroot, local_relpath,
                             scratch_pool, scratch_pool));
       if (*copyfrom_relpath)
         {
@@ -3378,7 +3379,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
       const char *base_del_relpath, *work_del_relpath;
 
       SVN_ERR(scan_deletion(&base_del_relpath, NULL, &work_del_relpath,
-                            wcroot, local_relpath, scratch_pool,
+                            src_wcroot, local_relpath, scratch_pool,
                             scratch_pool));
       if (work_del_relpath)
         {
@@ -3391,7 +3392,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
           SVN_ERR(scan_addition(NULL, &op_root_relpath,
                                 NULL, NULL, /* repos_* */
                                 copyfrom_relpath, copyfrom_id, copyfrom_rev,
-                                wcroot, parent_del_relpath,
+                                src_wcroot, parent_del_relpath,
                                 scratch_pool, scratch_pool));
           *copyfrom_relpath
             = svn_relpath_join(*copyfrom_relpath,
@@ -3405,7 +3406,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
                                 copyfrom_id,
                                 NULL, NULL, NULL, NULL, NULL,
                                 NULL, NULL, NULL, NULL,
-                                wcroot, local_relpath,
+                                src_wcroot, local_relpath,
                                 result_pool, scratch_pool));
         }
       else
@@ -3417,6 +3418,24 @@ get_info_for_copy(apr_int64_t *copyfrom_
       *copyfrom_rev = revision;
     }
 
+  if (src_wcroot != dst_wcroot && *copyfrom_relpath)
+    {
+      const char *repos_root_url;
+      const char *repos_uuid;
+
+      /* Pass the right repos-id for the destination db. We can't just use
+         the id of the source database, as this value can change after
+         relocation (and perhaps also when we start storing multiple
+         working copies in a single db)! */
+
+      SVN_ERR(fetch_repos_info(&repos_root_url, &repos_uuid,
+                               src_wcroot->sdb, *copyfrom_id,
+                               scratch_pool));
+
+      SVN_ERR(create_repos_id(copyfrom_id, repos_root_url, repos_uuid,
+                              dst_wcroot->sdb, scratch_pool));
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -3465,7 +3484,8 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
 
   SVN_ERR(get_info_for_copy(&copyfrom_id, &copyfrom_relpath, &copyfrom_rev,
                             &status, &kind, &op_root, &have_work, src_wcroot,
-                            src_relpath, scratch_pool, scratch_pool));
+                            src_relpath, dst_wcroot,
+                            scratch_pool, scratch_pool));
 
   SVN_ERR(op_depth_for_copy(&dst_op_depth, &dst_np_op_depth, copyfrom_id,
                             copyfrom_relpath, copyfrom_rev,
@@ -3616,21 +3636,6 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
     }
   else
     {
-      if (copyfrom_relpath)
-        {
-          const char *repos_root_url;
-          const char *repos_uuid;
-
-          /* Pass the right repos-id for the destination db! */
-
-          SVN_ERR(fetch_repos_info(&repos_root_url, &repos_uuid,
-                                   src_wcroot->sdb, copyfrom_id,
-                                   scratch_pool));
-
-          SVN_ERR(create_repos_id(&copyfrom_id, repos_root_url, repos_uuid,
-                                  dst_wcroot->sdb, scratch_pool));
-        }
-
       SVN_ERR(cross_db_copy(src_wcroot, src_relpath, dst_wcroot,
                             dst_relpath, dst_presence, dst_op_depth,
                             dst_np_op_depth, kind,

Modified: subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/deadprops.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/deadprops.c Sat Jul 25 21:43:57 2015
@@ -160,6 +160,23 @@ get_value(dav_db *db, const dav_prop_nam
 }
 
 
+static svn_error_t *
+change_txn_prop(svn_fs_txn_t *txn,
+                const char *propname,
+                const svn_string_t *value,
+                apr_pool_t *scratch_pool)
+{
+  if (strcmp(propname, SVN_PROP_REVISION_AUTHOR) == 0)
+    return svn_error_create(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+                            "Attempted to modify 'svn:author' property "
+                            "on a transaction");
+
+  SVN_ERR(svn_repos_fs_change_txn_prop(txn, propname, value, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+
 static dav_error *
 save_value(dav_db *db, const dav_prop_name *name,
            const svn_string_t *const *old_value_p,
@@ -210,9 +227,8 @@ save_value(dav_db *db, const dav_prop_na
     {
       if (db->resource->working)
         {
-          serr = svn_repos_fs_change_txn_prop(resource->info->root.txn,
-                                              propname, value,
-                                              subpool);
+          serr = change_txn_prop(resource->info->root.txn, propname,
+                                 value, subpool);
         }
       else
         {
@@ -251,8 +267,8 @@ save_value(dav_db *db, const dav_prop_na
     }
   else if (resource->info->restype == DAV_SVN_RESTYPE_TXN_COLLECTION)
     {
-      serr = svn_repos_fs_change_txn_prop(resource->info->root.txn,
-                                          propname, value, subpool);
+      serr = change_txn_prop(resource->info->root.txn, propname,
+                             value, subpool);
     }
   else
     {
@@ -561,8 +577,8 @@ db_remove(dav_db *db, const dav_prop_nam
   /* Working Baseline or Working (Version) Resource */
   if (db->resource->baselined)
     if (db->resource->working)
-      serr = svn_repos_fs_change_txn_prop(db->resource->info->root.txn,
-                                          propname, NULL, subpool);
+      serr = change_txn_prop(db->resource->info->root.txn, propname,
+                             NULL, subpool);
     else
       /* ### VIOLATING deltaV: you can't proppatch a baseline, it's
          not a working resource!  But this is how we currently

Modified: subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/deleted-rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/deleted-rev.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/deleted-rev.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/deleted-rev.c Sat Jul 25 21:43:57 2015
@@ -56,6 +56,9 @@ dav_svn__get_deleted_rev_report(const da
   dav_error *derr = NULL;
 
   /* Sanity check. */
+  if (!resource->info->repos_path)
+    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                              "The request does not specify a repository path");
   ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
   if (ns == -1)
     return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0,

Modified: subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/file-revs.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/file-revs.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/file-revs.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/file-revs.c Sat Jul 25 21:43:57 2015
@@ -251,6 +251,9 @@ dav_svn__file_revs_report(const dav_reso
   arb.repos = resource->info->repos;
 
   /* Sanity check. */
+  if (!resource->info->repos_path)
+    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                              "The request does not specify a repository path");
   ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
   /* ### This is done on other places, but the document element is
      in this namespace, so is this necessary at all? */

Modified: subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/get-location-segments.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/get-location-segments.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/get-location-segments.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/get-location-segments.c Sat Jul 25 21:43:57 2015
@@ -123,6 +123,9 @@ dav_svn__get_location_segments_report(co
   struct location_segment_baton location_segment_baton;
 
   /* Sanity check. */
+  if (!resource->info->repos_path)
+    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                              "The request does not specify a repository path");
   ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
   if (ns == -1)
     {
@@ -178,17 +181,36 @@ dav_svn__get_location_segments_report(co
                                   "Not all parameters passed.",
                                   SVN_DAV_ERROR_NAMESPACE,
                                   SVN_DAV_ERROR_TAG);
-  if (SVN_IS_VALID_REVNUM(start_rev)
-      && SVN_IS_VALID_REVNUM(end_rev)
-      && (end_rev > start_rev))
+
+  /* No START_REV or PEG_REVISION?  We'll use HEAD. */
+  if (!SVN_IS_VALID_REVNUM(start_rev) || !SVN_IS_VALID_REVNUM(peg_revision))
+    {
+      svn_revnum_t youngest;
+
+      serr = svn_fs_youngest_rev(&youngest, resource->info->repos->fs,
+                                 resource->pool);
+      if (serr != NULL)
+        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                    "Could not determine youngest revision",
+                                    resource->pool);
+
+      if (!SVN_IS_VALID_REVNUM(start_rev))
+        start_rev = youngest;
+      if (!SVN_IS_VALID_REVNUM(peg_revision))
+        peg_revision = youngest;
+    }
+
+  /* No END_REV?  We'll use 0. */
+  if (!SVN_IS_VALID_REVNUM(end_rev))
+    end_rev = 0;
+
+  if (end_rev > start_rev)
     return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0,
                                   "End revision must not be younger than "
                                   "start revision",
                                   SVN_DAV_ERROR_NAMESPACE,
                                   SVN_DAV_ERROR_TAG);
-  if (SVN_IS_VALID_REVNUM(peg_revision)
-      && SVN_IS_VALID_REVNUM(start_rev)
-      && (start_rev > peg_revision))
+  if (start_rev > peg_revision)
     return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0,
                                   "Start revision must not be younger than "
                                   "peg revision",

Modified: subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/get-locations.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/get-locations.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/get-locations.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/get-locations.c Sat Jul 25 21:43:57 2015
@@ -106,6 +106,9 @@ dav_svn__get_locations_report(const dav_
                                       sizeof(svn_revnum_t));
 
   /* Sanity check. */
+  if (!resource->info->repos_path)
+    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                              "The request does not specify a repository path");
   ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
   if (ns == -1)
     {

Modified: subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/log.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/log.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/log.c Sat Jul 25 21:43:57 2015
@@ -307,6 +307,9 @@ dav_svn__log_report(const dav_resource *
     = apr_array_make(resource->pool, 1, sizeof(const char *));
 
   /* Sanity check. */
+  if (!resource->info->repos_path)
+    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                              "The request does not specify a repository path");
   ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
   if (ns == -1)
     {

Modified: subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/mergeinfo.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/mergeinfo.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/reports/mergeinfo.c Sat Jul 25 21:43:57 2015
@@ -67,6 +67,9 @@ dav_svn__get_mergeinfo_report(const dav_
     = apr_array_make(resource->pool, 0, sizeof(const char *));
 
   /* Sanity check. */
+  if (!resource->info->repos_path)
+    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                              "The request does not specify a repository path");
   ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
   if (ns == -1)
     {

Modified: subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/repos.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/mod_dav_svn/repos.c Sat Jul 25 21:43:57 2015
@@ -506,6 +506,9 @@ parse_vtxnstub_uri(dav_resource_combined
   if (parse_txnstub_uri(comb, path, label, use_checked_in))
     return TRUE;
 
+  if (!comb->priv.root.txn_name)
+    return TRUE;
+
   comb->priv.root.vtxn_name = comb->priv.root.txn_name;
   comb->priv.root.txn_name = dav_svn__get_txn(comb->priv.repos,
                                               comb->priv.root.vtxn_name);
@@ -574,6 +577,9 @@ parse_vtxnroot_uri(dav_resource_combined
   if (parse_txnroot_uri(comb, path, label, use_checked_in))
     return TRUE;
 
+  if (!comb->priv.root.txn_name)
+    return TRUE;
+
   comb->priv.root.vtxn_name = comb->priv.root.txn_name;
   comb->priv.root.txn_name = dav_svn__get_txn(comb->priv.repos,
                                               comb->priv.root.vtxn_name);
@@ -919,6 +925,10 @@ prep_working(dav_resource_combined *comb
      point. */
   if (txn_name == NULL)
     {
+      if (!comb->priv.root.activity_id)
+        return dav_svn__new_error(comb->res.pool, HTTP_BAD_REQUEST, 0,
+                                  "The request did not specify an activity ID");
+
       txn_name = dav_svn__get_txn(comb->priv.repos,
                                   comb->priv.root.activity_id);
       if (txn_name == NULL)
@@ -1029,8 +1039,13 @@ prep_working(dav_resource_combined *comb
 static dav_error *
 prep_activity(dav_resource_combined *comb)
 {
-  const char *txn_name = dav_svn__get_txn(comb->priv.repos,
-                                          comb->priv.root.activity_id);
+  const char *txn_name;
+
+  if (!comb->priv.root.activity_id)
+    return dav_svn__new_error(comb->res.pool, HTTP_BAD_REQUEST, 0,
+                              "The request did not specify an activity ID");
+
+  txn_name = dav_svn__get_txn(comb->priv.repos, comb->priv.root.activity_id);
 
   comb->priv.root.txn_name = txn_name;
   comb->res.exists = txn_name != NULL;
@@ -1788,14 +1803,106 @@ do_out_of_date_check(dav_resource_combin
                                 "Could not get created rev of "
                                 "resource", r->pool);
 
-  if (comb->priv.version_name < created_rev)
+  if (SVN_IS_VALID_REVNUM(created_rev))
+    {
+      if (comb->priv.version_name < created_rev)
+        {
+          serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
+                                   comb->res.collection
+                                    ? "Directory '%s' is out of date"
+                                    : (comb->res.exists
+                                        ? "File '%s' is out of date"
+                                        : "'%s' is out of date"),
+                                   comb->priv.repos_path);
+          return dav_svn__convert_err(serr, HTTP_CONFLICT,
+                                      "Attempting to modify out-of-date resource.",
+                                      r->pool);
+        }
+    }
+  else if (SVN_IS_VALID_REVNUM(comb->priv.version_name)
+           && comb->res.collection)
     {
-      serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
-                               "Item '%s' is out of date",
-                               comb->priv.repos_path);
-      return dav_svn__convert_err(serr, HTTP_CONFLICT,
-                                  "Attempting to modify out-of-date resource.",
-                                  r->pool);
+      /* Issue #4480: With HTTPv2 we can receive the first change for a
+         directory after it has been made mutable, because one of its
+         descendants was changed before changing the directory.
+
+         We have to check if whatever the node is in HEAD is equivalent
+         to what it was in the provided BASE revision.
+
+         If the node was copied, we would process it before its decendants
+         and we already performed quite a few checks when making it mutable
+         via its descendant, so what we should really check here is if the
+         properties changed since the BASE version.
+
+         ### I think svn_fs_node_relation() checks for more changes than we
+             should check for here. Needs further review. But it looks like\
+             this check matches the checks in the libsvn_fs commit editor.
+
+             For now I would say reporting out of date in a few too many
+             cases is safer than not reporting out of date when we should.
+       */
+      svn_revnum_t youngest;
+      svn_fs_root_t *youngest_root;
+      svn_fs_root_t *rev_root;
+      const svn_fs_id_t *youngest_id;
+      const svn_fs_id_t *rev_id;
+
+      serr = svn_fs_youngest_rev(&youngest, comb->res.info->repos->fs,
+                                 r->pool);
+      if (serr != NULL)
+        {
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not determine the youngest "
+                                      "revision for verification against "
+                                      "the baseline being checked out",
+                                      r->pool);
+        }
+
+      if (comb->priv.version_name == youngest)
+        return NULL; /* Easy out: we commit against HEAD */
+
+      serr = svn_fs_revision_root(&youngest_root, comb->res.info->repos->fs,
+                                  youngest, r->pool);
+                                  
+      if (!serr)
+        serr = svn_fs_node_id(&youngest_id, youngest_root,
+                              comb->priv.repos_path, r->pool);
+
+      if (serr != NULL)
+        {
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not open youngest revision root "
+                                      "for verification against the base "
+                                      "revision", r->pool);
+        }
+
+      serr = svn_fs_revision_root(&rev_root, comb->res.info->repos->fs,
+                                  comb->priv.version_name, r->pool);
+
+      if (!serr)
+        serr = svn_fs_node_id(&rev_id, rev_root,
+                              comb->priv.repos_path, r->pool);
+
+      if (serr != NULL)
+        {
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not open the base revision"
+                                      "for verification against the youngest "
+                                      "revision", r->pool);
+        }
+
+      svn_fs_close_root(rev_root);
+      svn_fs_close_root(youngest_root);
+
+      if (0 != svn_fs_compare_ids(youngest_id, rev_id))
+        {
+          serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
+                                   "Directory '%s' is out of date",
+                                   comb->priv.repos_path);
+          return dav_svn__convert_err(serr, HTTP_CONFLICT,
+                                      "Attempting to modify out-of-date resource.",
+                                      r->pool);
+        }
     }
 
   return NULL;
@@ -4086,7 +4193,9 @@ typedef struct walker_ctx_t {
 
 
 static dav_error *
-do_walk(walker_ctx_t *ctx, int depth)
+do_walk(walker_ctx_t *ctx,
+        int depth,
+        apr_pool_t *scratch_pool)
 {
   const dav_walk_params *params = ctx->params;
   int isdir = ctx->res.collection;
@@ -4159,19 +4268,19 @@ do_walk(walker_ctx_t *ctx, int depth)
                            svn_log__get_dir(ctx->info.repos_path,
                                             ctx->info.root.rev,
                                             TRUE, FALSE, SVN_DIRENT_ALL,
-                                            params->pool));
+                                            scratch_pool));
 
   /* fetch this collection's children */
   serr = svn_fs_dir_entries(&children, ctx->info.root.root,
-                            ctx->info.repos_path, params->pool);
+                            ctx->info.repos_path, scratch_pool);
   if (serr != NULL)
     return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                 "could not fetch collection members",
                                 params->pool);
 
   /* iterate over the children in this collection */
-  iterpool = svn_pool_create(params->pool);
-  for (hi = apr_hash_first(params->pool, children); hi; hi = apr_hash_next(hi))
+  iterpool = svn_pool_create(scratch_pool);
+  for (hi = apr_hash_first(scratch_pool, children); hi; hi = apr_hash_next(hi))
     {
       const void *key;
       apr_ssize_t klen;
@@ -4224,7 +4333,7 @@ do_walk(walker_ctx_t *ctx, int depth)
           ctx->res.uri = ctx->uri->data;
 
           /* recurse on this collection */
-          err = do_walk(ctx, depth - 1);
+          err = do_walk(ctx, depth - 1, iterpool);
           if (err != NULL)
             return err;
 
@@ -4306,7 +4415,7 @@ walk(const dav_walk_params *params, int
   /* ### is the root already/always open? need to verify */
 
   /* always return the error, and any/all multistatus responses */
-  err = do_walk(&ctx, depth);
+  err = do_walk(&ctx, depth, params->pool);
   *response = ctx.wres.response;
 
   return err;

Modified: subversion/branches/1.7.x-r1542765/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/svnrdump/load_editor.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/svnrdump/load_editor.c Sat Jul 25 21:43:57 2015
@@ -41,6 +41,8 @@
 
 #define SVNRDUMP_PROP_LOCK SVN_PROP_PREFIX "rdump-lock"
 
+#define ARE_VALID_COPY_ARGS(p,r) ((p) && SVN_IS_VALID_REVNUM(r))
+
 #if 0
 #define LDR_DBG(x) SVN_DBG(x)
 #else
@@ -102,6 +104,15 @@ struct directory_baton
   void *baton;
   const char *relpath;
   int depth;
+
+  /* The copy-from source of this directory, no matter whether it is
+     copied explicitly (the root node of a copy) or implicitly (being an
+     existing child of a copied directory). For a node that is newly
+     added (without history), even inside a copied parent, these are
+     NULL and SVN_INVALID_REVNUM. */
+  const char *copyfrom_path;
+  svn_revnum_t copyfrom_rev;
+
   struct directory_baton *parent;
 };
 
@@ -115,12 +126,20 @@ struct node_baton
   svn_node_kind_t kind;
   enum svn_node_action action;
 
+  /* Is this directory explicitly added? If not, then it already existed
+     or is a child of a copy. */
+  svn_boolean_t is_added;
+
   svn_revnum_t copyfrom_rev;
   const char *copyfrom_path;
+  const char *copyfrom_url;
 
   void *file_baton;
   const char *base_checksum;
 
+  /* (const char *name) -> (svn_prop_t *) */
+  apr_hash_t *prop_changes;
+
   struct revision_baton *rb;
 };
 
@@ -436,6 +455,7 @@ new_revision_record(void **revision_bato
   pb = parse_baton;
   rb->pool = svn_pool_create(pool);
   rb->pb = pb;
+  rb->db = NULL;
 
   for (hi = apr_hash_first(pool, headers); hi; hi = apr_hash_next(hi))
     {
@@ -479,6 +499,47 @@ uuid_record(const char *uuid,
   return SVN_NO_ERROR;
 }
 
+/* Push information about another directory onto the linked list RB->db.
+ *
+ * CHILD_BATON is the baton returned by the commit editor. RELPATH is the
+ * repository-relative path of this directory. IS_ADDED is true iff this
+ * directory is being added (with or without history). If added with
+ * history then COPYFROM_PATH/COPYFROM_REV are the copyfrom source, else
+ * are NULL/SVN_INVALID_REVNUM.
+ */
+static void
+push_directory(struct revision_baton *rb,
+               void *child_baton,
+               const char *relpath,
+               svn_boolean_t is_added,
+               const char *copyfrom_path,
+               svn_revnum_t copyfrom_rev)
+{
+  struct directory_baton *child_db = apr_pcalloc(rb->pool, sizeof (*child_db));
+
+  SVN_ERR_ASSERT_NO_RETURN(
+    is_added || (copyfrom_path == NULL && copyfrom_rev == SVN_INVALID_REVNUM));
+
+  /* If this node is an existing (not newly added) child of a copied node,
+     calculate where it was copied from. */
+  if (!is_added
+      && ARE_VALID_COPY_ARGS(rb->db->copyfrom_path, rb->db->copyfrom_rev))
+    {
+      const char *name = svn_relpath_basename(relpath, NULL);
+
+      copyfrom_path = svn_relpath_join(rb->db->copyfrom_path, name,
+                                       rb->pool);
+      copyfrom_rev = rb->db->copyfrom_rev;
+    }
+
+  child_db->baton = child_baton;
+  child_db->relpath = relpath;
+  child_db->copyfrom_path = copyfrom_path;
+  child_db->copyfrom_rev = copyfrom_rev;
+  child_db->parent = rb->db;
+  rb->db = child_db;
+}
+
 static svn_error_t *
 new_node_record(void **node_baton,
                 apr_hash_t *headers,
@@ -489,17 +550,17 @@ new_node_record(void **node_baton,
   const struct svn_delta_editor_t *commit_editor = rb->pb->commit_editor;
   void *commit_edit_baton = rb->pb->commit_edit_baton;
   struct node_baton *nb;
-  struct directory_baton *child_db;
   apr_hash_index_t *hi;
   void *child_baton;
-  char *relpath_compose;
   const char *nb_dirname;
 
   nb = apr_pcalloc(rb->pool, sizeof(*nb));
   nb->rb = rb;
-
+  nb->is_added = FALSE;
   nb->copyfrom_path = NULL;
+  nb->copyfrom_url = NULL;
   nb->copyfrom_rev = SVN_INVALID_REVNUM;
+  nb->prop_changes = apr_hash_make(rb->pool);
 
   /* If the creation of commit_editor is pending, create it now and
      open_root on it; also create a top-level directory baton. */
@@ -532,13 +593,9 @@ new_node_record(void **node_baton,
 
       LDR_DBG(("Opened root %p\n", child_baton));
 
-      /* child_db corresponds to the root directory baton here */
-      child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
-      child_db->baton = child_baton;
-      child_db->depth = 0;
-      child_db->relpath = "";
-      child_db->parent = NULL;
-      rb->db = child_db;
+      /* child_baton corresponds to the root directory baton here */
+      push_directory(rb, child_baton, "", TRUE /*is_added*/,
+                     NULL, SVN_INVALID_REVNUM);
     }
 
   for (hi = apr_hash_first(rb->pool, headers); hi; hi = apr_hash_next(hi))
@@ -607,7 +664,7 @@ new_node_record(void **node_baton,
 
       for (i = 0; i < residual_open_path->nelts; i ++)
         {
-          relpath_compose =
+          char *relpath_compose =
             svn_relpath_join(rb->db->relpath,
                              APR_ARRAY_IDX(residual_open_path, i, const char *),
                              rb->pool);
@@ -616,12 +673,8 @@ new_node_record(void **node_baton,
                                                 rb->rev - rb->rev_offset - 1,
                                                 rb->pool, &child_baton));
           LDR_DBG(("Opened dir %p\n", child_baton));
-          child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
-          child_db->baton = child_baton;
-          child_db->depth = rb->db->depth + 1;
-          child_db->relpath = relpath_compose;
-          child_db->parent = rb->db;
-          rb->db = child_db;
+          push_directory(rb, child_baton, relpath_compose, TRUE /*is_added*/,
+                         NULL, SVN_INVALID_REVNUM);
         }
     }
 
@@ -649,7 +702,7 @@ new_node_record(void **node_baton,
       if (rb->pb->parent_dir)
         nb->copyfrom_path = svn_relpath_join(rb->pb->parent_dir,
                                              nb->copyfrom_path, rb->pool);
-      nb->copyfrom_path = svn_path_url_add_component2(rb->pb->root_url,
+      nb->copyfrom_url = svn_path_url_add_component2(rb->pb->root_url,
                                                       nb->copyfrom_path,
                                                       rb->pool);
     }
@@ -667,11 +720,12 @@ new_node_record(void **node_baton,
       else
         /* FALL THROUGH */;
     case svn_node_action_add:
+      nb->is_added = TRUE;
       switch (nb->kind)
         {
         case svn_node_file:
           SVN_ERR(commit_editor->add_file(nb->path, rb->db->baton,
-                                          nb->copyfrom_path,
+                                          nb->copyfrom_url,
                                           nb->copyfrom_rev,
                                           rb->pool, &(nb->file_baton)));
           LDR_DBG(("Added file %s to dir %p as %p\n",
@@ -679,17 +733,13 @@ new_node_record(void **node_baton,
           break;
         case svn_node_dir:
           SVN_ERR(commit_editor->add_directory(nb->path, rb->db->baton,
-                                               nb->copyfrom_path,
+                                               nb->copyfrom_url,
                                                nb->copyfrom_rev,
                                                rb->pool, &child_baton));
           LDR_DBG(("Added dir %s to dir %p as %p\n",
                    nb->path, rb->db->baton, child_baton));
-          child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
-          child_db->baton = child_baton;
-          child_db->depth = rb->db->depth + 1;
-          child_db->relpath = apr_pstrdup(rb->pool, nb->path);
-          child_db->parent = rb->db;
-          rb->db = child_db;
+          push_directory(rb, child_baton, nb->path, TRUE /*is_added*/,
+                         nb->copyfrom_path, nb->copyfrom_rev);
           break;
         default:
           break;
@@ -707,12 +757,8 @@ new_node_record(void **node_baton,
           SVN_ERR(commit_editor->open_directory(nb->path, rb->db->baton,
                                                 rb->rev - rb->rev_offset - 1,
                                                 rb->pool, &child_baton));
-          child_db = apr_pcalloc(rb->pool, sizeof(*child_db));
-          child_db->baton = child_baton;
-          child_db->depth = rb->db->depth + 1;
-          child_db->relpath = apr_pstrdup(rb->pool, nb->path);
-          child_db->parent = rb->db;
-          rb->db = child_db;
+          push_directory(rb, child_baton, nb->path, FALSE /*is_added*/,
+                         NULL, SVN_INVALID_REVNUM);
           break;
         }
       break;
@@ -763,8 +809,8 @@ set_node_property(void *baton,
                   const svn_string_t *value)
 {
   struct node_baton *nb = baton;
-  const struct svn_delta_editor_t *commit_editor = nb->rb->pb->commit_editor;
   apr_pool_t *pool = nb->rb->pool;
+  svn_prop_t *prop;
 
   if (value && strcmp(name, SVN_PROP_MERGEINFO) == 0)
     {
@@ -814,21 +860,11 @@ set_node_property(void *baton,
 
   SVN_ERR(svn_repos__validate_prop(name, value, pool));
 
-  switch (nb->kind)
-    {
-    case svn_node_file:
-      LDR_DBG(("Applying properties on %p\n", nb->file_baton));
-      SVN_ERR(commit_editor->change_file_prop(nb->file_baton, name,
-                                              value, pool));
-      break;
-    case svn_node_dir:
-      LDR_DBG(("Applying properties on %p\n", nb->rb->db->baton));
-      SVN_ERR(commit_editor->change_dir_prop(nb->rb->db->baton, name,
-                                             value, pool));
-      break;
-    default:
-      break;
-    }
+  prop = apr_palloc(nb->rb->pool, sizeof (*prop));
+  prop->name = apr_pstrdup(pool, name);
+  prop->value = value ? svn_string_dup(value, pool) : NULL;
+  apr_hash_set(nb->prop_changes, prop->name, APR_HASH_KEY_STRING, prop);
+
   return SVN_NO_ERROR;
 }
 
@@ -837,44 +873,84 @@ delete_node_property(void *baton,
                      const char *name)
 {
   struct node_baton *nb = baton;
-  const struct svn_delta_editor_t *commit_editor = nb->rb->pb->commit_editor;
   apr_pool_t *pool = nb->rb->pool;
+  svn_prop_t *prop;
 
   SVN_ERR(svn_repos__validate_prop(name, NULL, pool));
 
-  if (nb->kind == svn_node_file)
-    SVN_ERR(commit_editor->change_file_prop(nb->file_baton, name,
-                                            NULL, pool));
-  else
-    SVN_ERR(commit_editor->change_dir_prop(nb->rb->db->baton, name,
-                                           NULL, pool));
+  prop = apr_palloc(pool, sizeof (*prop));
+  prop->name = apr_pstrdup(pool, name);
+  prop->value = NULL;
+  apr_hash_set(nb->prop_changes, prop->name, APR_HASH_KEY_STRING, prop);
 
   return SVN_NO_ERROR;
 }
 
+/* Delete all the properties of the node, if any.
+ *
+ * The commit editor doesn't have a method to delete a node's properties
+ * without knowing what they are, so we have to first find out what
+ * properties the node would have had. If it's copied (explicitly or
+ * implicitly), we look at the copy source. If it's only being changed,
+ * we look at the node's current path in the head revision.
+ */
 static svn_error_t *
 remove_node_props(void *baton)
 {
   struct node_baton *nb = baton;
+  struct revision_baton *rb = nb->rb;
   apr_pool_t *pool = nb->rb->pool;
   apr_hash_index_t *hi;
   apr_hash_t *props;
+  const char *orig_path;
+  svn_revnum_t orig_rev;
+
+  /* Find the path and revision that has the node's original properties */
+  if (ARE_VALID_COPY_ARGS(nb->copyfrom_path, nb->copyfrom_rev))
+    {
+      LDR_DBG(("using nb->copyfrom  %s@%ld", nb->copyfrom_path, nb->copyfrom_rev));
+      orig_path = nb->copyfrom_path;
+      orig_rev = nb->copyfrom_rev;
+    }
+  else if (!nb->is_added
+           && ARE_VALID_COPY_ARGS(rb->db->copyfrom_path, rb->db->copyfrom_rev))
+    {
+      /* If this is a dir, then it's described by rb->db;
+         if this is a file, then it's a child of the dir in rb->db. */
+      LDR_DBG(("using rb->db->copyfrom (k=%d) %s@%ld",
+                 nb->kind, rb->db->copyfrom_path, rb->db->copyfrom_rev));
+      orig_path = (nb->kind == svn_node_dir)
+                    ? rb->db->copyfrom_path
+                    : svn_relpath_join(rb->db->copyfrom_path,
+                                       svn_relpath_basename(nb->path, NULL),
+                                       rb->pool);
+      orig_rev = rb->db->copyfrom_rev;
+    }
+  else
+    {
+      LDR_DBG(("using self.path@head  %s@%ld", nb->path, SVN_INVALID_REVNUM));
+      /* ### Should we query at a known, fixed, "head" revision number
+         instead of passing SVN_INVALID_REVNUM and getting a moving target? */
+      orig_path = nb->path;
+      orig_rev = SVN_INVALID_REVNUM;
+    }
+  LDR_DBG(("Trying %s@%ld", orig_path, orig_rev));
 
   if ((nb->action == svn_node_action_add
             || nb->action == svn_node_action_replace)
-      && ! SVN_IS_VALID_REVNUM(nb->copyfrom_rev))
+      && ! ARE_VALID_COPY_ARGS(orig_path, orig_rev))
     /* Add-without-history; no "old" properties to worry about. */
     return SVN_NO_ERROR;
 
   if (nb->kind == svn_node_file)
     {
-      SVN_ERR(svn_ra_get_file(nb->rb->pb->aux_session, nb->path,
-                              SVN_INVALID_REVNUM, NULL, NULL, &props, pool));
+      SVN_ERR(svn_ra_get_file(nb->rb->pb->aux_session,
+                              orig_path, orig_rev, NULL, NULL, &props, pool));
     }
   else  /* nb->kind == svn_node_dir */
     {
       SVN_ERR(svn_ra_get_dir2(nb->rb->pb->aux_session, NULL, NULL, &props,
-                              nb->path, SVN_INVALID_REVNUM, 0, pool));
+                              orig_path, orig_rev, 0, pool));
     }
 
   for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
@@ -928,6 +1004,29 @@ close_node(void *baton)
 {
   struct node_baton *nb = baton;
   const struct svn_delta_editor_t *commit_editor = nb->rb->pb->commit_editor;
+  apr_pool_t *pool = nb->rb->pool;
+  apr_hash_index_t *hi;
+
+  for (hi = apr_hash_first(pool, nb->prop_changes);
+       hi; hi = apr_hash_next(hi))
+    {
+      const char *name = svn__apr_hash_index_key(hi);
+      svn_prop_t *prop = svn__apr_hash_index_val(hi);
+
+      switch (nb->kind)
+        {
+        case svn_node_file:
+          SVN_ERR(commit_editor->change_file_prop(nb->file_baton,
+                                                  name, prop->value, pool));
+          break;
+        case svn_node_dir:
+          SVN_ERR(commit_editor->change_dir_prop(nb->rb->db->baton,
+                                                 name, prop->value, pool));
+          break;
+        default:
+          break;
+        }
+    }
 
   /* Pass a file node closure through to the editor *unless* we
      deleted the file (which doesn't require us to open it). */

Modified: subversion/branches/1.7.x-r1542765/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/svnserve/serve.c?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/svnserve/serve.c (original)
+++ subversion/branches/1.7.x-r1542765/subversion/svnserve/serve.c Sat Jul 25 21:43:57 2015
@@ -2266,9 +2266,30 @@ static svn_error_t *get_location_segment
 
   abs_path = svn_fspath__join(b->fs_path->data, relative_path, pool);
 
-  if (SVN_IS_VALID_REVNUM(start_rev)
-      && SVN_IS_VALID_REVNUM(end_rev)
-      && (end_rev > start_rev))
+  SVN_ERR(trivial_auth_request(conn, pool, b));
+  SVN_ERR(log_command(baton, conn, pool, "%s",
+                      svn_log__get_location_segments(abs_path, peg_revision,
+                                                     start_rev, end_rev,
+                                                     pool)));
+
+  /* No START_REV or PEG_REVISION?  We'll use HEAD. */
+  if (!SVN_IS_VALID_REVNUM(start_rev) || !SVN_IS_VALID_REVNUM(peg_revision))
+    {
+      svn_revnum_t youngest;
+
+      SVN_CMD_ERR(svn_fs_youngest_rev(&youngest, b->fs, pool));
+
+      if (!SVN_IS_VALID_REVNUM(start_rev))
+        start_rev = youngest;
+      if (!SVN_IS_VALID_REVNUM(peg_revision))
+        peg_revision = youngest;
+    }
+
+  /* No END_REV?  We'll use 0. */
+  if (!SVN_IS_VALID_REVNUM(end_rev))
+    end_rev = 0;
+
+  if (end_rev > start_rev)
     {
       err = svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
                               "Get-location-segments end revision must not be "
@@ -2276,9 +2297,7 @@ static svn_error_t *get_location_segment
       return log_fail_and_flush(err, b, conn, pool);
     }
 
-  if (SVN_IS_VALID_REVNUM(peg_revision)
-      && SVN_IS_VALID_REVNUM(start_rev)
-      && (start_rev > peg_revision))
+  if (start_rev > peg_revision)
     {
       err = svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
                               "Get-location-segments start revision must not "
@@ -2286,12 +2305,6 @@ static svn_error_t *get_location_segment
       return log_fail_and_flush(err, b, conn, pool);
     }
 
-  SVN_ERR(trivial_auth_request(conn, pool, b));
-  SVN_ERR(log_command(baton, conn, pool, "%s",
-                      svn_log__get_location_segments(abs_path, peg_revision,
-                                                     start_rev, end_rev,
-                                                     pool)));
-
   /* All the parameters are fine - let's perform the query against the
    * repository. */
 

Modified: subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/checkout_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/checkout_tests.py?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/checkout_tests.py (original)
+++ subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/checkout_tests.py Sat Jul 25 21:43:57 2015
@@ -27,6 +27,7 @@
 
 # General modules
 import sys, re, os, time, subprocess
+import datetime
 
 # Our testing module
 import svntest
@@ -658,11 +659,28 @@ def checkout_peg_rev_date(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  # note the current time to use it as peg revision date.
-  current_time = time.strftime("%Y-%m-%dT%H:%M:%S")
-
-  # sleep till the next second.
-  time.sleep(1.1)
+  ## Get svn:date.
+  exit_code, output, errput = svntest.main.run_svn(None, 'propget', 'svn:date',
+                                                   '--revprop', '-r1',
+                                                   '--strict',
+                                                   sbox.repo_url)
+  if exit_code or errput != [] or len(output) != 1:
+    raise svntest.Failure("svn:date propget failed")
+  r1_string = output[0]
+
+  ## Increment the svn:date date by one microsecond.
+  # TODO: pass tzinfo=UTC to datetime.datetime()
+  date_pattern = re.compile(r'(\d+)-(\d+)-(\d+)T(\d\d):(\d\d):(\d\d)\.(\d+)Z$')
+  r1_time = datetime.datetime(*map(int, date_pattern.match(r1_string).groups()))
+  peg_time = r1_time + datetime.timedelta(microseconds=1)
+  assert r1_time != peg_time
+  # peg_string is, by all likelihood, younger than r1's svn:date and older than
+  # r2's svn:date.  It is also not equal to either of them, so we test the
+  # binary search of svn:date values.
+  peg_string = '%04d-%02d-%02dT%02d:%02d:%02d.%06dZ' % \
+               tuple(getattr(peg_time, x)
+                     for x in ["year", "month", "day", "hour", "minute",
+                               "second", "microsecond"])
 
   # create a new revision
   mu_path = os.path.join(wc_dir, 'A', 'mu')
@@ -671,7 +689,7 @@ def checkout_peg_rev_date(sbox):
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'ci', '-m', 'changed file mu', wc_dir)
 
-  # now checkout the repo@current_time in another folder, this should create our
+  # now checkout the repo@peg_string in another folder, this should create our
   # initial wc without the change in mu.
   checkout_target = sbox.add_wc_path('checkout')
   os.mkdir(checkout_target)
@@ -684,7 +702,24 @@ def checkout_peg_rev_date(sbox):
 
   # use an old date to checkout, that way we're sure we get the first revision
   svntest.actions.run_and_verify_checkout(sbox.repo_url +
-                                          '@{' + current_time + '}',
+                                          '@{' + peg_string + '}',
+                                          checkout_target,
+                                          expected_output,
+                                          expected_wc)
+
+  # now try another checkout with repo@r1_string 
+  checkout_target = sbox.add_wc_path('checkout2')
+  os.mkdir(checkout_target)
+
+  expected_output = svntest.main.greek_state.copy()
+  expected_output.wc_dir = checkout_target
+  expected_output.tweak(status='A ', contents=None)
+
+  expected_wc = svntest.main.greek_state.copy()
+
+  # use an old date to checkout, that way we're sure we get the first revision
+  svntest.actions.run_and_verify_checkout(sbox.repo_url +
+                                          '@{' + r1_string + '}',
                                           checkout_target,
                                           expected_output,
                                           expected_wc)

Modified: subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/commit_tests.py?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/commit_tests.py Sat Jul 25 21:43:57 2015
@@ -2877,6 +2877,58 @@ def commit_add_subadd(sbox):
   svntest.main.run_svn(None, 'commit', '--targets', targets_file, '-mm')
 
 
+@Issue(4480)
+def commit_mergeinfo_ood(sbox):
+  "commit of mergeinfo that should cause out of date"
+
+  sbox.build()
+  sbox.simple_rm('A', 'iota')
+  sbox.simple_commit() # r2
+
+  sbox.simple_mkdir('trunk', 'branch')
+  sbox.simple_commit() # r3
+
+  sbox.simple_append('trunk/a', 'This is a\n')
+  sbox.simple_add('trunk/a')
+  sbox.simple_commit() # r4
+
+  sbox.simple_append('trunk/b', 'This is b\n')
+  sbox.simple_add('trunk/b')
+  sbox.simple_commit() # r5
+
+  sbox.simple_update() # To r5
+
+  expected_output = [
+    '--- Merging r4 into \'%s\':\n' % sbox.ospath('branch'),
+    'A    %s\n' % sbox.ospath('branch/a'),
+    '--- Recording mergeinfo for merge of r4' \
+                                ' into \'%s\':\n' % sbox.ospath('branch'),
+    ' U   %s\n' % sbox.ospath('branch'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge', '-c4', '^/trunk',
+                                     sbox.ospath('branch'))
+
+  sbox.simple_commit()
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'update', '-r5', sbox.wc_dir)
+
+  expected_output = [
+    '--- Merging r5 into \'%s\':\n' % sbox.ospath('branch'),
+    'A    %s\n' % sbox.ospath('branch/b'),
+    '--- Recording mergeinfo for merge of r5 into \'%s\':\n' % sbox.ospath('branch'),
+    ' U   %s\n' % sbox.ospath('branch'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge', '-c5', '^/trunk',
+                                     sbox.ospath('branch'))
+
+  # Currently this commit succeeds with dav over HTTPv2, while it should really fail
+  expected_err = '.*out of date.*'
+  svntest.actions.run_and_verify_svn(None, None, expected_err,
+                                     'commit', sbox.ospath(''), '-m', 'M')
+
 ########################################################################
 # Run the tests
 
@@ -2946,6 +2998,7 @@ test_list = [ None,
               commit_multiple_nested_deletes,
               commit_incomplete,
               commit_add_subadd,
+              commit_mergeinfo_ood,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/copy_tests.py?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/copy_tests.py Sat Jul 25 21:43:57 2015
@@ -5476,6 +5476,18 @@ def copy_deleted_dir(sbox):
                                      'cp', sbox.ospath('A/D'),
                                      sbox.ospath('new_D'))
 
+def resurrect_at_root(sbox):
+   "resurrect directory at root"
+   sbox.build(create_wc=False)
+
+   svntest.actions.run_and_verify_svn(None, None, [], 'rm',
+                                      sbox.repo_url + '/A',
+                                      '-m', '')
+
+   svntest.actions.run_and_verify_svn(None, None, [], 'cp',
+                                      sbox.repo_url + '/A/D/H@1',
+                                      sbox.repo_url + '/A', '-m', '')
+
 ########################################################################
 # Run the tests
 
@@ -5586,6 +5598,7 @@ test_list = [ None,
               case_only_rename,
               copy_and_move_conflicts,
               copy_deleted_dir,
+              resurrect_at_root,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/davautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/davautocheck.sh?rev=1692665&r1=1692664&r2=1692665&view=diff
==============================================================================
--- subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/davautocheck.sh (original)
+++ subversion/branches/1.7.x-r1542765/subversion/tests/cmdline/davautocheck.sh Sat Jul 25 21:43:57 2015
@@ -309,9 +309,17 @@ User                $(id -un)
 Group               $(id -gn)
 __EOF__
 else
+HTTPD_LOCK="$HTTPD_ROOT/lock"
+mkdir "$HTTPD_LOCK" \
+  || fail "couldn't create lock directory '$HTTPD_LOCK'"
   cat >> "$HTTPD_CFG" <<__EOF__
-# TODO: maybe uncomment this for prefork,worker MPMs only?
-# Mutex file:lock mpm-accept
+# worker and prefork MUST have a mpm-accept lockfile in 2.3.0+
+<IfModule worker.c>
+  Mutex "file:$HTTPD_LOCK" mpm-accept
+</IfModule>
+<IfModule prefork.c>
+  Mutex "file:$HTTPD_LOCK" mpm-accept
+</IfModule>
 __EOF__
 fi
 



Mime
View raw message