1/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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.
13
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 <http://www.gnu.org/licenses/>. */
17
18#include <glob.h>
19
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>
28
29#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
30# define WINDOWS32
31#endif
32
33#ifndef WINDOWS32
34# include <pwd.h>
35#endif
36
37#include <errno.h>
38#include <dirent.h>
39#include <stdlib.h>
40#include <string.h>
41#include <alloca.h>
42
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# include <shlib-compat.h>
61#else /* !_LIBC */
62# define __glob glob
63# define __getlogin_r(buf, len) getlogin_r (buf, len)
64# define __lstat64(fname, buf) lstat (fname, buf)
65# define __stat64(fname, buf) stat (fname, buf)
66# define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
67# define struct_stat64 struct stat
68# ifndef __MVS__
69# define __alloca alloca
70# endif
71# define __readdir readdir
72# define COMPILE_GLOB64
73#endif /* _LIBC */
74
75#include <fnmatch.h>
76
77#include <flexmember.h>
78#include <glob_internal.h>
79#include <scratch_buffer.h>
80
81static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
82
83typedef uint_fast8_t dirent_type;
84
85#if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
86/* Any distinct values will do here.
87 Undef any existing macros out of the way. */
88# undef DT_UNKNOWN
89# undef DT_DIR
90# undef DT_LNK
91# define DT_UNKNOWN 0
92# define DT_DIR 1
93# define DT_LNK 2
94#endif
95
96/* A representation of a directory entry which does not depend on the
97 layout of struct dirent, or the size of ino_t. */
98struct readdir_result
99{
100 const char *name;
101#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
102 dirent_type type;
103#endif
104};
105
106/* Initialize and return type member of struct readdir_result. */
107static dirent_type
108readdir_result_type (struct readdir_result d)
109{
110#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
111# define D_TYPE_TO_RESULT(source) (source)->d_type,
112 return d.type;
113#else
114# define D_TYPE_TO_RESULT(source)
115 return DT_UNKNOWN;
116#endif
117}
118
119/* Construct an initializer for a struct readdir_result object from a
120 struct dirent *. No copy of the name is made. */
121#define READDIR_RESULT_INITIALIZER(source) \
122 { \
123 source->d_name, \
124 D_TYPE_TO_RESULT (source) \
125 }
126
127/* Call gl_readdir on STREAM. This macro can be overridden to reduce
128 type safety if an old interface version needs to be supported. */
129#ifndef GL_READDIR
130# define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
131#endif
132
133/* Extract name and type from directory entry. No copy of the name is
134 made. If SOURCE is NULL, result name is NULL. Keep in sync with
135 convert_dirent64 below. */
136static struct readdir_result
137convert_dirent (const struct dirent *source)
138{
139 if (source == NULL)
140 {
141 struct readdir_result result = { NULL, };
142 return result;
143 }
144 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
145 return result;
146}
147
148#ifndef COMPILE_GLOB64
149/* Like convert_dirent, but works on struct dirent64 instead. Keep in
150 sync with convert_dirent above. */
151static struct readdir_result
152convert_dirent64 (const struct dirent64 *source)
153{
154 if (source == NULL)
155 {
156 struct readdir_result result = { NULL, };
157 return result;
158 }
159 struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
160 return result;
161}
162#endif
163
164#ifndef _LIBC
165/* The results of opendir() in this file are not used with dirfd and fchdir,
166 and we do not leak fds to any single-threaded code that could use stdio,
167 therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
168 FIXME - if the kernel ever adds support for multi-thread safety for
169 avoiding standard fds, then we should use opendir_safer. */
170# ifdef GNULIB_defined_opendir
171# undef opendir
172# endif
173# ifdef GNULIB_defined_closedir
174# undef closedir
175# endif
176
177/* Just use malloc. */
178# define __libc_use_alloca(n) false
179# define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
180# define extend_alloca_account(buf, len, newlen, avar) \
181 ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
182#endif
183
184static int
185glob_lstat (glob_t *pglob, int flags, const char *fullname)
186{
187/* Use on glob-lstat-compat.c to provide a compat symbol which does not
188 use lstat / gl_lstat. */
189#ifdef GLOB_NO_LSTAT
190# define GL_LSTAT gl_stat
191# define LSTAT64 __stat64
192#else
193# define GL_LSTAT gl_lstat
194# define LSTAT64 __lstat64
195#endif
196
197 union
198 {
199 struct stat st;
200 struct_stat64 st64;
201 } ust;
202 return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
203 ? pglob->GL_LSTAT (fullname, &ust.st)
204 : LSTAT64 (fullname, &ust.st64));
205}
206
207/* Set *R = A + B. Return true if the answer is mathematically
208 incorrect due to overflow; in this case, *R is the low order
209 bits of the correct answer. */
210
211static bool
212size_add_wrapv (size_t a, size_t b, size_t *r)
213{
214#if 5 <= __GNUC__ && !defined __ICC
215 return __builtin_add_overflow (a, b, r);
216#else
217 *r = a + b;
218 return *r < a;
219#endif
220}
221
222static bool
223glob_use_alloca (size_t alloca_used, size_t len)
224{
225 size_t size;
226 return (!size_add_wrapv (alloca_used, len, &size)
227 && __libc_use_alloca (size));
228}
229
230static int glob_in_dir (const char *pattern, const char *directory,
231 int flags, int (*errfunc) (const char *, int),
232 glob_t *pglob, size_t alloca_used);
233static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
234static int collated_compare (const void *, const void *) __THROWNL;
235
236
237/* Return true if FILENAME is a directory or a symbolic link to a directory.
238 Use FLAGS and PGLOB to resolve the filename. */
239static bool
240is_dir (char const *filename, int flags, glob_t const *pglob)
241{
242 struct stat st;
243 struct_stat64 st64;
244 return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
245 ? pglob->gl_stat (filename, &st) == 0 && S_ISDIR (st.st_mode)
246 : __stat64 (filename, &st64) == 0 && S_ISDIR (st64.st_mode));
247}
248
249/* Find the end of the sub-pattern in a brace expression. */
250static const char *
251next_brace_sub (const char *cp, int flags)
252{
253 size_t depth = 0;
254 while (*cp != '\0')
255 if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
256 {
257 if (*++cp == '\0')
258 break;
259 ++cp;
260 }
261 else
262 {
263 if ((*cp == '}' && depth-- == 0) || (*cp == ',' && depth == 0))
264 break;
265
266 if (*cp++ == '{')
267 depth++;
268 }
269
270 return *cp != '\0' ? cp : NULL;
271}
272
273#ifndef GLOB_ATTRIBUTE
274# define GLOB_ATTRIBUTE
275#endif
276
277/* Do glob searching for PATTERN, placing results in PGLOB.
278 The bits defined above may be set in FLAGS.
279 If a directory cannot be opened or read and ERRFUNC is not nil,
280 it is called with the pathname that caused the error, and the
281 'errno' value from the failing call; if it returns non-zero
282 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
283 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
284 Otherwise, 'glob' returns zero. */
285int
286GLOB_ATTRIBUTE
287__glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
288 glob_t *pglob)
289{
290 const char *filename;
291 char *dirname = NULL;
292 size_t dirlen;
293 int status;
294 size_t oldcount;
295 int meta;
296 int dirname_modified;
297 int malloc_dirname = 0;
298 glob_t dirs;
299 int retval = 0;
300 size_t alloca_used = 0;
301
302 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
303 {
304 __set_errno (EINVAL);
305 return -1;
306 }
307
308 /* POSIX requires all slashes to be matched. This means that with
309 a trailing slash we must match only directories. */
310 if (pattern[0] && pattern[strlen (pattern) - 1] == '/')
311 flags |= GLOB_ONLYDIR;
312
313 if (!(flags & GLOB_DOOFFS))
314 /* Have to do this so 'globfree' knows where to start freeing. It
315 also makes all the code that uses gl_offs simpler. */
316 pglob->gl_offs = 0;
317
318 if (!(flags & GLOB_APPEND))
319 {
320 pglob->gl_pathc = 0;
321 if (!(flags & GLOB_DOOFFS))
322 pglob->gl_pathv = NULL;
323 else
324 {
325 size_t i;
326
327 if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
328 return GLOB_NOSPACE;
329
330 pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
331 * sizeof (char *));
332 if (pglob->gl_pathv == NULL)
333 return GLOB_NOSPACE;
334
335 for (i = 0; i <= pglob->gl_offs; ++i)
336 pglob->gl_pathv[i] = NULL;
337 }
338 }
339
340 if (flags & GLOB_BRACE)
341 {
342 const char *begin;
343
344 if (flags & GLOB_NOESCAPE)
345 begin = strchr (pattern, '{');
346 else
347 {
348 begin = pattern;
349 while (1)
350 {
351 if (*begin == '\0')
352 {
353 begin = NULL;
354 break;
355 }
356
357 if (*begin == '\\' && begin[1] != '\0')
358 ++begin;
359 else if (*begin == '{')
360 break;
361
362 ++begin;
363 }
364 }
365
366 if (begin != NULL)
367 {
368 /* Allocate working buffer large enough for our work. Note that
369 we have at least an opening and closing brace. */
370 size_t firstc;
371 char *alt_start;
372 const char *p;
373 const char *next;
374 const char *rest;
375 size_t rest_len;
376 char *onealt;
377 size_t pattern_len = strlen (pattern) - 1;
378 int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
379 if (alloca_onealt)
380 onealt = alloca_account (pattern_len, alloca_used);
381 else
382 {
383 onealt = malloc (pattern_len);
384 if (onealt == NULL)
385 return GLOB_NOSPACE;
386 }
387
388 /* We know the prefix for all sub-patterns. */
389 alt_start = mempcpy (onealt, pattern, begin - pattern);
390
391 /* Find the first sub-pattern and at the same time find the
392 rest after the closing brace. */
393 next = next_brace_sub (begin + 1, flags);
394 if (next == NULL)
395 {
396 /* It is an invalid expression. */
397 illegal_brace:
398 if (__glibc_unlikely (!alloca_onealt))
399 free (onealt);
400 flags &= ~GLOB_BRACE;
401 goto no_brace;
402 }
403
404 /* Now find the end of the whole brace expression. */
405 rest = next;
406 while (*rest != '}')
407 {
408 rest = next_brace_sub (rest + 1, flags);
409 if (rest == NULL)
410 /* It is an illegal expression. */
411 goto illegal_brace;
412 }
413 /* Please note that we now can be sure the brace expression
414 is well-formed. */
415 rest_len = strlen (++rest) + 1;
416
417 /* We have a brace expression. BEGIN points to the opening {,
418 NEXT points past the terminator of the first element, and END
419 points past the final }. We will accumulate result names from
420 recursive runs for each brace alternative in the buffer using
421 GLOB_APPEND. */
422 firstc = pglob->gl_pathc;
423
424 p = begin + 1;
425 while (1)
426 {
427 int result;
428
429 /* Construct the new glob expression. */
430 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
431
432 result = __glob (onealt,
433 ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
434 | GLOB_APPEND),
435 errfunc, pglob);
436
437 /* If we got an error, return it. */
438 if (result && result != GLOB_NOMATCH)
439 {
440 if (__glibc_unlikely (!alloca_onealt))
441 free (onealt);
442 if (!(flags & GLOB_APPEND))
443 {
444 globfree (pglob);
445 pglob->gl_pathc = 0;
446 }
447 return result;
448 }
449
450 if (*next == '}')
451 /* We saw the last entry. */
452 break;
453
454 p = next + 1;
455 next = next_brace_sub (p, flags);
456 assert (next != NULL);
457 }
458
459 if (__glibc_unlikely (!alloca_onealt))
460 free (onealt);
461
462 if (pglob->gl_pathc != firstc)
463 /* We found some entries. */
464 return 0;
465 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
466 return GLOB_NOMATCH;
467 }
468 }
469
470 no_brace:
471 oldcount = pglob->gl_pathc + pglob->gl_offs;
472
473 /* Find the filename. */
474 filename = strrchr (pattern, '/');
475
476#if defined __MSDOS__ || defined WINDOWS32
477 /* The case of "d:pattern". Since ':' is not allowed in
478 file names, we can safely assume that wherever it
479 happens in pattern, it signals the filename part. This
480 is so we could some day support patterns like "[a-z]:foo". */
481 if (filename == NULL)
482 filename = strchr (pattern, ':');
483#endif /* __MSDOS__ || WINDOWS32 */
484
485 dirname_modified = 0;
486 if (filename == NULL)
487 {
488 /* This can mean two things: a simple name or "~name". The latter
489 case is nothing but a notation for a directory. */
490 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
491 {
492 dirname = (char *) pattern;
493 dirlen = strlen (pattern);
494
495 /* Set FILENAME to NULL as a special flag. This is ugly but
496 other solutions would require much more code. We test for
497 this special case below. */
498 filename = NULL;
499 }
500 else
501 {
502 if (__glibc_unlikely (pattern[0] == '\0'))
503 {
504 dirs.gl_pathv = NULL;
505 goto no_matches;
506 }
507
508 filename = pattern;
509 dirname = (char *) ".";
510 dirlen = 0;
511 }
512 }
513 else if (filename == pattern
514 || (filename == pattern + 1 && pattern[0] == '\\'
515 && (flags & GLOB_NOESCAPE) == 0))
516 {
517 /* "/pattern" or "\\/pattern". */
518 dirname = (char *) "/";
519 dirlen = 1;
520 ++filename;
521 }
522 else
523 {
524 char *newp;
525 dirlen = filename - pattern;
526#if defined __MSDOS__ || defined WINDOWS32
527 if (*filename == ':'
528 || (filename > pattern + 1 && filename[-1] == ':'))
529 {
530 char *drive_spec;
531
532 ++dirlen;
533 drive_spec = __alloca (dirlen + 1);
534 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
535 /* For now, disallow wildcards in the drive spec, to
536 prevent infinite recursion in glob. */
537 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
538 return GLOB_NOMATCH;
539 /* If this is "d:pattern", we need to copy ':' to DIRNAME
540 as well. If it's "d:/pattern", don't remove the slash
541 from "d:/", since "d:" and "d:/" are not the same.*/
542 }
543#endif
544
545 if (glob_use_alloca (alloca_used, dirlen + 1))
546 newp = alloca_account (dirlen + 1, alloca_used);
547 else
548 {
549 newp = malloc (dirlen + 1);
550 if (newp == NULL)
551 return GLOB_NOSPACE;
552 malloc_dirname = 1;
553 }
554 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
555 dirname = newp;
556 ++filename;
557
558#if defined __MSDOS__ || defined WINDOWS32
559 bool drive_root = (dirlen > 1
560 && (dirname[dirlen - 1] == ':'
561 || (dirlen > 2 && dirname[dirlen - 2] == ':'
562 && dirname[dirlen - 1] == '/')));
563#else
564 bool drive_root = false;
565#endif
566
567 if (filename[0] == '\0' && dirlen > 1 && !drive_root)
568 /* "pattern/". Expand "pattern", appending slashes. */
569 {
570 int orig_flags = flags;
571 if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
572 {
573 /* "pattern\\/". Remove the final backslash if it hasn't
574 been quoted. */
575 char *p = (char *) &dirname[dirlen - 1];
576
577 while (p > dirname && p[-1] == '\\') --p;
578 if ((&dirname[dirlen] - p) & 1)
579 {
580 *(char *) &dirname[--dirlen] = '\0';
581 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
582 }
583 }
584 int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob);
585 if (val == 0)
586 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
587 | (flags & GLOB_MARK));
588 else if (val == GLOB_NOMATCH && flags != orig_flags)
589 {
590 /* Make sure globfree (&dirs); is a nop. */
591 dirs.gl_pathv = NULL;
592 flags = orig_flags;
593 oldcount = pglob->gl_pathc + pglob->gl_offs;
594 goto no_matches;
595 }
596 retval = val;
597 goto out;
598 }
599 }
600
601 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
602 {
603 if (dirname[1] == '\0' || dirname[1] == '/'
604 || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
605 && (dirname[2] == '\0' || dirname[2] == '/')))
606 {
607 /* Look up home directory. */
608 char *home_dir = getenv ("HOME");
609 int malloc_home_dir = 0;
610 if (home_dir == NULL || home_dir[0] == '\0')
611 {
612#ifdef WINDOWS32
613 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give
614 preference to HOME, because the user can change HOME. */
615 const char *home_drive = getenv ("HOMEDRIVE");
616 const char *home_path = getenv ("HOMEPATH");
617
618 if (home_drive != NULL && home_path != NULL)
619 {
620 size_t home_drive_len = strlen (home_drive);
621 size_t home_path_len = strlen (home_path);
622 char *mem = alloca (home_drive_len + home_path_len + 1);
623
624 memcpy (mem, home_drive, home_drive_len);
625 memcpy (mem + home_drive_len, home_path, home_path_len + 1);
626 home_dir = mem;
627 }
628 else
629 home_dir = "c:/users/default"; /* poor default */
630#else
631 int err;
632 struct passwd *p;
633 struct passwd pwbuf;
634 struct scratch_buffer s;
635 scratch_buffer_init (&s);
636 while (true)
637 {
638 p = NULL;
639 err = __getlogin_r (s.data, s.length);
640 if (err == 0)
641 {
642# if defined HAVE_GETPWNAM_R || defined _LIBC
643 size_t ssize = strlen (s.data) + 1;
644 char *sdata = s.data;
645 err = getpwnam_r (sdata, &pwbuf, sdata + ssize,
646 s.length - ssize, &p);
647# else
648 p = getpwnam (s.data);
649 if (p == NULL)
650 err = errno;
651# endif
652 }
653 if (err != ERANGE)
654 break;
655 if (!scratch_buffer_grow (&s))
656 {
657 retval = GLOB_NOSPACE;
658 goto out;
659 }
660 }
661 if (err == 0)
662 {
663 home_dir = strdup (p->pw_dir);
664 malloc_home_dir = 1;
665 }
666 scratch_buffer_free (&s);
667 if (err == 0 && home_dir == NULL)
668 {
669 retval = GLOB_NOSPACE;
670 goto out;
671 }
672#endif /* WINDOWS32 */
673 }
674 if (home_dir == NULL || home_dir[0] == '\0')
675 {
676 if (__glibc_unlikely (malloc_home_dir))
677 free (home_dir);
678 if (flags & GLOB_TILDE_CHECK)
679 {
680 retval = GLOB_NOMATCH;
681 goto out;
682 }
683 else
684 {
685 home_dir = (char *) "~"; /* No luck. */
686 malloc_home_dir = 0;
687 }
688 }
689 /* Now construct the full directory. */
690 if (dirname[1] == '\0')
691 {
692 if (__glibc_unlikely (malloc_dirname))
693 free (dirname);
694
695 dirname = home_dir;
696 dirlen = strlen (dirname);
697 malloc_dirname = malloc_home_dir;
698 }
699 else
700 {
701 char *newp;
702 size_t home_len = strlen (home_dir);
703 int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
704 if (use_alloca)
705 newp = alloca_account (home_len + dirlen, alloca_used);
706 else
707 {
708 newp = malloc (home_len + dirlen);
709 if (newp == NULL)
710 {
711 if (__glibc_unlikely (malloc_home_dir))
712 free (home_dir);
713 retval = GLOB_NOSPACE;
714 goto out;
715 }
716 }
717
718 mempcpy (mempcpy (newp, home_dir, home_len),
719 &dirname[1], dirlen);
720
721 if (__glibc_unlikely (malloc_dirname))
722 free (dirname);
723
724 dirname = newp;
725 dirlen += home_len - 1;
726 malloc_dirname = !use_alloca;
727
728 if (__glibc_unlikely (malloc_home_dir))
729 free (home_dir);
730 }
731 dirname_modified = 1;
732 }
733 else
734 {
735#ifndef WINDOWS32
736 char *end_name = strchr (dirname, '/');
737 char *user_name;
738 int malloc_user_name = 0;
739 char *unescape = NULL;
740
741 if (!(flags & GLOB_NOESCAPE))
742 {
743 if (end_name == NULL)
744 {
745 unescape = strchr (dirname, '\\');
746 if (unescape)
747 end_name = strchr (unescape, '\0');
748 }
749 else
750 unescape = memchr (dirname, '\\', end_name - dirname);
751 }
752 if (end_name == NULL)
753 user_name = dirname + 1;
754 else
755 {
756 char *newp;
757 if (glob_use_alloca (alloca_used, end_name - dirname))
758 newp = alloca_account (end_name - dirname, alloca_used);
759 else
760 {
761 newp = malloc (end_name - dirname);
762 if (newp == NULL)
763 {
764 retval = GLOB_NOSPACE;
765 goto out;
766 }
767 malloc_user_name = 1;
768 }
769 if (unescape != NULL)
770 {
771 char *p = mempcpy (newp, dirname + 1,
772 unescape - dirname - 1);
773 char *q = unescape;
774 while (q != end_name)
775 {
776 if (*q == '\\')
777 {
778 if (q + 1 == end_name)
779 {
780 /* "~fo\\o\\" unescape to user_name "foo\\",
781 but "~fo\\o\\/" unescape to user_name
782 "foo". */
783 if (filename == NULL)
784 *p++ = '\\';
785 break;
786 }
787 ++q;
788 }
789 *p++ = *q++;
790 }
791 *p = '\0';
792 }
793 else
794 *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1))
795 = '\0';
796 user_name = newp;
797 }
798
799 /* Look up specific user's home directory. */
800 {
801 struct passwd *p;
802 struct scratch_buffer pwtmpbuf;
803 scratch_buffer_init (&pwtmpbuf);
804
805# if defined HAVE_GETPWNAM_R || defined _LIBC
806 struct passwd pwbuf;
807
808 while (getpwnam_r (user_name, &pwbuf,
809 pwtmpbuf.data, pwtmpbuf.length, &p)
810 == ERANGE)
811 {
812 if (!scratch_buffer_grow (&pwtmpbuf))
813 {
814 retval = GLOB_NOSPACE;
815 goto out;
816 }
817 }
818# else
819 p = getpwnam (user_name);
820# endif
821
822 if (__glibc_unlikely (malloc_user_name))
823 free (user_name);
824
825 /* If we found a home directory use this. */
826 if (p != NULL)
827 {
828 size_t home_len = strlen (p->pw_dir);
829 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
830 char *d;
831
832 if (__glibc_unlikely (malloc_dirname))
833 free (dirname);
834 malloc_dirname = 0;
835
836 if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
837 dirname = alloca_account (home_len + rest_len + 1,
838 alloca_used);
839 else
840 {
841 dirname = malloc (home_len + rest_len + 1);
842 if (dirname == NULL)
843 {
844 scratch_buffer_free (&pwtmpbuf);
845 retval = GLOB_NOSPACE;
846 goto out;
847 }
848 malloc_dirname = 1;
849 }
850 d = mempcpy (dirname, p->pw_dir, home_len);
851 if (end_name != NULL)
852 d = mempcpy (d, end_name, rest_len);
853 *d = '\0';
854
855 dirlen = home_len + rest_len;
856 dirname_modified = 1;
857 }
858 else
859 {
860 if (flags & GLOB_TILDE_CHECK)
861 {
862 /* We have to regard it as an error if we cannot find the
863 home directory. */
864 retval = GLOB_NOMATCH;
865 goto out;
866 }
867 }
868 scratch_buffer_free (&pwtmpbuf);
869 }
870#endif /* !WINDOWS32 */
871 }
872 }
873
874 /* Now test whether we looked for "~" or "~NAME". In this case we
875 can give the answer now. */
876 if (filename == NULL)
877 {
878 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
879 char **new_gl_pathv;
880
881 if (newcount > SIZE_MAX / sizeof (char *) - 2)
882 {
883 nospace:
884 free (pglob->gl_pathv);
885 pglob->gl_pathv = NULL;
886 pglob->gl_pathc = 0;
887 retval = GLOB_NOSPACE;
888 goto out;
889 }
890
891 new_gl_pathv = realloc (pglob->gl_pathv,
892 (newcount + 2) * sizeof (char *));
893 if (new_gl_pathv == NULL)
894 goto nospace;
895 pglob->gl_pathv = new_gl_pathv;
896
897 if (flags & GLOB_MARK && is_dir (dirname, flags, pglob))
898 {
899 char *p;
900 pglob->gl_pathv[newcount] = malloc (dirlen + 2);
901 if (pglob->gl_pathv[newcount] == NULL)
902 goto nospace;
903 p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
904 p[0] = '/';
905 p[1] = '\0';
906 if (__glibc_unlikely (malloc_dirname))
907 free (dirname);
908 }
909 else
910 {
911 if (__glibc_unlikely (malloc_dirname))
912 pglob->gl_pathv[newcount] = dirname;
913 else
914 {
915 pglob->gl_pathv[newcount] = strdup (dirname);
916 if (pglob->gl_pathv[newcount] == NULL)
917 goto nospace;
918 }
919 }
920 pglob->gl_pathv[++newcount] = NULL;
921 ++pglob->gl_pathc;
922 pglob->gl_flags = flags;
923
924 return 0;
925 }
926
927 meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
928 /* meta is 1 if correct glob pattern containing metacharacters.
929 If meta has bit (1 << 2) set, it means there was an unterminated
930 [ which we handle the same, using fnmatch. Broken unterminated
931 pattern bracket expressions ought to be rare enough that it is
932 not worth special casing them, fnmatch will do the right thing. */
933 if (meta & (GLOBPAT_SPECIAL | GLOBPAT_BRACKET))
934 {
935 /* The directory name contains metacharacters, so we
936 have to glob for the directory, and then glob for
937 the pattern in each directory found. */
938 size_t i;
939
940 if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\')
941 {
942 /* "foo\\/bar". Remove the final backslash from dirname
943 if it has not been quoted. */
944 char *p = (char *) &dirname[dirlen - 1];
945
946 while (p > dirname && p[-1] == '\\') --p;
947 if ((&dirname[dirlen] - p) & 1)
948 *(char *) &dirname[--dirlen] = '\0';
949 }
950
951 if (__glibc_unlikely ((flags & GLOB_ALTDIRFUNC) != 0))
952 {
953 /* Use the alternative access functions also in the recursive
954 call. */
955 dirs.gl_opendir = pglob->gl_opendir;
956 dirs.gl_readdir = pglob->gl_readdir;
957 dirs.gl_closedir = pglob->gl_closedir;
958 dirs.gl_stat = pglob->gl_stat;
959 dirs.gl_lstat = pglob->gl_lstat;
960 }
961
962 status = __glob (dirname,
963 ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
964 | GLOB_NOSORT | GLOB_ONLYDIR),
965 errfunc, &dirs);
966 if (status != 0)
967 {
968 if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
969 {
970 retval = status;
971 goto out;
972 }
973 goto no_matches;
974 }
975
976 /* We have successfully globbed the preceding directory name.
977 For each name we found, call glob_in_dir on it and FILENAME,
978 appending the results to PGLOB. */
979 for (i = 0; i < dirs.gl_pathc; ++i)
980 {
981 size_t old_pathc;
982
983 old_pathc = pglob->gl_pathc;
984 status = glob_in_dir (filename, dirs.gl_pathv[i],
985 ((flags | GLOB_APPEND)
986 & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
987 errfunc, pglob, alloca_used);
988 if (status == GLOB_NOMATCH)
989 /* No matches in this directory. Try the next. */
990 continue;
991
992 if (status != 0)
993 {
994 globfree (&dirs);
995 globfree (pglob);
996 pglob->gl_pathc = 0;
997 retval = status;
998 goto out;
999 }
1000
1001 /* Stick the directory on the front of each name. */
1002 if (prefix_array (dirs.gl_pathv[i],
1003 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1004 pglob->gl_pathc - old_pathc))
1005 {
1006 globfree (&dirs);
1007 globfree (pglob);
1008 pglob->gl_pathc = 0;
1009 retval = GLOB_NOSPACE;
1010 goto out;
1011 }
1012 }
1013
1014 flags |= GLOB_MAGCHAR;
1015
1016 /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1017 But if we have not found any matching entry and the GLOB_NOCHECK
1018 flag was set we must return the input pattern itself. */
1019 if (pglob->gl_pathc + pglob->gl_offs == oldcount)
1020 {
1021 no_matches:
1022 /* No matches. */
1023 if (flags & GLOB_NOCHECK)
1024 {
1025 size_t newcount = pglob->gl_pathc + pglob->gl_offs;
1026 char **new_gl_pathv;
1027
1028 if (newcount > SIZE_MAX / sizeof (char *) - 2)
1029 {
1030 nospace2:
1031 globfree (&dirs);
1032 retval = GLOB_NOSPACE;
1033 goto out;
1034 }
1035
1036 new_gl_pathv = realloc (pglob->gl_pathv,
1037 (newcount + 2) * sizeof (char *));
1038 if (new_gl_pathv == NULL)
1039 goto nospace2;
1040 pglob->gl_pathv = new_gl_pathv;
1041
1042 pglob->gl_pathv[newcount] = strdup (pattern);
1043 if (pglob->gl_pathv[newcount] == NULL)
1044 {
1045 globfree (&dirs);
1046 globfree (pglob);
1047 pglob->gl_pathc = 0;
1048 retval = GLOB_NOSPACE;
1049 goto out;
1050 }
1051
1052 ++pglob->gl_pathc;
1053 ++newcount;
1054
1055 pglob->gl_pathv[newcount] = NULL;
1056 pglob->gl_flags = flags;
1057 }
1058 else
1059 {
1060 globfree (&dirs);
1061 retval = GLOB_NOMATCH;
1062 goto out;
1063 }
1064 }
1065
1066 globfree (&dirs);
1067 }
1068 else
1069 {
1070 size_t old_pathc = pglob->gl_pathc;
1071 int orig_flags = flags;
1072
1073 if (meta & GLOBPAT_BACKSLASH)
1074 {
1075 char *p = strchr (dirname, '\\'), *q;
1076 /* We need to unescape the dirname string. It is certainly
1077 allocated by alloca, as otherwise filename would be NULL
1078 or dirname wouldn't contain backslashes. */
1079 q = p;
1080 do
1081 {
1082 if (*p == '\\')
1083 {
1084 *q = *++p;
1085 --dirlen;
1086 }
1087 else
1088 *q = *p;
1089 ++q;
1090 }
1091 while (*p++ != '\0');
1092 dirname_modified = 1;
1093 }
1094 if (dirname_modified)
1095 flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
1096 status = glob_in_dir (filename, dirname, flags, errfunc, pglob,
1097 alloca_used);
1098 if (status != 0)
1099 {
1100 if (status == GLOB_NOMATCH && flags != orig_flags
1101 && pglob->gl_pathc + pglob->gl_offs == oldcount)
1102 {
1103 /* Make sure globfree (&dirs); is a nop. */
1104 dirs.gl_pathv = NULL;
1105 flags = orig_flags;
1106 goto no_matches;
1107 }
1108 retval = status;
1109 goto out;
1110 }
1111
1112 if (dirlen > 0)
1113 {
1114 /* Stick the directory on the front of each name. */
1115 if (prefix_array (dirname,
1116 &pglob->gl_pathv[old_pathc + pglob->gl_offs],
1117 pglob->gl_pathc - old_pathc))
1118 {
1119 globfree (pglob);
1120 pglob->gl_pathc = 0;
1121 retval = GLOB_NOSPACE;
1122 goto out;
1123 }
1124 }
1125 }
1126
1127 if (flags & GLOB_MARK)
1128 {
1129 /* Append slashes to directory names. */
1130 size_t i;
1131
1132 for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; ++i)
1133 if (is_dir (pglob->gl_pathv[i], flags, pglob))
1134 {
1135 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1136 char *new = realloc (pglob->gl_pathv[i], len);
1137 if (new == NULL)
1138 {
1139 globfree (pglob);
1140 pglob->gl_pathc = 0;
1141 retval = GLOB_NOSPACE;
1142 goto out;
1143 }
1144 strcpy (&new[len - 2], "/");
1145 pglob->gl_pathv[i] = new;
1146 }
1147 }
1148
1149 if (!(flags & GLOB_NOSORT))
1150 {
1151 /* Sort the vector. */
1152 qsort (&pglob->gl_pathv[oldcount],
1153 pglob->gl_pathc + pglob->gl_offs - oldcount,
1154 sizeof (char *), collated_compare);
1155 }
1156
1157 out:
1158 if (__glibc_unlikely (malloc_dirname))
1159 free (dirname);
1160
1161 return retval;
1162}
1163#if defined _LIBC && !defined __glob
1164versioned_symbol (libc, __glob, glob, GLIBC_2_27);
1165libc_hidden_ver (__glob, glob)
1166#endif
1167
1168
1169/* Do a collated comparison of A and B. */
1170static int
1171collated_compare (const void *a, const void *b)
1172{
1173 char *const *ps1 = a; char *s1 = *ps1;
1174 char *const *ps2 = b; char *s2 = *ps2;
1175
1176 if (s1 == s2)
1177 return 0;
1178 if (s1 == NULL)
1179 return 1;
1180 if (s2 == NULL)
1181 return -1;
1182 return strcoll (s1, s2);
1183}
1184
1185
1186/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1187 elements in place. Return nonzero if out of memory, zero if successful.
1188 A slash is inserted between DIRNAME and each elt of ARRAY,
1189 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1190static int
1191prefix_array (const char *dirname, char **array, size_t n)
1192{
1193 size_t i;
1194 size_t dirlen = strlen (dirname);
1195 char dirsep_char = '/';
1196
1197 if (dirlen == 1 && dirname[0] == '/')
1198 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1199 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1200 dirlen = 0;
1201
1202#if defined __MSDOS__ || defined WINDOWS32
1203 if (dirlen > 1)
1204 {
1205 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1206 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1207 --dirlen;
1208 else if (dirname[dirlen - 1] == ':')
1209 {
1210 /* DIRNAME is "d:". Use ':' instead of '/'. */
1211 --dirlen;
1212 dirsep_char = ':';
1213 }
1214 }
1215#endif
1216
1217 for (i = 0; i < n; ++i)
1218 {
1219 size_t eltlen = strlen (array[i]) + 1;
1220 char *new = malloc (dirlen + 1 + eltlen);
1221 if (new == NULL)
1222 {
1223 while (i > 0)
1224 free (array[--i]);
1225 return 1;
1226 }
1227
1228 {
1229 char *endp = mempcpy (new, dirname, dirlen);
1230 *endp++ = dirsep_char;
1231 mempcpy (endp, array[i], eltlen);
1232 }
1233 free (array[i]);
1234 array[i] = new;
1235 }
1236
1237 return 0;
1238}
1239
1240/* Like 'glob', but PATTERN is a final pathname component,
1241 and matches are searched for in DIRECTORY.
1242 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1243 The GLOB_APPEND flag is assumed to be set (always appends). */
1244static int
1245glob_in_dir (const char *pattern, const char *directory, int flags,
1246 int (*errfunc) (const char *, int),
1247 glob_t *pglob, size_t alloca_used)
1248{
1249 size_t dirlen = strlen (directory);
1250 void *stream = NULL;
1251# define GLOBNAMES_MEMBERS(nnames) \
1252 struct globnames *next; size_t count; char *name[nnames];
1253 struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
1254 struct { GLOBNAMES_MEMBERS (64) } init_names_buf;
1255 struct globnames *init_names = (struct globnames *) &init_names_buf;
1256 struct globnames *names = init_names;
1257 struct globnames *names_alloca = init_names;
1258 size_t nfound = 0;
1259 size_t cur = 0;
1260 int meta;
1261 int save;
1262 int result;
1263
1264 alloca_used += sizeof init_names_buf;
1265
1266 init_names->next = NULL;
1267 init_names->count = ((sizeof init_names_buf
1268 - offsetof (struct globnames, name))
1269 / sizeof init_names->name[0]);
1270
1271 meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
1272 if (meta == GLOBPAT_NONE && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
1273 {
1274 /* We need not do any tests. The PATTERN contains no meta
1275 characters and we must not return an error therefore the
1276 result will always contain exactly one name. */
1277 flags |= GLOB_NOCHECK;
1278 }
1279 else if (meta == GLOBPAT_NONE)
1280 {
1281 size_t patlen = strlen (pattern);
1282 size_t fullsize;
1283 bool alloca_fullname
1284 = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize)
1285 && glob_use_alloca (alloca_used, fullsize));
1286 char *fullname;
1287 if (alloca_fullname)
1288 fullname = alloca_account (fullsize, alloca_used);
1289 else
1290 {
1291 fullname = malloc (fullsize);
1292 if (fullname == NULL)
1293 return GLOB_NOSPACE;
1294 }
1295
1296 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1297 "/", 1),
1298 pattern, patlen + 1);
1299 if (glob_lstat (pglob, flags, fullname) == 0
1300 || errno == EOVERFLOW)
1301 /* We found this file to be existing. Now tell the rest
1302 of the function to copy this name into the result. */
1303 flags |= GLOB_NOCHECK;
1304
1305 if (__glibc_unlikely (!alloca_fullname))
1306 free (fullname);
1307 }
1308 else
1309 {
1310 stream = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1311 ? (*pglob->gl_opendir) (directory)
1312 : opendir (directory));
1313 if (stream == NULL)
1314 {
1315 if (errno != ENOTDIR
1316 && ((errfunc != NULL && (*errfunc) (directory, errno))
1317 || (flags & GLOB_ERR)))
1318 return GLOB_ABORTED;
1319 }
1320 else
1321 {
1322 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1323 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
1324 flags |= GLOB_MAGCHAR;
1325
1326 while (1)
1327 {
1328 struct readdir_result d;
1329 {
1330 if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1331 d = convert_dirent (GL_READDIR (pglob, stream));
1332 else
1333 {
1334#ifdef COMPILE_GLOB64
1335 d = convert_dirent (__readdir (stream));
1336#else
1337 d = convert_dirent64 (__readdir64 (stream));
1338#endif
1339 }
1340 }
1341 if (d.name == NULL)
1342 break;
1343
1344 /* If we shall match only directories use the information
1345 provided by the dirent call if possible. */
1346 if (flags & GLOB_ONLYDIR)
1347 switch (readdir_result_type (d))
1348 {
1349 case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
1350 default: continue;
1351 }
1352
1353 if (fnmatch (pattern, d.name, fnm_flags) == 0)
1354 {
1355 if (cur == names->count)
1356 {
1357 struct globnames *newnames;
1358 size_t count = names->count * 2;
1359 size_t nameoff = offsetof (struct globnames, name);
1360 size_t size = FLEXSIZEOF (struct globnames, name,
1361 count * sizeof (char *));
1362 if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
1363 < names->count)
1364 goto memory_error;
1365 if (glob_use_alloca (alloca_used, size))
1366 newnames = names_alloca
1367 = alloca_account (size, alloca_used);
1368 else if ((newnames = malloc (size))
1369 == NULL)
1370 goto memory_error;
1371 newnames->count = count;
1372 newnames->next = names;
1373 names = newnames;
1374 cur = 0;
1375 }
1376 names->name[cur] = strdup (d.name);
1377 if (names->name[cur] == NULL)
1378 goto memory_error;
1379 ++cur;
1380 ++nfound;
1381 if (SIZE_MAX - pglob->gl_offs <= nfound)
1382 goto memory_error;
1383 }
1384 }
1385 }
1386 }
1387
1388 if (nfound == 0 && (flags & GLOB_NOCHECK))
1389 {
1390 size_t len = strlen (pattern);
1391 nfound = 1;
1392 names->name[cur] = malloc (len + 1);
1393 if (names->name[cur] == NULL)
1394 goto memory_error;
1395 *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
1396 }
1397
1398 result = GLOB_NOMATCH;
1399 if (nfound != 0)
1400 {
1401 char **new_gl_pathv;
1402 result = 0;
1403
1404 if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
1405 < pglob->gl_offs + nfound + 1)
1406 goto memory_error;
1407
1408 new_gl_pathv
1409 = realloc (pglob->gl_pathv,
1410 (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1411 * sizeof (char *));
1412
1413 if (new_gl_pathv == NULL)
1414 {
1415 memory_error:
1416 while (1)
1417 {
1418 struct globnames *old = names;
1419 for (size_t i = 0; i < cur; ++i)
1420 free (names->name[i]);
1421 names = names->next;
1422 /* NB: we will not leak memory here if we exit without
1423 freeing the current block assigned to OLD. At least
1424 the very first block is always allocated on the stack
1425 and this is the block assigned to OLD here. */
1426 if (names == NULL)
1427 {
1428 assert (old == init_names);
1429 break;
1430 }
1431 cur = names->count;
1432 if (old == names_alloca)
1433 names_alloca = names;
1434 else
1435 free (old);
1436 }
1437 result = GLOB_NOSPACE;
1438 }
1439 else
1440 {
1441 while (1)
1442 {
1443 struct globnames *old = names;
1444 for (size_t i = 0; i < cur; ++i)
1445 new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++]
1446 = names->name[i];
1447 names = names->next;
1448 /* NB: we will not leak memory here if we exit without
1449 freeing the current block assigned to OLD. At least
1450 the very first block is always allocated on the stack
1451 and this is the block assigned to OLD here. */
1452 if (names == NULL)
1453 {
1454 assert (old == init_names);
1455 break;
1456 }
1457 cur = names->count;
1458 if (old == names_alloca)
1459 names_alloca = names;
1460 else
1461 free (old);
1462 }
1463
1464 pglob->gl_pathv = new_gl_pathv;
1465
1466 pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
1467
1468 pglob->gl_flags = flags;
1469 }
1470 }
1471
1472 if (stream != NULL)
1473 {
1474 save = errno;
1475 if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
1476 (*pglob->gl_closedir) (stream);
1477 else
1478 closedir (stream);
1479 __set_errno (save);
1480 }
1481
1482 return result;
1483}
1484