Hi,
the fixes for issue 3242 ("Subversion demands unnecessary access
to parent directories of operations") currently in trunk do not address
scenario gicen below.

[[[
Fix another scenario related to issue #3242:

- user has no access in repo root, only in /project
- someone else renames some file below /project and commits
- user tries to update his working copy of /project
  (that still has the old name)
- update deletes the old name and then fails with
  "access to 'http://host/repo-root' forbidden"

* subversion/libsvn_client/update.c
  (file_fetcher): When opening an auxiliary session, don't open it at the
  repository root (where the user might not have read permission), but
  at the dirname of the file to fetch.
]]]


The first attached patch amends authz_tests.py with a test for the
above scenario,
the second patch is the actual fix.

Cheers, Roderich
Index: subversion/tests/cmdline/authz_tests.py
===================================================================
--- subversion/tests/cmdline/authz_tests.py	(revision 929632)
+++ subversion/tests/cmdline/authz_tests.py	(working copy)
@@ -903,7 +903,43 @@
                        root_url + '/A-copy/B/E/beta',
                        root_url + '/A-copy/C')
 
+def authz_access_required_at_repo_root2(sbox):
+  "more authz issue #3242 - update to renamed file"
 
+  sbox.build(create_wc = False)
+  root_url = sbox.repo_url
+
+  # Now we get all restrictive.
+  write_authz_file(sbox, {'/': '* =',
+                          '/A': 'jrandom = rw'})
+  write_restrictive_svnserve_conf(sbox.repo_dir)
+
+  # Rename a file.
+  svntest.main.run_svn(None, 'mv',
+                       '-m', 'rename file in readable writable space',
+                       root_url + '/A/B/E/alpha',
+                       root_url + '/A/B/E/alpha-renamed')
+  
+  # Check out original greek sub tree below /A/B/E 
+  # and update it to the above rename.
+  wc_dir = sbox.add_wc_path('ABE')
+  os.mkdir(wc_dir)
+  svntest.main.run_svn(None, 'co', '-r', '1', root_url + '/A/B/E', wc_dir)
+  svntest.main.run_svn(None, 'up', wc_dir)
+
+  # Rename a directory.
+  svntest.main.run_svn(None, 'mv',
+                       '-m', 'rename diretory in readable writable space',
+                       root_url + '/A/D/H',
+                       root_url + '/A/D/a g e')
+  
+  # Check out original greek sub tree below /A/D
+  # and update it to the above rename.
+  wc_dir = sbox.add_wc_path('AD')
+  os.mkdir(wc_dir)
+  svntest.main.run_svn(None, 'co', '-r', '1', root_url + '/A/D', wc_dir)
+  svntest.main.run_svn(None, 'up', wc_dir)
+
 def multiple_matches(sbox):
   "multiple lines matching a user"
 
@@ -962,6 +998,8 @@
                          svntest.main.is_ra_type_file)),
               Skip(authz_access_required_at_repo_root,
                    svntest.main.is_ra_type_file),
+              Skip(authz_access_required_at_repo_root2,
+                   svntest.main.is_ra_type_file),
               Skip(multiple_matches, svntest.main.is_ra_type_file),
              ]
 

Index: subversion/libsvn_client/update.c
===================================================================
--- subversion/libsvn_client/update.c	(revision 929632)
+++ subversion/libsvn_client/update.c	(working copy)
@@ -68,13 +68,22 @@
              apr_pool_t *pool)
 {
   struct ff_baton *ffb = (struct ff_baton *)baton;
+  const char *dirpath, *base_name, *session_url, *old_session_url;
 
-  if (! ffb->session)
-    SVN_ERR(svn_client__open_ra_session_internal(&(ffb->session),
-                                                 ffb->repos_root,
-                                                 NULL, NULL, FALSE, TRUE,
-                                                 ffb->ctx, ffb->pool));
-  return svn_ra_get_file(ffb->session, path, revision, stream,
+  svn_relpath_split(path, &dirpath, &base_name, ffb->pool);
+  session_url = svn_path_url_add_component2(ffb->repos_root, 
+                                            dirpath, ffb->pool);
+
+  if (ffb->session)
+      SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ffb->session,
+						session_url, ffb->pool));
+  else
+      SVN_ERR(svn_client__open_ra_session_internal(&(ffb->session),
+						   session_url,
+						   NULL, NULL, FALSE, TRUE,
+						   ffb->ctx, ffb->pool));
+
+  return svn_ra_get_file(ffb->session, base_name, revision, stream,
                          fetched_rev, props, pool);
 }
 

Reply via email to