Author: jpeck
Date: Wed Jul 8 20:42:08 2026
New Revision: 1936013
Log:
Fix HTTP requests against <Location> paths with escapable characters.
This isn't really part of the mod_dav_svn proxy fixes, but this fix is
required to test the fix in 1936011. HTTPv2 commits failed with a 400
Bad Request against any mod_dav_svn repository whose <Location> path
contains a URI-escapable character.
get_resource() expects its ROOT_PATH argument in the decoded domain: it
strips it from the decoded r->uri (ap_stripprefix) and re-encodes it
for href output itself. mod_dav's own method dispatch passes its
per-dir config, which is decoded, which is why plain DAV methods
(GET, PROPFIND, OPTIONS) always worked. But three mod_dav_svn-internal
callers passed dav_svn__get_root_dir(), which is stored canonical and
URI-encoded. Under "/svn repo", stripping "/svn%20repo" from
"/svn repo/!svn/me" fails, the URI parses as an ordinary repository
path, and dav_svn__method_post() bogusly rejects the transaction-
creation POST. The same mismatch garbled the %f log path in
translate_name and made the SVNListParentPath root comparison never
match.
The domain contract, now honored by all in-tree callers: anything
comparing the stored root dir against r->uri must decode it first,
anything building client-visible URIs from it uses it as-is.
Regression-tested, updated tests coming in follow up commit
* subversion/mod_dav_svn/repos.c
(dav_svn__method_post): Decode the stored root dir before handing it
to get_resource().
* subversion/mod_dav_svn/mod_dav_svn.c
(dav_svn__translate_name): Likewise for dav_svn_split_uri().
* subversion/mod_dav_svn/util.c
(dav_svn__is_parentpath_list): Decode before comparing against r->uri.
Modified:
subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/mod_dav_svn.c
subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/repos.c
subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/util.c
Modified:
subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/mod_dav_svn.c
==============================================================================
---
subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/mod_dav_svn.c
Wed Jul 8 20:32:27 2026 (r1936012)
+++
subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/mod_dav_svn.c
Wed Jul 8 20:42:08 2026 (r1936013)
@@ -1236,8 +1236,12 @@ static int dav_svn__translate_name(reque
}
else
{
- /* Retrieve path to repo and within repo for the request */
- dav_error *err = dav_svn_split_uri(r, r->uri, dav_svn__get_root_dir(r),
+ /* Retrieve path to repo and within repo for the request.
+ dav_svn_split_uri() strips the root from the decoded r->uri, so
+ hand it the decoded form of the (encoded, canonical) root dir. */
+ const char *root_dir_decoded =
+ svn_path_uri_decode(dav_svn__get_root_dir(r), r->pool);
+ dav_error *err = dav_svn_split_uri(r, r->uri, root_dir_decoded,
&ignore_cleaned_uri,
&ignore_had_slash, &repos_basename,
&ignore_relative_path, &repos_path);
Modified: subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/repos.c
==============================================================================
--- subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/repos.c
Wed Jul 8 20:32:27 2026 (r1936012)
+++ subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/repos.c
Wed Jul 8 20:42:08 2026 (r1936013)
@@ -4955,9 +4955,16 @@ int dav_svn__method_post(request_rec *r)
dav_resource *resource;
dav_error *derr;
const char *content_type;
+ const char *root_dir_decoded;
- /* We only allow POSTs against the "me resource" right now. */
- derr = get_resource(r, dav_svn__get_root_dir(r),
+ /* We only allow POSTs against the "me resource" right now.
+ get_resource() expects ROOT_PATH in the decoded domain, it strips
+ it from the (decoded) r->uri and re-encodes it for href output
+ itself, but dav_svn__get_root_dir() is stored canonical and
+ URI-encoded. Decode it or the strip fails for any <Location>
+ containing a URI-escapable character. */
+ root_dir_decoded = svn_path_uri_decode(dav_svn__get_root_dir(r), r->pool);
+ derr = get_resource(r, root_dir_decoded,
"ignored", 0, &resource);
if (derr != NULL)
return derr->status;
Modified: subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/util.c
==============================================================================
--- subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/util.c
Wed Jul 8 20:32:27 2026 (r1936012)
+++ subversion/branches/proxy-move-copy-fix/subversion/mod_dav_svn/util.c
Wed Jul 8 20:42:08 2026 (r1936013)
@@ -434,7 +434,10 @@ dav_svn__is_parentpath_list(request_rec
if (fs_parent_path && dav_svn__get_list_parentpath_flag(r))
{
- const char *root_path = dav_svn__get_root_dir(r);
+ /* r->uri is decoded, but the stored root dir is canonical and
+ URI-encoded, decode it so the comparison is like-with-like. */
+ const char *root_path =
+ svn_path_uri_decode(dav_svn__get_root_dir(r), r->pool);
char *uri = apr_pstrdup(r->pool, r->uri);
char *parentpath = apr_pstrdup(r->pool, root_path);
apr_size_t uri_len = strlen(uri);