diff options
author | Ulrich Drepper <drepper@redhat.com> | 2000-07-28 19:52:40 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2000-07-28 19:52:40 +0000 |
commit | 5e4633932782f08412e8cee75236f4f458591a3d (patch) | |
tree | 692ccf39058d6d1df8ac1067462731b8b7d8dfb1 /posix/fnmatch.c | |
parent | eac4282fa6325e5633bdfee7a6afd9f943b34b1a (diff) | |
download | glibc-5e4633932782f08412e8cee75236f4f458591a3d.tar.gz |
Update.
2000-07-27 Bruno Haible <haible@clisp.cons.org>
* locale/C-ctype.c (_nl_C_LC_CTYPE): Swap the two names in
_NL_CTYPE_MAP_NAMES.
* locale/localeinfo.h (__TOW_toupper, __TOW_tolower): New enum values.
* wctype/wcfuncs.c (towlower, towupper): Use them.
* wctype/wcfuncs_l.c (__towlower_l, __towupper_l): Likewise.
* wctype/wctrans.c (wctrans): Likewise.
* wctype/wctrans_l.c (__wctrans_l): Likewise.
2000-07-27 Bruno Haible <haible@clisp.cons.org>
* posix/fnmatch.c (is_char_class): Fix logic. Avoid buffer overrun.
Use the optimized version of this function outside glibc as well.
Diffstat (limited to 'posix/fnmatch.c')
-rw-r--r-- | posix/fnmatch.c | 83 |
1 files changed, 49 insertions, 34 deletions
diff --git a/posix/fnmatch.c b/posix/fnmatch.c index 62cfa5fee5..b6f67ae0b3 100644 --- a/posix/fnmatch.c +++ b/posix/fnmatch.c @@ -224,13 +224,13 @@ __wcschrnul (s, c) # define SUFFIX WC # define WIDE_CHAR_VERSION 1 - # undef IS_CHAR_CLASS -# ifdef _LIBC /* We have to convert the wide character string in a multibyte string. But - we know that the character class names are ASCII strings and since the - internal wide character encoding is UCS4 we can use a simplified method - to convert the string to a multibyte character string. */ + we know that the character class names consist of alphanumeric characters + from the portable character set, and since the wide character encoding + for a member of the portable character set is the same code point as + its single-byte encoding, we can use a simplified method to convert the + string to a multibyte character string. */ static wctype_t is_char_class (const wchar_t *wcs) { @@ -239,47 +239,62 @@ is_char_class (const wchar_t *wcs) do { - if (*wcs < 0x20 || *wcs >= 0x7f) - return 0; - - *cp++ = (char) *wcs; - } - while (*wcs++ != L'\0'); - - return __wctype (s); -} + /* Test for a printable character from the portable character set. */ +# ifdef _LIBC + if (*wcs < 0x20 || *wcs > 0x7e + || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60) + return (wctype_t) 0; # else -/* Since we cannot assume anything about the internal encoding we have to - convert the string back to multibyte representation the hard way. */ -static wctype_t -is_char_class (const wchar_t *wcs) -{ - mbstate_t ps; - const wchar_t *pwc; - char *s; - size_t n; + switch (*wcs) + { + case L' ': case L'!': case L'"': case L'#': case L'%': + case L'&': case L'\'': case L'(': case L')': case L'*': + case L'+': case L',': case L'-': case L'.': case L'/': + case L'0': case L'1': case L'2': case L'3': case L'4': + case L'5': case L'6': case L'7': case L'8': case L'9': + case L':': case L';': case L'<': case L'=': case L'>': + case L'?': + case L'A': case L'B': case L'C': case L'D': case L'E': + case L'F': case L'G': case L'H': case L'I': case L'J': + case L'K': case L'L': case L'M': case L'N': case L'O': + case L'P': case L'Q': case L'R': case L'S': case L'T': + case L'U': case L'V': case L'W': case L'X': case L'Y': + case L'Z': + case L'[': case L'\\': case L']': case L'^': case L'_': + case L'a': case L'b': case L'c': case L'd': case L'e': + case L'f': case L'g': case L'h': case L'i': case L'j': + case L'k': case L'l': case L'm': case L'n': case L'o': + case L'p': case L'q': case L'r': case L's': case L't': + case L'u': case L'v': case L'w': case L'x': case L'y': + case L'z': case L'{': case L'|': case L'}': case L'~': + break; + default: + return (wctype_t) 0; + } +# endif - memset (&ps, '\0', sizeof (ps)); + /* Avoid overrunning the buffer. */ + if (cp == s + CHAR_CLASS_MAX_LENGTH) + return (wctype_t) 0; - pwc = wcs; - n = wcsrtombs (NULL, &pwc, 0, &ps); - if (n == (size_t) -1) - /* Something went wrong. */ - return 0; + *cp++ = (char) *wcs++; + } + while (*wcs != L'\0'); - s = alloca (n + 1); - assert (mbsinit (&ps)); - pwc = wcs; - (void) wcsrtombs (s, &pwc, n + 1, &ps); + *cp = '\0'; +# ifdef _LIBC + return __wctype (s); +# else return wctype (s); -} # endif +} # define IS_CHAR_CLASS(string) is_char_class (string) # include "fnmatch_loop.c" # endif + int fnmatch (pattern, string, flags) const char *pattern; |