@@ -341,8 +341,7 @@ void add_exclude(const char *string, const char *base,
341341 x -> flags = flags ;
342342 if (!strchr (string , '/' ))
343343 x -> flags |= EXC_FLAG_NODIR ;
344- if (no_wildcard (string ))
345- x -> flags |= EXC_FLAG_NOWILDCARD ;
344+ x -> nowildcardlen = simple_length (string );
346345 if (* string == '*' && no_wildcard (string + 1 ))
347346 x -> flags |= EXC_FLAG_ENDSWITH ;
348347 ALLOC_GROW (which -> excludes , which -> nr + 1 , which -> alloc );
@@ -518,8 +517,9 @@ int excluded_from_list(const char *pathname,
518517
519518 for (i = el -> nr - 1 ; 0 <= i ; i -- ) {
520519 struct exclude * x = el -> excludes [i ];
521- const char * exclude = x -> pattern ;
520+ const char * name , * exclude = x -> pattern ;
522521 int to_exclude = x -> to_exclude ;
522+ int namelen , prefix = x -> nowildcardlen ;
523523
524524 if (x -> flags & EXC_FLAG_MUSTBEDIR ) {
525525 if (* dtype == DT_UNKNOWN )
@@ -530,7 +530,7 @@ int excluded_from_list(const char *pathname,
530530
531531 if (x -> flags & EXC_FLAG_NODIR ) {
532532 /* match basename */
533- if (x -> flags & EXC_FLAG_NOWILDCARD ) {
533+ if (prefix == x -> patternlen ) {
534534 if (!strcmp_icase (exclude , basename ))
535535 return to_exclude ;
536536 } else if (x -> flags & EXC_FLAG_ENDSWITH ) {
@@ -544,26 +544,37 @@ int excluded_from_list(const char *pathname,
544544 continue ;
545545 }
546546
547-
548547 /* match with FNM_PATHNAME:
549548 * exclude has base (baselen long) implicitly in front of it.
550549 */
551- if (* exclude == '/' )
550+ if (* exclude == '/' ) {
552551 exclude ++ ;
552+ prefix -- ;
553+ }
553554
554555 if (pathlen < x -> baselen ||
555556 (x -> baselen && pathname [x -> baselen - 1 ] != '/' ) ||
556557 strncmp_icase (pathname , x -> base , x -> baselen ))
557558 continue ;
558559
559- if (x -> flags & EXC_FLAG_NOWILDCARD ) {
560- if (!strcmp_icase (exclude , pathname + x -> baselen ))
561- return to_exclude ;
562- } else {
563- if (fnmatch_icase (exclude , pathname + x -> baselen ,
564- FNM_PATHNAME ) == 0 )
565- return to_exclude ;
560+ namelen = x -> baselen ? pathlen - x -> baselen : pathlen ;
561+ name = pathname + pathlen - namelen ;
562+
563+ /* if the non-wildcard part is longer than the
564+ remaining pathname, surely it cannot match */
565+ if (prefix > namelen )
566+ continue ;
567+
568+ if (prefix ) {
569+ if (strncmp_icase (exclude , name , prefix ))
570+ continue ;
571+ exclude += prefix ;
572+ name += prefix ;
573+ namelen -= prefix ;
566574 }
575+
576+ if (!namelen || !fnmatch_icase (exclude , name , FNM_PATHNAME ))
577+ return to_exclude ;
567578 }
568579 return -1 ; /* undecided */
569580}
0 commit comments