diff options
author | Yann Ylavic <ylavic@apache.org> | 2023-03-13 14:49:13 +0100 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2023-03-13 14:49:13 +0100 |
commit | bced8a7711cf1e48f7b8f0c77e1b78bc3944233f (patch) | |
tree | 0a246ab662f5870f531a180fdee71d8900bed059 | |
parent | Do not double encode encoded slashes (diff) | |
download | apache2-bced8a7711cf1e48f7b8f0c77e1b78bc3944233f.tar.xz apache2-bced8a7711cf1e48f7b8f0c77e1b78bc3944233f.zip |
mod_rewrite: New BNEG flag to negate B=, BCTLS and B= not mutually exclusive.
* modules/mappers/mod_rewrite.c(escape_backref):
Handle [B=...,BNEG] to encode anthing not in B=, and [B=...,BCTLS] to
encode both controls/space characters and anything set in B=.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908347 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | modules/mappers/mod_rewrite.c | 49 |
1 files changed, 16 insertions, 33 deletions
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 458d0c0e8e..8c1fd1a162 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -99,6 +99,8 @@ #include "util_charset.h" #endif +#include "test_char.h" + static ap_dbd_t *(*dbd_acquire)(request_rec*) = NULL; static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL; static const char* really_last_key = "rewrite_really_last"; @@ -175,6 +177,7 @@ static const char* really_last_key = "rewrite_really_last"; #define RULEFLAG_QSLAST (1<<19) #define RULEFLAG_QSNONE (1<<20) /* programattic only */ #define RULEFLAG_ESCAPECTLS (1<<21) +#define RULEFLAG_ESCAPENEG (1<<22) /* return code of the rewrite rule * the result may be escaped - or not @@ -685,27 +688,19 @@ static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix, * Escapes a backreference in a similar way as php's urlencode does. * Based on ap_os_escape_path in server/util.c */ -static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int flags) { - char *copy = apr_palloc(p, 3 * strlen(path) + 3); +static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int flags) +{ + char *copy = apr_palloc(p, 3 * strlen(path) + 1); const unsigned char *s = (const unsigned char *)path; unsigned char *d = (unsigned char *)copy; - unsigned c; - int noplus = flags & RULEFLAG_ESCAPENOPLUS; - int ctls = flags & RULEFLAG_ESCAPECTLS; + int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0; + int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0; + int neg = (flags & RULEFLAG_ESCAPENEG) != 0; + unsigned char c; while ((c = *s)) { - if (ctls) { - if (c == ' ' && !noplus) { - *d++ = '+'; - } - else if (apr_iscntrl(c)) { - d = c2x(c, '%', d); - } - else { - *d++ = c; - } - } - else if (!escapeme) { + if ((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme) + || (escapeme && ((ap_strchr_c(escapeme, c) != NULL) ^ neg))) { if (apr_isalnum(c) || c == '_') { *d++ = c; } @@ -717,22 +712,7 @@ static char *escape_backref(apr_pool_t *p, const char *path, const char *escapem } } else { - const char *esc = escapeme; - while (*esc) { - if (c == *esc) { - if (c == ' ' && !noplus) { - *d++ = '+'; - } - else { - d = c2x(c, '%', d); - } - break; - } - ++esc; - } - if (!*esc) { - *d++ = c; - } + *d++ = c; } ++s; } @@ -3603,6 +3583,9 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg, cfg->escapes = val; } } + else if (!strcasecmp(key, "NEG")) { + cfg->flags |= RULEFLAG_ESCAPENEG; + } else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) { cfg->flags |= RULEFLAG_ESCAPENOPLUS; } |