coar 99/05/03 13:48:44
Modified: src/modules/standard mod_autoindex.c Log: Improve the filename pattern matching so that we only do wildcard processing when we must, and simple scanning when we can. Revision Changes Path 1.106 +49 -13 apache-1.3/src/modules/standard/mod_autoindex.c Index: mod_autoindex.c =================================================================== RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_autoindex.c,v retrieving revision 1.105 retrieving revision 1.106 diff -u -r1.105 -r1.106 --- mod_autoindex.c 1999/05/03 19:05:17 1.105 +++ mod_autoindex.c 1999/05/03 20:48:43 1.106 @@ -136,6 +136,7 @@ char *pattern; char *description; int full_path; + int wildcards; } ai_desc_t; typedef struct autoindex_config_struct { @@ -269,16 +270,27 @@ } /* - * Add description text for a filename pattern. Prefix the pattern - * with a wildcard unless it begins with '/' signifying an absolute - * path. If the pattern contains a '/' anywhere, add a slash to the - * prefix so that "bar/bletch" won't be matched by "foobar/bletch", - * and make a note that there's a delimiter; the matching routine - * simplifies to just the actual filename whenever it can. This allows - * definitions in parent directories to be made for files in subordinate - * ones using relative paths. Always postfix with a wildard so that - * partial or leading names will match. + * Add description text for a filename pattern. If the pattern has + * wildcards already (or we need to add them), add leading and + * trailing wildcards to it to ensure substring processing. If the + * pattern contains a '/' anywhere, force wildcard matching mode, + * add a slash to the prefix so that "bar/bletch" won't be matched + * by "foobar/bletch", and make a note that there's a delimiter; + * the matching routine simplifies to just the actual filename + * whenever it can. This allows definitions in parent directories + * to be made for files in subordinate ones using relative paths. */ + +/* + * Absent a strcasestr() function, we have to force wildcards on + * systems for which "AAA" and "aaa" mean the same file. + */ +#ifdef CASE_BLIND_FILESYSTEM +#define WILDCARDS_REQUIRED 1 +#else +#define WILDCARDS_REQUIRED 0 +#endif + static const char *add_desc(cmd_parms *cmd, void *d, char *desc, char *to) { autoindex_config_rec *dcfg = (autoindex_config_rec *) d; @@ -287,11 +299,17 @@ desc_entry = (ai_desc_t *) ap_push_array(dcfg->desc_list); desc_entry->full_path = (strchr(to, '/') == NULL) ? 0 : 1; - if (*to != '/') { + desc_entry->wildcards = (WILDCARDS_REQUIRED + || desc_entry->full_path + || ap_is_fnmatch(to)); + if (desc_entry->wildcards) { prefix = desc_entry->full_path ? "*/" : "*"; + desc_entry->pattern = ap_pstrcat(dcfg->desc_list->pool, + prefix, to, "*", NULL); } - desc_entry->pattern = ap_pstrcat(dcfg->desc_list->pool, - prefix, to, "*", NULL); + else { + desc_entry->pattern = ap_pstrdup(dcfg->desc_list->pool, to); + } desc_entry->description = ap_pstrdup(dcfg->desc_list->pool, desc); return NULL; } @@ -745,6 +763,13 @@ * same as the order in which directives were processed, earlier matching * directives will dominate. */ + +#ifdef CASE_BLIND_FILESYSTEM +#define MATCH_FLAGS FNM_CASE_BLIND +#else +#define MATCH_FLAGS 0 +#endif + static char *find_desc(autoindex_config_rec *dcfg, request_rec *r) { int i; @@ -765,12 +790,23 @@ } for (i = 0; i < dcfg->desc_list->nelts; ++i) { ai_desc_t *tuple = &list[i]; + int found; /* * Only use the full-path filename if the pattern contains '/'s. */ filename = (tuple->full_path) ? filename_full : filename_only; - if (ap_fnmatch(tuple->pattern, filename, 0) == 0) { + /* + * Make the comparison using the cheapest method; only do + * wildcard checking if we must. + */ + if (tuple->wildcards) { + found = (ap_fnmatch(tuple->pattern, filename, MATCH_FLAGS) == 0); + } + else { + found = (strstr(filename, tuple->pattern) != NULL); + } + if (found) { return tuple->description; } }