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;
}
}