summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2023-03-13 21:17:52 +0000
committerYann Ylavic <ylavic@apache.org>2023-03-13 21:17:52 +0000
commitfb626cc5ba9160cc8faf4161267aaa5ebdb768f1 (patch)
treeeddab8d35db1139997d4e2743e42ba5c31c2ad42 /modules
parent54317bdf45669b764b5fcfb20a16bb065eaa4f3e (diff)
downloadhttpd-fb626cc5ba9160cc8faf4161267aaa5ebdb768f1.tar.gz
mod_rewrite: Follow up to r1908347: Use [B, BNE=...] rather than [B=...,BNEG].
Replaces BNEG with BNE= for a more flexible syntax. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/mappers/mod_rewrite.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 8c1fd1a162..af77e58eeb 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -177,7 +177,6 @@ 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
@@ -328,7 +327,8 @@ typedef struct {
data_item *cookie; /* added cookies */
int skip; /* number of next rules to skip */
int maxrounds; /* limit on number of loops with N flag */
- char *escapes; /* specific backref escapes */
+ const char *escapes; /* specific backref escapes */
+ const char *noescapes; /* specific backref chars not to escape */
} rewriterule_entry;
typedef struct {
@@ -429,7 +429,9 @@ static apr_global_mutex_t *rewrite_mapr_lock_acquire = NULL;
static const char *rewritemap_mutex_type = "rewrite-map";
/* Optional functions imported from mod_ssl when loaded: */
-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int flags);
+static char *escape_backref(apr_pool_t *p, const char *path,
+ const char *escapeme, const char *noescapeme,
+ int flags);
/*
* +-------------------------------------------------------+
@@ -688,19 +690,21 @@ 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)
+static char *escape_backref(apr_pool_t *p, const char *path,
+ const char *escapeme, const char *noescapeme,
+ 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;
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 ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
- || (escapeme && ((ap_strchr_c(escapeme, c) != NULL) ^ neg))) {
+ if (((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
+ || (escapeme && ap_strchr_c(escapeme, c)))
+ && (!noescapeme || !ap_strchr_c(noescapeme, c))) {
if (apr_isalnum(c) || c == '_') {
*d++ = c;
}
@@ -2491,7 +2495,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry,
/* escape the backreference */
char *tmp2, *tmp;
tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so, span);
- tmp2 = escape_backref(pool, tmp, entry->escapes, entry->flags);
+ tmp2 = escape_backref(pool, tmp, entry->escapes, entry->noescapes,
+ entry->flags);
rewritelog(ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
tmp, tmp2);
@@ -3583,8 +3588,13 @@ 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, "NE")) {
+ if (val && *val) {
+ cfg->noescapes = val;
+ }
+ else {
+ return "flag 'BNE' wants a list of characters (i.e. [BNE=...])";
+ }
}
else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) {
cfg->flags |= RULEFLAG_ESCAPENOPLUS;
@@ -3854,7 +3864,6 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
err, a1, a2, a3);
}
- /* arg3: optional flags field */
newrule->forced_mimetype = NULL;
newrule->forced_handler = NULL;
newrule->forced_responsecode = HTTP_MOVED_TEMPORARILY;
@@ -3863,6 +3872,9 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
newrule->cookie = NULL;
newrule->skip = 0;
newrule->maxrounds = REWRITE_MAX_ROUNDS;
+ newrule->escapes = newrule->noescapes = NULL;
+
+ /* arg3: optional flags field */
if (a3 != NULL) {
if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
cmd_rewriterule_setflag)) != NULL) {