fnmatch.c revision 1.1 1 1.1 christos /* Copyright (C) 1991-2020 Free Software Foundation, Inc.
2 1.1 christos This file is part of the GNU C Library.
3 1.1 christos
4 1.1 christos The GNU C Library is free software; you can redistribute it and/or
5 1.1 christos modify it under the terms of the GNU General Public
6 1.1 christos License as published by the Free Software Foundation; either
7 1.1 christos version 3 of the License, or (at your option) any later version.
8 1.1 christos
9 1.1 christos The GNU C Library is distributed in the hope that it will be useful,
10 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
11 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 1.1 christos General Public License for more details.
13 1.1 christos
14 1.1 christos You should have received a copy of the GNU General Public
15 1.1 christos License along with the GNU C Library; if not, see
16 1.1 christos <https://www.gnu.org/licenses/>. */
17 1.1 christos
18 1.1 christos #ifndef _LIBC
19 1.1 christos # include <libc-config.h>
20 1.1 christos #endif
21 1.1 christos
22 1.1 christos /* Enable GNU extensions in fnmatch.h. */
23 1.1 christos #ifndef _GNU_SOURCE
24 1.1 christos # define _GNU_SOURCE 1
25 1.1 christos #endif
26 1.1 christos
27 1.1 christos #include <fnmatch.h>
28 1.1 christos
29 1.1 christos #include <assert.h>
30 1.1 christos #include <errno.h>
31 1.1 christos #include <ctype.h>
32 1.1 christos #include <string.h>
33 1.1 christos #include <stdlib.h>
34 1.1 christos #if defined _LIBC || HAVE_ALLOCA
35 1.1 christos # include <alloca.h>
36 1.1 christos #endif
37 1.1 christos #include <wchar.h>
38 1.1 christos #include <wctype.h>
39 1.1 christos #include <stddef.h>
40 1.1 christos #include <stdbool.h>
41 1.1 christos
42 1.1 christos /* We need some of the locale data (the collation sequence information)
43 1.1 christos but there is no interface to get this information in general. Therefore
44 1.1 christos we support a correct implementation only in glibc. */
45 1.1 christos #ifdef _LIBC
46 1.1 christos # include "../locale/localeinfo.h"
47 1.1 christos # include "../locale/coll-lookup.h"
48 1.1 christos # include <shlib-compat.h>
49 1.1 christos
50 1.1 christos # define CONCAT(a,b) __CONCAT(a,b)
51 1.1 christos # define btowc __btowc
52 1.1 christos # define iswctype __iswctype
53 1.1 christos # define mbsrtowcs __mbsrtowcs
54 1.1 christos # define mempcpy __mempcpy
55 1.1 christos # define strnlen __strnlen
56 1.1 christos # define towlower __towlower
57 1.1 christos # define wcscat __wcscat
58 1.1 christos # define wcslen __wcslen
59 1.1 christos # define wctype __wctype
60 1.1 christos # define wmemchr __wmemchr
61 1.1 christos # define wmempcpy __wmempcpy
62 1.1 christos # define fnmatch __fnmatch
63 1.1 christos extern int fnmatch (const char *pattern, const char *string, int flags);
64 1.1 christos #endif
65 1.1 christos
66 1.1 christos #ifdef _LIBC
67 1.1 christos # if __GNUC__ < 7
68 1.1 christos # define FALLTHROUGH ((void) 0)
69 1.1 christos # else
70 1.1 christos # define FALLTHROUGH __attribute__ ((__fallthrough__))
71 1.1 christos # endif
72 1.1 christos #else
73 1.1 christos # include "attribute.h"
74 1.1 christos #endif
75 1.1 christos
76 1.1 christos #include <intprops.h>
77 1.1 christos #include <flexmember.h>
78 1.1 christos
79 1.1 christos /* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */
80 1.1 christos #define NO_LEADING_PERIOD(flags) \
81 1.1 christos ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
82 1.1 christos
83 1.1 christos #ifndef _LIBC
84 1.1 christos # if HAVE_ALLOCA
85 1.1 christos /* The OS usually guarantees only one guard page at the bottom of the stack,
86 1.1 christos and a page size can be as small as 4096 bytes. So we cannot safely
87 1.1 christos allocate anything larger than 4096 bytes. Also care for the possibility
88 1.1 christos of a few compiler-allocated temporary stack slots. */
89 1.1 christos # define __libc_use_alloca(n) ((n) < 4032)
90 1.1 christos # else
91 1.1 christos /* Just use malloc. */
92 1.1 christos # define __libc_use_alloca(n) false
93 1.1 christos # undef alloca
94 1.1 christos # define alloca(n) malloc (n)
95 1.1 christos # endif
96 1.1 christos # define alloca_account(size, avar) ((avar) += (size), alloca (size))
97 1.1 christos #endif
98 1.1 christos
99 1.1 christos /* Provide support for user-defined character classes, based on the functions
100 1.1 christos from ISO C 90 amendment 1. */
101 1.1 christos #ifdef CHARCLASS_NAME_MAX
102 1.1 christos # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
103 1.1 christos #else
104 1.1 christos /* This shouldn't happen but some implementation might still have this
105 1.1 christos problem. Use a reasonable default value. */
106 1.1 christos # define CHAR_CLASS_MAX_LENGTH 256
107 1.1 christos #endif
108 1.1 christos
109 1.1 christos #define IS_CHAR_CLASS(string) wctype (string)
110 1.1 christos
111 1.1 christos /* Avoid depending on library functions or files
112 1.1 christos whose names are inconsistent. */
113 1.1 christos
114 1.1 christos /* Global variable. */
115 1.1 christos static int posixly_correct;
116 1.1 christos
117 1.1 christos /* Note that this evaluates C many times. */
118 1.1 christos #define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
119 1.1 christos #define CHAR char
120 1.1 christos #define UCHAR unsigned char
121 1.1 christos #define INT int
122 1.1 christos #define FCT internal_fnmatch
123 1.1 christos #define EXT ext_match
124 1.1 christos #define END end_pattern
125 1.1 christos #define STRUCT fnmatch_struct
126 1.1 christos #define L_(CS) CS
127 1.1 christos #define BTOWC(C) btowc (C)
128 1.1 christos #define STRLEN(S) strlen (S)
129 1.1 christos #define STRCAT(D, S) strcat (D, S)
130 1.1 christos #define MEMPCPY(D, S, N) mempcpy (D, S, N)
131 1.1 christos #define MEMCHR(S, C, N) memchr (S, C, N)
132 1.1 christos #define WIDE_CHAR_VERSION 0
133 1.1 christos #ifdef _LIBC
134 1.1 christos # include <locale/weight.h>
135 1.1 christos # define FINDIDX findidx
136 1.1 christos #endif
137 1.1 christos #include "fnmatch_loop.c"
138 1.1 christos
139 1.1 christos
140 1.1 christos #define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
141 1.1 christos #define CHAR wchar_t
142 1.1 christos #define UCHAR wint_t
143 1.1 christos #define INT wint_t
144 1.1 christos #define FCT internal_fnwmatch
145 1.1 christos #define EXT ext_wmatch
146 1.1 christos #define END end_wpattern
147 1.1 christos #define L_(CS) L##CS
148 1.1 christos #define BTOWC(C) (C)
149 1.1 christos #define STRLEN(S) wcslen (S)
150 1.1 christos #define STRCAT(D, S) wcscat (D, S)
151 1.1 christos #define MEMPCPY(D, S, N) wmempcpy (D, S, N)
152 1.1 christos #define MEMCHR(S, C, N) wmemchr (S, C, N)
153 1.1 christos #define WIDE_CHAR_VERSION 1
154 1.1 christos #ifdef _LIBC
155 1.1 christos /* Change the name the header defines so it doesn't conflict with
156 1.1 christos the <locale/weight.h> version included above. */
157 1.1 christos # define findidx findidxwc
158 1.1 christos # include <locale/weightwc.h>
159 1.1 christos # undef findidx
160 1.1 christos # define FINDIDX findidxwc
161 1.1 christos #endif
162 1.1 christos
163 1.1 christos #undef IS_CHAR_CLASS
164 1.1 christos /* We have to convert the wide character string in a multibyte string. But
165 1.1 christos we know that the character class names consist of alphanumeric characters
166 1.1 christos from the portable character set, and since the wide character encoding
167 1.1 christos for a member of the portable character set is the same code point as
168 1.1 christos its single-byte encoding, we can use a simplified method to convert the
169 1.1 christos string to a multibyte character string. */
170 1.1 christos static wctype_t
171 1.1 christos is_char_class (const wchar_t *wcs)
172 1.1 christos {
173 1.1 christos char s[CHAR_CLASS_MAX_LENGTH + 1];
174 1.1 christos char *cp = s;
175 1.1 christos
176 1.1 christos do
177 1.1 christos {
178 1.1 christos /* Test for a printable character from the portable character set. */
179 1.1 christos #ifdef _LIBC
180 1.1 christos if (*wcs < 0x20 || *wcs > 0x7e
181 1.1 christos || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
182 1.1 christos return (wctype_t) 0;
183 1.1 christos #else
184 1.1 christos switch (*wcs)
185 1.1 christos {
186 1.1 christos case L' ': case L'!': case L'"': case L'#': case L'%':
187 1.1 christos case L'&': case L'\'': case L'(': case L')': case L'*':
188 1.1 christos case L'+': case L',': case L'-': case L'.': case L'/':
189 1.1 christos case L'0': case L'1': case L'2': case L'3': case L'4':
190 1.1 christos case L'5': case L'6': case L'7': case L'8': case L'9':
191 1.1 christos case L':': case L';': case L'<': case L'=': case L'>':
192 1.1 christos case L'?':
193 1.1 christos case L'A': case L'B': case L'C': case L'D': case L'E':
194 1.1 christos case L'F': case L'G': case L'H': case L'I': case L'J':
195 1.1 christos case L'K': case L'L': case L'M': case L'N': case L'O':
196 1.1 christos case L'P': case L'Q': case L'R': case L'S': case L'T':
197 1.1 christos case L'U': case L'V': case L'W': case L'X': case L'Y':
198 1.1 christos case L'Z':
199 1.1 christos case L'[': case L'\\': case L']': case L'^': case L'_':
200 1.1 christos case L'a': case L'b': case L'c': case L'd': case L'e':
201 1.1 christos case L'f': case L'g': case L'h': case L'i': case L'j':
202 1.1 christos case L'k': case L'l': case L'm': case L'n': case L'o':
203 1.1 christos case L'p': case L'q': case L'r': case L's': case L't':
204 1.1 christos case L'u': case L'v': case L'w': case L'x': case L'y':
205 1.1 christos case L'z': case L'{': case L'|': case L'}': case L'~':
206 1.1 christos break;
207 1.1 christos default:
208 1.1 christos return (wctype_t) 0;
209 1.1 christos }
210 1.1 christos #endif
211 1.1 christos
212 1.1 christos /* Avoid overrunning the buffer. */
213 1.1 christos if (cp == s + CHAR_CLASS_MAX_LENGTH)
214 1.1 christos return (wctype_t) 0;
215 1.1 christos
216 1.1 christos *cp++ = (char) *wcs++;
217 1.1 christos }
218 1.1 christos while (*wcs != L'\0');
219 1.1 christos
220 1.1 christos *cp = '\0';
221 1.1 christos
222 1.1 christos return wctype (s);
223 1.1 christos }
224 1.1 christos #define IS_CHAR_CLASS(string) is_char_class (string)
225 1.1 christos
226 1.1 christos #include "fnmatch_loop.c"
227 1.1 christos
228 1.1 christos
229 1.1 christos int
230 1.1 christos fnmatch (const char *pattern, const char *string, int flags)
231 1.1 christos {
232 1.1 christos if (__glibc_unlikely (MB_CUR_MAX != 1))
233 1.1 christos {
234 1.1 christos mbstate_t ps;
235 1.1 christos size_t n;
236 1.1 christos const char *p;
237 1.1 christos wchar_t *wpattern_malloc = NULL;
238 1.1 christos wchar_t *wpattern;
239 1.1 christos wchar_t *wstring_malloc = NULL;
240 1.1 christos wchar_t *wstring;
241 1.1 christos size_t alloca_used = 0;
242 1.1 christos
243 1.1 christos /* Convert the strings into wide characters. */
244 1.1 christos memset (&ps, '\0', sizeof (ps));
245 1.1 christos p = pattern;
246 1.1 christos n = strnlen (pattern, 1024);
247 1.1 christos if (__glibc_likely (n < 1024))
248 1.1 christos {
249 1.1 christos wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
250 1.1 christos alloca_used);
251 1.1 christos n = mbsrtowcs (wpattern, &p, n + 1, &ps);
252 1.1 christos if (__glibc_unlikely (n == (size_t) -1))
253 1.1 christos /* Something wrong.
254 1.1 christos XXX Do we have to set 'errno' to something which mbsrtows hasn't
255 1.1 christos already done? */
256 1.1 christos return -1;
257 1.1 christos if (p)
258 1.1 christos {
259 1.1 christos memset (&ps, '\0', sizeof (ps));
260 1.1 christos goto prepare_wpattern;
261 1.1 christos }
262 1.1 christos }
263 1.1 christos else
264 1.1 christos {
265 1.1 christos prepare_wpattern:
266 1.1 christos n = mbsrtowcs (NULL, &pattern, 0, &ps);
267 1.1 christos if (__glibc_unlikely (n == (size_t) -1))
268 1.1 christos /* Something wrong.
269 1.1 christos XXX Do we have to set 'errno' to something which mbsrtows hasn't
270 1.1 christos already done? */
271 1.1 christos return -1;
272 1.1 christos if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
273 1.1 christos {
274 1.1 christos __set_errno (ENOMEM);
275 1.1 christos return -2;
276 1.1 christos }
277 1.1 christos wpattern_malloc = wpattern
278 1.1 christos = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
279 1.1 christos assert (mbsinit (&ps));
280 1.1 christos if (wpattern == NULL)
281 1.1 christos return -2;
282 1.1 christos (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
283 1.1 christos }
284 1.1 christos
285 1.1 christos assert (mbsinit (&ps));
286 1.1 christos n = strnlen (string, 1024);
287 1.1 christos p = string;
288 1.1 christos if (__glibc_likely (n < 1024))
289 1.1 christos {
290 1.1 christos wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
291 1.1 christos alloca_used);
292 1.1 christos n = mbsrtowcs (wstring, &p, n + 1, &ps);
293 1.1 christos if (__glibc_unlikely (n == (size_t) -1))
294 1.1 christos {
295 1.1 christos /* Something wrong.
296 1.1 christos XXX Do we have to set 'errno' to something which
297 1.1 christos mbsrtows hasn't already done? */
298 1.1 christos free_return:
299 1.1 christos free (wpattern_malloc);
300 1.1 christos return -1;
301 1.1 christos }
302 1.1 christos if (p)
303 1.1 christos {
304 1.1 christos memset (&ps, '\0', sizeof (ps));
305 1.1 christos goto prepare_wstring;
306 1.1 christos }
307 1.1 christos }
308 1.1 christos else
309 1.1 christos {
310 1.1 christos prepare_wstring:
311 1.1 christos n = mbsrtowcs (NULL, &string, 0, &ps);
312 1.1 christos if (__glibc_unlikely (n == (size_t) -1))
313 1.1 christos /* Something wrong.
314 1.1 christos XXX Do we have to set 'errno' to something which mbsrtows hasn't
315 1.1 christos already done? */
316 1.1 christos goto free_return;
317 1.1 christos if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
318 1.1 christos {
319 1.1 christos free (wpattern_malloc);
320 1.1 christos __set_errno (ENOMEM);
321 1.1 christos return -2;
322 1.1 christos }
323 1.1 christos
324 1.1 christos wstring_malloc = wstring
325 1.1 christos = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
326 1.1 christos if (wstring == NULL)
327 1.1 christos {
328 1.1 christos free (wpattern_malloc);
329 1.1 christos return -2;
330 1.1 christos }
331 1.1 christos assert (mbsinit (&ps));
332 1.1 christos (void) mbsrtowcs (wstring, &string, n + 1, &ps);
333 1.1 christos }
334 1.1 christos
335 1.1 christos int res = internal_fnwmatch (wpattern, wstring, wstring + n,
336 1.1 christos flags & FNM_PERIOD, flags, NULL,
337 1.1 christos alloca_used);
338 1.1 christos
339 1.1 christos free (wstring_malloc);
340 1.1 christos free (wpattern_malloc);
341 1.1 christos
342 1.1 christos return res;
343 1.1 christos }
344 1.1 christos
345 1.1 christos return internal_fnmatch (pattern, string, string + strlen (string),
346 1.1 christos flags & FNM_PERIOD, flags, NULL, 0);
347 1.1 christos }
348 1.1 christos
349 1.1 christos #undef fnmatch
350 1.1 christos versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
351 1.1 christos #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
352 1.1 christos strong_alias (__fnmatch, __fnmatch_old)
353 1.1 christos compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
354 1.1 christos #endif
355 1.1 christos libc_hidden_ver (__fnmatch, fnmatch)
356