@@ -341,8 +341,7 @@ void add_exclude(const char *string, const char *base,
341
341
x -> flags = flags ;
342
342
if (!strchr (string , '/' ))
343
343
x -> flags |= EXC_FLAG_NODIR ;
344
- if (no_wildcard (string ))
345
- x -> flags |= EXC_FLAG_NOWILDCARD ;
344
+ x -> nowildcardlen = simple_length (string );
346
345
if (* string == '*' && no_wildcard (string + 1 ))
347
346
x -> flags |= EXC_FLAG_ENDSWITH ;
348
347
ALLOC_GROW (which -> excludes , which -> nr + 1 , which -> alloc );
@@ -518,8 +517,9 @@ int excluded_from_list(const char *pathname,
518
517
519
518
for (i = el -> nr - 1 ; 0 <= i ; i -- ) {
520
519
struct exclude * x = el -> excludes [i ];
521
- const char * exclude = x -> pattern ;
520
+ const char * name , * exclude = x -> pattern ;
522
521
int to_exclude = x -> to_exclude ;
522
+ int namelen , prefix = x -> nowildcardlen ;
523
523
524
524
if (x -> flags & EXC_FLAG_MUSTBEDIR ) {
525
525
if (* dtype == DT_UNKNOWN )
@@ -530,7 +530,7 @@ int excluded_from_list(const char *pathname,
530
530
531
531
if (x -> flags & EXC_FLAG_NODIR ) {
532
532
/* match basename */
533
- if (x -> flags & EXC_FLAG_NOWILDCARD ) {
533
+ if (prefix == x -> patternlen ) {
534
534
if (!strcmp_icase (exclude , basename ))
535
535
return to_exclude ;
536
536
} else if (x -> flags & EXC_FLAG_ENDSWITH ) {
@@ -544,26 +544,37 @@ int excluded_from_list(const char *pathname,
544
544
continue ;
545
545
}
546
546
547
-
548
547
/* match with FNM_PATHNAME:
549
548
* exclude has base (baselen long) implicitly in front of it.
550
549
*/
551
- if (* exclude == '/' )
550
+ if (* exclude == '/' ) {
552
551
exclude ++ ;
552
+ prefix -- ;
553
+ }
553
554
554
555
if (pathlen < x -> baselen ||
555
556
(x -> baselen && pathname [x -> baselen - 1 ] != '/' ) ||
556
557
strncmp_icase (pathname , x -> base , x -> baselen ))
557
558
continue ;
558
559
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 ;
566
574
}
575
+
576
+ if (!namelen || !fnmatch_icase (exclude , name , FNM_PATHNAME ))
577
+ return to_exclude ;
567
578
}
568
579
return -1 ; /* undecided */
569
580
}
0 commit comments