]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Backport r730274
authorNick Kew <niq@apache.org>
Thu, 8 Jan 2009 01:13:36 +0000 (01:13 +0000)
committerNick Kew <niq@apache.org>
Thu, 8 Jan 2009 01:13:36 +0000 (01:13 +0000)
Fix mod_rewrite "B" flag breakage
PR 45529

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@732578 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
modules/mappers/mod_rewrite.c

diff --git a/CHANGES b/CHANGES
index 85da92c82d626600dde31d36d52ee08749685e0f..9e2bf58574223c5b97f205eb7c214ad6e85207d4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.2.12
 
+  *) mod_rewrite: fix "B" flag breakage by reverting r589343
+     PR 45529 [Bob Ionescu <bobsiegen googlemail.com>]
+
   *) mod_cgid: fix segfault problem on solaris.
      PR 39332 [Masaoki Kobayashi <masaoki techfirm.co.jp>, Jeff Trawick]
 
diff --git a/STATUS b/STATUS
index e985cb9d0b7b8373b25ef89a216f6df5f1e84509..6529e0aa56b1e886d6217606843a3458e6932d60 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -102,11 +102,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
         http://people.apache.org/~niq/patches/25202
     +1: niq, rpluem, covener
 
-  * mod_rewrite: fix "B" flag breakage by reverting r5589343
-    PR 45529
-    http://svn.apache.org/viewvc?view=rev&revision=730274
-    +1: niq, rpluem, covener
-
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
   [ New proposals should be added at the end of the list ]
 
index 863d69e101157bb8a5bb63e3879e5a87c6bf7d6f..ec631bc1c4a66357f771cc00a9c10f2cb69c1a8b 100644 (file)
@@ -380,6 +380,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);
 
 /*
  * +-------------------------------------------------------+
@@ -628,6 +629,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.
@@ -2240,15 +2281,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;
                 }