From 9af2172ee42a59d9280cdfef0bb7c0b2be6c954b Mon Sep 17 00:00:00 2001 From: Bill Stoddard Date: Wed, 3 Oct 2001 22:35:19 +0000 Subject: [PATCH] Fix a mismatching issue, where index.html.foo.en had recognized .html and .en components, and exceptions index and foo. This patch will ignore the 'missing' exception html from the request, and go on to test the exception foo in the list. This does -not- imply that a request for index.foo will succeed, in the example above. The pattern match tests index.foo[.*] so we wouldn't find index.html.foo.anything. The pattern matching proposed at one time by Francis Daly would allow index.foo to succeed as well [although many to many matching is dangerous, see comments in this patch.] Port of patch from 2.0 by Bill Rowe git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@91266 13f79535-47bb-0310-9956-ffa450edef68 --- src/modules/standard/mod_negotiation.c | 45 +++++++++++++++++--------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/modules/standard/mod_negotiation.c b/src/modules/standard/mod_negotiation.c index 44863b076da..f32be3b342a 100644 --- a/src/modules/standard/mod_negotiation.c +++ b/src/modules/standard/mod_negotiation.c @@ -972,26 +972,41 @@ static int read_types_multi(negotiation_state *neg) continue; } - /* - * Simple enough for now, every unreconized 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. + /* Each unregonized bit better match our base name, in sequence. + * A test of index.html.foo will match index.foo or index.html.foo, + * but it will never transpose the segments and allow index.foo.html + * because that would introduce too much CPU consumption. Better that + * we don't attempt a many-to-many match here. */ { - char *base = ap_array_pstrcat(sub_req->pool, exception_list, '.'); - int base_len = strlen(base); - if (base_len > prefix_len + int nexcept = exception_list->nelts; + char **cur_except = (char**)exception_list->elts; + char *segstart = filp, *segend, saveend; + + while (*segstart && nexcept) { + if (!(segend = strchr(segstart, '.'))) + segend = strchr(segstart, '\0'); + saveend = *segend; + *segend = '\0'; + #ifdef CASE_BLIND_FILESYSTEM - || strncasecmp(base, filp, base_len) + if (strcasecmp(segstart, *cur_except) == 0) { #else - || strncmp(base, filp, base_len) + if (strcmp(segstart, *cur_except) == 0) { #endif - || (prefix_len > base_len && filp[base_len] != '.')) { - /* - * Something you don't know is, something you don't know... + --nexcept; + ++cur_except; + } + + if (!saveend) + break; + + *segend = saveend; + segstart = segend + 1; + } + + if (nexcept) { + /* Something you don't know is, something you don't know... */ ap_destroy_sub_req(sub_req); continue; -- 2.47.2