diff --git a/src/regex/fnmatch.c b/src/regex/fnmatch.c index 4df10a3c..7f6b65f3 100644 --- a/src/regex/fnmatch.c +++ b/src/regex/fnmatch.c @@ -97,7 +97,13 @@ escaped: return pat[0]; } -static int match_bracket(const char *p, int k) +static int casefold(int k) +{ + int c = towupper(k); + return c == k ? towlower(k) : c; +} + +static int match_bracket(const char *p, int k, int kfold) { wchar_t wc; int inv = 0; @@ -119,7 +125,10 @@ static int match_bracket(const char *p, int k) wchar_t wc2; int l = mbtowc(&wc2, p+1, 4); if (l < 0) return 0; - if (wc<=wc2 && (unsigned)k-wc <= wc2-wc) return !inv; + if (wc <= wc2) + if ((unsigned)k-wc <= wc2-wc || + (unsigned)kfold-wc <= wc2-wc) + return !inv; p += l-1; continue; } @@ -132,7 +141,9 @@ static int match_bracket(const char *p, int k) char buf[16]; memcpy(buf, p0, p-1-p0); buf[p-1-p0] = 0; - if (iswctype(k, wctype(buf))) return !inv; + if (iswctype(k, wctype(buf)) || + iswctype(kfold, wctype(buf))) + return !inv; } continue; } @@ -143,7 +154,7 @@ static int match_bracket(const char *p, int k) if (l < 0) return 0; p += l-1; } - if (wc==k) return !inv; + if (wc==k || wc==kfold) return !inv; } return inv; } @@ -153,7 +164,7 @@ static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n const char *p, *ptail, *endpat; const char *s, *stail, *endstr; size_t pinc, sinc, tailcnt=0; - int c, k; + int c, k, kfold; if (flags & FNM_PERIOD) { if (*str == '.' && *pat != '.') @@ -173,10 +184,11 @@ static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n return (c==END) ? 0 : FNM_NOMATCH; str += sinc; n -= sinc; + kfold = flags & FNM_CASEFOLD ? casefold(k) : k; if (c == BRACKET) { - if (!match_bracket(pat, k)) + if (!match_bracket(pat, k, kfold)) return FNM_NOMATCH; - } else if (c != QUESTION && k != c) { + } else if (c != QUESTION && k != c && kfold != c) { return FNM_NOMATCH; } pat+=pinc; @@ -233,10 +245,11 @@ static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n break; } s += sinc; + kfold = flags & FNM_CASEFOLD ? casefold(k) : k; if (c == BRACKET) { - if (!match_bracket(p-pinc, k)) + if (!match_bracket(p-pinc, k, kfold)) return FNM_NOMATCH; - } else if (c != QUESTION && k != c) { + } else if (c != QUESTION && k != c && kfold != c) { return FNM_NOMATCH; } } @@ -261,10 +274,11 @@ static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n k = str_next(s, endstr-s, &sinc); if (!k) return FNM_NOMATCH; + kfold = flags & FNM_CASEFOLD ? casefold(k) : k; if (c == BRACKET) { - if (!match_bracket(p-pinc, k)) + if (!match_bracket(p-pinc, k, kfold)) break; - } else if (c != QUESTION && k != c) { + } else if (c != QUESTION && k != c && kfold != c) { break; } s += sinc;