summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorEric Covener <covener@apache.org>2023-03-11 22:10:09 +0000
committerEric Covener <covener@apache.org>2023-03-11 22:10:09 +0000
commit3fc1d07f3b33412a123311e7147be7a60bd31238 (patch)
tree07d0786532aecd2b3aa1dfbabac81c6159fdaf5c /modules
parent1a4aac3d209f4314bcb511d73cf12f8c25c8c984 (diff)
downloadhttpd-3fc1d07f3b33412a123311e7147be7a60bd31238.tar.gz
add [BCTLS] alternative to [B] for 2.4.56 problems
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908301 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/mappers/mod_rewrite.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 8f81a89715..458d0c0e8e 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -174,6 +174,7 @@ static const char* really_last_key = "rewrite_really_last";
#define RULEFLAG_ESCAPENOPLUS (1<<18)
#define RULEFLAG_QSLAST (1<<19)
#define RULEFLAG_QSNONE (1<<20) /* programattic only */
+#define RULEFLAG_ESCAPECTLS (1<<21)
/* return code of the rewrite rule
* the result may be escaped - or not
@@ -425,7 +426,7 @@ 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 noplus);
+static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int flags);
/*
* +-------------------------------------------------------+
@@ -684,14 +685,27 @@ 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 noplus) {
+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);
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;
while ((c = *s)) {
- if (!escapeme) {
+ if (ctls) {
+ if (c == ' ' && !noplus) {
+ *d++ = '+';
+ }
+ else if (apr_iscntrl(c)) {
+ d = c2x(c, '%', d);
+ }
+ else {
+ *d++ = c;
+ }
+ }
+ else if (!escapeme) {
if (apr_isalnum(c) || c == '_') {
*d++ = c;
}
@@ -702,9 +716,9 @@ static char *escape_backref(apr_pool_t *p, const char *path, const char *escapem
d = c2x(c, '%', d);
}
}
- else {
+ else {
const char *esc = escapeme;
- while (*esc) {
+ while (*esc) {
if (c == *esc) {
if (c == ' ' && !noplus) {
*d++ = '+';
@@ -2497,7 +2511,7 @@ 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 & RULEFLAG_ESCAPENOPLUS);
+ tmp2 = escape_backref(pool, tmp, entry->escapes, entry->flags);
rewritelog(ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
tmp, tmp2);
@@ -3585,13 +3599,16 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
case 'B':
if (!*key || !strcasecmp(key, "ackrefescaping")) {
cfg->flags |= RULEFLAG_ESCAPEBACKREF;
- if (val && *val) {
+ if (val && *val) {
cfg->escapes = val;
}
}
else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) {
cfg->flags |= RULEFLAG_ESCAPENOPLUS;
}
+ else if (!strcasecmp(key, "CTLS")) {
+ cfg->flags |= RULEFLAG_ESCAPECTLS|RULEFLAG_ESCAPEBACKREF;
+ }
else {
++error;
}