1 /* Copyright (C) 1991-1993, 1996-2007, 2009-2012 Free Software Foundation, Inc. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; either version 3, or (at your option) 6 any later version. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program; if not, see <http://www.gnu.org/licenses/>. */ 15 16 #ifndef _LIBC 17 # include <config.h> 18 #endif 19 20 /* Enable GNU extensions in fnmatch.h. */ 21 #ifndef _GNU_SOURCE 22 # define _GNU_SOURCE 1 23 #endif 24 25 #if ! defined __builtin_expect && __GNUC__ < 3 26 # define __builtin_expect(expr, expected) (expr) 27 #endif 28 29 #include <fnmatch.h> 30 31 #include <alloca.h> 32 #include <assert.h> 33 #include <ctype.h> 34 #include <errno.h> 35 #include <stddef.h> 36 #include <stdbool.h> 37 #include <stdlib.h> 38 #include <string.h> 39 40 #define WIDE_CHAR_SUPPORT \ 41 (HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \ 42 && HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY)) 43 44 /* For platform which support the ISO C amendment 1 functionality we 45 support user defined character classes. */ 46 #if defined _LIBC || WIDE_CHAR_SUPPORT 47 # include <wctype.h> 48 # include <wchar.h> 49 #endif 50 51 /* We need some of the locale data (the collation sequence information) 52 but there is no interface to get this information in general. Therefore 53 we support a correct implementation only in glibc. */ 54 #ifdef _LIBC 55 # include "../locale/localeinfo.h" 56 # include "../locale/elem-hash.h" 57 # include "../locale/coll-lookup.h" 58 # include <shlib-compat.h> 59 60 # define CONCAT(a,b) __CONCAT(a,b) 61 # define mbsrtowcs __mbsrtowcs 62 # define fnmatch __fnmatch 63 extern int fnmatch (const char *pattern, const char *string, int flags); 64 #endif 65 66 #ifndef SIZE_MAX 67 # define SIZE_MAX ((size_t) -1) 68 #endif 69 70 /* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */ 71 #define NO_LEADING_PERIOD(flags) \ 72 ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD)) 73 74 /* Comment out all this code if we are using the GNU C Library, and are not 75 actually compiling the library itself, and have not detected a bug 76 in the library. This code is part of the GNU C 77 Library, but also included in many other GNU distributions. Compiling 78 and linking in this code is a waste when using the GNU C library 79 (especially if it is a shared library). Rather than having every GNU 80 program understand 'configure --with-gnu-libc' and omit the object files, 81 it is simpler to just do this in the source for each such file. */ 82 83 #if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU 84 85 86 # if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) 87 # define isblank(c) ((c) == ' ' || (c) == '\t') 88 # endif 89 90 # define STREQ(s1, s2) (strcmp (s1, s2) == 0) 91 92 # if defined _LIBC || WIDE_CHAR_SUPPORT 93 /* The GNU C library provides support for user-defined character classes 94 and the functions from ISO C amendment 1. */ 95 # ifdef CHARCLASS_NAME_MAX 96 # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX 97 # else 98 /* This shouldn't happen but some implementation might still have this 99 problem. Use a reasonable default value. */ 100 # define CHAR_CLASS_MAX_LENGTH 256 101 # endif 102 103 # ifdef _LIBC 104 # define IS_CHAR_CLASS(string) __wctype (string) 105 # else 106 # define IS_CHAR_CLASS(string) wctype (string) 107 # endif 108 109 # ifdef _LIBC 110 # define ISWCTYPE(WC, WT) __iswctype (WC, WT) 111 # else 112 # define ISWCTYPE(WC, WT) iswctype (WC, WT) 113 # endif 114 115 # if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC 116 /* In this case we are implementing the multibyte character handling. */ 117 # define HANDLE_MULTIBYTE 1 118 # endif 119 120 # else 121 # define CHAR_CLASS_MAX_LENGTH 6 /* Namely, 'xdigit'. */ 122 123 # define IS_CHAR_CLASS(string) \ 124 (STREQ (string, "alpha") || STREQ (string, "upper") \ 125 || STREQ (string, "lower") || STREQ (string, "digit") \ 126 || STREQ (string, "alnum") || STREQ (string, "xdigit") \ 127 || STREQ (string, "space") || STREQ (string, "print") \ 128 || STREQ (string, "punct") || STREQ (string, "graph") \ 129 || STREQ (string, "cntrl") || STREQ (string, "blank")) 130 # endif 131 132 /* Avoid depending on library functions or files 133 whose names are inconsistent. */ 134 135 /* Global variable. */ 136 static int posixly_correct; 137 138 # ifndef internal_function 139 /* Inside GNU libc we mark some function in a special way. In other 140 environments simply ignore the marking. */ 141 # define internal_function 142 # endif 143 144 /* Note that this evaluates C many times. */ 145 # define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) 146 # define CHAR char 147 # define UCHAR unsigned char 148 # define INT int 149 # define FCT internal_fnmatch 150 # define EXT ext_match 151 # define END end_pattern 152 # define L_(CS) CS 153 # ifdef _LIBC 154 # define BTOWC(C) __btowc (C) 155 # else 156 # define BTOWC(C) btowc (C) 157 # endif 158 # define STRLEN(S) strlen (S) 159 # define STRCAT(D, S) strcat (D, S) 160 # ifdef _LIBC 161 # define MEMPCPY(D, S, N) __mempcpy (D, S, N) 162 # else 163 # if HAVE_MEMPCPY 164 # define MEMPCPY(D, S, N) mempcpy (D, S, N) 165 # else 166 # define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) 167 # endif 168 # endif 169 # define MEMCHR(S, C, N) memchr (S, C, N) 170 # include "fnmatch_loop.c" 171 172 173 # if HANDLE_MULTIBYTE 174 # define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c)) 175 # define CHAR wchar_t 176 # define UCHAR wint_t 177 # define INT wint_t 178 # define FCT internal_fnwmatch 179 # define EXT ext_wmatch 180 # define END end_wpattern 181 # define L_(CS) L##CS 182 # define BTOWC(C) (C) 183 # ifdef _LIBC 184 # define STRLEN(S) __wcslen (S) 185 # define STRCAT(D, S) __wcscat (D, S) 186 # define MEMPCPY(D, S, N) __wmempcpy (D, S, N) 187 # else 188 # define STRLEN(S) wcslen (S) 189 # define STRCAT(D, S) wcscat (D, S) 190 # if HAVE_WMEMPCPY 191 # define MEMPCPY(D, S, N) wmempcpy (D, S, N) 192 # else 193 # define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N)) 194 # endif 195 # endif 196 # define MEMCHR(S, C, N) wmemchr (S, C, N) 197 # define WIDE_CHAR_VERSION 1 198 199 # undef IS_CHAR_CLASS 200 /* We have to convert the wide character string in a multibyte string. But 201 we know that the character class names consist of alphanumeric characters 202 from the portable character set, and since the wide character encoding 203 for a member of the portable character set is the same code point as 204 its single-byte encoding, we can use a simplified method to convert the 205 string to a multibyte character string. */ 206 static wctype_t 207 is_char_class (const wchar_t *wcs) 208 { 209 char s[CHAR_CLASS_MAX_LENGTH + 1]; 210 char *cp = s; 211 212 do 213 { 214 /* Test for a printable character from the portable character set. */ 215 # ifdef _LIBC 216 if (*wcs < 0x20 || *wcs > 0x7e 217 || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60) 218 return (wctype_t) 0; 219 # else 220 switch (*wcs) 221 { 222 case L' ': case L'!': case L'"': case L'#': case L'%': 223 case L'&': case L'\'': case L'(': case L')': case L'*': 224 case L'+': case L',': case L'-': case L'.': case L'/': 225 case L'0': case L'1': case L'2': case L'3': case L'4': 226 case L'5': case L'6': case L'7': case L'8': case L'9': 227 case L':': case L';': case L'<': case L'=': case L'>': 228 case L'?': 229 case L'A': case L'B': case L'C': case L'D': case L'E': 230 case L'F': case L'G': case L'H': case L'I': case L'J': 231 case L'K': case L'L': case L'M': case L'N': case L'O': 232 case L'P': case L'Q': case L'R': case L'S': case L'T': 233 case L'U': case L'V': case L'W': case L'X': case L'Y': 234 case L'Z': 235 case L'[': case L'\\': case L']': case L'^': case L'_': 236 case L'a': case L'b': case L'c': case L'd': case L'e': 237 case L'f': case L'g': case L'h': case L'i': case L'j': 238 case L'k': case L'l': case L'm': case L'n': case L'o': 239 case L'p': case L'q': case L'r': case L's': case L't': 240 case L'u': case L'v': case L'w': case L'x': case L'y': 241 case L'z': case L'{': case L'|': case L'}': case L'~': 242 break; 243 default: 244 return (wctype_t) 0; 245 } 246 # endif 247 248 /* Avoid overrunning the buffer. */ 249 if (cp == s + CHAR_CLASS_MAX_LENGTH) 250 return (wctype_t) 0; 251 252 *cp++ = (char) *wcs++; 253 } 254 while (*wcs != L'\0'); 255 256 *cp = '\0'; 257 258 # ifdef _LIBC 259 return __wctype (s); 260 # else 261 return wctype (s); 262 # endif 263 } 264 # define IS_CHAR_CLASS(string) is_char_class (string) 265 266 # include "fnmatch_loop.c" 267 # endif 268 269 270 int 271 fnmatch (const char *pattern, const char *string, int flags) 272 { 273 # if HANDLE_MULTIBYTE 274 # define ALLOCA_LIMIT 2000 275 if (__builtin_expect (MB_CUR_MAX, 1) != 1) 276 { 277 mbstate_t ps; 278 size_t patsize; 279 size_t strsize; 280 size_t totsize; 281 wchar_t *wpattern; 282 wchar_t *wstring; 283 int res; 284 285 /* Calculate the size needed to convert the strings to 286 wide characters. */ 287 memset (&ps, '\0', sizeof (ps)); 288 patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1; 289 if (__builtin_expect (patsize != 0, 1)) 290 { 291 assert (mbsinit (&ps)); 292 strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1; 293 if (__builtin_expect (strsize != 0, 1)) 294 { 295 assert (mbsinit (&ps)); 296 totsize = patsize + strsize; 297 if (__builtin_expect (! (patsize <= totsize 298 && totsize <= SIZE_MAX / sizeof (wchar_t)), 299 0)) 300 { 301 errno = ENOMEM; 302 return -1; 303 } 304 305 /* Allocate room for the wide characters. */ 306 if (__builtin_expect (totsize < ALLOCA_LIMIT, 1)) 307 wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t)); 308 else 309 { 310 wpattern = malloc (totsize * sizeof (wchar_t)); 311 if (__builtin_expect (! wpattern, 0)) 312 { 313 errno = ENOMEM; 314 return -1; 315 } 316 } 317 wstring = wpattern + patsize; 318 319 /* Convert the strings into wide characters. */ 320 mbsrtowcs (wpattern, &pattern, patsize, &ps); 321 assert (mbsinit (&ps)); 322 mbsrtowcs (wstring, &string, strsize, &ps); 323 324 res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1, 325 flags & FNM_PERIOD, flags); 326 327 if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0)) 328 free (wpattern); 329 return res; 330 } 331 } 332 } 333 334 # endif /* HANDLE_MULTIBYTE */ 335 336 return internal_fnmatch (pattern, string, string + strlen (string), 337 flags & FNM_PERIOD, flags); 338 } 339 340 # ifdef _LIBC 341 # undef fnmatch 342 versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3); 343 # if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3) 344 strong_alias (__fnmatch, __fnmatch_old) 345 compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0); 346 # endif 347 libc_hidden_ver (__fnmatch, fnmatch) 348 # endif 349 350 #endif /* _LIBC or not __GNU_LIBRARY__. */ 351