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__':