You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by sv...@apache.org on 2012/07/01 06:01:30 UTC
svn commit: r1355849 - in /subversion/branches/1.7.x: ./ STATUS
subversion/libsvn_repos/replay.c subversion/tests/cmdline/README
subversion/tests/cmdline/svnsync_tests.py
subversion/tests/cmdline/svntest/sandbox.py
Author: svn-role
Date: Sun Jul 1 04:01:29 2012
New Revision: 1355849
URL: http://svn.apache.org/viewvc?rev=1355849&view=rev
Log:
Merge the r1293945 group from trunk:
* r1293945, r1293972, r1293976, r1293998, r1294136, r1294236;
r1294134, r1294147, r1294586
Two interdependent changes:
Fix issue #4121: copy followed by delete of unreadable child.
Fix svn:// authz in Python tests.
Justification:
User resorted to patching the commit editor to work around this.
Tests are broken.
Notes:
r1293945,r1293972,r1293976 are cosmetics.
r1293998 is the fix.
r1294136 is a test.
r1294236 fixes an uninitialized variable.
Notes:
r1294134 extends a test to demonstrate its brokenness.
r1294147 fixes said brokenness.
r1294586 fixes r1294147 for Windows.
Votes:
+1: danielsh, stsp, rhuijben
Modified:
subversion/branches/1.7.x/ (props changed)
subversion/branches/1.7.x/STATUS
subversion/branches/1.7.x/subversion/libsvn_repos/replay.c
subversion/branches/1.7.x/subversion/tests/cmdline/README
subversion/branches/1.7.x/subversion/tests/cmdline/svnsync_tests.py
subversion/branches/1.7.x/subversion/tests/cmdline/svntest/sandbox.py
Propchange: subversion/branches/1.7.x/
------------------------------------------------------------------------------
Merged /subversion/trunk:r1293945,1293972,1293976,1293998,1294134,1294136,1294147,1294236,1294586
Modified: subversion/branches/1.7.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1355849&r1=1355848&r2=1355849&view=diff
==============================================================================
--- subversion/branches/1.7.x/STATUS (original)
+++ subversion/branches/1.7.x/STATUS Sun Jul 1 04:01:29 2012
@@ -104,23 +104,3 @@ Veto-blocked changes:
Approved changes:
=================
-
- * r1293945, r1293972, r1293976, r1293998, r1294136, r1294236;
- r1294134, r1294147, r1294586
- Two interdependent changes:
- Fix issue #4121: copy followed by delete of unreadable child.
- Fix svn:// authz in Python tests.
- Justification:
- User resorted to patching the commit editor to work around this.
- Tests are broken.
- Notes:
- r1293945,r1293972,r1293976 are cosmetics.
- r1293998 is the fix.
- r1294136 is a test.
- r1294236 fixes an uninitialized variable.
- Notes:
- r1294134 extends a test to demonstrate its brokenness.
- r1294147 fixes said brokenness.
- r1294586 fixes r1294147 for Windows.
- Votes:
- +1: danielsh, stsp, rhuijben
Modified: subversion/branches/1.7.x/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_repos/replay.c?rev=1355849&r1=1355848&r2=1355849&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_repos/replay.c Sun Jul 1 04:01:29 2012
@@ -352,6 +352,116 @@ is_within_base_path(const char *path, co
return FALSE;
}
+/* Given PATH deleted under ROOT, return in READABLE whether the path was
+ readable prior to the deletion. Consult COPIES (a stack of 'struct
+ copy_info') and AUTHZ_READ_FUNC. */
+static svn_error_t *
+was_readable(svn_boolean_t *readable,
+ svn_fs_root_t *root,
+ const char *path,
+ apr_array_header_t *copies,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_fs_root_t *inquire_root;
+ const char *inquire_path;
+ struct copy_info *info = NULL;
+ const char *relpath;
+
+ /* Short circuit. */
+ if (! authz_read_func)
+ {
+ *readable = TRUE;
+ return SVN_NO_ERROR;
+ }
+
+ if (copies->nelts != 0)
+ info = &APR_ARRAY_IDX(copies, copies->nelts - 1, struct copy_info);
+
+ /* Are we under a copy? */
+ if (info && (relpath = svn_relpath_skip_ancestor(info->path, path)))
+ {
+ SVN_ERR(svn_fs_revision_root(&inquire_root, svn_fs_root_fs(root),
+ info->copyfrom_rev, scratch_pool));
+ inquire_path = svn_fspath__join(info->copyfrom_path, relpath,
+ scratch_pool);
+ }
+ else
+ {
+ /* Compute the revision that ROOT is based on. (Note that ROOT is not
+ r0's root, since this function is only called for deletions.)
+ ### Need a more succinct way to express this */
+ svn_revnum_t inquire_rev = SVN_INVALID_REVNUM;
+ if (svn_fs_is_txn_root(root))
+ inquire_rev = svn_fs_txn_root_base_revision(root);
+ if (svn_fs_is_revision_root(root))
+ inquire_rev = svn_fs_revision_root_revision(root)-1;
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(inquire_rev));
+
+ SVN_ERR(svn_fs_revision_root(&inquire_root, svn_fs_root_fs(root),
+ inquire_rev, scratch_pool));
+ inquire_path = path;
+ }
+
+ SVN_ERR(authz_read_func(readable, inquire_root, inquire_path,
+ authz_read_baton, result_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Initialize COPYFROM_ROOT, COPYFROM_PATH, and COPYFROM_REV with the
+ revision root, fspath, and revnum of the copyfrom of CHANGE, which
+ corresponds to PATH under ROOT. If the copyfrom info is valid
+ (i.e., is not (NULL, SVN_INVALID_REVNUM)), then initialize SRC_READABLE
+ too, consulting AUTHZ_READ_FUNC and AUTHZ_READ_BATON if provided. */
+static svn_error_t *
+fill_copyfrom(svn_fs_root_t **copyfrom_root,
+ const char **copyfrom_path,
+ svn_revnum_t *copyfrom_rev,
+ svn_boolean_t *src_readable,
+ svn_fs_root_t *root,
+ svn_fs_path_change2_t *change,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ const char *path,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ if (! change->copyfrom_known)
+ {
+ SVN_ERR(svn_fs_copied_from(&(change->copyfrom_rev),
+ &(change->copyfrom_path),
+ root, path, result_pool));
+ change->copyfrom_known = TRUE;
+ }
+ *copyfrom_rev = change->copyfrom_rev;
+ *copyfrom_path = change->copyfrom_path;
+
+ if (*copyfrom_path && SVN_IS_VALID_REVNUM(*copyfrom_rev))
+ {
+ SVN_ERR(svn_fs_revision_root(copyfrom_root,
+ svn_fs_root_fs(root),
+ *copyfrom_rev, result_pool));
+
+ if (authz_read_func)
+ {
+ SVN_ERR(authz_read_func(src_readable, *copyfrom_root,
+ *copyfrom_path,
+ authz_read_baton, result_pool));
+ }
+ else
+ *src_readable = TRUE;
+ }
+ else
+ {
+ *copyfrom_root = NULL;
+ /* SRC_READABLE left uninitialized */
+ }
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
path_driver_cb_func(void **dir_baton,
void *parent_baton,
@@ -368,7 +478,6 @@ path_driver_cb_func(void **dir_baton,
void *file_baton = NULL;
svn_revnum_t copyfrom_rev;
const char *copyfrom_path;
- svn_boolean_t src_readable = TRUE;
svn_fs_root_t *source_root = cb->compare_root;
const char *source_fspath = NULL;
const char *base_path = cb->base_path;
@@ -419,8 +528,18 @@ path_driver_cb_func(void **dir_baton,
/* Handle any deletions. */
if (do_delete)
- SVN_ERR(editor->delete_entry(edit_path, SVN_INVALID_REVNUM,
- parent_baton, pool));
+ {
+ svn_boolean_t readable;
+
+ /* Issue #4121: delete under under a copy, of a path that was unreadable
+ at its pre-copy location. */
+ SVN_ERR(was_readable(&readable, root, edit_path, cb->copies,
+ cb->authz_read_func, cb->authz_read_baton,
+ pool, pool));
+ if (readable)
+ SVN_ERR(editor->delete_entry(edit_path, SVN_INVALID_REVNUM,
+ parent_baton, pool));
+ }
/* Fetch the node kind if it makes sense to do so. */
if (! do_delete || do_add)
@@ -437,31 +556,14 @@ path_driver_cb_func(void **dir_baton,
/* Handle any adds/opens. */
if (do_add)
{
- svn_fs_root_t *copyfrom_root = NULL;
- /* Was this node copied? */
- if (! change->copyfrom_known)
- {
- SVN_ERR(svn_fs_copied_from(&(change->copyfrom_rev),
- &(change->copyfrom_path),
- root, edit_path, pool));
- change->copyfrom_known = TRUE;
- }
- copyfrom_rev = change->copyfrom_rev;
- copyfrom_path = change->copyfrom_path;
+ svn_boolean_t src_readable;
+ svn_fs_root_t *copyfrom_root;
- if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_rev))
- {
- SVN_ERR(svn_fs_revision_root(©from_root,
- svn_fs_root_fs(root),
- copyfrom_rev, pool));
-
- if (cb->authz_read_func)
- {
- SVN_ERR(cb->authz_read_func(&src_readable, copyfrom_root,
- copyfrom_path,
- cb->authz_read_baton, pool));
- }
- }
+ /* Was this node copied? */
+ SVN_ERR(fill_copyfrom(©from_root, ©from_path, ©from_rev,
+ &src_readable, root, change,
+ cb->authz_read_func, cb->authz_read_baton,
+ edit_path, pool, pool));
/* If we have a copyfrom path, and we can't read it or we're just
ignoring it, or the copyfrom rev is prior to the low water mark
Modified: subversion/branches/1.7.x/subversion/tests/cmdline/README
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/tests/cmdline/README?rev=1355849&r1=1355848&r2=1355849&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/tests/cmdline/README (original)
+++ subversion/branches/1.7.x/subversion/tests/cmdline/README Sun Jul 1 04:01:29 2012
@@ -333,7 +333,8 @@ svntest/tree.py. It will explain the ge
Finally, try copying-and-pasting a simple test and then edit from
there. Don't forget to add your test to the 'test_list' variable at
-the bottom of the file.
+the bottom of the file. To avoid renumbering of existing tests, you
+should add new tests to the end of the list.
Testing Compatability With Previous Release
Modified: subversion/branches/1.7.x/subversion/tests/cmdline/svnsync_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/tests/cmdline/svnsync_tests.py?rev=1355849&r1=1355848&r2=1355849&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/tests/cmdline/svnsync_tests.py (original)
+++ subversion/branches/1.7.x/subversion/tests/cmdline/svnsync_tests.py Sun Jul 1 04:01:29 2012
@@ -394,25 +394,32 @@ def basic_authz(sbox):
run_init(dest_sbox.repo_url, sbox.repo_url)
+ args = map(lambda x: x.authz_name(), [sbox, sbox, dest_sbox])
svntest.main.file_write(sbox.authz_file,
- "[svnsync-basic-authz:/]\n"
+ "[%s:/]\n"
"* = r\n"
"\n"
- "[svnsync-basic-authz:/A/B]\n"
+ "[%s:/A/B]\n"
"* = \n"
"\n"
- "[svnsync-basic-authz-1:/]\n"
- "* = rw\n")
+ "[%s:/]\n"
+ "* = rw\n" % tuple(args))
run_sync(dest_sbox.repo_url)
lambda_url = dest_sbox.repo_url + '/A/B/lambda'
+ iota_url = dest_sbox.repo_url + '/iota'
# this file should have been blocked by authz
svntest.actions.run_and_verify_svn(None,
[], svntest.verify.AnyOutput,
'cat',
lambda_url)
+ # this file should have been synced
+ svntest.actions.run_and_verify_svn(None,
+ svntest.verify.AnyOutput, [],
+ 'cat',
+ iota_url)
#----------------------------------------------------------------------
@Skip(svntest.main.is_ra_type_file)
@@ -465,29 +472,17 @@ def copy_from_unreadable_dir(sbox):
svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
- fp = open(sbox.authz_file, 'w')
-
- # For mod_dav_svn's parent path setup we need per-repos permissions in
- # the authz file...
- if sbox.repo_url.startswith('http'):
- fp.write("[svnsync-copy-from-unreadable-dir:/]\n" +
- "* = r\n" +
- "\n" +
- "[svnsync-copy-from-unreadable-dir:/A/B]\n" +
- "* = \n" +
- "\n" +
- "[svnsync-copy-from-unreadable-dir-1:/]\n" +
- "* = rw")
-
- # Otherwise we can just go with the permissions needed for the source
- # repository.
- else:
- fp.write("[/]\n" +
- "* = r\n" +
- "\n" +
- "[/A/B]\n" +
- "* =\n")
- fp.close()
+ args = map(lambda x: x.authz_name(), [sbox, sbox, dest_sbox])
+ open(sbox.authz_file, 'w').write(
+ "[%s:/]\n"
+ "* = r\n"
+ "\n"
+ "[%s:/A/B]\n"
+ "* = \n"
+ "\n"
+ "[%s:/]\n"
+ "* = rw"
+ % tuple(args))
run_init(dest_sbox.repo_url, sbox.repo_url)
@@ -591,29 +586,17 @@ def copy_with_mod_from_unreadable_dir(sb
svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
- fp = open(sbox.authz_file, 'w')
-
- # For mod_dav_svn's parent path setup we need per-repos permissions in
- # the authz file...
- if sbox.repo_url.startswith('http'):
- fp.write("[svnsync-copy-with-mod-from-unreadable-dir:/]\n" +
- "* = r\n" +
- "\n" +
- "[svnsync-copy-with-mod-from-unreadable-dir:/A/B]\n" +
- "* = \n" +
- "\n" +
- "[svnsync-copy-with-mod-from-unreadable-dir-1:/]\n" +
- "* = rw")
-
- # Otherwise we can just go with the permissions needed for the source
- # repository.
- else:
- fp.write("[/]\n" +
- "* = r\n" +
- "\n" +
- "[/A/B]\n" +
- "* =\n")
- fp.close()
+ args = map(lambda x: x.authz_name(), [sbox, sbox, dest_sbox])
+ open(sbox.authz_file, 'w').write(
+ "[%s:/]\n"
+ "* = r\n"
+ "\n"
+ "[%s:/A/B]\n"
+ "* = \n"
+ "\n"
+ "[%s:/]\n"
+ "* = rw"
+ % tuple(args))
run_init(dest_sbox.repo_url, sbox.repo_url)
@@ -695,29 +678,17 @@ def copy_with_mod_from_unreadable_dir_an
svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
- fp = open(sbox.authz_file, 'w')
-
- # For mod_dav_svn's parent path setup we need per-repos permissions in
- # the authz file...
- if sbox.repo_url.startswith('http'):
- fp.write("[svnsync-copy-with-mod-from-unreadable-dir-and-copy:/]\n" +
- "* = r\n" +
- "\n" +
- "[svnsync-copy-with-mod-from-unreadable-dir-and-copy:/A/B]\n" +
- "* = \n" +
- "\n" +
- "[svnsync-copy-with-mod-from-unreadable-dir-and-copy-1:/]\n" +
- "* = rw")
-
- # Otherwise we can just go with the permissions needed for the source
- # repository.
- else:
- fp.write("[/]\n" +
- "* = r\n" +
- "\n" +
- "[/A/B]\n" +
- "* =\n")
- fp.close()
+ args = map(lambda x: x.authz_name(), [sbox, sbox, dest_sbox])
+ open(sbox.authz_file, 'w').write(
+ "[%s:/]\n"
+ "* = r\n"
+ "\n"
+ "[%s:/A/B]\n"
+ "* = \n"
+ "\n"
+ "[%s:/]\n"
+ "* = rw"
+ % tuple(args))
run_init(dest_sbox.repo_url, sbox.repo_url)
@@ -1021,6 +992,46 @@ def fd_leak_sync_from_serf_to_local(sbox
import resource
resource.setrlimit(resource.RLIMIT_NOFILE, (128, 128))
run_test(sbox, "largemods.dump", is_src_ra_local=None, is_dest_ra_local=True)
+@Issue(4121)
+@Skip(svntest.main.is_ra_type_file)
+def copy_delete_unreadable_child(sbox):
+ "copy, then rm at-src-unreadable child"
+
+ ## Prepare the source: Greek tree (r1), cp+rm (r2).
+ sbox.build("copy-delete-unreadable-child")
+ svntest.actions.run_and_verify_svnmucc(None, None, [],
+ '-m', 'r2',
+ '-U', sbox.repo_url,
+ 'cp', 'HEAD', '/', 'branch',
+ 'rm', 'branch/A')
+
+ ## Create the destination.
+ dest_sbox = sbox.clone_dependent()
+ build_repos(dest_sbox)
+ svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
+
+ ## Lock down the source.
+ args = map(lambda x: x.authz_name(), [sbox, sbox])
+ write_restrictive_svnserve_conf(sbox.repo_dir, anon_access='read')
+ svntest.main.file_write(sbox.authz_file,
+ "[%s:/]\n"
+ "* = r\n"
+ "[%s:/A]\n"
+ "* = \n"
+ % tuple(args)
+ )
+
+ dest_url = svntest.main.file_scheme_prefix \
+ + svntest.main.pathname2url(os.path.abspath(dest_sbox.repo_dir))
+ run_init(dest_url, sbox.repo_url)
+ run_sync(dest_url)
+
+ # sanity check
+ svntest.actions.run_and_verify_svn(None,
+ ["iota\n"], [],
+ 'ls', dest_url+'/branch@2')
+
+
########################################################################
# Run the tests
@@ -1062,6 +1073,7 @@ test_list = [ None,
descend_into_replace,
delete_revprops,
fd_leak_sync_from_serf_to_local,
+ copy_delete_unreadable_child,
]
serial_only = True
Modified: subversion/branches/1.7.x/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/tests/cmdline/svntest/sandbox.py?rev=1355849&r1=1355848&r2=1355849&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/1.7.x/subversion/tests/cmdline/svntest/sandbox.py Sun Jul 1 04:01:29 2012
@@ -101,6 +101,14 @@ class Sandbox:
svntest.actions.make_repo_and_wc(self, create_wc, read_only)
self._is_built = True
+ def authz_name(self, repo_dir=None):
+ "return this sandbox's name for use in an authz file"
+ repo_dir = repo_dir or self.repo_dir
+ if self.repo_url.startswith("http"):
+ return os.path.basename(repo_dir)
+ else:
+ return repo_dir.replace('\\', '/')
+
def add_test_path(self, path, remove=True):
self.test_paths.append(path)
if remove: