1 /* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2007
2 	Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA
18    02110-1335, USA.  */
19 
20 /* This file comes from the GNU C Library and has been modified for use in
21  * ProFTPD.
22  *
23  * Changes are released under the GNU Public License, version 2.
24  * Copyright (C) 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net>
25  * Copyright (C) 2010-2012 The ProFTPD Project
26  */
27 
28 /* AIX requires this to be the first thing in the file.  */
29 #if defined _AIX && !defined __GNUC__
30  #pragma alloca
31 #endif
32 
33 #include <config.h>
34 
35 /* Make alloca work the best possible way.  */
36 #ifdef __GNUC__
37 #define alloca __builtin_alloca
38 #else /* not __GNUC__ */
39 #if HAVE_ALLOCA_H
40 #include <alloca.h>
41 #else /* not __GNUC__ or HAVE_ALLOCA_H */
42 #ifndef _AIX /* Already did AIX, up at the top.  */
43 char *alloca ();
44 #endif /* not _AIX */
45 #endif /* not HAVE_ALLOCA_H */
46 #endif /* not __GNUC__ */
47 
48 /* Necessary for platforms which don't use __alloca. */
49 #define __alloca alloca
50 
51 /* Required to tell conf.h not to include the standard ProFTPD
52  * header files
53  */
54 
55 #define __PROFTPD_SUPPORT_LIBRARY
56 
57 #include <conf.h>
58 #include <libsupp.h>
59 
60 #if 0 /* Not used in ProFTPD */
61 /* Enable GNU extensions in fnmatch.h.  */
62 #ifndef _GNU_SOURCE
63 # define _GNU_SOURCE	1
64 #endif
65 
66 #include <assert.h>
67 #include <errno.h>
68 #include <fnmatch.h>
69 #include <ctype.h>
70 
71 #if HAVE_STRING_H || defined _LIBC
72 # include <string.h>
73 #else
74 # include <strings.h>
75 #endif
76 
77 #if defined STDC_HEADERS || defined _LIBC
78 # include <stdlib.h>
79 #endif
80 
81 /* For platform which support the ISO C amendement 1 functionality we
82    support user defined character classes.  */
83 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
84 /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
85 # include <wchar.h>
86 # include <wctype.h>
87 #endif
88 
89 /* We need some of the locale data (the collation sequence information)
90    but there is no interface to get this information in general.  Therefore
91    we support a correct implementation only in glibc.  */
92 #ifdef _LIBC
93 # include "../locale/localeinfo.h"
94 # include "../locale/elem-hash.h"
95 # include "../locale/coll-lookup.h"
96 # include <shlib-compat.h>
97 
98 # define CONCAT(a,b) __CONCAT(a,b)
99 # define mbsrtowcs __mbsrtowcs
100 # define fnmatch __fnmatch
101 extern int fnmatch (const char *pattern, const char *string, int flags);
102 #endif
103 #endif /* Not used in ProFTPD */
104 
105 /* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set.  */
106 #define NO_LEADING_PERIOD(flags) \
107   ((flags & (PR_FNM_FILE_NAME | PR_FNM_PERIOD)) == (PR_FNM_FILE_NAME | PR_FNM_PERIOD))
108 
109 /* Comment out all this code if we are using the GNU C Library, and are not
110    actually compiling the library itself.  This code is part of the GNU C
111    Library, but also included in many other GNU distributions.  Compiling
112    and linking in this code is a waste when using the GNU C library
113    (especially if it is a shared library).  Rather than having every GNU
114    program understand `configure --with-gnu-libc' and omit the object files,
115    it is simpler to just do this in the source for each such file.  */
116 
117 /* The comment above notwithstanding, we do want to use our own version to
118  * ensure cross-platform compatibility...among other things.
119  */
120 #undef _LIBC
121 #undef __GNU_LIBRARY__
122 
123 /* Provide an implementation of the gcc-specific __builtin_expect macro,
124  * for the non-gcc compilers out there.
125  */
126 #ifndef __builtin_expect
127 # define __builtin_expect(e, n)	(e)
128 #endif /* __builtin_expect */
129 
130 #if defined _LIBC || !defined __GNU_LIBRARY__
131 
132 
133 # if defined STDC_HEADERS || !defined isascii
134 #  define ISASCII(c) 1
135 # else
136 #  define ISASCII(c) isascii(c)
137 # endif
138 
139 # ifdef isblank
140 #  define ISBLANK(c) (ISASCII (c) && isblank (c))
141 # else
142 #  define ISBLANK(c) ((c) == ' ' || (c) == '\t')
143 # endif
144 # ifdef isgraph
145 #  define ISGRAPH(c) (ISASCII (c) && isgraph (c))
146 # else
147 #  define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
148 # endif
149 
150 # define ISPRINT(c) (ISASCII (c) && isprint (c))
151 # define ISDIGIT(c) (ISASCII (c) && isdigit (c))
152 # define ISALNUM(c) (ISASCII (c) && isalnum (c))
153 # define ISALPHA(c) (ISASCII (c) && isalpha (c))
154 # define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
155 # define ISLOWER(c) (ISASCII (c) && islower (c))
156 # define ISPUNCT(c) (ISASCII (c) && ispunct (c))
157 # define ISSPACE(c) (ISASCII (c) && isspace (c))
158 # define ISUPPER(c) (ISASCII (c) && isupper (c))
159 # define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
160 
161 # define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
162 
163 # define HANDLE_MULTIBYTE       0
164 
165 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
166 /* The GNU C library provides support for user-defined character classes
167    and the functions from ISO C amendement 1.  */
168 #  ifdef CHARCLASS_NAME_MAX
169 #   define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
170 #  else
171 /* This shouldn't happen but some implementation might still have this
172    problem.  Use a reasonable default value.  */
173 #   define CHAR_CLASS_MAX_LENGTH 256
174 #  endif
175 
176 #  ifdef _LIBC
177 #   define IS_CHAR_CLASS(string) __wctype (string)
178 #  else
179 #   define IS_CHAR_CLASS(string) wctype (string)
180 #  endif
181 
182 #  ifdef _LIBC
183 #   define ISWCTYPE(WC, WT)	__iswctype (WC, WT)
184 #  else
185 #   define ISWCTYPE(WC, WT)	iswctype (WC, WT)
186 #  endif
187 
188 #  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
189 /* In this case we are implementing the multibyte character handling.  */
190 #   define HANDLE_MULTIBYTE	1
191 #  endif
192 
193 # else
194 #  define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
195 
196 #  define IS_CHAR_CLASS(string)						      \
197    (STREQ (string, "alpha") || STREQ (string, "upper")			      \
198     || STREQ (string, "lower") || STREQ (string, "digit")		      \
199     || STREQ (string, "alnum") || STREQ (string, "xdigit")		      \
200     || STREQ (string, "space") || STREQ (string, "print")		      \
201     || STREQ (string, "punct") || STREQ (string, "graph")		      \
202     || STREQ (string, "cntrl") || STREQ (string, "blank"))
203 # endif
204 
205 /* Avoid depending on library functions or files
206    whose names are inconsistent.  */
207 
208 # ifndef errno
209 extern int errno;
210 # endif
211 
212 /* Global variable.  */
213 static int posixly_correct;
214 
215 # if HANDLE_MULTIBYTE && !defined HAVE___STRCHRNUL && !defined _LIBC
216 static wchar_t *
__wcschrnul(const wchar_t * s,wint_t c)217 __wcschrnul (const wchar_t *s, wint_t c)
218 {
219   wchar_t *result = wcschr (s, c);
220   if (result == NULL)
221     result = wcschr (s, '\0');
222   return result;
223 }
224 # endif
225 
226 # ifndef internal_function
227 /* Inside GNU libc we mark some function in a special way.  In other
228    environments simply ignore the marking.  */
229 #  define internal_function
230 # endif
231 
232 /* Note that this evaluates C many times.  */
233 # ifdef _LIBC
234 #  define FOLD(c) ((flags & PR_FNM_CASEFOLD) ? tolower (c) : (c))
235 # else
236 #  define FOLD(c) ((flags & PR_FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
237 # endif
238 # define CHAR	char
239 # define UCHAR	unsigned char
240 # define INT	int
241 # define FCT	internal_fnmatch
242 # define EXT	ext_match
243 # define END	end_pattern
244 # define STRUCT	fnmatch_struct
245 # define L(CS)	CS
246 # ifdef _LIBC
247 #  define BTOWC(C)	__btowc (C)
248 # else
249 #  define BTOWC(C)	btowc (C)
250 # endif
251 # define STRLEN(S) strlen (S)
252 # define STRCAT(D, S) strcat (D, S)
253 # ifdef HAVE_MEMPCPY
254 #  define MEMPCPY(D, S, N) mempcpy (D, S, N)
255 # else
256 #  define MEMPCPY(D, S, N) __mempcpy (D, S, N)
257 # endif
258 # define MEMCHR(S, C, N) memchr (S, C, N)
259 # define STRCOLL(S1, S2) strcoll (S1, S2)
260 # include "pr_fnmatch_loop.c"
261 
262 
263 # if HANDLE_MULTIBYTE
264 /* Note that this evaluates C many times.  */
265 #  ifdef _LIBC
266 #   define FOLD(c) ((flags & PR_FNM_CASEFOLD) ? towlower (c) : (c))
267 #  else
268 #   define FOLD(c) ((flags & PR_FNM_CASEFOLD) && ISUPPER (c) ? towlower (c) : (c))
269 #  endif
270 #  define CHAR	wchar_t
271 #  define UCHAR	wint_t
272 #  define INT	wint_t
273 #  define FCT	internal_fnwmatch
274 #  define EXT	ext_wmatch
275 #  define END	end_wpattern
276 #  define STRUCT fnwmatch_struct
277 #  define L(CS)	L##CS
278 #  define BTOWC(C)	(C)
279 #  define STRLEN(S) __wcslen (S)
280 #  define STRCAT(D, S) __wcscat (D, S)
281 #  define MEMPCPY(D, S, N) wmempcpy (D, S, N)
282 #  define MEMCHR(S, C, N) wmemchr (S, C, N)
283 #  define STRCOLL(S1, S2) wcscoll (S1, S2)
284 #  define WIDE_CHAR_VERSION 1
285 
286 #  undef IS_CHAR_CLASS
287 /* We have to convert the wide character string in a multibyte string.  But
288    we know that the character class names consist of alphanumeric characters
289    from the portable character set, and since the wide character encoding
290    for a member of the portable character set is the same code point as
291    its single-byte encoding, we can use a simplified method to convert the
292    string to a multibyte character string.  */
293 static wctype_t
is_char_class(const wchar_t * wcs)294 is_char_class (const wchar_t *wcs)
295 {
296   char s[CHAR_CLASS_MAX_LENGTH + 1];
297   char *cp = s;
298 
299   do
300     {
301       /* Test for a printable character from the portable character set.  */
302 #  ifdef _LIBC
303       if (*wcs < 0x20 || *wcs > 0x7e
304 	  || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
305 	return (wctype_t) 0;
306 #  else
307       switch (*wcs)
308 	{
309 	case L' ': case L'!': case L'"': case L'#': case L'%':
310 	case L'&': case L'\'': case L'(': case L')': case L'*':
311 	case L'+': case L',': case L'-': case L'.': case L'/':
312 	case L'0': case L'1': case L'2': case L'3': case L'4':
313 	case L'5': case L'6': case L'7': case L'8': case L'9':
314 	case L':': case L';': case L'<': case L'=': case L'>':
315 	case L'?':
316 	case L'A': case L'B': case L'C': case L'D': case L'E':
317 	case L'F': case L'G': case L'H': case L'I': case L'J':
318 	case L'K': case L'L': case L'M': case L'N': case L'O':
319 	case L'P': case L'Q': case L'R': case L'S': case L'T':
320 	case L'U': case L'V': case L'W': case L'X': case L'Y':
321 	case L'Z':
322 	case L'[': case L'\\': case L']': case L'^': case L'_':
323 	case L'a': case L'b': case L'c': case L'd': case L'e':
324 	case L'f': case L'g': case L'h': case L'i': case L'j':
325 	case L'k': case L'l': case L'm': case L'n': case L'o':
326 	case L'p': case L'q': case L'r': case L's': case L't':
327 	case L'u': case L'v': case L'w': case L'x': case L'y':
328 	case L'z': case L'{': case L'|': case L'}': case L'~':
329 	  break;
330 	default:
331 	  return (wctype_t) 0;
332 	}
333 #  endif
334 
335       /* Avoid overrunning the buffer.  */
336       if (cp == s + CHAR_CLASS_MAX_LENGTH)
337 	return (wctype_t) 0;
338 
339       *cp++ = (char) *wcs++;
340     }
341   while (*wcs != L'\0');
342 
343   *cp = '\0';
344 
345 #  ifdef _LIBC
346   return __wctype (s);
347 #  else
348   return wctype (s);
349 #  endif
350 }
351 #  define IS_CHAR_CLASS(string) is_char_class (string)
352 
353 #  include "pr_fnmatch_loop.c"
354 # endif
355 
356 
357 int
pr_fnmatch(pattern,string,flags)358 pr_fnmatch (pattern, string, flags)
359      const char *pattern;
360      const char *string;
361      int flags;
362 {
363 # if HANDLE_MULTIBYTE
364   if (__builtin_expect (MB_CUR_MAX, 1) != 1)
365     {
366       mbstate_t ps;
367       size_t n;
368       const char *p;
369       wchar_t *wpattern;
370       wchar_t *wstring;
371 
372       /* Convert the strings into wide characters.  */
373       memset (&ps, '\0', sizeof (ps));
374       p = pattern;
375 #ifdef _LIBC
376       n = strnlen (pattern, 1024);
377 #else
378       n = strlen (pattern);
379 #endif
380       if (__builtin_expect (n < 1024, 1))
381 	{
382 	  wpattern = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t));
383 	  n = mbsrtowcs (wpattern, &p, n + 1, &ps);
384 	  if (__builtin_expect (n == (size_t) -1, 0))
385 	    /* Something wrong.
386 	       XXX Do we have to set `errno' to something which mbsrtows hasn't
387 	       already done?  */
388 	    return -1;
389 	  if (p)
390 	    {
391 	      memset (&ps, '\0', sizeof (ps));
392 	      goto prepare_wpattern;
393 	    }
394 	}
395       else
396 	{
397 	prepare_wpattern:
398 	  n = mbsrtowcs (NULL, &pattern, 0, &ps);
399 	  if (__builtin_expect (n == (size_t) -1, 0))
400 	    /* Something wrong.
401 	       XXX Do we have to set `errno' to something which mbsrtows hasn't
402 	       already done?  */
403 	    return -1;
404 	  wpattern = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t));
405 	  assert (mbsinit (&ps));
406 	  (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
407 	}
408 
409       assert (mbsinit (&ps));
410 #ifdef _LIBC
411       n = strnlen (string, 1024);
412 #else
413       n = strlen (string);
414 #endif
415       p = string;
416       if (__builtin_expect (n < 1024, 1))
417 	{
418 	  wstring = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t));
419 	  n = mbsrtowcs (wstring, &p, n + 1, &ps);
420 	  if (__builtin_expect (n == (size_t) -1, 0))
421 	    /* Something wrong.
422 	       XXX Do we have to set `errno' to something which mbsrtows hasn't
423 	       already done?  */
424 	    return -1;
425 	  if (p)
426 	    {
427 	      memset (&ps, '\0', sizeof (ps));
428 	      goto prepare_wstring;
429 	    }
430 	}
431       else
432 	{
433 	prepare_wstring:
434 	  n = mbsrtowcs (NULL, &string, 0, &ps);
435 	  if (__builtin_expect (n == (size_t) -1, 0))
436 	    /* Something wrong.
437 	       XXX Do we have to set `errno' to something which mbsrtows hasn't
438 	       already done?  */
439 	    return -1;
440 	  wstring = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t));
441 	  assert (mbsinit (&ps));
442 	  (void) mbsrtowcs (wstring, &string, n + 1, &ps);
443 	}
444 
445       return internal_fnwmatch (wpattern, wstring, wstring + n,
446 				flags & PR_FNM_PERIOD, flags, NULL);
447     }
448 # endif  /* mbstate_t and mbsrtowcs or _LIBC.  */
449 
450   return internal_fnmatch (pattern, string, string + strlen (string),
451 			   flags & PR_FNM_PERIOD, flags, NULL);
452 }
453 
454 #endif	/* _LIBC or not __GNU_LIBRARY__.  */
455