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