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 2017/05/14 20:22:49 UTC
svn commit: r1795116 - in /subversion/trunk/subversion: libsvn_fs_fs/tree.c
libsvn_fs_x/dag_cache.c tests/libsvn_fs/fs-test.c
Author: stefan2
Date: Sun May 14 20:22:49 2017
New Revision: 1795116
URL: http://svn.apache.org/viewvc?rev=1795116&view=rev
Log:
Fix issue #4677.
When non-exitent paths are allowed as a result of a DAG-walk
(as opposed to creating a "path not found" error on those),
we may encounter file nodes in the "parent" path. Those are
not an error but simply an indication that there won't be any
sub-paths.
* subversion/libsvn_fs_fs/tree.c
(open_path): If n/a paths are allowed, non-dir parents are, too.
* subversion/libsvn_fs_x/dag_cache.c
(svn_fs_x__get_dag_path): Same.
* subversion/tests/libsvn_fs/fs-test.c
(closest_copy_test_svn_4677): Add regression test.
(test_funcs): Register new test.
Modified:
subversion/trunk/subversion/libsvn_fs_fs/tree.c
subversion/trunk/subversion/libsvn_fs_x/dag_cache.c
subversion/trunk/subversion/tests/libsvn_fs/fs-test.c
Modified: subversion/trunk/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/tree.c?rev=1795116&r1=1795115&r2=1795116&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/tree.c Sun May 14 20:22:49 2017
@@ -1143,8 +1143,20 @@ open_path(parent_path_t **parent_path_p,
/* The path isn't finished yet; we'd better be in a directory. */
if (svn_fs_fs__dag_node_kind(child) != svn_node_dir)
- SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far->data),
- apr_psprintf(iterpool, _("Failure opening '%s'"), path));
+ {
+ /* Since this is not a directory and we are looking for some
+ sub-path, that sub-path will not exist. That will be o.k.,
+ if we are just here to check for the path's existence. */
+ if (flags & open_path_allow_null)
+ {
+ parent_path = NULL;
+ break;
+ }
+
+ /* It's really a problem ... */
+ SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far->data),
+ apr_psprintf(iterpool, _("Failure opening '%s'"), path));
+ }
rest = next;
here = child;
Modified: subversion/trunk/subversion/libsvn_fs_x/dag_cache.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/dag_cache.c?rev=1795116&r1=1795115&r2=1795116&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/dag_cache.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/dag_cache.c Sun May 14 20:22:49 2017
@@ -890,6 +890,16 @@ svn_fs_x__get_dag_path(svn_fs_x__dag_pat
{
svn_pool_clear(iterpool);
+ /* If the current node is not a directory and we are just here to
+ * check for the path's existence, then that's o.k.
+ * Otherwise, non-dir nodes will cause an error in dag_step. */
+ if ( (flags & svn_fs_x__dag_path_allow_null)
+ && (svn_fs_x__dag_node_kind(dag_path->node) != svn_node_dir))
+ {
+ dag_path = NULL;
+ break;
+ }
+
/* Find the sub-node. */
SVN_ERR(dag_step(&here, root, dag_path->node, entry, &path, change_set,
TRUE, iterpool));
Modified: subversion/trunk/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs/fs-test.c?rev=1795116&r1=1795115&r2=1795116&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs/fs-test.c Sun May 14 20:22:49 2017
@@ -7317,6 +7317,58 @@ test_rep_sharing_strict_content_check(co
return SVN_NO_ERROR;
}
+static svn_error_t *
+closest_copy_test_svn_4677(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root, *rev_root, *croot;
+ svn_revnum_t after_rev;
+ const char *cpath;
+ apr_pool_t *spool = svn_pool_create(pool);
+
+ /* Prepare a filesystem. */
+ SVN_ERR(svn_test__create_fs(&fs, "test-repo-svn-4677",
+ opts, pool));
+
+ /* In first txn, create file A/foo. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, spool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, spool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "A", spool));
+ SVN_ERR(svn_fs_make_file(txn_root, "A/foo", spool));
+ SVN_ERR(test_commit_txn(&after_rev, txn, NULL, spool));
+ svn_pool_clear(spool);
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, spool));
+
+ /* Move A to B, and commit. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, spool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, spool));
+ SVN_ERR(svn_fs_copy(rev_root, "A", txn_root, "B", spool));
+ SVN_ERR(svn_fs_delete(txn_root, "A", spool));
+ SVN_ERR(test_commit_txn(&after_rev, txn, NULL, spool));
+ svn_pool_clear(spool);
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, spool));
+
+ /* Replace file B/foo with directory B/foo, add B/foo/bar, and commit. */
+ SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, spool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, spool));
+ SVN_ERR(svn_fs_delete(txn_root, "B/foo", spool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "B/foo", spool));
+ SVN_ERR(svn_fs_make_file(txn_root, "B/foo/bar", spool));
+ SVN_ERR(test_commit_txn(&after_rev, txn, NULL, spool));
+ svn_pool_clear(spool);
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, spool));
+
+ /* B/foo/bar has been copied.
+ Issue 4677 was caused by returning an error in this situation. */
+ SVN_ERR(svn_fs_closest_copy(&croot, &cpath, rev_root, "B/foo/bar", spool));
+ SVN_TEST_ASSERT(cpath == NULL);
+ SVN_TEST_ASSERT(croot == NULL);
+
+ return SVN_NO_ERROR;
+}
+
/* ------------------------------------------------------------------------ */
/* The test table. */
@@ -7459,6 +7511,8 @@ static struct svn_test_descriptor_t test
"test clearing the cache while streaming a rep"),
SVN_TEST_OPTS_PASS(test_rep_sharing_strict_content_check,
"test rep-sharing on content rather than SHA1"),
+ SVN_TEST_OPTS_PASS(closest_copy_test_svn_4677,
+ "test issue SVN-4677 regression"),
SVN_TEST_NULL
};