41a6c3
Index: modules/dav/fs/repos.c
41a6c3
===================================================================
41a6c3
--- a/modules/dav/fs/repos.c	(revision 1533447)
41a6c3
+++ b/modules/dav/fs/repos.c	(revision 1533448)
41a6c3
@@ -717,13 +717,13 @@
41a6c3
     resource->pool = r->pool;
41a6c3
 
41a6c3
     /* make sure the URI does not have a trailing "/" */
41a6c3
-    len = strlen(r->uri);
41a6c3
-    if (len > 1 && r->uri[len - 1] == '/') {
41a6c3
-        s = apr_pstrmemdup(r->pool, r->uri, len-1);
41a6c3
+    len = strlen(r->unparsed_uri);
41a6c3
+    if (len > 1 && r->unparsed_uri[len - 1] == '/') {
41a6c3
+        s = apr_pstrmemdup(r->pool, r->unparsed_uri, len-1);
41a6c3
         resource->uri = s;
41a6c3
     }
41a6c3
     else {
41a6c3
-        resource->uri = r->uri;
41a6c3
+        resource->uri = r->unparsed_uri;
41a6c3
     }
41a6c3
 
41a6c3
     if (r->finfo.filetype != APR_NOFILE) {
41a6c3
@@ -1482,6 +1482,18 @@
41a6c3
     return dav_fs_deleteset(info->pool, resource);
41a6c3
 }
41a6c3
 
41a6c3
+/* Take an unescaped path component and escape it and append it onto a
41a6c3
+ * dav_buffer for a URI */
41a6c3
+static apr_size_t dav_fs_append_uri(apr_pool_t *p, dav_buffer *pbuf,
41a6c3
+                                    const char *path, apr_size_t pad)
41a6c3
+{
41a6c3
+    const char *epath = ap_escape_uri(p, path);
41a6c3
+    apr_size_t epath_len = strlen(epath);
41a6c3
+
41a6c3
+    dav_buffer_place_mem(p, pbuf, epath, epath_len + 1, pad);
41a6c3
+    return epath_len;
41a6c3
+}
41a6c3
+
41a6c3
 /* ### move this to dav_util? */
41a6c3
 /* Walk recursively down through directories, *
41a6c3
  * including lock-null resources as we go.    */
41a6c3
@@ -1537,6 +1549,7 @@
41a6c3
     }
