Index: include/httpd.h
===================================================================
--- include/httpd.h	(revision 587183)
+++ include/httpd.h	(working copy)
@@ -1480,6 +1480,18 @@
 #define ap_escape_uri(ppool,path) ap_os_escape_path(ppool,path,1)
 
 /**
+ * Convert an unescaped URL to a query string.
+ * This function escapes the passed path in the following way:
+ * - If the character in the path is alphanumeric, it stays the same way, otherwise
+ * - if the character is a white space (' '), it is converted to '+', otherwise
+ * - it is converted to its hexadecimal form with a preceding %
+ * @param p The pool to allocate from
+ * @param path The path to convert
+ * @return The converted URL
+ */
+AP_DECLARE(char *) ap_escape_query_string(apr_pool_t *p, const char *path);
+
+/**
  * Escape an html string
  * @param p The pool to allocate from
  * @param s The html to escape
Index: modules/mappers/mod_rewrite.c
===================================================================
--- modules/mappers/mod_rewrite.c	(revision 587183)
+++ modules/mappers/mod_rewrite.c	(working copy)
@@ -386,7 +386,6 @@
 /* Optional functions imported from mod_ssl when loaded: */
 static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL;
 static APR_OPTIONAL_FN_TYPE(ssl_is_https) *rewrite_is_https = NULL;
-static char *escape_uri(apr_pool_t *p, const char *path);
 
 /*
  * +-------------------------------------------------------+
@@ -639,47 +638,7 @@
     return 0;
 }
 
-static const char c2x_table[] = "0123456789abcdef";
-
-static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix,
-                                     unsigned char *where)
-{
-#if APR_CHARSET_EBCDIC
-    what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what);
-#endif /*APR_CHARSET_EBCDIC*/
-    *where++ = prefix;
-    *where++ = c2x_table[what >> 4];
-    *where++ = c2x_table[what & 0xf];
-    return where;
-}
-
 /*
- * Escapes a uri in a similar way as php's urlencode does.
- * Based on ap_os_escape_path in server/util.c
- */
-static char *escape_uri(apr_pool_t *p, const char *path) {
-    char *copy = apr_palloc(p, 3 * strlen(path) + 3);
-    const unsigned char *s = (const unsigned char *)path;
-    unsigned char *d = (unsigned char *)copy;
-    unsigned c;
-
-    while ((c = *s)) {
-        if (apr_isalnum(c) || c == '_') {
-            *d++ = c;
-        }
-        else if (c == ' ') {
-            *d++ = '+';
-        }
-        else {
-            d = c2x(c, '%', d);
-        }
-        ++s;
-    }
-    *d = '\0';
-    return copy;
-}
-
-/*
  * escape absolute uri, which may or may not be path oriented.
  * So let's handle them differently.
  */
@@ -2369,16 +2328,15 @@
                 if (entry && (entry->flags & RULEFLAG_ESCAPEBACKREF)) {
                     /* escape the backreference */
                     char *tmp2, *tmp;
-                    tmp = apr_palloc(pool, span + 1);
-                    strncpy(tmp, bri->source + bri->regmatch[n].rm_so, span);
-                    tmp[span] = '\0';
-                    tmp2 = escape_uri(pool, tmp);
+                    tmp = apr_pstrndup(pool, bri->source + bri->regmatch[n].rm_so, span);
+                    tmp2 = ap_escape_query_string(pool, tmp);
                     rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
                             tmp, tmp2));
 
                     current->len = span = strlen(tmp2);
                     current->string = tmp2;
-                } else {
+                }
+                else {
                     current->len = span;
                     current->string = bri->source + bri->regmatch[n].rm_so;
                 }
Index: server/util.c
===================================================================
--- server/util.c	(revision 587183)
+++ server/util.c	(working copy)
@@ -1734,6 +1734,28 @@
 
 /* ap_escape_uri is now a macro for os_escape_path */
 
+AP_DECLARE(char *) ap_escape_query_string(apr_pool_t *p, const char *path) {
+    char *copy = apr_palloc(p, 3 * strlen(path) + 3);
+    const unsigned char *s = (const unsigned char *)path;
+    unsigned char *d = (unsigned char *)copy;
+    unsigned c;
+
+    while ((c = *s)) {
+        if (apr_isalnum(c) || c == '_') {
+            *d++ = c;
+        }
+        else if (c == ' ') {
+            *d++ = '+';
+        }
+        else {
+            d = c2x(c, '%', d);
+        }
+        ++s;
+    }
+    *d = '\0';
+    return copy;
+}
+
 AP_DECLARE(char *) ap_escape_html(apr_pool_t *p, const char *s)
 {
     int i, j;
