diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-25 04:41:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-25 04:41:28 +0000 |
commit | b1a1c1d95059e2fefd7b5671eb110ab690409a84 (patch) | |
tree | 97ecfcc9425e2d09d2cd669594d626a616f324a3 /modules/mappers | |
parent | Releasing progress-linux version 2.4.38-3+deb10u10progress5u1. (diff) | |
download | apache2-b1a1c1d95059e2fefd7b5671eb110ab690409a84.tar.xz apache2-b1a1c1d95059e2fefd7b5671eb110ab690409a84.zip |
Merging upstream version 2.4.59.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules/mappers')
-rw-r--r-- | modules/mappers/config9.m4 | 5 | ||||
-rw-r--r-- | modules/mappers/mod_alias.c | 186 | ||||
-rw-r--r-- | modules/mappers/mod_imagemap.c | 2 | ||||
-rw-r--r-- | modules/mappers/mod_negotiation.c | 10 | ||||
-rw-r--r-- | modules/mappers/mod_rewrite.c | 288 | ||||
-rw-r--r-- | modules/mappers/mod_rewrite.mak | 4 | ||||
-rw-r--r-- | modules/mappers/mod_speling.c | 37 | ||||
-rw-r--r-- | modules/mappers/mod_vhost_alias.c | 2 |
8 files changed, 340 insertions, 194 deletions
diff --git a/modules/mappers/config9.m4 b/modules/mappers/config9.m4 index 55a97ab..7120b72 100644 --- a/modules/mappers/config9.m4 +++ b/modules/mappers/config9.m4 @@ -14,6 +14,11 @@ APACHE_MODULE(userdir, mapping of requests to user-specific directories, , , mos APACHE_MODULE(alias, mapping of requests to different filesystem parts, , , yes) APACHE_MODULE(rewrite, rule based URL manipulation, , , most) +if test "x$enable_rewrite" != "xno"; then + # mod_rewrite needs test_char.h + APR_ADDTO(INCLUDES, [-I\$(top_builddir)/server]) +fi + APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) APACHE_MODPATH_FINISH diff --git a/modules/mappers/mod_alias.c b/modules/mappers/mod_alias.c index 79d58d8..35eca74 100644 --- a/modules/mappers/mod_alias.c +++ b/modules/mappers/mod_alias.c @@ -37,6 +37,12 @@ #include "ap_expr.h" +#define ALIAS_FLAG_DEFAULT -1 +#define ALIAS_FLAG_OFF 0 +#define ALIAS_FLAG_ON 1 + +#define ALIAS_PRESERVE_PATH_DEFAULT 0 + typedef struct { const char *real; const char *fake; @@ -55,9 +61,12 @@ typedef struct { unsigned int redirect_set:1; apr_array_header_t *redirects; const ap_expr_info_t *alias; + const char *alias_fake; char *handler; const ap_expr_info_t *redirect; int redirect_status; /* 301, 302, 303, 410, etc */ + int allow_relative; /* skip ap_construct_url() */ + int alias_preserve_path; /* map full path */ } alias_dir_conf; module AP_MODULE_DECLARE_DATA alias_module; @@ -80,6 +89,8 @@ static void *create_alias_dir_config(apr_pool_t *p, char *d) alias_dir_conf *a = (alias_dir_conf *) apr_pcalloc(p, sizeof(alias_dir_conf)); a->redirects = apr_array_make(p, 2, sizeof(alias_entry)); + a->allow_relative = ALIAS_FLAG_DEFAULT; + a->alias_preserve_path = ALIAS_FLAG_DEFAULT; return a; } @@ -105,12 +116,19 @@ static void *merge_alias_dir_config(apr_pool_t *p, void *basev, void *overridesv a->redirects = apr_array_append(p, overrides->redirects, base->redirects); a->alias = (overrides->alias_set == 0) ? base->alias : overrides->alias; + a->alias_fake = (overrides->alias_set == 0) ? base->alias_fake : overrides->alias_fake; a->handler = (overrides->alias_set == 0) ? base->handler : overrides->handler; a->alias_set = overrides->alias_set || base->alias_set; a->redirect = (overrides->redirect_set == 0) ? base->redirect : overrides->redirect; a->redirect_status = (overrides->redirect_set == 0) ? base->redirect_status : overrides->redirect_status; a->redirect_set = overrides->redirect_set || base->redirect_set; + a->allow_relative = (overrides->allow_relative != ALIAS_FLAG_DEFAULT) + ? overrides->allow_relative + : base->allow_relative; + a->alias_preserve_path = (overrides->alias_preserve_path != ALIAS_FLAG_DEFAULT) + ? overrides->alias_preserve_path + : base->alias_preserve_path; return a; } @@ -210,6 +228,7 @@ static const char *add_alias(cmd_parms *cmd, void *dummy, const char *fake, NULL); } + dirconf->alias_fake = cmd->path; dirconf->handler = cmd->info; dirconf->alias_set = 1; @@ -373,33 +392,6 @@ static const char *add_redirect_regex(cmd_parms *cmd, void *dirconf, return add_redirect_internal(cmd, dirconf, arg1, arg2, arg3, 1); } -static const command_rec alias_cmds[] = -{ - AP_INIT_TAKE12("Alias", add_alias, NULL, RSRC_CONF | ACCESS_CONF, - "a fakename and a realname, or a realname in a Location"), - AP_INIT_TAKE12("ScriptAlias", add_alias, "cgi-script", RSRC_CONF | ACCESS_CONF, - "a fakename and a realname, or a realname in a Location"), - AP_INIT_TAKE123("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY, - OR_FILEINFO, - "an optional status, then document to be redirected and " - "destination URL"), - AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF, - "a regular expression and a filename"), - AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF, - "a regular expression and a filename"), - AP_INIT_TAKE23("RedirectMatch", add_redirect_regex, - (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO, - "an optional status, then a regular expression and " - "destination URL"), - AP_INIT_TAKE2("RedirectTemp", add_redirect2, - (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO, - "a document to be redirected, then the destination URL"), - AP_INIT_TAKE2("RedirectPermanent", add_redirect2, - (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO, - "a document to be redirected, then the destination URL"), - {NULL} -}; - static int alias_matches(const char *uri, const char *alias_fakename) { const char *aliasp = alias_fakename, *urip = uri; @@ -455,6 +447,17 @@ static char *try_alias(request_rec *r) return PREGSUB_ERROR; } + if (dirconf->alias_fake && dirconf->alias_preserve_path == ALIAS_FLAG_ON) { + int l; + + l = alias_matches(r->uri, dirconf->alias_fake); + + if (l > 0) { + ap_set_context_info(r, dirconf->alias_fake, found); + found = apr_pstrcat(r->pool, found, r->uri + l, NULL); + } + } + if (dirconf->handler) { /* Set handler, and leave a note for mod_cgi */ r->handler = dirconf->handler; apr_table_setn(r->notes, "alias-forced-type", r->handler); @@ -618,31 +621,33 @@ static int translate_alias_redir(request_rec *r) if (ret == PREGSUB_ERROR) return HTTP_INTERNAL_SERVER_ERROR; if (ap_is_HTTP_REDIRECT(status)) { - if (ret[0] == '/') { - char *orig_target = ret; - - ret = ap_construct_url(r->pool, ret, r); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00673) - "incomplete redirection target of '%s' for " - "URI '%s' modified to '%s'", - orig_target, r->uri, ret); - } - if (!ap_is_url(ret)) { - status = HTTP_INTERNAL_SERVER_ERROR; - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00674) - "cannot redirect '%s' to '%s'; " - "target is not a valid absoluteURI or abs_path", - r->uri, ret); - } - else { - /* append requested query only, if the config didn't - * supply its own. - */ - if (r->args && !ap_strchr(ret, '?')) { - ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL); + alias_dir_conf *dirconf = (alias_dir_conf *) + ap_get_module_config(r->per_dir_config, &alias_module); + if (dirconf->allow_relative != ALIAS_FLAG_ON || ret[0] != '/') { + if (ret[0] == '/') { + char *orig_target = ret; + + ret = ap_construct_url(r->pool, ret, r); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00673) + "incomplete redirection target of '%s' for " + "URI '%s' modified to '%s'", + orig_target, r->uri, ret); } - apr_table_setn(r->headers_out, "Location", ret); + if (!ap_is_url(ret)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00674) + "cannot redirect '%s' to '%s'; " + "target is not a valid absoluteURI or abs_path", + r->uri, ret); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + /* append requested query only, if the config didn't + * supply its own. + */ + if (r->args && !ap_strchr(ret, '?')) { + ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL); } + apr_table_setn(r->headers_out, "Location", ret); } return status; } @@ -673,31 +678,31 @@ static int fixup_redir(request_rec *r) if (ret == PREGSUB_ERROR) return HTTP_INTERNAL_SERVER_ERROR; if (ap_is_HTTP_REDIRECT(status)) { - if (ret[0] == '/') { - char *orig_target = ret; - - ret = ap_construct_url(r->pool, ret, r); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00675) - "incomplete redirection target of '%s' for " - "URI '%s' modified to '%s'", - orig_target, r->uri, ret); - } - if (!ap_is_url(ret)) { - status = HTTP_INTERNAL_SERVER_ERROR; - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00676) - "cannot redirect '%s' to '%s'; " - "target is not a valid absoluteURI or abs_path", - r->uri, ret); - } - else { - /* append requested query only, if the config didn't - * supply its own. - */ - if (r->args && !ap_strchr(ret, '?')) { - ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL); + if (dirconf->allow_relative != ALIAS_FLAG_ON || ret[0] != '/') { + if (ret[0] == '/') { + char *orig_target = ret; + + ret = ap_construct_url(r->pool, ret, r); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00675) + "incomplete redirection target of '%s' for " + "URI '%s' modified to '%s'", + orig_target, r->uri, ret); } - apr_table_setn(r->headers_out, "Location", ret); + if (!ap_is_url(ret)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00676) + "cannot redirect '%s' to '%s'; " + "target is not a valid absoluteURI or abs_path", + r->uri, ret); + return HTTP_INTERNAL_SERVER_ERROR; + } + } + /* append requested query only, if the config didn't + * supply its own. + */ + if (r->args && !ap_strchr(ret, '?')) { + ret = apr_pstrcat(r->pool, ret, "?", r->args, NULL); } + apr_table_setn(r->headers_out, "Location", ret); } return status; } @@ -705,6 +710,41 @@ static int fixup_redir(request_rec *r) return DECLINED; } +static const command_rec alias_cmds[] = +{ + AP_INIT_TAKE12("Alias", add_alias, NULL, RSRC_CONF | ACCESS_CONF, + "a fakename and a realname, or a realname in a Location"), + AP_INIT_TAKE12("ScriptAlias", add_alias, "cgi-script", RSRC_CONF | ACCESS_CONF, + "a fakename and a realname, or a realname in a Location"), + AP_INIT_TAKE123("Redirect", add_redirect, (void *) HTTP_MOVED_TEMPORARILY, + OR_FILEINFO, + "an optional status, then document to be redirected and " + "destination URL"), + AP_INIT_TAKE2("AliasMatch", add_alias_regex, NULL, RSRC_CONF, + "a regular expression and a filename"), + AP_INIT_TAKE2("ScriptAliasMatch", add_alias_regex, "cgi-script", RSRC_CONF, + "a regular expression and a filename"), + AP_INIT_TAKE23("RedirectMatch", add_redirect_regex, + (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO, + "an optional status, then a regular expression and " + "destination URL"), + AP_INIT_TAKE2("RedirectTemp", add_redirect2, + (void *) HTTP_MOVED_TEMPORARILY, OR_FILEINFO, + "a document to be redirected, then the destination URL"), + AP_INIT_TAKE2("RedirectPermanent", add_redirect2, + (void *) HTTP_MOVED_PERMANENTLY, OR_FILEINFO, + "a document to be redirected, then the destination URL"), + AP_INIT_FLAG("RedirectRelative", ap_set_flag_slot, + (void*)APR_OFFSETOF(alias_dir_conf, allow_relative), OR_FILEINFO, + "Set to ON to allow relative redirect targets to be issued as-is"), + AP_INIT_FLAG("AliasPreservePath", ap_set_flag_slot, + (void*)APR_OFFSETOF(alias_dir_conf, alias_preserve_path), OR_FILEINFO, + "Set to ON to map the full path after the fakename to the realname."), + + {NULL} +}; + + static void register_hooks(apr_pool_t *p) { static const char * const aszSucc[]={ "mod_userdir.c", diff --git a/modules/mappers/mod_imagemap.c b/modules/mappers/mod_imagemap.c index 187a500..206c0b6 100644 --- a/modules/mappers/mod_imagemap.c +++ b/modules/mappers/mod_imagemap.c @@ -319,7 +319,7 @@ static void read_quoted(char **string, char **quoted_part) static const char *imap_url(request_rec *r, const char *base, const char *value) { /* translates a value into a URL. */ - int slen, clen; + apr_size_t slen, clen; char *string_pos = NULL; const char *string_pos_const = NULL; char *directory = NULL; diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c index b6dfedc..c056b28 100644 --- a/modules/mappers/mod_negotiation.c +++ b/modules/mappers/mod_negotiation.c @@ -774,7 +774,7 @@ static enum header_state get_header_line(char *buffer, int len, apr_file_t *map) /* We need to shortcut the rest of this block following the Body: * tag - we will not look for continutation after this line. */ - if (!strncasecmp(buffer, "Body:", 5)) + if (!ap_cstr_casecmpn(buffer, "Body:", 5)) return header_seen; while (apr_file_getc(&c, map) != APR_EOF) { @@ -988,19 +988,17 @@ static int read_type_map(apr_file_t **map, negotiation_state *neg, has_content = 1; } else if (!strncmp(buffer, "content-length:", 15)) { - char *errp; - apr_off_t number; + apr_off_t clen; body1 = ap_get_token(neg->pool, &body, 0); - if (apr_strtoff(&number, body1, &errp, 10) != APR_SUCCESS - || *errp || number < 0) { + if (!ap_parse_strict_length(&clen, body1)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00684) "Parse error in type map, Content-Length: " "'%s' in %s is invalid.", body1, r->filename); break; } - mime_info.bytes = number; + mime_info.bytes = clen; has_content = 1; } else if (!strncmp(buffer, "content-language:", 17)) { diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 68a33b6..bbcc11b 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -55,6 +55,12 @@ #include "apr_global_mutex.h" #include "apr_dbm.h" #include "apr_dbd.h" + +#include "apr_version.h" +#if !APR_VERSION_AT_LEAST(2,0,0) +#include "apu_version.h" +#endif + #include "mod_dbd.h" #if APR_HAS_THREADS @@ -93,14 +99,15 @@ #include "http_core.h" #include "http_log.h" #include "http_protocol.h" +#include "http_ssl.h" #include "http_vhost.h" #include "util_mutex.h" -#include "mod_ssl.h" - #include "mod_rewrite.h" #include "ap_expr.h" +#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"; @@ -168,6 +175,8 @@ static const char* really_last_key = "rewrite_really_last"; #define RULEFLAG_END (1<<17) #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 @@ -321,7 +330,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 { @@ -421,9 +431,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 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_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, const char *noescapeme, + int flags); /* * +-------------------------------------------------------+ @@ -524,7 +534,7 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs) switch (*uri++) { case 'a': case 'A': - if (!strncasecmp(uri, "jp://", 5)) { /* ajp:// */ + if (!ap_cstr_casecmpn(uri, "jp://", 5)) { /* ajp:// */ *sqs = 1; return 6; } @@ -532,7 +542,7 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs) case 'b': case 'B': - if (!strncasecmp(uri, "alancer://", 10)) { /* balancer:// */ + if (!ap_cstr_casecmpn(uri, "alancer://", 10)) { /* balancer:// */ *sqs = 1; return 11; } @@ -540,10 +550,10 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs) case 'f': case 'F': - if (!strncasecmp(uri, "tp://", 5)) { /* ftp:// */ + if (!ap_cstr_casecmpn(uri, "tp://", 5)) { /* ftp:// */ return 6; } - if (!strncasecmp(uri, "cgi://", 6)) { /* fcgi:// */ + if (!ap_cstr_casecmpn(uri, "cgi://", 6)) { /* fcgi:// */ *sqs = 1; return 7; } @@ -551,26 +561,26 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs) case 'g': case 'G': - if (!strncasecmp(uri, "opher://", 8)) { /* gopher:// */ + if (!ap_cstr_casecmpn(uri, "opher://", 8)) { /* gopher:// */ return 9; } break; case 'h': case 'H': - if (!strncasecmp(uri, "ttp://", 6)) { /* http:// */ + if (!ap_cstr_casecmpn(uri, "ttp://", 6)) { /* http:// */ *sqs = 1; return 7; } - else if (!strncasecmp(uri, "ttps://", 7)) { /* https:// */ + else if (!ap_cstr_casecmpn(uri, "ttps://", 7)) { /* https:// */ *sqs = 1; return 8; } - else if (!strncasecmp(uri, "2://", 4)) { /* h2:// */ + else if (!ap_cstr_casecmpn(uri, "2://", 4)) { /* h2:// */ *sqs = 1; return 5; } - else if (!strncasecmp(uri, "2c://", 5)) { /* h2c:// */ + else if (!ap_cstr_casecmpn(uri, "2c://", 5)) { /* h2c:// */ *sqs = 1; return 6; } @@ -578,14 +588,14 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs) case 'l': case 'L': - if (!strncasecmp(uri, "dap://", 6)) { /* ldap:// */ + if (!ap_cstr_casecmpn(uri, "dap://", 6)) { /* ldap:// */ return 7; } break; case 'm': case 'M': - if (!strncasecmp(uri, "ailto:", 6)) { /* mailto: */ + if (!ap_cstr_casecmpn(uri, "ailto:", 6)) { /* mailto: */ *sqs = 1; return 7; } @@ -593,17 +603,17 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs) case 'n': case 'N': - if (!strncasecmp(uri, "ews:", 4)) { /* news: */ + if (!ap_cstr_casecmpn(uri, "ews:", 4)) { /* news: */ return 5; } - else if (!strncasecmp(uri, "ntp://", 6)) { /* nntp:// */ + else if (!ap_cstr_casecmpn(uri, "ntp://", 6)) { /* nntp:// */ return 7; } break; case 's': case 'S': - if (!strncasecmp(uri, "cgi://", 6)) { /* scgi:// */ + if (!ap_cstr_casecmpn(uri, "cgi://", 6)) { /* scgi:// */ *sqs = 1; return 7; } @@ -611,15 +621,22 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs) case 'w': case 'W': - if (!strncasecmp(uri, "s://", 4)) { /* ws:// */ + if (!ap_cstr_casecmpn(uri, "s://", 4)) { /* ws:// */ *sqs = 1; return 5; } - else if (!strncasecmp(uri, "ss://", 5)) { /* wss:// */ + else if (!ap_cstr_casecmpn(uri, "ss://", 5)) { /* wss:// */ *sqs = 1; return 6; } break; + + case 'u': + case 'U': + if (!ap_cstr_casecmpn(uri, "nix:", 4)) { /* unix: */ + *sqs = 1; + return (uri[4] == '/' && uri[5] == '/') ? 7 : 5; + } } return 0; @@ -643,14 +660,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 noplus) { - char *copy = apr_palloc(p, 3 * strlen(path) + 3); +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; - unsigned c; + int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0; + int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0; + unsigned char c; while ((c = *s)) { - if (!escapeme) { + 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; } @@ -661,23 +685,8 @@ static char *escape_backref(apr_pool_t *p, const char *path, const char *escapem d = c2x(c, '%', d); } } - 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; - } + else { + *d++ = c; } ++s; } @@ -723,7 +732,7 @@ static char *escape_absolute_uri(apr_pool_t *p, char *uri, unsigned scheme) * [dn ["?" [attributes] ["?" [scope] * ["?" [filter] ["?" extensions]]]]]] */ - if (!strncasecmp(uri, "ldap", 4)) { + if (!ap_cstr_casecmpn(uri, "ldap", 4)) { char *token[5]; int c = 0; @@ -759,27 +768,35 @@ static char *escape_absolute_uri(apr_pool_t *p, char *uri, unsigned scheme) * split out a QUERY_STRING part from * the current URI string */ -static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard, - int qslast) +static void splitout_queryargs(request_rec *r, int flags) { char *q; - int split; + int split, skip; + int qsappend = flags & RULEFLAG_QSAPPEND; + int qsdiscard = flags & RULEFLAG_QSDISCARD; + int qslast = flags & RULEFLAG_QSLAST; + + if (flags & RULEFLAG_QSNONE) { + rewritelog((r, 2, NULL, "discarding query string, no parse from substitution")); + r->args = NULL; + return; + } /* don't touch, unless it's a scheme for which a query string makes sense. * See RFC 1738 and RFC 2368. */ - if (is_absolute_uri(r->filename, &split) + if ((skip = is_absolute_uri(r->filename, &split)) && !split) { r->args = NULL; /* forget the query that's still flying around */ return; } - if ( qsdiscard ) { + if (qsdiscard) { r->args = NULL; /* Discard query string */ rewritelog((r, 2, NULL, "discarding query string")); } - q = qslast ? ap_strrchr(r->filename, '?') : ap_strchr(r->filename, '?'); + q = qslast ? ap_strrchr(r->filename + skip, '?') : ap_strchr(r->filename + skip, '?'); if (q != NULL) { char *olduri; @@ -788,7 +805,7 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard, olduri = apr_pstrdup(r->pool, r->filename); *q++ = '\0'; if (qsappend) { - if (*q) { + if (*q) { r->args = apr_pstrcat(r->pool, q, "&" , r->args, NULL); } } @@ -796,9 +813,9 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard, r->args = apr_pstrdup(r->pool, q); } - if (r->args) { + if (r->args) { len = strlen(r->args); - + if (!len) { r->args = NULL; } @@ -810,8 +827,6 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard, rewritelog((r, 3, NULL, "split uri=%s -> uri=%s, args=%s", olduri, r->filename, r->args ? r->args : "<none>")); } - - return; } /* @@ -825,7 +840,7 @@ static void reduce_uri(request_rec *r) cp = (char *)ap_http_scheme(r); l = strlen(cp); if ( strlen(r->filename) > l+3 - && strncasecmp(r->filename, cp, l) == 0 + && ap_cstr_casecmpn(r->filename, cp, l) == 0 && r->filename[l] == ':' && r->filename[l+1] == '/' && r->filename[l+2] == '/' ) { @@ -1029,6 +1044,7 @@ static void set_cache_value(const char *name, apr_time_t t, char *key, #endif return; } + apr_pool_tag(p, "rewrite_cachedmap"); map = apr_palloc(cachep->pool, sizeof(cachedmap)); map->pool = p; @@ -1106,6 +1122,7 @@ static int init_cache(apr_pool_t *p) cachep = NULL; /* turns off cache */ return 0; } + apr_pool_tag(cachep->pool, "rewrite_cachep"); cachep->maps = apr_hash_make(cachep->pool); #if APR_HAS_THREADS @@ -1353,12 +1370,31 @@ static char *lookup_map_txtfile(request_rec *r, const char *file, char *key) static char *lookup_map_dbmfile(request_rec *r, const char *file, const char *dbmtype, char *key) { +#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) + const apr_dbm_driver_t *driver; + const apu_err_t *err; +#endif apr_dbm_t *dbmfp = NULL; apr_datum_t dbmkey; apr_datum_t dbmval; char *value; apr_status_t rv; +#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) + if ((rv = apr_dbm_get_driver(&driver, dbmtype, &err, + r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10287) + "mod_rewrite: can't load DBM library '%s': %s", + err->reason, err->msg); + return NULL; + } + if ((rv = apr_dbm_open2(&dbmfp, driver, file, APR_DBM_READONLY, + APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00656) + "mod_rewrite: can't open DBM RewriteMap %s", file); + return NULL; + } +#else if ((rv = apr_dbm_open_ex(&dbmfp, dbmtype, file, APR_DBM_READONLY, APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) { @@ -1366,6 +1402,7 @@ static char *lookup_map_dbmfile(request_rec *r, const char *file, "mod_rewrite: can't open DBM RewriteMap %s", file); return NULL; } +#endif dbmkey.dptr = key; dbmkey.dsize = strlen(key); @@ -1864,8 +1901,8 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx) result = getenv(var); } } - else if (var[4] && !strncasecmp(var, "SSL", 3) && rewrite_ssl_lookup) { - result = rewrite_ssl_lookup(r->pool, r->server, r->connection, r, + else if (var[4] && !strncasecmp(var, "SSL", 3)) { + result = ap_ssl_var_lookup(r->pool, r->server, r->connection, r, var + 4); } } @@ -1963,7 +2000,7 @@ static char *lookup_variable(char *var, rewrite_ctx *ctx) case 5: if (!strcmp(var, "HTTPS")) { - int flag = rewrite_is_https && rewrite_is_https(r->connection); + int flag = ap_ssl_conn_is_ssl(r->connection); return apr_pstrdup(r->pool, flag ? "on" : "off"); } break; @@ -2430,7 +2467,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 & RULEFLAG_ESCAPENOPLUS); + tmp2 = escape_backref(pool, tmp, entry->escapes, entry->noescapes, + entry->flags); rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'", tmp, tmp2)); @@ -2538,6 +2576,7 @@ static void add_cookie(request_rec *r, char *s) char *path; char *secure; char *httponly; + char *samesite; char *tok_cntx; char *cookie; @@ -2572,6 +2611,7 @@ static void add_cookie(request_rec *r, char *s) path = expires ? apr_strtok(NULL, sep, &tok_cntx) : NULL; secure = path ? apr_strtok(NULL, sep, &tok_cntx) : NULL; httponly = secure ? apr_strtok(NULL, sep, &tok_cntx) : NULL; + samesite = httponly ? apr_strtok(NULL, sep, &tok_cntx) : NULL; if (expires) { apr_time_exp_t tms; @@ -2599,18 +2639,23 @@ static void add_cookie(request_rec *r, char *s) : NULL, expires ? (exp_time ? exp_time : "") : NULL, - (secure && (!strcasecmp(secure, "true") + (secure && (!ap_cstr_casecmp(secure, "true") || !strcmp(secure, "1") - || !strcasecmp(secure, + || !ap_cstr_casecmp(secure, "secure"))) ? "; secure" : NULL, - (httponly && (!strcasecmp(httponly, "true") + (httponly && (!ap_cstr_casecmp(httponly, "true") || !strcmp(httponly, "1") - || !strcasecmp(httponly, + || !ap_cstr_casecmp(httponly, "HttpOnly"))) ? "; HttpOnly" : NULL, NULL); + if (samesite && strcmp(samesite, "0") && ap_cstr_casecmp(samesite,"false")) { + cookie = apr_pstrcat(rmain->pool, cookie, "; SameSite=", + samesite, NULL); + } + apr_table_addn(rmain->err_headers_out, "Set-Cookie", cookie); apr_pool_userdata_set("set", notename, NULL, rmain->pool); rewritelog((rmain, 5, NULL, "setting cookie '%s'", cookie)); @@ -2724,7 +2769,7 @@ static apr_status_t rewritelock_remove(void *data) * XXX: what an inclined parser. Seems we have to leave it so * for backwards compat. *sigh* */ -static int parseargline(char *str, char **a1, char **a2, char **a3) +static int parseargline(char *str, char **a1, char **a2, char **a2_end, char **a3) { char quote; @@ -2775,8 +2820,10 @@ static int parseargline(char *str, char **a1, char **a2, char **a3) if (!*str) { *a3 = NULL; /* 3rd argument is optional */ + *a2_end = str; return 0; } + *a2_end = str; *str++ = '\0'; while (apr_isspace(*str)) { @@ -3316,7 +3363,7 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf, rewrite_server_conf *sconf; rewritecond_entry *newcond; ap_regex_t *regexp; - char *a1 = NULL, *a2 = NULL, *a3 = NULL; + char *a1 = NULL, *a2 = NULL, *a2_end, *a3 = NULL; const char *err; sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module); @@ -3334,7 +3381,7 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf, * of the argument line. So we can use a1 .. a3 without * copying them again. */ - if (parseargline(str, &a1, &a2, &a3)) { + if (parseargline(str, &a1, &a2, &a2_end, &a3)) { return apr_pstrcat(cmd->pool, "RewriteCond: bad argument line '", str, "'", NULL); } @@ -3493,13 +3540,24 @@ 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, "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; } + else if (!strcasecmp(key, "CTLS")) { + cfg->flags |= RULEFLAG_ESCAPECTLS|RULEFLAG_ESCAPEBACKREF; + } else { ++error; } @@ -3742,7 +3800,7 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf, rewrite_server_conf *sconf; rewriterule_entry *newrule; ap_regex_t *regexp; - char *a1 = NULL, *a2 = NULL, *a3 = NULL; + char *a1 = NULL, *a2 = NULL, *a2_end, *a3 = NULL; const char *err; sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module); @@ -3756,12 +3814,11 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf, } /* parse the argument line ourself */ - if (parseargline(str, &a1, &a2, &a3)) { + if (parseargline(str, &a1, &a2, &a2_end, &a3)) { return apr_pstrcat(cmd->pool, "RewriteRule: bad argument line '", str, "'", NULL); } - /* arg3: optional flags field */ newrule->forced_mimetype = NULL; newrule->forced_handler = NULL; newrule->forced_responsecode = HTTP_MOVED_TEMPORARILY; @@ -3770,6 +3827,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) { @@ -3803,6 +3863,25 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf, newrule->flags |= RULEFLAG_NOSUB; } + if (*(a2_end-1) == '?') { + /* a literal ? at the end of the unsubstituted rewrite rule */ + if (newrule->flags & RULEFLAG_QSAPPEND) { + /* with QSA, splitout_queryargs will safely handle it if RULEFLAG_QSLAST is set */ + newrule->flags |= RULEFLAG_QSLAST; + } + else { + /* avoid getting a query string via inadvertent capture */ + newrule->flags |= RULEFLAG_QSNONE; + /* trailing ? has done its job, but splitout_queryargs will not chop it off */ + *(a2_end-1) = '\0'; + } + } + else if (newrule->flags & RULEFLAG_QSDISCARD) { + if (NULL == ap_strchr(newrule->output, '?')) { + newrule->flags |= RULEFLAG_QSNONE; + } + } + /* now, if the server or per-dir config holds an * array of RewriteCond entries, we take it for us * and clear the array @@ -4090,7 +4169,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) } /* Additionally we strip the physical path from the url to match - * it independent from the underlaying filesystem. + * it independent from the underlying filesystem. */ if (!is_proxyreq && strlen(ctx->uri) >= dirlen && !strncmp(ctx->uri, ctx->perdir, dirlen)) { @@ -4208,9 +4287,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx) r->path_info = NULL; } - splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND, - p->flags & RULEFLAG_QSDISCARD, - p->flags & RULEFLAG_QSLAST); + splitout_queryargs(r, p->flags); /* Add the previously stripped per-directory location prefix, unless * (1) it's an absolute URL path and @@ -4516,9 +4593,6 @@ static int post_config(apr_pool_t *p, } } - rewrite_ssl_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); - rewrite_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https); - return OK; } @@ -4692,8 +4766,25 @@ static int hook_uri2file(request_rec *r) } if (rulestatus) { - unsigned skip; - apr_size_t flen; + apr_size_t flen = r->filename ? strlen(r->filename) : 0; + unsigned skip_absolute = flen ? is_absolute_uri(r->filename, NULL) : 0; + int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0); + int will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE); + + if (r->args + && !will_escape + && *(ap_scan_vchar_obstext(r->args))) { + /* + * We have a raw control character or a ' ' in r->args. + * Correct encoding was missed. + * Correct encoding was missed and we're not going to escape + * it before returning. + */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410) + "Rewritten query string contains control " + "characters or spaces"); + return HTTP_FORBIDDEN; + } if (ACTION_STATUS == rulestatus) { int n = r->status; @@ -4702,8 +4793,7 @@ static int hook_uri2file(request_rec *r) return n; } - flen = r->filename ? strlen(r->filename) : 0; - if (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0) { + if (to_proxyreq) { /* it should be go on as an internal proxy request */ /* check if the proxy module is enabled, so @@ -4745,7 +4835,7 @@ static int hook_uri2file(request_rec *r) r->filename)); return OK; } - else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) { + else if (skip_absolute > 0) { int n; /* it was finally rewritten to a remote URL */ @@ -4753,7 +4843,7 @@ static int hook_uri2file(request_rec *r) if (rulestatus != ACTION_NOESCAPE) { rewritelog((r, 1, NULL, "escaping %s for redirect", r->filename)); - r->filename = escape_absolute_uri(r->pool, r->filename, skip); + r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute); } /* append the QUERY_STRING part */ @@ -4977,7 +5067,26 @@ static int hook_fixup(request_rec *r) */ rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory); if (rulestatus) { - unsigned skip; + unsigned skip_absolute = is_absolute_uri(r->filename, NULL); + int to_proxyreq = 0; + int will_escape = 0; + + l = strlen(r->filename); + to_proxyreq = l > 6 && strncmp(r->filename, "proxy:", 6) == 0; + will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE); + + if (r->args + && !will_escape + && *(ap_scan_vchar_obstext(r->args))) { + /* + * We have a raw control character or a ' ' in r->args. + * Correct encoding was missed. + */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10411) + "Rewritten query string contains control " + "characters or spaces"); + return HTTP_FORBIDDEN; + } if (ACTION_STATUS == rulestatus) { int n = r->status; @@ -4986,8 +5095,7 @@ static int hook_fixup(request_rec *r) return n; } - l = strlen(r->filename); - if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) { + if (to_proxyreq) { /* it should go on as an internal proxy request */ /* make sure the QUERY_STRING and @@ -5011,7 +5119,7 @@ static int hook_fixup(request_rec *r) "%s [OK]", r->filename)); return OK; } - else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) { + else if (skip_absolute > 0) { /* it was finally rewritten to a remote URL */ /* because we are in a per-dir context @@ -5020,7 +5128,7 @@ static int hook_fixup(request_rec *r) */ if (dconf->baseurl != NULL) { /* skip 'scheme://' */ - cp = r->filename + skip; + cp = r->filename + skip_absolute; if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) { rewritelog((r, 2, dconf->directory, @@ -5065,7 +5173,7 @@ static int hook_fixup(request_rec *r) if (rulestatus != ACTION_NOESCAPE) { rewritelog((r, 1, dconf->directory, "escaping %s for redirect", r->filename)); - r->filename = escape_absolute_uri(r->pool, r->filename, skip); + r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute); } /* append the QUERY_STRING part */ diff --git a/modules/mappers/mod_rewrite.mak b/modules/mappers/mod_rewrite.mak index 3b08cab..860dd8b 100644 --- a/modules/mappers/mod_rewrite.mak +++ b/modules/mappers/mod_rewrite.mak @@ -62,7 +62,7 @@ CLEAN : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /c +CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< @@ -166,7 +166,7 @@ CLEAN : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /EHsc /c +CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../database" /I "../ssl" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../server" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_rewrite_src" /FD /EHsc /c .c{$(INTDIR)}.obj:: $(CPP) @<< diff --git a/modules/mappers/mod_speling.c b/modules/mappers/mod_speling.c index 3e97423..2ed65eb 100644 --- a/modules/mappers/mod_speling.c +++ b/modules/mappers/mod_speling.c @@ -22,8 +22,6 @@ #define APR_WANT_STRFUNC #include "apr_want.h" -#define WANT_BASENAME_MATCH - #include "httpd.h" #include "http_core.h" #include "http_config.h" @@ -59,7 +57,8 @@ module AP_MODULE_DECLARE_DATA speling_module; typedef struct { int enabled; - int case_only; + int check_case_only; + int check_basename_match; } spconfig; /* @@ -76,7 +75,8 @@ static void *mkconfig(apr_pool_t *p) spconfig *cfg = apr_pcalloc(p, sizeof(spconfig)); cfg->enabled = 0; - cfg->case_only = 0; + cfg->check_case_only = 0; + cfg->check_basename_match = 1; return cfg; } @@ -107,8 +107,11 @@ static const command_rec speling_cmds[] = (void*)APR_OFFSETOF(spconfig, enabled), OR_OPTIONS, "whether or not to fix miscapitalized/misspelled requests"), AP_INIT_FLAG("CheckCaseOnly", ap_set_flag_slot, - (void*)APR_OFFSETOF(spconfig, case_only), OR_OPTIONS, + (void*)APR_OFFSETOF(spconfig, check_case_only), OR_OPTIONS, "whether or not to fix only miscapitalized requests"), + AP_INIT_FLAG("CheckBasenameMatch", ap_set_flag_slot, + (void*)APR_OFFSETOF(spconfig, check_basename_match), OR_OPTIONS, + "whether or not to fix files with the same base name"), { NULL } }; @@ -302,7 +305,7 @@ static int check_speling(request_rec *r) * simple typing errors are checked next (like, e.g., * missing/extra/transposed char) */ - else if ((cfg->case_only == 0) + else if ((cfg->check_case_only == 0) && ((q = spdist(bad, dirent.name)) != SP_VERYDIFFERENT)) { misspelled_file *sp_new; @@ -316,22 +319,14 @@ static int check_speling(request_rec *r) * requests. It is of questionable use to continue looking for * files with the same base name, but potentially of totally wrong * type (index.html <-> index.db). - * I would propose to not set the WANT_BASENAME_MATCH define. - * 08-Aug-1997 <Martin.Kraemer@Mch.SNI.De> * - * However, Alexei replied giving some reasons to add it anyway: - * > Oh, by the way, I remembered why having the - * > extension-stripping-and-matching stuff is a good idea: - * > - * > If you're using MultiViews, and have a file named foobar.html, - * > which you refer to as "foobar", and someone tried to access - * > "Foobar", mod_speling won't find it, because it won't find - * > anything matching that spelling. With the extension-munging, - * > it would locate "foobar.html". Not perfect, but I ran into - * > that problem when I first wrote the module. + * If you're using MultiViews, and have a file named foobar.html, + * which you refer to as "foobar", and someone tried to access + * "Foobar", without CheckBasenameMatch, mod_speling won't find it, + * because it won't find anything matching that spelling. + * With the extension-munging, it would locate "foobar.html". */ - else { -#ifdef WANT_BASENAME_MATCH + else if (cfg->check_basename_match == 1) { /* * Okay... we didn't find anything. Now we take out the hard-core * power tools. There are several cases here. Someone might have @@ -356,7 +351,6 @@ static int check_speling(request_rec *r) sp_new->name = apr_pstrdup(r->pool, dirent.name); sp_new->quality = SP_VERYDIFFERENT; } -#endif } } apr_dir_close(dir); @@ -425,6 +419,7 @@ static int check_speling(request_rec *r) if (apr_pool_create(&sub_pool, p) != APR_SUCCESS) return DECLINED; + apr_pool_tag(sub_pool, "speling_sub"); t = apr_array_make(sub_pool, candidates->nelts * 8 + 8, sizeof(char *)); diff --git a/modules/mappers/mod_vhost_alias.c b/modules/mappers/mod_vhost_alias.c index 0b61694..b1e5bfb 100644 --- a/modules/mappers/mod_vhost_alias.c +++ b/modules/mappers/mod_vhost_alias.c @@ -152,7 +152,7 @@ static const char *vhost_alias_set(cmd_parms *cmd, void *dummy, const char *map) } if (!ap_os_is_path_absolute(cmd->pool, map)) { - if (strcasecmp(map, "none")) { + if (ap_cstr_casecmp(map, "none")) { return "format string must be an absolute path, or 'none'"; } *pmap = NULL; |