fix fnmatch corner cases related to escaping

the FNM_PATHNAME logic for advancing by /-delimited components was
incorrect when the / character was escaped (i.e. \/), and a final \ at
the end of pattern was not handled correctly.
This commit is contained in:
Rich Felker 2013-12-01 14:36:22 -05:00
parent da0fcdb8e9
commit 6ec82a3b58
1 changed files with 4 additions and 4 deletions

View File

@ -19,7 +19,7 @@
#include <wchar.h> #include <wchar.h>
#include <wctype.h> #include <wctype.h>
#define END -1 #define END 0
#define UNMATCHABLE -2 #define UNMATCHABLE -2
#define BRACKET -3 #define BRACKET -3
#define QUESTION -4 #define QUESTION -4
@ -53,7 +53,7 @@ static int pat_next(const char *pat, size_t m, size_t *step, int flags)
return END; return END;
} }
*step = 1; *step = 1;
if (pat[0]=='\\' && !(flags & FNM_NOESCAPE)) { if (pat[0]=='\\' && pat[1] && !(flags & FNM_NOESCAPE)) {
*step = 2; *step = 2;
pat++; pat++;
esc = 1; esc = 1;
@ -288,12 +288,12 @@ int fnmatch(const char *pat, const char *str, int flags)
if (flags & FNM_PATHNAME) for (;;) { if (flags & FNM_PATHNAME) for (;;) {
for (s=str; *s && *s!='/'; s++); for (s=str; *s && *s!='/'; s++);
for (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc); for (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc);
if (*p!=*s) return FNM_NOMATCH; if (c!=*s) return FNM_NOMATCH;
if (fnmatch_internal(pat, p-pat, str, s-str, flags)) if (fnmatch_internal(pat, p-pat, str, s-str, flags))
return FNM_NOMATCH; return FNM_NOMATCH;
if (!*s) return 0; if (!*s) return 0;
str = s+1; str = s+1;
pat = p+1; pat = p+inc;
} }
return fnmatch_internal(pat, -1, str, -1, flags); return fnmatch_internal(pat, -1, str, -1, flags);
} }