]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Restore functionality broken by the mod_rewrite security fix:
authorTony Finch <fanf@apache.org>
Wed, 18 Oct 2000 04:50:25 +0000 (04:50 +0000)
committerTony Finch <fanf@apache.org>
Wed, 18 Oct 2000 04:50:25 +0000 (04:50 +0000)
rewrite map lookup keys and default values are now expanded
so that the lookup can depend on the requested URI etc.

Because the new code is recursive you can now write configurations
like the following (with nested map lookups) which wasn't directly
possible before -- you had to use a RewriteCond and a %N backref
instead, as in http://www.apache.org/docs/vhosts/mass.html#xtra-conf

RewriteMap tolower int:tolower
RewriteMap host2user txt:/home/www/conf/virtusertbl
RewriteRule /(.*) /home/${host2user:${tolower:%{HTTP_HOST}}|www}/public_html

PR: 6671

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

modules/mappers/mod_rewrite.c
modules/mappers/mod_rewrite.h

index 4ff21fa69d0fb19c1f016503d3b069472135848a..a5e48940ecddfe337b50da7f23fa186c4c4bc39a 100644 (file)
@@ -2320,30 +2320,50 @@ static void do_expand(request_rec *r, char *input, char *buffer, int nbuf,
        /* now we have a '$' or a '%' */
        if (inp[1] == '{') {
            char *endp;
-           endp = strchr(inp, '}');
+           endp = find_closing_bracket(inp+2, '{', '}');
            if (endp == NULL) {
                goto skip;
            }
            *endp = '\0';
            if (inp[0] == '$') {
                /* ${...} map lookup expansion */
+               /*
+                * To make rewrite maps useful the lookup key and
+                * default values must be expanded, so we make
+                * recursive calls to do the work. For security
+                * reasons we must never expand a string that includes
+                * verbatim data from the network. The recursion here
+                * isn't a problem because the result of expansion is
+                * only passed to lookup_map() so it cannot be
+                * re-expanded, only re-looked-up. Another way of
+                * looking at it is that the recursion is entirely
+                * driven by the syntax of the nested curly brackets.
+                */
                char *key, *dflt, *result;
+               char xkey[MAX_STRING_LEN];
+               char xdflt[MAX_STRING_LEN];
+               char *empty = "";
                key = strchr(inp, ':');
                if (key == NULL) {
                    goto skip;
                }
                *key++ = '\0';
                dflt = strchr(key, '|');
-               if (dflt) {
+               if (dflt == NULL) {
+                   dflt = empty;
+               }
+               else
                    *dflt++ = '\0';
                }
-               result = lookup_map(r, inp+2, key);
+               do_expand(r, key,  xkey,  sizeof(xkey),  briRR, briRC);
+               do_expand(r, dflt, xdflt, sizeof(xdflt), briRR, briRC);
+               result = lookup_map(r, inp+2, xkey);
                if (result == NULL) {
-                   result = dflt ? dflt : "";
+                   result = xdflt;
                }
                span = apr_cpystrn(outp, result, space) - outp;
                key[-1] = ':';
-               if (dflt) {
+               if (dflt != empty) {
                    dflt[-1] = '|';
                }
            }
@@ -4086,6 +4106,28 @@ static int compare_lexicography(char *cpNum1, char *cpNum2)
     return 0;
 }
 
+/*
+**
+**  Find end of bracketed expression
+**  s points after the opening bracket
+**
+*/
+
+static char *find_closing_bracket(char *s, int left, int right)
+{
+    int depth;
+
+    for (depth = 1; *s; ++s) {
+       if (*s == right && --depth == 0) {
+           return s;
+       }
+       else if (*s == left) {
+           ++depth;
+       }
+    }
+    return NULL;
+}
+
 #ifdef NETWARE
 int main(int argc, char *argv[]) 
 {
index ed497d7b6e85ffa40fbc0d8142209fd4caebf0db..d70f32fdc9a2faffa5467b7542f48bc00a39be04 100644 (file)
@@ -469,6 +469,9 @@ static int    subreq_ok(request_rec *r);
     /* Lexicographic Comparison */
 static int compare_lexicography(char *cpNum1, char *cpNum2);
 
+    /* Find end of bracketed expression */
+static char *find_closing_bracket(char *s, int left, int right);
+
 #endif /* _MOD_REWRITE_H */
 
 /*EOF*/