From: Nick Kew Date: Wed, 31 Dec 2008 00:08:00 +0000 (+0000) Subject: Fix mod_rewrite "B" flag breakage by reverting r589343 X-Git-Tag: 2.3.1~37 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=774d09ec2323c4ebb48213b6d69f258699d8ac1c;p=thirdparty%2Fapache%2Fhttpd.git Fix mod_rewrite "B" flag breakage by reverting r589343 PR#45529 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@730274 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 580a2ead29a..1a057604c80 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.3.1 [ When backported to 2.2.x, remove entry from this file ] + *) mod_rewrite: fix "B" flag breakage by reverting r5589343 + PR 45529 [Bob Ionescu ] + *) CGI: return 504 (Gateway timeout) rather than 500 when a script times out before returning status line/headers. PR 42190 [Nick Kew] diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 96209d9b8c3..a92c256b90f 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -389,6 +389,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); /* * +-------------------------------------------------------+ @@ -658,6 +659,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. @@ -2363,15 +2404,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; }