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