From f96ecb7c51c007dccdd2c9cdf0536171b51d24c5 Mon Sep 17 00:00:00 2001 From: "William A. Rowe Jr" Date: Sat, 4 Aug 2001 04:32:59 +0000 Subject: [PATCH] Subtle variation for security. If the mod_mime file has nothing specific to say about a given set of file extentions (and has only based the resolved fields on the default language, encoding and content type) then tell us we can ignore the result by leaving the exception list entirely undefined. If mod_mime adds anything (a language, charset, or whatnot) then proceed to use the file in the Multiviews evaluation, otherwise mod_negotation will ignore the file found. This points out a need for a slightly twisted DefaultClientLanguage, as opposed to creating foo.html.html files. Either that, or introduce a 'neutral' entity that the user can list (say, .default) for mod_mime to declare it as a fallback language/encoding/content-type/handler. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89919 13f79535-47bb-0310-9956-ffa450edef68 --- modules/http/mod_mime.c | 10 +++-- modules/mappers/mod_negotiation.c | 61 ++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/modules/http/mod_mime.c b/modules/http/mod_mime.c index c16bd92c25..6d0e73ebea 100644 --- a/modules/http/mod_mime.c +++ b/modules/http/mod_mime.c @@ -787,6 +787,7 @@ static int find_ct(request_rec *r) char *ext; const char *type; const char *charset = NULL; + int found_any = 0; apr_array_header_t *exception_list = apr_array_make(r->pool, 2, sizeof(char *)); @@ -869,15 +870,18 @@ static int find_ct(request_rec *r) /* Not good... nobody claims it. */ - if (!found) + if (found) + found_any = 1; + else *((const char **) apr_array_push(exception_list)) = ext; } /* * Need to set a notes entry on r for unrecognized elements. - * Somebody better claim them! + * Somebody better claim them! If we did absolutely nothing, + * skip the notes to alert mod_negotiation we are clueless. */ - if (exception_list->nelts) { + if (found_any) { apr_table_setn(r->notes, "ap-mime-exceptions-list", (void *)exception_list); } diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c index 4d972b6935..30392adc82 100644 --- a/modules/mappers/mod_negotiation.c +++ b/modules/mappers/mod_negotiation.c @@ -962,36 +962,54 @@ static int read_types_multi(negotiation_state *neg) sub_req->content_type = CGI_MAGIC_TYPE; } + /* + * mod_mime will _always_ provide us the base name in the + * ap-mime-exception-list, if it processed anything. If + * this list is empty, give up immediately, there was + * nothing interesting. For example, looking at the files + * readme.txt and readme.foo, we will throw away .foo if + * it's an insignificant file (e.g. did not identify a + * language, charset, encoding, content type or handler,) + */ exception_list = (apr_array_header_t *)apr_table_get(sub_req->notes, "ap-mime-exceptions-list"); - if (exception_list) { - /* Every last missing bit danged well better be in our table! - * Simple enough for now, every unregonized bit better match - * our base name. When we break up our base name and allow - * index.en to match index.html.en, this gets tricker. - */ - char *base = apr_array_pstrcat(sub_req->pool, exception_list, '.'); - int base_len = strlen(base); - if (base_len > prefix_len + + if (!exception_list) { + ap_destroy_sub_req(sub_req); + continue; + } + + /* + * Simple enough for now, every unregonized bit better match + * our base name. When we break up our base name and allow + * index.en to match index.html.en, this gets tricker. + * XXX: index.html.foo won't be caught by testing index.html + * since the exceptions result is index.foo - this should be + * fixed as part of a new match-parts logic here. + */ + char *base = apr_array_pstrcat(sub_req->pool, exception_list, '.'); + int base_len = strlen(base); + if (base_len > prefix_len #ifdef CASE_BLIND_FILESYSTEM - || strncasecmp(base, filp, base_len) + || strncasecmp(base, filp, base_len) #else - || strncmp(base, filp, base_len) + || strncmp(base, filp, base_len) #endif - || (prefix_len > base_len && filp[base_len] != '.')) { - /* - * Something you don't know is, something you don't know... - */ - ap_destroy_sub_req(sub_req); - continue; - } + || (prefix_len > base_len && filp[base_len] != '.')) { + /* + * Something you don't know is, something you don't know... + */ + ap_destroy_sub_req(sub_req); + continue; } - /* XXX If we successfully negotate ANYTHING, continue + /* + * ###: be warned, the _default_ content type is already + * picked up here! If we failed the subrequest, or don't + * know what we are serving, then continue. */ - if (sub_req->status != HTTP_OK || - (!sub_req->content_type && !exception_list)) { + if (sub_req->status != HTTP_OK || (!sub_req->content_type) { ap_destroy_sub_req(sub_req); continue; } @@ -999,7 +1017,6 @@ static int read_types_multi(negotiation_state *neg) /* If it's a map file, we use that instead of the map * we're building... */ - if (((sub_req->content_type) && !strcmp(sub_req->content_type, MAP_FILE_MAGIC_TYPE)) || ((sub_req->handler) && -- 2.40.0