You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/08/23 13:27:00 UTC

svn commit: r988076 - in /subversion/trunk/subversion: libsvn_client/merge.c svn/merge-cmd.c tests/cmdline/input_validation_tests.py

Author: stsp
Date: Mon Aug 23 11:27:00 2010
New Revision: 988076

URL: http://svn.apache.org/viewvc?rev=988076&view=rev
Log:
As part of work on issue #3620, improve input validation in 'svn merge'.

* subversion/libsvn_client/merge.c
  (do_merge, merge_locked, merge_peg_locked): Make sure that the merge
   target exists, and require either two paths or two URLs as merge sources.

* subversion/tests/cmdline/input_validation_tests.py
  (invalid_merge_args, test_list): New test.

* subversion/svn/merge-cmd.c
  (svn_cl__merge): Require either two paths or two URLs as merge sources.

Modified:
    subversion/trunk/subversion/libsvn_client/merge.c
    subversion/trunk/subversion/svn/merge-cmd.c
    subversion/trunk/subversion/tests/cmdline/input_validation_tests.py

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=988076&r1=988075&r2=988076&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Mon Aug 23 11:27:00 2010
@@ -8316,6 +8316,11 @@ do_merge(apr_hash_t **modified_subtrees,
 
   SVN_ERR(svn_wc_read_kind(&target_kind, ctx->wc_ctx, target_abspath, FALSE,
                            pool));
+  if (target_kind != svn_node_dir && target_kind != svn_node_file)
+    return svn_error_return(svn_error_createf(
+                              SVN_ERR_ILLEGAL_TARGET, NULL,
+                              _("Merge target '%s' does not exist in the "
+                                "working copy"), target_abspath));
 
   /* Ensure a known depth. */
   if (depth == svn_depth_unknown)
@@ -8693,12 +8698,18 @@ merge_locked(const char *source1,
   apr_pool_t *sesspool;
   svn_boolean_t same_repos;
   const char *source_repos_uuid1, *source_repos_uuid2;
+  svn_node_kind_t target_kind;
 
-  /* Sanity check our input -- we require specified revisions. */
+  /* Sanity check our input -- we require specified revisions,
+   * and either 2 paths or 2 URLs. */
   if ((revision1->kind == svn_opt_revision_unspecified)
       || (revision2->kind == svn_opt_revision_unspecified))
     return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL,
                             _("Not all required revisions are specified"));
+  if (svn_path_is_url(source1) != svn_path_is_url(source2))
+    return svn_error_return(svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                             _("Merge sources must both be "
+                                               "either paths or URLs")));
 
   /* ### FIXME: This function really ought to do a history check on
      the left and right sides of the merge source, and -- if one is an
@@ -8726,6 +8737,14 @@ merge_locked(const char *source1,
                              _("'%s' has no URL"),
                              svn_dirent_local_style(source2, scratch_pool));
 
+  SVN_ERR(svn_wc_read_kind(&target_kind, ctx->wc_ctx, target_abspath, FALSE,
+                           scratch_pool));
+  if (target_kind != svn_node_dir && target_kind != svn_node_file)
+    return svn_error_return(svn_error_createf(
+                              SVN_ERR_ILLEGAL_TARGET, NULL,
+                              _("Merge target '%s' does not exist in the "
+                                "working copy"), target_abspath));
+
   /* Determine the working copy target's repository root URL. */
   working_rev.kind = svn_opt_revision_working;
   SVN_ERR(svn_client__get_repos_root(&wc_repos_root, target_abspath,
@@ -10216,6 +10235,7 @@ merge_peg_locked(const char *source,
   svn_boolean_t use_sleep = FALSE;
   svn_error_t *err;
   svn_boolean_t same_repos;
+  svn_node_kind_t target_kind;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(target_abspath));
 
@@ -10227,6 +10247,14 @@ merge_peg_locked(const char *source,
                              _("'%s' has no URL"),
                              svn_dirent_local_style(source, scratch_pool));
 
+  SVN_ERR(svn_wc_read_kind(&target_kind, ctx->wc_ctx, target_abspath, FALSE,
+                           scratch_pool));
+  if (target_kind != svn_node_dir && target_kind != svn_node_file)
+    return svn_error_return(svn_error_createf(
+                              SVN_ERR_ILLEGAL_TARGET, NULL,
+                              _("Merge target '%s' does not exist in the "
+                                "working copy"), target_abspath));
+
   /* Determine the working copy target's repository root URL. */
   working_rev.kind = svn_opt_revision_working;
   SVN_ERR(svn_client__get_repos_root(&wc_repos_root, target_abspath,

Modified: subversion/trunk/subversion/svn/merge-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/merge-cmd.c?rev=988076&r1=988075&r2=988076&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/merge-cmd.c (original)
+++ subversion/trunk/subversion/svn/merge-cmd.c Mon Aug 23 11:27:00 2010
@@ -337,6 +337,11 @@ svn_cl__merge(apr_getopt_t *os,
     }
   else
     {
+      if (svn_path_is_url(sourcepath1) != svn_path_is_url(sourcepath2))
+        return svn_error_return(svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR,
+                                                 NULL,
+                                                 _("Merge sources must both be "
+                                                   "either paths or URLs")));
       err = svn_client_merge3(sourcepath1,
                               &first_range_start,
                               sourcepath2,

Modified: subversion/trunk/subversion/tests/cmdline/input_validation_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/input_validation_tests.py?rev=988076&r1=988075&r2=988076&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/input_validation_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/input_validation_tests.py Mon Aug 23 11:27:00 2010
@@ -149,6 +149,26 @@ def invalid_log_targets(sbox):
                              "specified after a URL for 'svn log', but.*is " +
                              "not a relative path", 'log', target1, target2)
 
+def invalid_merge_args(sbox):
+  "invalid arguments for 'merge'"
+  sbox.build(read_only=True)
+  run_and_verify_svn_in_wc(sbox, "svn: A working copy merge source needs "
+                           "an explicit revision", 'merge', 'iota', '^/')
+  for (src, target) in [('iota@HEAD', '^/'), ('iota@BASE', 'file://')]:
+    run_and_verify_svn_in_wc(sbox, "svn: Merge sources must both be either "
+                             "paths or URLs", 'merge', src, target)
+  run_and_verify_svn_in_wc(sbox, "svn: Merge target.*does not exist in " +
+                           "the working copy",
+                           'merge', 'iota@BASE', 'iota@HEAD', 'nonexistent')
+  run_and_verify_svn_in_wc(sbox, "svn: Too many arguments given",
+                          'merge', '-c42', '^/A/B', '^/A/C', 'iota')
+  run_and_verify_svn_in_wc(sbox, "svn: Cannot specify a revision range with" +
+                           " two URLs", 'merge', '-c42', '^/mu', '^/')
+  run_and_verify_svn_in_wc(sbox, "svn: Merge target.*does not exist in " +
+                           "the working copy",
+                           'merge', '-c42', '^/mu', 'nonexistent')
+
+
 ########################################################################
 # Run the tests
 
@@ -165,6 +185,7 @@ test_list = [ None,
               invalid_export_targets,
               invalid_import_args,
               invalid_log_targets,
+              invalid_merge_args,
              ]
 
 if __name__ == '__main__':