glob: pacify fuzzer for mempcpy
[gnulib.git] / lib / glob.c
blob33030ec72bb2502a2b93823c5e02bbf40ac195ae
1 /* Copyright (C) 1991-2017 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 #include <glob.h>
20 #include <errno.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <stdbool.h>
24 #include <stddef.h>
25 #include <stdint.h>
26 #include <assert.h>
27 #include <unistd.h>
29 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
30 # define WINDOWS32
31 #endif
33 #ifndef WINDOWS32
34 # include <pwd.h>
35 #endif
37 #include <errno.h>
38 #include <dirent.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <alloca.h>
43 #ifdef _LIBC
44 # undef strdup
45 # define strdup(str) __strdup (str)
46 # define sysconf(id) __sysconf (id)
47 # define closedir(dir) __closedir (dir)
48 # define opendir(name) __opendir (name)
49 # define readdir(str) __readdir64 (str)
50 # define getpwnam_r(name, bufp, buf, len, res) \
51 __getpwnam_r (name, bufp, buf, len, res)
52 # ifndef __lstat64
53 # define __lstat64(fname, buf) __lxstat64 (_STAT_VER, fname, buf)
54 # endif
55 # ifndef __stat64
56 # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
57 # endif
58 # define struct_stat64 struct stat64
59 # define FLEXIBLE_ARRAY_MEMBER
60 #else /* !_LIBC */
61 # define __getlogin_r(buf, len) getlogin_r (buf, len)
62 # define __lstat64(fname, buf) lstat (fname, buf)
63 # define __stat64(fname, buf) stat (fname, buf)
64 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
65 # define struct_stat64 struct stat
66 # ifndef __MVS__
67 # define __alloca alloca
68 # endif
69 # define __readdir readdir
70 # define COMPILE_GLOB64
71 #endif /* _LIBC */
73 #include <fnmatch.h>
75 #include <flexmember.h>
76 #include <glob_internal.h>
77 #include <scratch_buffer.h>
79 static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
81 typedef uint_fast8_t dirent_type;
83 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
84 /* Any distinct values will do here.
85 Undef any existing macros out of the way. */
86 # undef DT_UNKNOWN
87 # undef DT_DIR
88 # undef DT_LNK
89 # define DT_UNKNOWN 0
90 # define DT_DIR 1
91 # define DT_LNK 2
92 #endif
94 /* A representation of a directory entry which does not depend on the
95 layout of struct dirent, or the size of ino_t. */
96 struct readdir_result
98 const char *name;
99 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
100 dirent_type type;
101 #endif
104 /* Initialize and return type member of struct readdir_result. */
105 static dirent_type
106 readdir_result_type (struct readdir_result d)
108 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
109 # define D_TYPE_TO_RESULT(source) (source)->d_type,
110 return d.type;
111 #else
112 # define D_TYPE_TO_RESULT(source)
113 return DT_UNKNOWN;
114 #endif
117 /* Construct an initializer for a struct readdir_result object from a
118 struct dirent *. No copy of the name is made. */
119 #define READDIR_RESULT_INITIALIZER(source) \
121 source->d_name, \
122 D_TYPE_TO_RESULT (source) \
125 /* Call gl_readdir on STREAM. This macro can be overridden to reduce
126 type safety if an old interface version needs to be supported. */
127 #ifndef GL_READDIR
128 # define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
129 #endif
131 /* Extract name and type from directory entry. No copy of the name is
132 made. If SOURCE is NULL, result name is NULL. Keep in sync with
133 convert_dirent64 below. */
134 static struct readdir_result
135 convert_dirent (const struct dirent *source)
137 if (source == NULL)
139 struct readdir_result result = { NULL, };
140 return result;
142 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
143 return result;
146 #ifndef COMPILE_GLOB64
147 /* Like convert_dirent, but works on struct dirent64 instead. Keep in
148 sync with convert_dirent above. */
149 static struct readdir_result
150 convert_dirent64 (const struct dirent64 *source)
152 if (source == NULL)
154 struct readdir_result result = { NULL, };
155 return result;
157 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
158 return result;
160 #endif
162 #ifndef _LIBC
163 /* The results of opendir() in this file are not used with dirfd and fchdir,
164 and we do not leak fds to any single-threaded code that could use stdio,
165 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
166 FIXME - if the kernel ever adds support for multi-thread safety for
167 avoiding standard fds, then we should use opendir_safer. */
168 # ifdef GNULIB_defined_opendir
169 # undef opendir
170 # endif
171 # ifdef GNULIB_defined_closedir
172 # undef closedir
173 # endif
175 /* Just use malloc. */
176 # define __libc_use_alloca(n) false
177 # define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
178 # define extend_alloca_account(buf, len, newlen, avar) \
179 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
180 #endif
182 /* Set *R = A + B. Return true if the answer is mathematically
183 incorrect due to overflow; in this case, *R is the low order
184 bits of the correct answer. */
186 static bool
187 size_add_wrapv (size_t a, size_t b, size_t *r)
189 #if 5 <= __GNUC__ && !defined __ICC
190 return __builtin_add_overflow (a, b, r);
191 #else
192 *r = a + b;
193 return *r < a;
194 #endif
197 static bool
198 glob_use_alloca (size_t alloca_used, size_t len)
200 size_t size;
201 return (!size_add_wrapv (alloca_used, len, &size)
202 && __libc_use_alloca (size));
205 static int glob_in_dir (const char *pattern, const char *directory,
206 int flags, int (*errfunc) (const char *, int),
207 glob_t *pglob, size_t alloca_used);
208 static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
209 static int collated_compare (const void *, const void *) __THROWNL;
212 /* Return true if FILENAME is a directory or a symbolic link to a directory.
213 Use FLAGS and PGLOB to resolve the filename. */
214 static bool
215 is_dir (char const *filename, int flags, glob_t const *pglob)
217 struct stat st;
218 struct_stat64 st64;
219 return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
220 ? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
221 : __stat64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
224 /* Find the end of the sub-pattern in a brace expression. */
225 static const char *
226 next_brace_sub (const char *cp, int flags)
228 size_t depth = 0;
229 while (*cp != '\0')
230 if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
232 if (*++cp == '\0')
233 break;
234 ++cp;
236 else
238 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
239 break;
241 if (*cp++ == '{')
242 depth++;
245 return *cp != '\0' ? cp : NULL;
249 /* Do glob searching for PATTERN, placing results in PGLOB.
250 The bits defined above may be set in FLAGS.
251 If a directory cannot be opened or read and ERRFUNC is not nil,
252 it is called with the pathname that caused the error, and the
253 'errno' value from the failing call; if it returns non-zero
254 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
255 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
256 Otherwise, 'glob' returns zero. */
258 #ifdef GLOB_ATTRIBUTE
259 GLOB_ATTRIBUTE
260 #endif
261 glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
262 glob_t *pglob)
264 const char *filename;
265 char *dirname = NULL;
266 size_t dirlen;
267 int status;
268 size_t oldcount;
269 int meta;
270 int dirname_modified;
271 int malloc_dirname = 0;
272 glob_t dirs;
273 int retval = 0;
274 size_t alloca_used = 0;
276 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
278 __set_errno (EINVAL);
279 return -1;
282 /* POSIX requires all slashes to be matched. This means that with
283 a trailing slash we must match only directories. */
284 if (pattern[0] && pattern[strlen (pattern) - 1] == '/')
285 flags |= GLOB_ONLYDIR;
287 if (!(flags & GLOB_DOOFFS))
288 /* Have to do this so 'globfree' knows where to start freeing. It
289 also makes all the code that uses gl_offs simpler. */
290 pglob->gl_offs = 0;
292 if (!(flags & GLOB_APPEND))
294 pglob->gl_pathc = 0;
295 if (!(flags & GLOB_DOOFFS))
296 pglob->gl_pathv = NULL;
297 else
299 size_t i;
301 if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
302 return GLOB_NOSPACE;
304 pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
305 * sizeof (char *));
306 if (pglob->gl_pathv == NULL)
307 return GLOB_NOSPACE;
309 for (i = 0; i <= pglob->gl_offs; ++i)
310 pglob->gl_pathv[i] = NULL;
314 if (flags & GLOB_BRACE)
316 const char *begin;
318 if (flags & GLOB_NOESCAPE)
319 begin = strchr (pattern, '{');
320 else
322 begin = pattern;
323 while (1)
325 if (*begin == '\0')
327 begin = NULL;
328 break;
331 if (*begin == '\\' && begin[1] != '\0')
332 ++begin;
333 else if (*begin == '{')
334 break;
336 ++begin;
340 if (begin != NULL)
342 /* Allocate working buffer large enough for our work. Note that
343 we have at least an opening and closing brace. */
344 size_t firstc;
345 char *alt_start;
346 const char *p;
347 const char *next;
348 const char *rest;
349 size_t rest_len;
350 char *onealt;
351 size_t pattern_len = strlen (pattern) - 1;
352 int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
353 if (alloca_onealt)
354 onealt = alloca_account (pattern_len, alloca_used);
355 else
357 onealt = malloc (pattern_len);
358 if (onealt == NULL)
359 return GLOB_NOSPACE;
362 /* We know the prefix for all sub-patterns. */
363 alt_start = mempcpy (onealt, pattern, begin - pattern);
365 /* Find the first sub-pattern and at the same time find the
366 rest after the closing brace. */
367 next = next_brace_sub (begin + 1, flags);
368 if (next == NULL)
370 /* It is an invalid expression. */
371 illegal_brace:
372 if (__glibc_unlikely (!alloca_onealt))
373 free (onealt);
374 flags &= ~GLOB_BRACE;
375 goto no_brace;
378 /* Now find the end of the whole brace expression. */
379 rest = next;
380 while (*rest != '}')
382 rest = next_brace_sub (rest + 1, flags);
383 if (rest == NULL)
384 /* It is an illegal expression. */
385 goto illegal_brace;
387 /* Please note that we now can be sure the brace expression
388 is well-formed. */
389 rest_len = strlen (++rest) + 1;
391 /* We have a brace expression. BEGIN points to the opening {,
392 NEXT points past the terminator of the first element, and END
393 points past the final }. We will accumulate result names from
394 recursive runs for each brace alternative in the buffer using
395 GLOB_APPEND. */
396 firstc = pglob->gl_pathc;
398 p = begin + 1;
399 while (1)
401 int result;
403 /* Construct the new glob expression. */
404 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
406 result = glob (onealt,
407 ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
408 | GLOB_APPEND), errfunc, pglob);
410 /* If we got an error, return it. */
411 if (result && result != GLOB_NOMATCH)
413 if (__glibc_unlikely (!alloca_onealt))
414 free (onealt);
415 if (!(flags & GLOB_APPEND))
417 globfree (pglob);
418 pglob->gl_pathc = 0;
420 return result;
423 if (*next == '}')
424 /* We saw the last entry. */
425 break;
427 p = next + 1;
428 next = next_brace_sub (p, flags);
429 assert (next != NULL);
432 if (__glibc_unlikely (!alloca_onealt))
433 free (onealt);
435 if (pglob->gl_pathc != firstc)
436 /* We found some entries. */
437 return 0;
438 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
439 return GLOB_NOMATCH;
443 no_brace:
444 oldcount = pglob->gl_pathc + pglob->gl_offs;
446 /* Find the filename. */
447 filename = strrchr (pattern, '/');
449 #if defined __MSDOS__ || defined WINDOWS32
450 /* The case of "d:pattern". Since ':' is not allowed in
451 file names, we can safely assume that wherever it
452 happens in pattern, it signals the filename part. This
453 is so we could some day support patterns like "[a-z]:foo". */
454 if (filename == NULL)
455 filename = strchr (pattern, ':');
456 #endif /* __MSDOS__ || WINDOWS32 */
458 dirname_modified = 0;
459 if (filename == NULL)
461 /* This can mean two things: a simple name or "~name". The latter
462 case is nothing but a notation for a directory. */
463 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
465 dirname = (char *) pattern;
466 dirlen = strlen (pattern);
468 /* Set FILENAME to NULL as a special flag. This is ugly but
469 other solutions would require much more code. We test for
470 this special case below. */
471 filename = NULL;
473 else
475 if (__glibc_unlikely (pattern[0] == '\0'))
477 dirs.gl_pathv = NULL;
478 goto no_matches;
481 filename = pattern;
482 dirname = (char *) ".";
483 dirlen = 0;
486 else if (filename == pattern
487 || (filename == pattern + 1 && pattern[0] == '\\'
488 && (flags & GLOB_NOESCAPE) == 0))
490 /* "/pattern" or "\\/pattern". */
491 dirname = (char *) "/";
492 dirlen = 1;
493 ++filename;
495 else
497 char *newp;
498 dirlen = filename - pattern;
500 #if defined __MSDOS__ || defined WINDOWS32
501 if (*filename == ':'
502 || (filename > pattern + 1 && filename[-1] == ':'))
504 char *drive_spec;
506 ++dirlen;
507 drive_spec = __alloca (dirlen + 1);
508 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
509 /* For now, disallow wildcards in the drive spec, to
510 prevent infinite recursion in glob. */
511 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
512 return GLOB_NOMATCH;
513 /* If this is "d:pattern", we need to copy ':' to DIRNAME
514 as well. If it's "d:/pattern", don't remove the slash
515 from "d:/", since "d:" and "d:/" are not the same.*/
517 #endif
519 if (glob_use_alloca (alloca_used, dirlen + 1))
520 newp = alloca_account (dirlen + 1, alloca_used);
521 else
523 newp = malloc (dirlen + 1);
524 if (newp == NULL)
525 return GLOB_NOSPACE;
526 malloc_dirname = 1;
528 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
529 dirname = newp;
530 ++filename;
532 #if defined __MSDOS__ || defined WINDOWS32
533 bool drive_root = (dirlen > 1
534 && (dirname[dirlen - 1] == ':'
535 || (dirlen > 2 && dirname[dirlen - 2] == ':'
536 && dirname[dirlen - 1] == '/')));
537 #else
538 bool drive_root = false;
539 #endif
541 if (filename[0] == '\0' && dirlen > 1 && !drive_root)
542 /* "pattern/". Expand "pattern", appending slashes. */
544 int orig_flags = flags;
545 if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
547 /* "pattern\\/". Remove the final backslash if it hasn't
548 been quoted. */
549 char *p = (char *) &dirname[dirlen - 1];
551 while (p > dirname && p[-1] == '\\') --p;
552 if ((&dirname[dirlen] - p) & 1)
554 *(char *) &dirname[--dirlen] = '\0';
555 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
558 int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
559 if (val == 0)
560 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
561 | (flags & GLOB_MARK));
562 else if (val == GLOB_NOMATCH && flags != orig_flags)
564 /* Make sure globfree (&dirs); is a nop. */
565 dirs.gl_pathv = NULL;
566 flags = orig_flags;
567 oldcount = pglob->gl_pathc + pglob->gl_offs;
568 goto no_matches;
570 retval = val;
571 goto out;
575 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
577 if (dirname[1] == '\0' || dirname[1] == '/'
578 || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
579 && (dirname[2] == '\0' || dirname[2] == '/')))
581 /* Look up home directory. */
582 char *home_dir = getenv ("HOME");
583 int malloc_home_dir = 0;
584 if (home_dir == NULL || home_dir[0] == '\0')
586 #ifdef WINDOWS32
587 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
588 preference to HOME, because the user can change HOME. */
589 const char *home_drive = getenv ("HOMEDRIVE");
590 const char *home_path = getenv ("HOMEPATH");
592 if (home_drive != NULL && home_path != NULL)
594 size_t home_drive_len = strlen (home_drive);
595 size_t home_path_len = strlen (home_path);
596 char *mem = alloca (home_drive_len + home_path_len + 1);
598 memcpy (mem, home_drive, home_drive_len);
599 memcpy (mem + home_drive_len, home_path, home_path_len + 1);
600 home_dir = mem;
602 else
603 home_dir = "c:/users/default"; /* poor default */
604 #else
605 int err;
606 struct passwd *p;
607 struct passwd pwbuf;
608 struct scratch_buffer s;
609 scratch_buffer_init (&s);
610 while (true)
612 p = NULL;
613 err = __getlogin_r (s.data, s.length);
614 if (err == 0)
616 # if defined HAVE_GETPWNAM_R || defined _LIBC
617 size_t ssize = strlen (s.data) + 1;
618 err = getpwnam_r (s.data, &pwbuf, s.data + ssize,
619 s.length - ssize, &p);
620 # else
621 p = getpwnam (s.data);
622 if (p == NULL)
623 err = errno;
624 # endif
626 if (err != ERANGE)
627 break;
628 if (!scratch_buffer_grow (&s))
630 retval = GLOB_NOSPACE;
631 goto out;
634 if (err == 0)
636 home_dir = strdup (p->pw_dir);
637 malloc_home_dir = 1;
639 scratch_buffer_free (&s);
640 if (err == 0 && home_dir == NULL)
642 retval = GLOB_NOSPACE;
643 goto out;
645 #endif /* WINDOWS32 */
647 if (home_dir == NULL || home_dir[0] == '\0')
649 if (__glibc_unlikely (malloc_home_dir))
650 free (home_dir);
651 if (flags & GLOB_TILDE_CHECK)
653 retval = GLOB_NOMATCH;
654 goto out;
656 else
658 home_dir = (char *) "~"; /* No luck. */
659 malloc_home_dir = 0;
662 /* Now construct the full directory. */
663 if (dirname[1] == '\0')
665 if (__glibc_unlikely (malloc_dirname))
666 free (dirname);
668 dirname = home_dir;
669 dirlen = strlen (dirname);
670 malloc_dirname = malloc_home_dir;
672 else
674 char *newp;
675 size_t home_len = strlen (home_dir);
676 int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
677 if (use_alloca)
678 newp = alloca_account (home_len + dirlen, alloca_used);
679 else
681 newp = malloc (home_len + dirlen);
682 if (newp == NULL)
684 if (__glibc_unlikely (malloc_home_dir))
685 free (home_dir);
686 retval = GLOB_NOSPACE;
687 goto out;
691 mempcpy (mempcpy (newp, home_dir, home_len),
692 &dirname[1], dirlen);
694 if (__glibc_unlikely (malloc_dirname))
695 free (dirname);
697 dirname = newp;
698 dirlen += home_len - 1;
699 malloc_dirname = !use_alloca;
701 if (__glibc_unlikely (malloc_home_dir))
702 free (home_dir);
704 dirname_modified = 1;
706 else
708 #ifndef WINDOWS32
709 char *end_name = strchr (dirname, '/');
710 char *user_name;
711 int malloc_user_name = 0;
712 char *unescape = NULL;
714 if (!(flags & GLOB_NOESCAPE))
716 if (end_name == NULL)
718 unescape = strchr (dirname, '\\');
719 if (unescape)
720 end_name = strchr (unescape, '\0');
722 else
723 unescape = memchr (dirname, '\\', end_name - dirname);
725 if (end_name == NULL)
726 user_name = dirname + 1;
727 else
729 char *newp;
730 if (glob_use_alloca (alloca_used, end_name - dirname))
731 newp = alloca_account (end_name - dirname, alloca_used);
732 else
734 newp = malloc (end_name - dirname);
735 if (newp == NULL)
737 retval = GLOB_NOSPACE;
738 goto out;
740 malloc_user_name = 1;
742 if (unescape != NULL)
744 char *p = mempcpy (newp, dirname + 1,
745 unescape - dirname - 1);
746 char *q = unescape;
747 while (*q != '\0')
749 if (*q == '\\')
751 if (q[1] == '\0')
753 /* "~fo\\o\\" unescape to user_name "foo\\",
754 but "~fo\\o\\/" unescape to user_name
755 "foo". */
756 if (filename == NULL)
757 *p++ = '\\';
758 break;
760 ++q;
762 *p++ = *q++;
764 *p = '\0';
766 else
767 *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
768 = '\0';
769 user_name = newp;
772 /* Look up specific user's home directory. */
774 struct passwd *p;
775 struct scratch_buffer pwtmpbuf;
776 scratch_buffer_init (&pwtmpbuf);
778 # if defined HAVE_GETPWNAM_R || defined _LIBC
779 struct passwd pwbuf;
781 while (getpwnam_r (user_name, &pwbuf,
782 pwtmpbuf.data, pwtmpbuf.length, &p)
783 == ERANGE)
785 if (!scratch_buffer_grow (&pwtmpbuf))
787 retval = GLOB_NOSPACE;
788 goto out;
791 # else
792 p = getpwnam (user_name);
793 # endif
795 if (__glibc_unlikely (malloc_user_name))
796 free (user_name);
798 /* If we found a home directory use this. */
799 if (p != NULL)
801 size_t home_len = strlen (p->pw_dir);
802 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
803 char *d;
805 if (__glibc_unlikely (malloc_dirname))
806 free (dirname);
807 malloc_dirname = 0;
809 if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
810 dirname = alloca_account (home_len + rest_len + 1,
811 alloca_used);
812 else
814 dirname = malloc (home_len + rest_len + 1);
815 if (dirname == NULL)
817 scratch_buffer_free (&pwtmpbuf);
818 retval = GLOB_NOSPACE;
819 goto out;
821 malloc_dirname = 1;
823 d = mempcpy (dirname, p->pw_dir, home_len);
824 if (end_name != NULL)
825 d = mempcpy (d, end_name, rest_len);
826 *d = '\0';
828 dirlen = home_len + rest_len;
829 dirname_modified = 1;
831 else
833 if (flags & GLOB_TILDE_CHECK)
835 /* We have to regard it as an error if we cannot find the
836 home directory. */
837 retval = GLOB_NOMATCH;
838 goto out;
841 scratch_buffer_free (&pwtmpbuf);
843 #endif /* !WINDOWS32 */
847 /* Now test whether we looked for "~" or "~NAME". In this case we
848 can give the answer now. */
849 if (filename == NULL)
851 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
852 char **new_gl_pathv;
854 if (newcount > SIZE_MAX / sizeof (char *) - 2)
856 nospace:
857 free (pglob->gl_pathv);
858 pglob->gl_pathv = NULL;
859 pglob->gl_pathc = 0;
860 retval = GLOB_NOSPACE;
861 goto out;
864 new_gl_pathv = realloc (pglob->gl_pathv,
865 (newcount + 2) * sizeof (char *));
866 if (new_gl_pathv == NULL)
867 goto nospace;
868 pglob->gl_pathv = new_gl_pathv;
870 if (flags & GLOB_MARK && is_dir (dirname, flags, pglob))
872 char *p;
873 pglob->gl_pathv[newcount] = malloc (dirlen + 2);
874 if (pglob->gl_pathv[newcount] == NULL)
875 goto nospace;
876 p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
877 p[0] = '/';
878 p[1] = '\0';
879 if (__glibc_unlikely (malloc_dirname))
880 free (dirname);
882 else
884 if (__glibc_unlikely (malloc_dirname))
885 pglob->gl_pathv[newcount] = dirname;
886 else
888 pglob->gl_pathv[newcount] = strdup (dirname);
889 if (pglob->gl_pathv[newcount] == NULL)
890 goto nospace;
893 pglob->gl_pathv[++newcount] = NULL;
894 ++pglob->gl_pathc;
895 pglob->gl_flags = flags;
897 return 0;
900 meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
901 /* meta is 1 if correct glob pattern containing metacharacters.
902 If meta has bit (1 << 2) set, it means there was an unterminated
903 [ which we handle the same, using fnmatch. Broken unterminated
904 pattern bracket expressions ought to be rare enough that it is
905 not worth special casing them, fnmatch will do the right thing. */
906 if (meta & (GLOBPAT_SPECIAL | GLOBPAT_BRACKET))
908 /* The directory name contains metacharacters, so we
909 have to glob for the directory, and then glob for
910 the pattern in each directory found. */
911 size_t i;
913 if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\')
915 /* "foo\\/bar". Remove the final backslash from dirname
916 if it has not been quoted. */
917 char *p = (char *) &dirname[dirlen - 1];
919 while (p > dirname && p[-1] == '\\') --p;
920 if ((&dirname[dirlen] - p) & 1)
921 *(char *) &dirname[--dirlen] = '\0';
924 if (__glibc_unlikely ((flags & GLOB_ALTDIRFUNC) != 0))
926 /* Use the alternative access functions also in the recursive
927 call. */
928 dirs.gl_opendir = pglob->gl_opendir;
929 dirs.gl_readdir = pglob->gl_readdir;
930 dirs.gl_closedir = pglob->gl_closedir;
931 dirs.gl_stat = pglob->gl_stat;
932 dirs.gl_lstat = pglob->gl_lstat;
935 status = glob (dirname,
936 ((flags & (GLOB_ERR | GLOB_NOESCAPE
937 | GLOB_ALTDIRFUNC))
938 | GLOB_NOSORT | GLOB_ONLYDIR),
939 errfunc, &dirs);
940 if (status != 0)
942 if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
944 retval = status;
945 goto out;
947 goto no_matches;
950 /* We have successfully globbed the preceding directory name.
951 For each name we found, call glob_in_dir on it and FILENAME,
952 appending the results to PGLOB. */
953 for (i = 0; i < dirs.gl_pathc; ++i)
955 size_t old_pathc;
957 old_pathc = pglob->gl_pathc;
958 status = glob_in_dir (filename, dirs.gl_pathv[i],
959 ((flags | GLOB_APPEND)
960 & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
961 errfunc, pglob, alloca_used);
962 if (status == GLOB_NOMATCH)
963 /* No matches in this directory. Try the next. */
964 continue;
966 if (status != 0)
968 globfree (&dirs);
969 globfree (pglob);
970 pglob->gl_pathc = 0;
971 retval = status;
972 goto out;
975 /* Stick the directory on the front of each name. */
976 if (prefix_array (dirs.gl_pathv[i],
977 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
978 pglob->gl_pathc - old_pathc))
980 globfree (&dirs);
981 globfree (pglob);
982 pglob->gl_pathc = 0;
983 retval = GLOB_NOSPACE;
984 goto out;
988 flags |= GLOB_MAGCHAR;
990 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
991 But if we have not found any matching entry and the GLOB_NOCHECK
992 flag was set we must return the input pattern itself. */
993 if (pglob->gl_pathc + pglob->gl_offs == oldcount)
995 no_matches:
996 /* No matches. */
997 if (flags & GLOB_NOCHECK)
999 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
1000 char **new_gl_pathv;
1002 if (newcount > SIZE_MAX / sizeof (char *) - 2)
1004 nospace2:
1005 globfree (&dirs);
1006 retval = GLOB_NOSPACE;
1007 goto out;
1010 new_gl_pathv = realloc (pglob->gl_pathv,
1011 (newcount + 2) * sizeof (char *));
1012 if (new_gl_pathv == NULL)
1013 goto nospace2;
1014 pglob->gl_pathv = new_gl_pathv;
1016 pglob->gl_pathv[newcount] = strdup (pattern);
1017 if (pglob->gl_pathv[newcount] == NULL)
1019 globfree (&dirs);
1020 globfree (pglob);
1021 pglob->gl_pathc = 0;
1022 retval = GLOB_NOSPACE;
1023 goto out;
1026 ++pglob->gl_pathc;
1027 ++newcount;
1029 pglob->gl_pathv[newcount] = NULL;
1030 pglob->gl_flags = flags;
1032 else
1034 globfree (&dirs);
1035 retval = GLOB_NOMATCH;
1036 goto out;
1040 globfree (&dirs);
1042 else
1044 size_t old_pathc = pglob->gl_pathc;
1045 int orig_flags = flags;
1047 if (meta & GLOBPAT_BACKSLASH)
1049 char *p = strchr (dirname, '\\'), *q;
1050 /* We need to unescape the dirname string. It is certainly
1051 allocated by alloca, as otherwise filename would be NULL
1052 or dirname wouldn't contain backslashes. */
1053 q = p;
1056 if (*p == '\\')
1058 *q = *++p;
1059 --dirlen;
1061 else
1062 *q = *p;
1063 ++q;
1065 while (*p++ != '\0');
1066 dirname_modified = 1;
1068 if (dirname_modified)
1069 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
1070 status = glob_in_dir (filename, dirname, flags, errfunc, pglob,
1071 alloca_used);
1072 if (status != 0)
1074 if (status == GLOB_NOMATCH && flags != orig_flags
1075 && pglob->gl_pathc + pglob->gl_offs == oldcount)
1077 /* Make sure globfree (&dirs); is a nop. */
1078 dirs.gl_pathv = NULL;
1079 flags = orig_flags;
1080 goto no_matches;
1082 retval = status;
1083 goto out;
1086 if (dirlen > 0)
1088 /* Stick the directory on the front of each name. */
1089 if (prefix_array (dirname,
1090 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1091 pglob->gl_pathc - old_pathc))
1093 globfree (pglob);
1094 pglob->gl_pathc = 0;
1095 retval = GLOB_NOSPACE;
1096 goto out;
1101 if (flags & GLOB_MARK)
1103 /* Append slashes to directory names. */
1104 size_t i;
1106 for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i)
1107 if (is_dir (pglob->gl_pathv[i], flags, pglob))
1109 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1110 char *new = realloc (pglob->gl_pathv[i], len);
1111 if (new == NULL)
1113 globfree (pglob);
1114 pglob->gl_pathc = 0;
1115 retval = GLOB_NOSPACE;
1116 goto out;
1118 strcpy (&new[len - 2], "/");
1119 pglob->gl_pathv[i] = new;
1123 if (!(flags & GLOB_NOSORT))
1125 /* Sort the vector. */
1126 qsort (&pglob->gl_pathv[oldcount],
1127 pglob->gl_pathc + pglob->gl_offs - oldcount,
1128 sizeof (char *), collated_compare);
1131 out:
1132 if (__glibc_unlikely (malloc_dirname))
1133 free (dirname);
1135 return retval;
1137 #if defined _LIBC && !defined glob
1138 libc_hidden_def (glob)
1139 #endif
1142 /* Do a collated comparison of A and B. */
1143 static int
1144 collated_compare (const void *a, const void *b)
1146 char *const *ps1 = a; char *s1 = *ps1;
1147 char *const *ps2 = b; char *s2 = *ps2;
1149 if (s1 == s2)
1150 return 0;
1151 if (s1 == NULL)
1152 return 1;
1153 if (s2 == NULL)
1154 return -1;
1155 return strcoll (s1, s2);
1159 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1160 elements in place. Return nonzero if out of memory, zero if successful.
1161 A slash is inserted between DIRNAME and each elt of ARRAY,
1162 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1163 static int
1164 prefix_array (const char *dirname, char **array, size_t n)
1166 size_t i;
1167 size_t dirlen = strlen (dirname);
1168 char dirsep_char = '/';
1170 if (dirlen == 1 && dirname[0] == '/')
1171 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1172 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1173 dirlen = 0;
1175 #if defined __MSDOS__ || defined WINDOWS32
1176 if (dirlen > 1)
1178 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1179 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1180 --dirlen;
1181 else if (dirname[dirlen - 1] == ':')
1183 /* DIRNAME is "d:". Use ':' instead of '/'. */
1184 --dirlen;
1185 dirsep_char = ':';
1188 #endif
1190 for (i = 0; i < n; ++i)
1192 size_t eltlen = strlen (array[i]) + 1;
1193 char *new = malloc (dirlen + 1 + eltlen);
1194 if (new == NULL)
1196 while (i > 0)
1197 free (array[--i]);
1198 return 1;
1202 char *endp = mempcpy (new, dirname, dirlen);
1203 *endp++ = dirsep_char;
1204 mempcpy (endp, array[i], eltlen);
1206 free (array[i]);
1207 array[i] = new;
1210 return 0;
1213 /* Like 'glob', but PATTERN is a final pathname component,
1214 and matches are searched for in DIRECTORY.
1215 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1216 The GLOB_APPEND flag is assumed to be set (always appends). */
1217 static int
1218 glob_in_dir (const char *pattern, const char *directory, int flags,
1219 int (*errfunc) (const char *, int),
1220 glob_t *pglob, size_t alloca_used)
1222 size_t dirlen = strlen (directory);
1223 void *stream = NULL;
1224 # define GLOBNAMES_MEMBERS(nnames) \
1225 struct globnames *next; size_t count; char *name[nnames];
1226 struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
1227 struct { GLOBNAMES_MEMBERS (64) } init_names_buf;
1228 struct globnames *init_names = (struct globnames *) &init_names_buf;
1229 struct globnames *names = init_names;
1230 struct globnames *names_alloca = init_names;
1231 size_t nfound = 0;
1232 size_t cur = 0;
1233 int meta;
1234 int save;
1235 int result;
1237 alloca_used += sizeof init_names_buf;
1239 init_names->next = NULL;
1240 init_names->count = ((sizeof init_names_buf
1241 - offsetof (struct globnames, name))
1242 / sizeof init_names->name[0]);
1244 meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
1245 if (meta == GLOBPAT_NONE && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
1247 /* We need not do any tests. The PATTERN contains no meta
1248 characters and we must not return an error therefore the
1249 result will always contain exactly one name. */
1250 flags |= GLOB_NOCHECK;
1252 else if (meta == GLOBPAT_NONE)
1254 union
1256 struct stat st;
1257 struct_stat64 st64;
1258 } ust;
1259 size_t patlen = strlen (pattern);
1260 size_t fullsize;
1261 bool alloca_fullname
1262 = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize)
1263 && glob_use_alloca (alloca_used, fullsize));
1264 char *fullname;
1265 if (alloca_fullname)
1266 fullname = alloca_account (fullsize, alloca_used);
1267 else
1269 fullname = malloc (fullsize);
1270 if (fullname == NULL)
1271 return GLOB_NOSPACE;
1274 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1275 "/", 1),
1276 pattern, patlen + 1);
1277 if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1278 ? (*pglob->gl_lstat) (fullname, &ust.st)
1279 : __lstat64 (fullname, &ust.st64))
1280 == 0)
1281 || errno == EOVERFLOW)
1282 /* We found this file to be existing. Now tell the rest
1283 of the function to copy this name into the result. */
1284 flags |= GLOB_NOCHECK;
1286 if (__glibc_unlikely (!alloca_fullname))
1287 free (fullname);
1289 else
1291 stream = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1292 ? (*pglob->gl_opendir) (directory)
1293 : opendir (directory));
1294 if (stream == NULL)
1296 if (errno != ENOTDIR
1297 && ((errfunc != NULL && (*errfunc) (directory, errno))
1298 || (flags & GLOB_ERR)))
1299 return GLOB_ABORTED;
1301 else
1303 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1304 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
1305 flags |= GLOB_MAGCHAR;
1307 while (1)
1309 struct readdir_result d;
1311 if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1312 d = convert_dirent (GL_READDIR (pglob, stream));
1313 else
1315 #ifdef COMPILE_GLOB64
1316 d = convert_dirent (__readdir (stream));
1317 #else
1318 d = convert_dirent64 (__readdir64 (stream));
1319 #endif
1322 if (d.name == NULL)
1323 break;
1325 /* If we shall match only directories use the information
1326 provided by the dirent call if possible. */
1327 if (flags & GLOB_ONLYDIR)
1328 switch (readdir_result_type (d))
1330 case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
1331 default: continue;
1334 if (fnmatch (pattern, d.name, fnm_flags) == 0)
1336 if (cur == names->count)
1338 struct globnames *newnames;
1339 size_t count = names->count * 2;
1340 size_t nameoff = offsetof (struct globnames, name);
1341 size_t size = FLEXSIZEOF (struct globnames, name,
1342 count * sizeof (char *));
1343 if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
1344 < names->count)
1345 goto memory_error;
1346 if (glob_use_alloca (alloca_used, size))
1347 newnames = names_alloca
1348 = alloca_account (size, alloca_used);
1349 else if ((newnames = malloc (size))
1350 == NULL)
1351 goto memory_error;
1352 newnames->count = count;
1353 newnames->next = names;
1354 names = newnames;
1355 cur = 0;
1357 names->name[cur] = strdup (d.name);
1358 if (names->name[cur] == NULL)
1359 goto memory_error;
1360 ++cur;
1361 ++nfound;
1362 if (SIZE_MAX - pglob->gl_offs <= nfound)
1363 goto memory_error;
1369 if (nfound == 0 && (flags & GLOB_NOCHECK))
1371 size_t len = strlen (pattern);
1372 nfound = 1;
1373 names->name[cur] = malloc (len + 1);
1374 if (names->name[cur] == NULL)
1375 goto memory_error;
1376 *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
1379 result = GLOB_NOMATCH;
1380 if (nfound != 0)
1382 char **new_gl_pathv;
1383 result = 0;
1385 if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
1386 < pglob->gl_offs + nfound + 1)
1387 goto memory_error;
1389 new_gl_pathv
1390 = realloc (pglob->gl_pathv,
1391 (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1392 * sizeof (char *));
1394 if (new_gl_pathv == NULL)
1396 memory_error:
1397 while (1)
1399 struct globnames *old = names;
1400 for (size_t i = 0; i < cur; ++i)
1401 free (names->name[i]);
1402 names = names->next;
1403 /* NB: we will not leak memory here if we exit without
1404 freeing the current block assigned to OLD. At least
1405 the very first block is always allocated on the stack
1406 and this is the block assigned to OLD here. */
1407 if (names == NULL)
1409 assert (old == init_names);
1410 break;
1412 cur = names->count;
1413 if (old == names_alloca)
1414 names_alloca = names;
1415 else
1416 free (old);
1418 result = GLOB_NOSPACE;
1420 else
1422 while (1)
1424 struct globnames *old = names;
1425 for (size_t i = 0; i < cur; ++i)
1426 new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++]
1427 = names->name[i];
1428 names = names->next;
1429 /* NB: we will not leak memory here if we exit without
1430 freeing the current block assigned to OLD. At least
1431 the very first block is always allocated on the stack
1432 and this is the block assigned to OLD here. */
1433 if (names == NULL)
1435 assert (old == init_names);
1436 break;
1438 cur = names->count;
1439 if (old == names_alloca)
1440 names_alloca = names;
1441 else
1442 free (old);
1445 pglob->gl_pathv = new_gl_pathv;
1447 pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
1449 pglob->gl_flags = flags;
1453 if (stream != NULL)
1455 save = errno;
1456 if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
1457 (*pglob->gl_closedir) (stream);
1458 else
1459 closedir (stream);
1460 __set_errno (save);
1463 return result;