]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Fix mod_rewrite "B" flag breakage by reverting r589343
authorNick Kew <niq@apache.org>
Wed, 31 Dec 2008 00:08:00 +0000 (00:08 +0000)
committerNick Kew <niq@apache.org>
Wed, 31 Dec 2008 00:08:00 +0000 (00:08 +0000)
PR#45529

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@730274 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/mappers/mod_rewrite.c

diff --git a/CHANGES b/CHANGES
index 580a2ead29a2b9fa9ca353db44600d8a94c9253c..1a057604c808a972b5b6687d8dc5310546b7d548 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,9 @@
 Changes with Apache 2.3.1
 [ When backported to 2.2.x, remove entry from this file ]
 
+ *) mod_rewrite: fix "B" flag breakage by reverting r5589343
+    PR 45529 [Bob Ionescu <bobsiegen googlemail.com>]
+
  *) CGI: return 504 (Gateway timeout) rather than 500 when a script
     times out before returning status line/headers.
     PR 42190 [Nick Kew]
index 96209d9b8c354e232ee9961d03bde0646582e517..a92c256b90f23cee0fc7074191ee930bee5fc078 100644 (file)
@@ -389,6 +389,7 @@ static apr_global_mutex_t *rewrite_log_lock = NULL;
 /* 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);
 
 /*
  * +-------------------------------------------------------+
@@ -658,6 +659,46 @@ static unsigned is_absolute_uri(char *uri)
     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.
@@ -2363,15 +2404,16 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
                 if (entry && (entry->flags & RULEFLAG_ESCAPEBACKREF)) {
                     /* escape the backreference */
                     char *tmp2, *tmp;
-                    tmp = apr_pstrndup(pool, bri->source + bri->regmatch[n].rm_so, span);
-                    tmp2 = ap_escape_path_segment(pool, 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);
                     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;
                 }