]> git.ipfire.org Git - thirdparty/glibc.git/blame - posix/fnmatch.c
Fix fnmatch towlower namespace (bug 18469).
[thirdparty/glibc.git] / posix / fnmatch.c
CommitLineData
b168057a 1/* Copyright (C) 1991-2015 Free Software Foundation, Inc.
c84142e8 2 This file is part of the GNU C Library.
28f540f4 3
41bdb6e2
AJ
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
28f540f4 8
41bdb6e2 9 The GNU C Library is distributed in the hope that it will be useful,
c84142e8
UD
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
28f540f4 13
41bdb6e2 14 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
28f540f4 17
ba1ffaa1
UD
18#if HAVE_CONFIG_H
19# include <config.h>
28f540f4
RM
20#endif
21
97aa195c
RM
22/* Enable GNU extensions in fnmatch.h. */
23#ifndef _GNU_SOURCE
ba1ffaa1 24# define _GNU_SOURCE 1
97aa195c
RM
25#endif
26
1fc82a56 27#include <assert.h>
28f540f4
RM
28#include <errno.h>
29#include <fnmatch.h>
30#include <ctype.h>
3f3dd810 31#include <string.h>
a9ddb793 32
69050873 33#if defined STDC_HEADERS || defined _LIBC
a9ddb793
UD
34# include <stdlib.h>
35#endif
36
f15ce4d8
UD
37#ifdef _LIBC
38# include <alloca.h>
39#else
40# define alloca_account(size., var) alloca (size)
41#endif
42
a9ddb793
UD
43/* For platform which support the ISO C amendement 1 functionality we
44 support user defined character classes. */
45#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
46/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
47# include <wchar.h>
48# include <wctype.h>
49#endif
28f540f4 50
acb5ee2e
UD
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"
f3e29a1a 56# include "../locale/elem-hash.h"
04ea3b0f 57# include "../locale/coll-lookup.h"
821a6bb4 58# include <shlib-compat.h>
acb5ee2e
UD
59
60# define CONCAT(a,b) __CONCAT(a,b)
4aebaa6b 61# define mbsrtowcs __mbsrtowcs
821a6bb4
UD
62# define fnmatch __fnmatch
63extern int fnmatch (const char *pattern, const char *string, int flags);
acb5ee2e
UD
64#endif
65
955994e1
UD
66/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */
67#define NO_LEADING_PERIOD(flags) \
68 ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
69
28f540f4
RM
70/* Comment out all this code if we are using the GNU C Library, and are not
71 actually compiling the library itself. This code is part of the GNU C
72 Library, but also included in many other GNU distributions. Compiling
73 and linking in this code is a waste when using the GNU C library
74 (especially if it is a shared library). Rather than having every GNU
75 program understand `configure --with-gnu-libc' and omit the object files,
76 it is simpler to just do this in the source for each such file. */
77
c84142e8 78#if defined _LIBC || !defined __GNU_LIBRARY__
28f540f4
RM
79
80
c84142e8 81# if defined STDC_HEADERS || !defined isascii
ba1ffaa1
UD
82# define ISASCII(c) 1
83# else
84# define ISASCII(c) isascii(c)
85# endif
86
78148569
UD
87# ifdef isblank
88# define ISBLANK(c) (ISASCII (c) && isblank (c))
89# else
90# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
91# endif
92# ifdef isgraph
93# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
94# else
95# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
96# endif
a9ddb793 97
78148569
UD
98# define ISPRINT(c) (ISASCII (c) && isprint (c))
99# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
100# define ISALNUM(c) (ISASCII (c) && isalnum (c))
101# define ISALPHA(c) (ISASCII (c) && isalpha (c))
102# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
103# define ISLOWER(c) (ISASCII (c) && islower (c))
104# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
105# define ISSPACE(c) (ISASCII (c) && isspace (c))
106# define ISUPPER(c) (ISASCII (c) && isupper (c))
107# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
a9ddb793
UD
108
109# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
110
111# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
112/* The GNU C library provides support for user-defined character classes
113 and the functions from ISO C amendement 1. */
114# ifdef CHARCLASS_NAME_MAX
115# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
116# else
117/* This shouldn't happen but some implementation might still have this
118 problem. Use a reasonable default value. */
119# define CHAR_CLASS_MAX_LENGTH 256
120# endif
121
122# ifdef _LIBC
123# define IS_CHAR_CLASS(string) __wctype (string)
124# else
125# define IS_CHAR_CLASS(string) wctype (string)
126# endif
1fc82a56 127
ea6eb383
UD
128# ifdef _LIBC
129# define ISWCTYPE(WC, WT) __iswctype (WC, WT)
130# else
131# define ISWCTYPE(WC, WT) iswctype (WC, WT)
132# endif
133
1fc82a56
UD
134# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
135/* In this case we are implementing the multibyte character handling. */
136# define HANDLE_MULTIBYTE 1
137# endif
138
a9ddb793
UD
139# else
140# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
141
142# define IS_CHAR_CLASS(string) \
143 (STREQ (string, "alpha") || STREQ (string, "upper") \
144 || STREQ (string, "lower") || STREQ (string, "digit") \
145 || STREQ (string, "alnum") || STREQ (string, "xdigit") \
146 || STREQ (string, "space") || STREQ (string, "print") \
147 || STREQ (string, "punct") || STREQ (string, "graph") \
148 || STREQ (string, "cntrl") || STREQ (string, "blank"))
149# endif
150
151/* Avoid depending on library functions or files
152 whose names are inconsistent. */
ba1ffaa1 153
a9ddb793
UD
154# if !defined _LIBC && !defined getenv
155extern char *getenv ();
156# endif
ba1ffaa1
UD
157
158# ifndef errno
28f540f4 159extern int errno;
ba1ffaa1 160# endif
28f540f4 161
955994e1
UD
162/* Global variable. */
163static int posixly_correct;
164
722c33bb
UD
165/* This function doesn't exist on most systems. */
166
167# if !defined HAVE___STRCHRNUL && !defined _LIBC
168static char *
169__strchrnul (s, c)
170 const char *s;
171 int c;
172{
173 char *result = strchr (s, c);
174 if (result == NULL)
175 result = strchr (s, '\0');
176 return result;
177}
178# endif
179
ea6eb383
UD
180# if HANDLE_MULTIBYTE && !defined HAVE___STRCHRNUL && !defined _LIBC
181static wchar_t *
182__wcschrnul (s, c)
183 const wchar_t *s;
184 wint_t c;
185{
186 wchar_t *result = wcschr (s, c);
187 if (result == NULL)
188 result = wcschr (s, '\0');
189 return result;
190}
191# endif
192
78148569
UD
193# ifndef internal_function
194/* Inside GNU libc we mark some function in a special way. In other
195 environments simply ignore the marking. */
196# define internal_function
197# endif
198
6d52618b 199/* Note that this evaluates C many times. */
a9ddb793
UD
200# ifdef _LIBC
201# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
202# else
203# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
204# endif
1fc82a56
UD
205# define CHAR char
206# define UCHAR unsigned char
955994e1 207# define INT int
1fc82a56 208# define FCT internal_fnmatch
955994e1
UD
209# define EXT ext_match
210# define END end_pattern
9700b039 211# define STRUCT fnmatch_struct
1fc82a56 212# define L(CS) CS
ea6eb383
UD
213# ifdef _LIBC
214# define BTOWC(C) __btowc (C)
215# else
216# define BTOWC(C) btowc (C)
217# endif
821a6bb4
UD
218# define STRLEN(S) strlen (S)
219# define STRCAT(D, S) strcat (D, S)
955994e1
UD
220# define MEMPCPY(D, S, N) __mempcpy (D, S, N)
221# define MEMCHR(S, C, N) memchr (S, C, N)
1827fc4c 222# define STRCOLL(S1, S2) strcoll (S1, S2)
059bf913 223# define WIDE_CHAR_VERSION 0
8c0ab919
RM
224# include <locale/weight.h>
225# define FINDIDX findidx
1fc82a56 226# include "fnmatch_loop.c"
28f540f4 227
a9ddb793 228
1fc82a56
UD
229# if HANDLE_MULTIBYTE
230/* Note that this evaluates C many times. */
231# ifdef _LIBC
bb4acb52 232# define FOLD(c) ((flags & FNM_CASEFOLD) ? __towlower (c) : (c))
1fc82a56
UD
233# else
234# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? towlower (c) : (c))
235# endif
236# define CHAR wchar_t
237# define UCHAR wint_t
955994e1 238# define INT wint_t
1fc82a56 239# define FCT internal_fnwmatch
955994e1 240# define EXT ext_wmatch
9700b039
UD
241# define END end_wpattern
242# define STRUCT fnwmatch_struct
1fc82a56 243# define L(CS) L##CS
ea6eb383 244# define BTOWC(C) (C)
821a6bb4
UD
245# define STRLEN(S) __wcslen (S)
246# define STRCAT(D, S) __wcscat (D, S)
955994e1
UD
247# define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
248# define MEMCHR(S, C, N) wmemchr (S, C, N)
acb5ee2e 249# define STRCOLL(S1, S2) wcscoll (S1, S2)
acb5ee2e 250# define WIDE_CHAR_VERSION 1
8c0ab919
RM
251/* Change the name the header defines so it doesn't conflict with
252 the <locale/weight.h> version included above. */
253# define findidx findidxwc
254# include <locale/weightwc.h>
255# undef findidx
256# define FINDIDX findidxwc
acb5ee2e 257
1fc82a56 258# undef IS_CHAR_CLASS
1fc82a56 259/* We have to convert the wide character string in a multibyte string. But
5e463393
UD
260 we know that the character class names consist of alphanumeric characters
261 from the portable character set, and since the wide character encoding
262 for a member of the portable character set is the same code point as
263 its single-byte encoding, we can use a simplified method to convert the
264 string to a multibyte character string. */
1fc82a56
UD
265static wctype_t
266is_char_class (const wchar_t *wcs)
267{
268 char s[CHAR_CLASS_MAX_LENGTH + 1];
269 char *cp = s;
28f540f4 270
1fc82a56
UD
271 do
272 {
5e463393
UD
273 /* Test for a printable character from the portable character set. */
274# ifdef _LIBC
275 if (*wcs < 0x20 || *wcs > 0x7e
276 || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
277 return (wctype_t) 0;
1fc82a56 278# else
5e463393
UD
279 switch (*wcs)
280 {
281 case L' ': case L'!': case L'"': case L'#': case L'%':
282 case L'&': case L'\'': case L'(': case L')': case L'*':
283 case L'+': case L',': case L'-': case L'.': case L'/':
284 case L'0': case L'1': case L'2': case L'3': case L'4':
285 case L'5': case L'6': case L'7': case L'8': case L'9':
286 case L':': case L';': case L'<': case L'=': case L'>':
287 case L'?':
288 case L'A': case L'B': case L'C': case L'D': case L'E':
289 case L'F': case L'G': case L'H': case L'I': case L'J':
290 case L'K': case L'L': case L'M': case L'N': case L'O':
291 case L'P': case L'Q': case L'R': case L'S': case L'T':
292 case L'U': case L'V': case L'W': case L'X': case L'Y':
293 case L'Z':
294 case L'[': case L'\\': case L']': case L'^': case L'_':
295 case L'a': case L'b': case L'c': case L'd': case L'e':
296 case L'f': case L'g': case L'h': case L'i': case L'j':
297 case L'k': case L'l': case L'm': case L'n': case L'o':
298 case L'p': case L'q': case L'r': case L's': case L't':
299 case L'u': case L'v': case L'w': case L'x': case L'y':
300 case L'z': case L'{': case L'|': case L'}': case L'~':
301 break;
302 default:
303 return (wctype_t) 0;
304 }
305# endif
1fc82a56 306
5e463393
UD
307 /* Avoid overrunning the buffer. */
308 if (cp == s + CHAR_CLASS_MAX_LENGTH)
309 return (wctype_t) 0;
28f540f4 310
5e463393
UD
311 *cp++ = (char) *wcs++;
312 }
313 while (*wcs != L'\0');
28f540f4 314
5e463393 315 *cp = '\0';
ba1ffaa1 316
5e463393
UD
317# ifdef _LIBC
318 return __wctype (s);
319# else
ea6eb383 320 return wctype (s);
1fc82a56 321# endif
5e463393 322}
1fc82a56 323# define IS_CHAR_CLASS(string) is_char_class (string)
28f540f4 324
1fc82a56
UD
325# include "fnmatch_loop.c"
326# endif
d8aaef00 327
5e463393 328
d8aaef00
UD
329int
330fnmatch (pattern, string, flags)
331 const char *pattern;
332 const char *string;
333 int flags;
334{
1fc82a56 335# if HANDLE_MULTIBYTE
955994e1
UD
336 if (__builtin_expect (MB_CUR_MAX, 1) != 1)
337 {
338 mbstate_t ps;
339 size_t n;
7a409a1a 340 const char *p;
f15ce4d8 341 wchar_t *wpattern_malloc = NULL;
955994e1 342 wchar_t *wpattern;
f15ce4d8 343 wchar_t *wstring_malloc = NULL;
955994e1 344 wchar_t *wstring;
f15ce4d8 345 size_t alloca_used = 0;
955994e1
UD
346
347 /* Convert the strings into wide characters. */
348 memset (&ps, '\0', sizeof (ps));
7a409a1a
UD
349 p = pattern;
350#ifdef _LIBC
351 n = strnlen (pattern, 1024);
352#else
353 n = strlen (pattern);
354#endif
a1ffb40e 355 if (__glibc_likely (n < 1024))
7a409a1a 356 {
f15ce4d8
UD
357 wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
358 alloca_used);
7a409a1a 359 n = mbsrtowcs (wpattern, &p, n + 1, &ps);
a1ffb40e 360 if (__glibc_unlikely (n == (size_t) -1))
7a409a1a
UD
361 /* Something wrong.
362 XXX Do we have to set `errno' to something which mbsrtows hasn't
363 already done? */
364 return -1;
365 if (p)
701666b7
UD
366 {
367 memset (&ps, '\0', sizeof (ps));
368 goto prepare_wpattern;
369 }
7a409a1a 370 }
701666b7 371 else
7a409a1a 372 {
701666b7 373 prepare_wpattern:
7a409a1a 374 n = mbsrtowcs (NULL, &pattern, 0, &ps);
a1ffb40e 375 if (__glibc_unlikely (n == (size_t) -1))
7a409a1a
UD
376 /* Something wrong.
377 XXX Do we have to set `errno' to something which mbsrtows hasn't
378 already done? */
379 return -1;
a1ffb40e 380 if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
8126d904
UD
381 {
382 __set_errno (ENOMEM);
383 return -2;
384 }
f15ce4d8
UD
385 wpattern_malloc = wpattern
386 = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
7a409a1a 387 assert (mbsinit (&ps));
f15ce4d8
UD
388 if (wpattern == NULL)
389 return -2;
7a409a1a
UD
390 (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
391 }
955994e1
UD
392
393 assert (mbsinit (&ps));
7a409a1a
UD
394#ifdef _LIBC
395 n = strnlen (string, 1024);
396#else
397 n = strlen (string);
398#endif
399 p = string;
a1ffb40e 400 if (__glibc_likely (n < 1024))
7a409a1a 401 {
f15ce4d8
UD
402 wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
403 alloca_used);
7a409a1a 404 n = mbsrtowcs (wstring, &p, n + 1, &ps);
a1ffb40e 405 if (__glibc_unlikely (n == (size_t) -1))
f15ce4d8
UD
406 {
407 /* Something wrong.
408 XXX Do we have to set `errno' to something which
409 mbsrtows hasn't already done? */
410 free_return:
411 free (wpattern_malloc);
412 return -1;
413 }
7a409a1a 414 if (p)
701666b7
UD
415 {
416 memset (&ps, '\0', sizeof (ps));
417 goto prepare_wstring;
418 }
7a409a1a 419 }
701666b7 420 else
7a409a1a 421 {
701666b7 422 prepare_wstring:
7a409a1a 423 n = mbsrtowcs (NULL, &string, 0, &ps);
a1ffb40e 424 if (__glibc_unlikely (n == (size_t) -1))
7a409a1a
UD
425 /* Something wrong.
426 XXX Do we have to set `errno' to something which mbsrtows hasn't
427 already done? */
f15ce4d8 428 goto free_return;
a1ffb40e 429 if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
8126d904
UD
430 {
431 free (wpattern_malloc);
432 __set_errno (ENOMEM);
433 return -2;
434 }
f15ce4d8
UD
435
436 wstring_malloc = wstring
437 = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
438 if (wstring == NULL)
439 {
440 free (wpattern_malloc);
441 return -2;
442 }
7a409a1a
UD
443 assert (mbsinit (&ps));
444 (void) mbsrtowcs (wstring, &string, n + 1, &ps);
445 }
955994e1 446
f15ce4d8
UD
447 int res = internal_fnwmatch (wpattern, wstring, wstring + n,
448 flags & FNM_PERIOD, flags, NULL,
449 alloca_used);
450
451 free (wstring_malloc);
452 free (wpattern_malloc);
453
454 return res;
955994e1 455 }
1fc82a56 456# endif /* mbstate_t and mbsrtowcs or _LIBC. */
955994e1
UD
457
458 return internal_fnmatch (pattern, string, string + strlen (string),
f15ce4d8 459 flags & FNM_PERIOD, flags, NULL, 0);
d8aaef00
UD
460}
461
821a6bb4
UD
462# ifdef _LIBC
463# undef fnmatch
464versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
465# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
466strong_alias (__fnmatch, __fnmatch_old)
467compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
468# endif
a14f26ef 469libc_hidden_ver (__fnmatch, fnmatch)
821a6bb4
UD
470# endif
471
28f540f4 472#endif /* _LIBC or not __GNU_LIBRARY__. */