diff options
Diffstat (limited to 'posix')
-rw-r--r-- | posix/fnmatch.c | 42 | ||||
-rw-r--r-- | posix/testfnm.c | 3 |
2 files changed, 32 insertions, 13 deletions
diff --git a/posix/fnmatch.c b/posix/fnmatch.c index b147f47d36..eb3f1cc2d4 100644 --- a/posix/fnmatch.c +++ b/posix/fnmatch.c @@ -157,7 +157,9 @@ internal_fnmatch (const char *pattern, const char *string, return FNM_NOMATCH; else if (*n == '/' && (flags & FNM_FILE_NAME)) return FNM_NOMATCH; - else if (*n == '.' && no_leading_period) + else if (*n == '.' && no_leading_period + && (n == string + || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) return FNM_NOMATCH; break; @@ -175,7 +177,9 @@ internal_fnmatch (const char *pattern, const char *string, break; case '*': - if (*n == '.' && no_leading_period) + if (*n == '.' && no_leading_period + && (n == string + || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) return FNM_NOMATCH; for (c = *p++; c == '?' || c == '*'; c = *p++) @@ -212,11 +216,17 @@ internal_fnmatch (const char *pattern, const char *string, if (c == '[') { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + for (--p; n < endp; ++n) if (internal_fnmatch (p, n, - (n == string) && no_leading_period, - ((flags & FNM_FILE_NAME) - ? flags : (flags & ~FNM_PERIOD))) + (no_leading_period + && (n == string + || (n[-1] == '/' + && (flags + & FNM_FILE_NAME)))), + flags2) == 0) return 0; } @@ -231,18 +241,21 @@ internal_fnmatch (const char *pattern, const char *string, } else { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + if (c == '\\' && !(flags & FNM_NOESCAPE)) c = *p; c = FOLD (c); for (--p; n < endp; ++n) if (FOLD ((unsigned char) *n) == c && (internal_fnmatch (p, n, - ((n == string) - && no_leading_period), - ((flags & FNM_FILE_NAME) - ? flags - : (flags & ~FNM_PERIOD))) - == 0)) + (no_leading_period + && (n == string + || (n[-1] == '/' + && (flags + & FNM_FILE_NAME)))), + flags2) == 0)) return 0; } } @@ -263,7 +276,10 @@ internal_fnmatch (const char *pattern, const char *string, if (*n == '\0') return FNM_NOMATCH; - if (*n == '.' && no_leading_period) + if (*n == '.' && no_leading_period && (n == string + || (n[-1] == '/' + && (flags + & FNM_FILE_NAME)))) return FNM_NOMATCH; if (*n == '/' && (flags & FNM_FILE_NAME)) @@ -297,7 +313,7 @@ internal_fnmatch (const char *pattern, const char *string, # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) wctype_t wt; # endif - char *startp = p; + const char *startp = p; for (;;) { diff --git a/posix/testfnm.c b/posix/testfnm.c index e300565b1b..ebdfab41de 100644 --- a/posix/testfnm.c +++ b/posix/testfnm.c @@ -48,6 +48,9 @@ struct { { "a/b", "*[![:digit:]]*/[![:d-d]", FNM_PATHNAME, 0 }, { "a/[", "*[![:digit:]]*/[[:d-d]", FNM_PATHNAME, 0 }, { "a/[", "*[![:digit:]]*/[![:d-d]", FNM_PATHNAME, FNM_NOMATCH }, + { "a.b", "a?b", FNM_PATHNAME|FNM_PERIOD, 0 }, + { "a.b", "a*b", FNM_PATHNAME|FNM_PERIOD, 0 }, + { "a.b", "a[.]b", FNM_PATHNAME|FNM_PERIOD, 0 }, }; int |