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