41a6c3
     while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) {
41a6c3
         apr_size_t len;
41a6c3
+        apr_size_t escaped_len;
41a6c3
 
41a6c3
         len = strlen(dirent.name);
41a6c3
 
41a6c3
@@ -1579,7 +1592,7 @@
41a6c3
 
41a6c3
         /* copy the file to the URI, too. NOTE: we will pad an extra byte
41a6c3
            for the trailing slash later. */
41a6c3
-        dav_buffer_place_mem(pool, &fsctx->uri_buf, dirent.name, len + 1, 1);
41a6c3
+        escaped_len = dav_fs_append_uri(pool, &fsctx->uri_buf, dirent.name, 1);
41a6c3
 
41a6c3
         /* if there is a secondary path, then do that, too */
41a6c3
         if (fsctx->path2.buf != NULL) {
41a6c3
@@ -1612,7 +1625,7 @@
41a6c3
             fsctx->path2.cur_len += len;
41a6c3
 
41a6c3
             /* adjust URI length to incorporate subdir and a slash */
41a6c3
-            fsctx->uri_buf.cur_len += len + 1;
41a6c3
+            fsctx->uri_buf.cur_len += escaped_len + 1;
41a6c3
             fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/';
41a6c3
             fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0';
41a6c3
 
41a6c3
@@ -1678,8 +1691,8 @@
41a6c3
             */
41a6c3
             dav_buffer_place_mem(pool, &fsctx->path1,
41a6c3
                                  fsctx->locknull_buf.buf + offset, len + 1, 0);
41a6c3
-            dav_buffer_place_mem(pool, &fsctx->uri_buf,
41a6c3
-                                 fsctx->locknull_buf.buf + offset, len + 1, 0);
41a6c3
+            dav_fs_append_uri(pool, &fsctx->uri_buf,
41a6c3
+                              fsctx->locknull_buf.buf + offset, 0);
41a6c3
             if (fsctx->path2.buf != NULL) {
41a6c3
                 dav_buffer_place_mem(pool, &fsctx->path2,
41a6c3
                                      fsctx->locknull_buf.buf + offset,
41a6c3
Index: modules/dav/main/mod_dav.c
41a6c3
===================================================================
41a6c3
--- a/modules/dav/main/mod_dav.c	(revision 1533447)
41a6c3
+++ b/modules/dav/main/mod_dav.c	(revision 1533448)
41a6c3
@@ -396,11 +396,9 @@
41a6c3
  */
41a6c3
 static const char *dav_xml_escape_uri(apr_pool_t *p, const char *uri)
41a6c3
 {
41a6c3
-    const char *e_uri = ap_escape_uri(p, uri);
41a6c3
-
41a6c3
     /* check the easy case... */
41a6c3
-    if (ap_strchr_c(e_uri, '&') == NULL)
41a6c3
-        return e_uri;
41a6c3
+    if (ap_strchr_c(uri, '&') == NULL)
41a6c3
+        return uri;
41a6c3
 
41a6c3
     /* there was a '&', so more work is needed... sigh. */
41a6c3
 
41a6c3
@@ -408,7 +406,7 @@
41a6c3
      * Note: this is a teeny bit of overkill since we know there are no
41a6c3
      * '<' or '>' characters, but who cares.
41a6c3
      */
41a6c3
-    return apr_xml_quote_string(p, e_uri, 0);
41a6c3
+    return apr_xml_quote_string(p, uri, 0);
41a6c3
 }
41a6c3
 
41a6c3
 
41a6c3
@@ -604,7 +602,8 @@
41a6c3
     return DONE;
41a6c3
 }
41a6c3
 
41a6c3
-/* handy function for return values of methods that (may) create things */
41a6c3
+/* handy function for return values of methods that (may) create things.
41a6c3
+ * locn if provided is assumed to be escaped. */
41a6c3
 static int dav_created(request_rec *r, const char *locn, const char *what,
41a6c3
                        int replaced)
41a6c3
 {
41a6c3
@@ -612,8 +611,6 @@
41a6c3
 
41a6c3
     if (locn == NULL) {
41a6c3
         locn = r->unparsed_uri;
41a6c3
-    } else {
41a6c3
-        locn = ap_escape_uri(r->pool, locn);
41a6c3
     }
41a6c3
 
41a6c3
     /* did the target resource already exist? */
41a6c3
@@ -3004,7 +3001,7 @@
41a6c3
     }
41a6c3
 
41a6c3
     /* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */
41a6c3
-    return dav_created(r, lookup.rnew->uri, "Destination",
41a6c3
+    return dav_created(r, lookup.rnew->unparsed_uri, "Destination",
41a6c3
                        resnew_state == DAV_RESOURCE_EXISTS);
41a6c3
 }
41a6c3
 
41a6c3
@@ -4610,7 +4607,7 @@
41a6c3
 
41a6c3
     /* return an appropriate response (HTTP_CREATED) */
41a6c3
     /* ### spec doesn't say what happens when destination was replaced */
41a6c3
-    return dav_created(r, lookup.rnew->uri, "Binding", 0);
41a6c3
+    return dav_created(r, lookup.rnew->unparsed_uri, "Binding", 0);
41a6c3
 }
41a6c3
 
41a6c3
 
41a6c3
Index: modules/dav/main/mod_dav.h
41a6c3
===================================================================
41a6c3
--- a/modules/dav/main/mod_dav.h	(revision 1533447)
41a6c3
+++ b/modules/dav/main/mod_dav.h	(revision 1533448)
41a6c3
@@ -386,7 +386,7 @@
41a6c3
                          * REGULAR and WORKSPACE resources,
41a6c3
                          * and is always 1 for WORKING */
41a6c3
 
41a6c3
-    const char *uri;    /* the URI for this resource */
41a6c3
+    const char *uri;    /* the escaped URI for this resource */
41a6c3
 
41a6c3
     dav_resource_private *info;         /* the provider's private info */
41a6c3