httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cove...@apache.org
Subject svn commit: r1584417 - in /httpd/httpd/trunk: docs/manual/rewrite/flags.xml modules/mappers/mod_rewrite.c
Date Thu, 03 Apr 2014 21:53:14 GMT
Author: covener
Date: Thu Apr  3 21:53:14 2014
New Revision: 1584417

URL: http://svn.apache.org/r1584417
Log:
allow users to workaround the over-agressive backreference
escaping by selecting the characters to escape. 


Modified:
    httpd/httpd/trunk/docs/manual/rewrite/flags.xml
    httpd/httpd/trunk/modules/mappers/mod_rewrite.c

Modified: httpd/httpd/trunk/docs/manual/rewrite/flags.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/rewrite/flags.xml?rev=1584417&r1=1584416&r2=1584417&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/rewrite/flags.xml (original)
+++ httpd/httpd/trunk/docs/manual/rewrite/flags.xml Thu Apr  3 21:53:14 2014
@@ -67,8 +67,9 @@ of how you might use them.</p>
 <section id="flag_b"><title>B (escape backreferences)</title>
 <p>The [B] flag instructs <directive
 module="mod_rewrite">RewriteRule</directive> to escape non-alphanumeric
-characters before applying the transformation.
-</p>
+characters before applying the transformation.</p>
+<p>In 2.4.10 and later, you can limit the escaping to specific characters 
+in backreferences by listing them: <code>[B=#?;]</code> </p>
 
 <p><code>mod_rewrite</code> has to unescape URLs before mapping them,
 so backreferences are unescaped at the time they are applied.
@@ -95,6 +96,9 @@ returns a 404 if it sees one.</p>
 <p>This escaping is particularly necessary in a proxy situation,
 when the backend may break if presented with an unescaped URL.</p>
 
+<p>An alternative to this flag is using a <directive module="mod_rewrite"
+>RewriteCond</directive> to capture against %{THE_REQUEST} which will capture
+strings in the encoded form.</p>
 </section>
 
 <section id="flag_c"><title>C|chain</title>

Modified: httpd/httpd/trunk/modules/mappers/mod_rewrite.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/mappers/mod_rewrite.c?rev=1584417&r1=1584416&r2=1584417&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/mappers/mod_rewrite.c (original)
+++ httpd/httpd/trunk/modules/mappers/mod_rewrite.c Thu Apr  3 21:53:14 2014
@@ -319,6 +319,7 @@ typedef struct {
     data_item *cookie;               /* added cookies                         */
     int        skip;                 /* number of next rules to skip          */
     int        maxrounds;            /* limit on number of loops with N flag  */
+    char       *escapes;             /* specific backref escapes              */
 } rewriterule_entry;
 
 typedef struct {
@@ -419,7 +420,7 @@ static const char *rewritemap_mutex_type
 /* 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);
+static char *escape_uri(apr_pool_t *p, const char *path, const char *escapeme);
 
 /*
  * +-------------------------------------------------------+
@@ -631,21 +632,36 @@ static APR_INLINE unsigned char *c2x(uns
  * 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) {
+static char *escape_uri(apr_pool_t *p, const char *path, const char *escapeme) {
     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++ = '+';
+        if (!escapeme) { 
+            if (apr_isalnum(c) || c == '_') {
+                *d++ = c;
+            }
+            else if (c == ' ') {
+                *d++ = '+';
+            }
+            else {
+                d = c2x(c, '%', d);
+            }
         }
-        else {
-            d = c2x(c, '%', d);
+        else { 
+            const char *esc = escapeme;
+            while (*esc) { 
+                if (c == *esc) { 
+                    d = c2x(c, '%', d);
+                    break;
+                }
+                ++esc;
+            }
+            if (!*esc) { 
+                *d++ = c;
+            }
         }
         ++s;
     }
@@ -2368,7 +2384,7 @@ static char *do_expand(char *input, rewr
                     /* escape the backreference */
                     char *tmp2, *tmp;
                     tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so,
span);
-                    tmp2 = escape_uri(pool, tmp);
+                    tmp2 = escape_uri(pool, tmp, entry->escapes);
                     rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s'
to '%s'",
                             tmp, tmp2));
 
@@ -3415,6 +3431,9 @@ static const char *cmd_rewriterule_setfl
     case 'B':
         if (!*key || !strcasecmp(key, "ackrefescaping")) {
             cfg->flags |= RULEFLAG_ESCAPEBACKREF;
+            if (val && *val) { 
+                cfg->escapes = val;
+            }
         }
         else {
             ++error;



Mime
View raw message