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