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

Reply via email to