You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by Tim Newsome <nu...@cmu.edu> on 1997/09/21 03:00:05 UTC

mod_alias/1155: RedirectMatch does not correctly deal with URLs which need to be escaped.

>Number:         1155
>Category:       mod_alias
>Synopsis:       RedirectMatch does not correctly deal with URLs which need to be escaped.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    apache (Apache HTTP Project)
>State:          open
>Class:          sw-bug
>Submitter-Id:   apache
>Arrival-Date:   Sat Sep 20 18:00:03 1997
>Originator:     nuisance@cmu.edu
>Organization:
apache
>Release:        1.3a1
>Environment:
Linux 2.0.30
gcc 2.7.2
redhat 4.2
>Description:
RedirectMatch will not escape URLs it directs to if they have spaces in them.
(Ie request for /data/cool%20file will be redirected to something like 
otherserver/cool file (note the space))
>How-To-Repeat:
This patch is pretty crude, and I'm sure it's buggy somewhere. Just ran my server
for a few hours (getting quite a lot of hits) and nothing shows up in the
error log, and it doesn't seem to leak.
>Fix:
diff -ur apache_1.3a1/src/httpd.h apache_1.3a1-patched/src/httpd.h
--- apache_1.3a1/src/httpd.h    Tue Jul 22 20:06:06 1997
+++ apache_1.3a1-patched/src/httpd.h    Sat Sep 20 17:55:13 1997
@@ -709,6 +709,7 @@
      
 API_EXPORT(int) is_url(const char *u);
 API_EXPORT(int) unescape_url(char *url);
+API_EXPORT(char *) escape_url(pool *p, const char *url);
 API_EXPORT(void) no2slash(char *name);
 API_EXPORT(void) getparents(char *name);
 API_EXPORT(char *) escape_path_segment(pool *p, const char *s);
diff -ur apache_1.3a1/src/mod_alias.c apache_1.3a1-patched/src/mod_alias.c
--- apache_1.3a1/src/mod_alias.c        Thu Jul 17 18:27:31 1997
+++ apache_1.3a1-patched/src/mod_alias.c        Sat Sep 20 18:03:41 1997
@@ -273,6 +273,7 @@
     alias_entry *entries = (alias_entry *)aliases->elts;
     regmatch_t regm[10];
     char *found = NULL;
+    char *temp = NULL;
     int i;
     
     for (i = 0; i < aliases->nelts; ++i) {
@@ -280,9 +281,17 @@
        int l;
 
        if (p->regexp) {
-           if (!regexec(p->regexp, r->uri, p->regexp->re_nsub+1, regm, 0))
-               found = pregsub(r->pool, p->real, r->uri,
-                               p->regexp->re_nsub+1, regm);
+           if (!regexec(p->regexp, r->uri, p->regexp->re_nsub+1, regm, 0)) {
+               temp = pregsub(r->pool, p->real, r->uri,
+                       p->regexp->re_nsub+1, regm);
+               if (doesc) {
+                   /*char *escurl;*/
+                   found = escape_url(r->pool, temp);
+                   /*fprintf(stderr, "Escaped %s\n", escurl);
+                   found = pstrcpy(r->pool, p->real, escurl, NULL);*/
+               } else
+                   found = temp;
+           }
        }
        else {
            l = alias_matches (r->uri, p->fake);
diff -ur apache_1.3a1/src/util.c apache_1.3a1-patched/src/util.c
--- apache_1.3a1/src/util.c     Mon Jul 21 01:53:52 1997
+++ apache_1.3a1-patched/src/util.c     Sat Sep 20 18:00:50 1997
@@ -799,6 +799,31 @@
     return(digit);
 }
 
+#define c2x(what,where) sprintf(where,"%%%02x",(unsigned char)what)
+
+API_EXPORT(char *) escape_url(pool *p, const char *url) {
+    char *copy = palloc(p, 3 * strlen(url) + 3);
+    char *s = copy;
+    char c;
+    static const char valid[100] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ
RSTUVWXYZ01234567890.-_/~:";
+
+    if (copy == NULL)
+       return NULL;
+
+    while ((c = *(url++)) != '\0') {
+       if (strchr(valid, (int) c)) {
+           *s++ = c;
+       }
+       else {
+           c2x(c, s);
+           s += 3;
+       }
+    }
+
+    *s = '\0';
+    return copy;
+}
+
 /*
  * Unescapes a URL.
  * Returns 0 on success, non-zero on error
@@ -855,7 +880,6 @@
                    uri, NULL);
 }
 
-#define c2x(what,where) sprintf(where,"%%%02x",(unsigned char)what)
 
 /*
 escape_path_segment() escapes a path segment, as defined in RFC 1808. This
%0
>Audit-Trail:
>Unformatted: