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