From: Nick Kew Date: Thu, 8 Jan 2009 01:13:36 +0000 (+0000) Subject: Backport r730274 X-Git-Tag: 2.2.12~287 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=59ef0409ac8296a33bae1a27ec23f381e470703b;p=thirdparty%2Fapache%2Fhttpd.git Backport r730274 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 --- diff --git a/CHANGES b/CHANGES index 85da92c82d6..9e2bf585742 100644 --- 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 ] + *) mod_cgid: fix segfault problem on solaris. PR 39332 [Masaoki Kobayashi , Jeff Trawick] diff --git a/STATUS b/STATUS index e985cb9d0b7..6529e0aa56b 100644 --- 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 ] diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 863d69e1011..ec631bc1c4a 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -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; }