1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Guido van Rossum. 9 * 10 * Copyright (c) 2011 The FreeBSD Foundation 11 * 12 * Portions of this software were developed by David Chisnall 13 * under sponsorship from the FreeBSD Foundation. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 3. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 */ 39 40 /* 41 * glob(3) -- a superset of the one defined in POSIX 1003.2. 42 * 43 * The [!...] convention to negate a range is supported (SysV, Posix, ksh). 44 * 45 * Optional extra services, controlled by flags not defined by POSIX: 46 * 47 * GLOB_QUOTE: 48 * Escaping convention: \ inhibits any special meaning the following 49 * character might have (except \ at end of string is retained). 50 * GLOB_MAGCHAR: 51 * Set in gl_flags if pattern contained a globbing character. 52 * GLOB_NOMAGIC: 53 * Same as GLOB_NOCHECK, but it will only append pattern if it did 54 * not contain any magic characters. [Used in csh style globbing] 55 * GLOB_ALTDIRFUNC: 56 * Use alternately specified directory access functions. 57 * GLOB_TILDE: 58 * expand ~user/foo to the /home/dir/of/user/foo 59 * GLOB_BRACE: 60 * expand {1,2}{a,b} to 1a 1b 2a 2b 61 * gl_matchc: 62 * Number of matches in the current invocation of glob. 63 */ 64 65 /* 66 * Some notes on multibyte character support: 67 * 1. Patterns with illegal byte sequences match nothing - even if 68 * GLOB_NOCHECK is specified. 69 * 2. Illegal byte sequences in filenames are handled by treating them as 70 * single-byte characters with a values of such bytes of the sequence 71 * cast to wchar_t. 72 * 3. State-dependent encodings are not currently supported. 73 */ 74 75 #include <sys/param.h> 76 #include <sys/stat.h> 77 78 #include <ctype.h> 79 #include <dirent.h> 80 #include <errno.h> 81 #include <glob.h> 82 #include <limits.h> 83 #include <pwd.h> 84 #include <stdint.h> 85 #include <stdio.h> 86 #include <stdlib.h> 87 #include <string.h> 88 #include <unistd.h> 89 #include <wchar.h> 90 91 #include "block_abi.h" 92 #include "collate.h" 93 94 typedef DECLARE_BLOCK(int, glob_b_block, const char*, int); 95 96 /* 97 * glob(3) expansion limits. Stop the expansion if any of these limits 98 * is reached. This caps the runtime in the face of DoS attacks. See 99 * also CVE-2010-2632 100 */ 101 #define GLOB_LIMIT_BRACE 128 /* number of brace calls */ 102 #define GLOB_LIMIT_PATH 65536 /* number of path elements */ 103 #define GLOB_LIMIT_READDIR 16384 /* number of readdirs */ 104 #define GLOB_LIMIT_STAT 1024 /* number of stat system calls */ 105 #define GLOB_LIMIT_STRING ARG_MAX /* maximum total size for paths */ 106 107 struct glob_limit { 108 size_t l_brace_cnt; 109 size_t l_path_lim; 110 size_t l_readdir_cnt; 111 size_t l_stat_cnt; 112 size_t l_string_cnt; 113 }; 114 115 #define DOT L'.' 116 #define EOS L'\0' 117 #define LBRACKET L'[' 118 #define NOT L'!' 119 #define QUESTION L'?' 120 #define QUOTE L'\\' 121 #define RANGE L'-' 122 #define RBRACKET L']' 123 #define SEP L'/' 124 #define STAR L'*' 125 #define TILDE L'~' 126 #define LBRACE L'{' 127 #define RBRACE L'}' 128 #define COMMA L',' 129 130 #define M_QUOTE 0x8000000000ULL 131 #define M_PROTECT 0x4000000000ULL 132 #define M_MASK 0xffffffffffULL 133 #define M_CHAR 0x00ffffffffULL 134 135 typedef uint_fast64_t Char; 136 137 #define CHAR(c) ((Char)((c)&M_CHAR)) 138 #define META(c) ((Char)((c)|M_QUOTE)) 139 #define UNPROT(c) ((c) & ~M_PROTECT) 140 #define M_ALL META(L'*') 141 #define M_END META(L']') 142 #define M_NOT META(L'!') 143 #define M_ONE META(L'?') 144 #define M_RNG META(L'-') 145 #define M_SET META(L'[') 146 #define ismeta(c) (((c)&M_QUOTE) != 0) 147 #ifdef DEBUG 148 #define isprot(c) (((c)&M_PROTECT) != 0) 149 #endif 150 151 static int compare(const void *, const void *); 152 static int g_Ctoc(const Char *, char *, size_t); 153 static int g_lstat(Char *, struct stat *, glob_t *); 154 static DIR *g_opendir(Char *, glob_t *); 155 static const Char *g_strchr(const Char *, wchar_t); 156 #ifdef notdef 157 static Char *g_strcat(Char *, const Char *); 158 #endif 159 static int g_stat(Char *, struct stat *, glob_t *); 160 static int glob0(const Char *, glob_t *, struct glob_limit *, 161 const char *); 162 static int glob1(Char *, glob_t *, struct glob_limit *); 163 static int glob2(Char *, Char *, Char *, Char *, glob_t *, 164 struct glob_limit *); 165 static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, 166 struct glob_limit *); 167 static int globextend(const Char *, glob_t *, struct glob_limit *, 168 const char *); 169 static const Char * 170 globtilde(const Char *, Char *, size_t, glob_t *); 171 static int globexp0(const Char *, glob_t *, struct glob_limit *, 172 const char *); 173 static int globexp1(const Char *, glob_t *, struct glob_limit *); 174 static int globexp2(const Char *, const Char *, glob_t *, 175 struct glob_limit *); 176 static int globfinal(glob_t *, struct glob_limit *, size_t, 177 const char *); 178 static int match(Char *, Char *, Char *); 179 static int err_nomatch(glob_t *, struct glob_limit *, const char *); 180 static int err_aborted(glob_t *, int, char *); 181 #ifdef DEBUG 182 static void qprintf(const char *, Char *); 183 #endif 184 185 static int 186 __glob(const char *pattern, glob_t *pglob) 187 { 188 struct glob_limit limit = { 0, 0, 0, 0, 0 }; 189 const char *patnext; 190 Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot; 191 mbstate_t mbs; 192 wchar_t wc; 193 size_t clen; 194 int too_long; 195 196 patnext = pattern; 197 if (!(pglob->gl_flags & GLOB_APPEND)) { 198 pglob->gl_pathc = 0; 199 pglob->gl_pathv = NULL; 200 if (!(pglob->gl_flags & GLOB_DOOFFS)) 201 pglob->gl_offs = 0; 202 } 203 if (pglob->gl_flags & GLOB_LIMIT) { 204 limit.l_path_lim = pglob->gl_matchc; 205 if (limit.l_path_lim == 0) 206 limit.l_path_lim = GLOB_LIMIT_PATH; 207 } 208 pglob->gl_matchc = 0; 209 210 bufnext = patbuf; 211 bufend = bufnext + MAXPATHLEN - 1; 212 too_long = 1; 213 if (pglob->gl_flags & GLOB_NOESCAPE) { 214 memset(&mbs, 0, sizeof(mbs)); 215 while (bufnext <= bufend) { 216 clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); 217 if (clen == (size_t)-1 || clen == (size_t)-2) 218 return (err_nomatch(pglob, &limit, pattern)); 219 else if (clen == 0) { 220 too_long = 0; 221 break; 222 } 223 *bufnext++ = wc; 224 patnext += clen; 225 } 226 } else { 227 /* Protect the quoted characters. */ 228 memset(&mbs, 0, sizeof(mbs)); 229 while (bufnext <= bufend) { 230 if (*patnext == '\\') { 231 if (*++patnext == '\0') { 232 *bufnext++ = QUOTE; 233 continue; 234 } 235 prot = M_PROTECT; 236 } else 237 prot = 0; 238 clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); 239 if (clen == (size_t)-1 || clen == (size_t)-2) 240 return (err_nomatch(pglob, &limit, pattern)); 241 else if (clen == 0) { 242 too_long = 0; 243 break; 244 } 245 *bufnext++ = wc | prot; 246 patnext += clen; 247 } 248 } 249 if (too_long) 250 return (err_nomatch(pglob, &limit, pattern)); 251 *bufnext = EOS; 252 253 if (pglob->gl_flags & GLOB_BRACE) 254 return (globexp0(patbuf, pglob, &limit, pattern)); 255 else 256 return (glob0(patbuf, pglob, &limit, pattern)); 257 } 258 259 int 260 glob(const char * __restrict pattern, int flags, 261 int (*errfunc)(const char *, int), glob_t * __restrict pglob) 262 { 263 int rv; 264 265 pglob->gl_flags = flags & ~(GLOB_MAGCHAR | _GLOB_ERR_BLOCK); 266 pglob->gl_errfunc = errfunc; 267 rv = __glob(pattern, pglob); 268 pglob->gl_errfunc = NULL; 269 270 return (rv); 271 } 272 273 int 274 glob_b(const char * __restrict pattern, int flags, 275 glob_b_block block, glob_t * __restrict pglob) 276 { 277 int rv; 278 279 pglob->gl_flags = flags & ~GLOB_MAGCHAR; 280 pglob->gl_flags |= _GLOB_ERR_BLOCK; 281 pglob->gl_errblk = block; 282 rv = __glob(pattern, pglob); 283 pglob->gl_errblk = NULL; 284 285 return (rv); 286 } 287 288 static int 289 globexp0(const Char *pattern, glob_t *pglob, struct glob_limit *limit, 290 const char *origpat) 291 { 292 int rv; 293 size_t oldpathc; 294 295 /* Protect a single {}, for find(1), like csh */ 296 if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) { 297 if ((pglob->gl_flags & GLOB_LIMIT) && 298 limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) { 299 errno = E2BIG; 300 return (GLOB_NOSPACE); 301 } 302 return (glob0(pattern, pglob, limit, origpat)); 303 } 304 305 oldpathc = pglob->gl_pathc; 306 307 if ((rv = globexp1(pattern, pglob, limit)) != 0) 308 return rv; 309 310 return (globfinal(pglob, limit, oldpathc, origpat)); 311 } 312 313 /* 314 * Expand recursively a glob {} pattern. When there is no more expansion 315 * invoke the standard globbing routine to glob the rest of the magic 316 * characters 317 */ 318 static int 319 globexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit) 320 { 321 const Char* ptr; 322 323 if ((ptr = g_strchr(pattern, LBRACE)) != NULL) { 324 if ((pglob->gl_flags & GLOB_LIMIT) && 325 limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) { 326 errno = E2BIG; 327 return (GLOB_NOSPACE); 328 } 329 return (globexp2(ptr, pattern, pglob, limit)); 330 } 331 332 return (glob0(pattern, pglob, limit, NULL)); 333 } 334 335 336 /* 337 * Recursive brace globbing helper. Tries to expand a single brace. 338 * If it succeeds then it invokes globexp1 with the new pattern. 339 * If it fails then it tries to glob the rest of the pattern and returns. 340 */ 341 static int 342 globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, 343 struct glob_limit *limit) 344 { 345 int i, rv; 346 Char *lm, *ls; 347 const Char *pe, *pm, *pm1, *pl; 348 Char patbuf[MAXPATHLEN]; 349 350 /* copy part up to the brace */ 351 for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) 352 continue; 353 *lm = EOS; 354 ls = lm; 355 356 /* Find the balanced brace */ 357 for (i = 0, pe = ++ptr; *pe != EOS; pe++) 358 if (*pe == LBRACKET) { 359 /* Ignore everything between [] */ 360 for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) 361 continue; 362 if (*pe == EOS) { 363 /* 364 * We could not find a matching RBRACKET. 365 * Ignore and just look for RBRACE 366 */ 367 pe = pm; 368 } 369 } 370 else if (*pe == LBRACE) 371 i++; 372 else if (*pe == RBRACE) { 373 if (i == 0) 374 break; 375 i--; 376 } 377 378 /* Non matching braces; just glob the pattern */ 379 if (i != 0 || *pe == EOS) 380 return (glob0(pattern, pglob, limit, NULL)); 381 382 for (i = 0, pl = pm = ptr; pm <= pe; pm++) 383 switch (*pm) { 384 case LBRACKET: 385 /* Ignore everything between [] */ 386 for (pm1 = pm++; *pm != RBRACKET && *pm != EOS; pm++) 387 continue; 388 if (*pm == EOS) { 389 /* 390 * We could not find a matching RBRACKET. 391 * Ignore and just look for RBRACE 392 */ 393 pm = pm1; 394 } 395 break; 396 397 case LBRACE: 398 i++; 399 break; 400 401 case RBRACE: 402 if (i) { 403 i--; 404 break; 405 } 406 /* FALLTHROUGH */ 407 case COMMA: 408 if (i && *pm == COMMA) 409 break; 410 else { 411 /* Append the current string */ 412 for (lm = ls; (pl < pm); *lm++ = *pl++) 413 continue; 414 /* 415 * Append the rest of the pattern after the 416 * closing brace 417 */ 418 for (pl = pe + 1; (*lm++ = *pl++) != EOS;) 419 continue; 420 421 /* Expand the current pattern */ 422 #ifdef DEBUG 423 qprintf("globexp2:", patbuf); 424 #endif 425 rv = globexp1(patbuf, pglob, limit); 426 if (rv) 427 return (rv); 428 429 /* move after the comma, to the next string */ 430 pl = pm + 1; 431 } 432 break; 433 434 default: 435 break; 436 } 437 return (0); 438 } 439 440 441 442 /* 443 * expand tilde from the passwd file. 444 */ 445 static const Char * 446 globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) 447 { 448 struct passwd *pwd; 449 char *h, *sc; 450 const Char *p; 451 Char *b, *eb; 452 wchar_t wc; 453 wchar_t wbuf[MAXPATHLEN]; 454 wchar_t *wbufend, *dc; 455 size_t clen; 456 mbstate_t mbs; 457 int too_long; 458 459 if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) 460 return (pattern); 461 462 /* 463 * Copy up to the end of the string or / 464 */ 465 eb = &patbuf[patbuf_len - 1]; 466 for (p = pattern + 1, b = patbuf; 467 b < eb && *p != EOS && UNPROT(*p) != SEP; *b++ = *p++) 468 continue; 469 470 if (*p != EOS && UNPROT(*p) != SEP) 471 return (NULL); 472 473 *b = EOS; 474 h = NULL; 475 476 if (patbuf[0] == EOS) { 477 /* 478 * handle a plain ~ or ~/ by expanding $HOME first (iff 479 * we're not running setuid or setgid) and then trying 480 * the password file 481 */ 482 if ((h = secure_getenv("HOME")) == NULL) { 483 if (((h = getlogin()) != NULL && 484 (pwd = getpwnam(h)) != NULL) || 485 (pwd = getpwuid(getuid())) != NULL) 486 h = pwd->pw_dir; 487 else 488 return (pattern); 489 } 490 } 491 else { 492 /* 493 * Expand a ~user 494 */ 495 if (g_Ctoc(patbuf, (char *)wbuf, sizeof(wbuf))) 496 return (NULL); 497 if ((pwd = getpwnam((char *)wbuf)) == NULL) 498 return (pattern); 499 else 500 h = pwd->pw_dir; 501 } 502 503 /* Copy the home directory */ 504 dc = wbuf; 505 sc = h; 506 wbufend = wbuf + MAXPATHLEN - 1; 507 too_long = 1; 508 memset(&mbs, 0, sizeof(mbs)); 509 while (dc <= wbufend) { 510 clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); 511 if (clen == (size_t)-1 || clen == (size_t)-2) { 512 /* XXX See initial comment #2. */ 513 wc = (unsigned char)*sc; 514 clen = 1; 515 memset(&mbs, 0, sizeof(mbs)); 516 } 517 if ((*dc++ = wc) == EOS) { 518 too_long = 0; 519 break; 520 } 521 sc += clen; 522 } 523 if (too_long) 524 return (NULL); 525 526 dc = wbuf; 527 for (b = patbuf; b < eb && *dc != EOS; *b++ = *dc++ | M_PROTECT) 528 continue; 529 if (*dc != EOS) 530 return (NULL); 531 532 /* Append the rest of the pattern */ 533 if (*p != EOS) { 534 too_long = 1; 535 while (b <= eb) { 536 if ((*b++ = *p++) == EOS) { 537 too_long = 0; 538 break; 539 } 540 } 541 if (too_long) 542 return (NULL); 543 } else 544 *b = EOS; 545 546 return (patbuf); 547 } 548 549 550 /* 551 * The main glob() routine: compiles the pattern (optionally processing 552 * quotes), calls glob1() to do the real pattern matching, and finally 553 * sorts the list (unless unsorted operation is requested). Returns 0 554 * if things went well, nonzero if errors occurred. 555 */ 556 static int 557 glob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit, 558 const char *origpat) { 559 const Char *qpatnext; 560 int err; 561 size_t oldpathc; 562 Char *bufnext, c, patbuf[MAXPATHLEN]; 563 564 qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); 565 if (qpatnext == NULL) { 566 errno = E2BIG; 567 return (GLOB_NOSPACE); 568 } 569 oldpathc = pglob->gl_pathc; 570 bufnext = patbuf; 571 572 /* We don't need to check for buffer overflow any more. */ 573 while ((c = *qpatnext++) != EOS) { 574 switch (c) { 575 case LBRACKET: 576 c = *qpatnext; 577 if (c == NOT) 578 ++qpatnext; 579 if (*qpatnext == EOS || 580 g_strchr(qpatnext+1, RBRACKET) == NULL) { 581 *bufnext++ = LBRACKET; 582 if (c == NOT) 583 --qpatnext; 584 break; 585 } 586 *bufnext++ = M_SET; 587 if (c == NOT) 588 *bufnext++ = M_NOT; 589 c = *qpatnext++; 590 do { 591 *bufnext++ = CHAR(c); 592 if (*qpatnext == RANGE && 593 (c = qpatnext[1]) != RBRACKET) { 594 *bufnext++ = M_RNG; 595 *bufnext++ = CHAR(c); 596 qpatnext += 2; 597 } 598 } while ((c = *qpatnext++) != RBRACKET); 599 pglob->gl_flags |= GLOB_MAGCHAR; 600 *bufnext++ = M_END; 601 break; 602 case QUESTION: 603 pglob->gl_flags |= GLOB_MAGCHAR; 604 *bufnext++ = M_ONE; 605 break; 606 case STAR: 607 pglob->gl_flags |= GLOB_MAGCHAR; 608 /* collapse adjacent stars to one, 609 * to ensure "**" at the end continues to match the 610 * empty string 611 */ 612 if (bufnext == patbuf || bufnext[-1] != M_ALL) 613 *bufnext++ = M_ALL; 614 break; 615 default: 616 *bufnext++ = CHAR(c); 617 break; 618 } 619 } 620 *bufnext = EOS; 621 #ifdef DEBUG 622 qprintf("glob0:", patbuf); 623 #endif 624 625 if ((err = glob1(patbuf, pglob, limit)) != 0) 626 return(err); 627 628 if (origpat != NULL) 629 return (globfinal(pglob, limit, oldpathc, origpat)); 630 631 return (0); 632 } 633 634 static int 635 globfinal(glob_t *pglob, struct glob_limit *limit, size_t oldpathc, 636 const char *origpat) { 637 if (pglob->gl_pathc == oldpathc) 638 return (err_nomatch(pglob, limit, origpat)); 639 640 if (!(pglob->gl_flags & GLOB_NOSORT)) 641 qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, 642 pglob->gl_pathc - oldpathc, sizeof(char *), compare); 643 644 return (0); 645 } 646 647 static int 648 compare(const void *p, const void *q) 649 { 650 return (strcoll(*(char **)p, *(char **)q)); 651 } 652 653 static int 654 glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit) 655 { 656 Char pathbuf[MAXPATHLEN]; 657 658 /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ 659 if (*pattern == EOS) 660 return (0); 661 return (glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, 662 pattern, pglob, limit)); 663 } 664 665 /* 666 * The functions glob2 and glob3 are mutually recursive; there is one level 667 * of recursion for each segment in the pattern that contains one or more 668 * meta characters. 669 */ 670 static int 671 glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, 672 glob_t *pglob, struct glob_limit *limit) 673 { 674 struct stat sb; 675 Char *p, *q; 676 int anymeta; 677 678 /* 679 * Loop over pattern segments until end of pattern or until 680 * segment with meta character found. 681 */ 682 for (anymeta = 0;;) { 683 if (*pattern == EOS) { /* End of pattern? */ 684 *pathend = EOS; 685 if (g_lstat(pathbuf, &sb, pglob)) 686 return (0); 687 688 if ((pglob->gl_flags & GLOB_LIMIT) && 689 limit->l_stat_cnt++ >= GLOB_LIMIT_STAT) { 690 errno = E2BIG; 691 return (GLOB_NOSPACE); 692 } 693 if ((pglob->gl_flags & GLOB_MARK) && 694 UNPROT(pathend[-1]) != SEP && 695 (S_ISDIR(sb.st_mode) || 696 (S_ISLNK(sb.st_mode) && 697 g_stat(pathbuf, &sb, pglob) == 0 && 698 S_ISDIR(sb.st_mode)))) { 699 if (pathend + 1 > pathend_last) { 700 errno = E2BIG; 701 return (GLOB_NOSPACE); 702 } 703 *pathend++ = SEP; 704 *pathend = EOS; 705 } 706 ++pglob->gl_matchc; 707 return (globextend(pathbuf, pglob, limit, NULL)); 708 } 709 710 /* Find end of next segment, copy tentatively to pathend. */ 711 q = pathend; 712 p = pattern; 713 while (*p != EOS && UNPROT(*p) != SEP) { 714 if (ismeta(*p)) 715 anymeta = 1; 716 if (q + 1 > pathend_last) { 717 errno = E2BIG; 718 return (GLOB_NOSPACE); 719 } 720 *q++ = *p++; 721 } 722 723 if (!anymeta) { /* No expansion, do next segment. */ 724 pathend = q; 725 pattern = p; 726 while (UNPROT(*pattern) == SEP) { 727 if (pathend + 1 > pathend_last) { 728 errno = E2BIG; 729 return (GLOB_NOSPACE); 730 } 731 *pathend++ = *pattern++; 732 } 733 } else /* Need expansion, recurse. */ 734 return (glob3(pathbuf, pathend, pathend_last, pattern, 735 p, pglob, limit)); 736 } 737 /* NOTREACHED */ 738 } 739 740 static int 741 glob3(Char *pathbuf, Char *pathend, Char *pathend_last, 742 Char *pattern, Char *restpattern, 743 glob_t *pglob, struct glob_limit *limit) 744 { 745 struct dirent *dp; 746 DIR *dirp; 747 int err, too_long, saverrno, saverrno2; 748 char buf[MAXPATHLEN + MB_LEN_MAX - 1]; 749 750 struct dirent *(*readdirfunc)(DIR *); 751 752 if (pathend > pathend_last) { 753 errno = E2BIG; 754 return (GLOB_NOSPACE); 755 } 756 *pathend = EOS; 757 if ((pglob->gl_errfunc != NULL || pglob->gl_errblk != NULL) && 758 g_Ctoc(pathbuf, buf, sizeof(buf))) { 759 errno = E2BIG; 760 return (GLOB_NOSPACE); 761 } 762 763 saverrno = errno; 764 errno = 0; 765 if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { 766 if (errno == ENOENT || errno == ENOTDIR) 767 return (0); 768 err = err_aborted(pglob, errno, buf); 769 if (errno == 0) 770 errno = saverrno; 771 return (err); 772 } 773 774 err = 0; 775 776 /* pglob->gl_readdir takes a void *, fix this manually */ 777 if (pglob->gl_flags & GLOB_ALTDIRFUNC) 778 readdirfunc = (struct dirent *(*)(DIR *))pglob->gl_readdir; 779 else 780 readdirfunc = readdir; 781 782 errno = 0; 783 /* Search directory for matching names. */ 784 while ((dp = (*readdirfunc)(dirp)) != NULL) { 785 char *sc; 786 Char *dc; 787 wchar_t wc; 788 size_t clen; 789 mbstate_t mbs; 790 791 if ((pglob->gl_flags & GLOB_LIMIT) && 792 limit->l_readdir_cnt++ >= GLOB_LIMIT_READDIR) { 793 errno = E2BIG; 794 err = GLOB_NOSPACE; 795 break; 796 } 797 798 /* Initial DOT must be matched literally. */ 799 if (dp->d_name[0] == '.' && UNPROT(*pattern) != DOT) { 800 errno = 0; 801 continue; 802 } 803 memset(&mbs, 0, sizeof(mbs)); 804 dc = pathend; 805 sc = dp->d_name; 806 too_long = 1; 807 while (dc <= pathend_last) { 808 clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); 809 if (clen == (size_t)-1 || clen == (size_t)-2) { 810 /* XXX See initial comment #2. */ 811 wc = (unsigned char)*sc; 812 clen = 1; 813 memset(&mbs, 0, sizeof(mbs)); 814 } 815 if ((*dc++ = wc) == EOS) { 816 too_long = 0; 817 break; 818 } 819 sc += clen; 820 } 821 if (too_long && (err = err_aborted(pglob, ENAMETOOLONG, 822 buf))) { 823 errno = ENAMETOOLONG; 824 break; 825 } 826 if (too_long || !match(pathend, pattern, restpattern)) { 827 *pathend = EOS; 828 errno = 0; 829 continue; 830 } 831 if (errno == 0) 832 errno = saverrno; 833 err = glob2(pathbuf, --dc, pathend_last, restpattern, 834 pglob, limit); 835 if (err) 836 break; 837 errno = 0; 838 } 839 840 saverrno2 = errno; 841 if (pglob->gl_flags & GLOB_ALTDIRFUNC) 842 (*pglob->gl_closedir)(dirp); 843 else 844 closedir(dirp); 845 errno = saverrno2; 846 847 if (err) 848 return (err); 849 850 if (dp == NULL && errno != 0 && 851 (err = err_aborted(pglob, errno, buf))) 852 return (err); 853 854 if (errno == 0) 855 errno = saverrno; 856 return (0); 857 } 858 859 860 /* 861 * Extend the gl_pathv member of a glob_t structure to accommodate a new item, 862 * add the new item, and update gl_pathc. 863 * 864 * This assumes the BSD realloc, which only copies the block when its size 865 * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic 866 * behavior. 867 * 868 * Return 0 if new item added, error code if memory couldn't be allocated. 869 * 870 * Invariant of the glob_t structure: 871 * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and 872 * gl_pathv points to (gl_offs + gl_pathc + 1) items. 873 */ 874 static int 875 globextend(const Char *path, glob_t *pglob, struct glob_limit *limit, 876 const char *origpat) 877 { 878 char **pathv; 879 size_t i, newn, len; 880 char *copy; 881 const Char *p; 882 883 if ((pglob->gl_flags & GLOB_LIMIT) && 884 pglob->gl_matchc > limit->l_path_lim) { 885 errno = E2BIG; 886 return (GLOB_NOSPACE); 887 } 888 889 newn = 2 + pglob->gl_pathc + pglob->gl_offs; 890 /* reallocarray(NULL, newn, size) is equivalent to malloc(newn*size). */ 891 pathv = reallocarray(pglob->gl_pathv, newn, sizeof(*pathv)); 892 if (pathv == NULL) 893 return (GLOB_NOSPACE); 894 895 if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { 896 /* first time around -- clear initial gl_offs items */ 897 pathv += pglob->gl_offs; 898 for (i = pglob->gl_offs + 1; --i > 0; ) 899 *--pathv = NULL; 900 } 901 pglob->gl_pathv = pathv; 902 903 if (origpat != NULL) 904 copy = strdup(origpat); 905 else { 906 for (p = path; *p++ != EOS;) 907 continue; 908 len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */ 909 if ((copy = malloc(len)) != NULL) { 910 if (g_Ctoc(path, copy, len)) { 911 free(copy); 912 errno = E2BIG; 913 return (GLOB_NOSPACE); 914 } 915 } 916 } 917 if (copy != NULL) { 918 limit->l_string_cnt += strlen(copy) + 1; 919 if ((pglob->gl_flags & GLOB_LIMIT) && 920 limit->l_string_cnt >= GLOB_LIMIT_STRING) { 921 free(copy); 922 errno = E2BIG; 923 return (GLOB_NOSPACE); 924 } 925 pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; 926 } 927 pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; 928 return (copy == NULL ? GLOB_NOSPACE : 0); 929 } 930 931 /* 932 * pattern matching function for filenames. 933 */ 934 static int 935 match(Char *name, Char *pat, Char *patend) 936 { 937 int ok, negate_range; 938 Char c, k, *nextp, *nextn; 939 struct xlocale_collate *table = 940 (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; 941 942 nextn = NULL; 943 nextp = NULL; 944 945 while (1) { 946 while (pat < patend) { 947 c = *pat++; 948 switch (c & M_MASK) { 949 case M_ALL: 950 if (pat == patend) 951 return (1); 952 if (*name == EOS) 953 return (0); 954 nextn = name + 1; 955 nextp = pat - 1; 956 break; 957 case M_ONE: 958 if (*name++ == EOS) 959 goto fail; 960 break; 961 case M_SET: 962 ok = 0; 963 if ((k = *name++) == EOS) 964 goto fail; 965 negate_range = ((*pat & M_MASK) == M_NOT); 966 if (negate_range != 0) 967 ++pat; 968 while (((c = *pat++) & M_MASK) != M_END) 969 if ((*pat & M_MASK) == M_RNG) { 970 if (table->__collate_load_error ? 971 CHAR(c) <= CHAR(k) && 972 CHAR(k) <= CHAR(pat[1]) : 973 __wcollate_range_cmp(CHAR(c), 974 CHAR(k)) <= 0 && 975 __wcollate_range_cmp(CHAR(k), 976 CHAR(pat[1])) <= 0) 977 ok = 1; 978 pat += 2; 979 } else if (c == k) 980 ok = 1; 981 if (ok == negate_range) 982 goto fail; 983 break; 984 default: 985 if (*name++ != c) 986 goto fail; 987 break; 988 } 989 } 990 if (*name == EOS) 991 return (1); 992 993 fail: 994 if (nextn == NULL) 995 break; 996 pat = nextp; 997 name = nextn; 998 } 999 return (0); 1000 } 1001 1002 /* Free allocated data belonging to a glob_t structure. */ 1003 void 1004 globfree(glob_t *pglob) 1005 { 1006 size_t i; 1007 char **pp; 1008 1009 if (pglob->gl_pathv != NULL) { 1010 pp = pglob->gl_pathv + pglob->gl_offs; 1011 for (i = pglob->gl_pathc; i--; ++pp) 1012 if (*pp) 1013 free(*pp); 1014 free(pglob->gl_pathv); 1015 pglob->gl_pathv = NULL; 1016 } 1017 } 1018 1019 static DIR * 1020 g_opendir(Char *str, glob_t *pglob) 1021 { 1022 char buf[MAXPATHLEN + MB_LEN_MAX - 1]; 1023 1024 if (*str == EOS) 1025 strcpy(buf, "."); 1026 else { 1027 if (g_Ctoc(str, buf, sizeof(buf))) { 1028 errno = ENAMETOOLONG; 1029 return (NULL); 1030 } 1031 } 1032 1033 if (pglob->gl_flags & GLOB_ALTDIRFUNC) 1034 return ((*pglob->gl_opendir)(buf)); 1035 1036 return (opendir(buf)); 1037 } 1038 1039 static int 1040 g_lstat(Char *fn, struct stat *sb, glob_t *pglob) 1041 { 1042 char buf[MAXPATHLEN + MB_LEN_MAX - 1]; 1043 1044 if (g_Ctoc(fn, buf, sizeof(buf))) { 1045 errno = ENAMETOOLONG; 1046 return (-1); 1047 } 1048 if (pglob->gl_flags & GLOB_ALTDIRFUNC) 1049 return((*pglob->gl_lstat)(buf, sb)); 1050 return (lstat(buf, sb)); 1051 } 1052 1053 static int 1054 g_stat(Char *fn, struct stat *sb, glob_t *pglob) 1055 { 1056 char buf[MAXPATHLEN + MB_LEN_MAX - 1]; 1057 1058 if (g_Ctoc(fn, buf, sizeof(buf))) { 1059 errno = ENAMETOOLONG; 1060 return (-1); 1061 } 1062 if (pglob->gl_flags & GLOB_ALTDIRFUNC) 1063 return ((*pglob->gl_stat)(buf, sb)); 1064 return (stat(buf, sb)); 1065 } 1066 1067 static const Char * 1068 g_strchr(const Char *str, wchar_t ch) 1069 { 1070 1071 do { 1072 if (*str == ch) 1073 return (str); 1074 } while (*str++); 1075 return (NULL); 1076 } 1077 1078 static int 1079 g_Ctoc(const Char *str, char *buf, size_t len) 1080 { 1081 mbstate_t mbs; 1082 size_t clen; 1083 1084 memset(&mbs, 0, sizeof(mbs)); 1085 while (len >= MB_CUR_MAX) { 1086 clen = wcrtomb(buf, CHAR(*str), &mbs); 1087 if (clen == (size_t)-1) { 1088 /* XXX See initial comment #2. */ 1089 *buf = (char)CHAR(*str); 1090 clen = 1; 1091 memset(&mbs, 0, sizeof(mbs)); 1092 } 1093 if (CHAR(*str) == EOS) 1094 return (0); 1095 str++; 1096 buf += clen; 1097 len -= clen; 1098 } 1099 return (1); 1100 } 1101 1102 static int 1103 err_nomatch(glob_t *pglob, struct glob_limit *limit, const char *origpat) { 1104 /* 1105 * If there was no match we are going to append the origpat 1106 * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified 1107 * and the origpat did not contain any magic characters 1108 * GLOB_NOMAGIC is there just for compatibility with csh. 1109 */ 1110 if ((pglob->gl_flags & GLOB_NOCHECK) || 1111 ((pglob->gl_flags & GLOB_NOMAGIC) && 1112 !(pglob->gl_flags & GLOB_MAGCHAR))) 1113 return (globextend(NULL, pglob, limit, origpat)); 1114 return (GLOB_NOMATCH); 1115 } 1116 1117 static int 1118 err_aborted(glob_t *pglob, int err, char *buf) 1119 { 1120 int rv = 0; 1121 1122 if ((pglob->gl_flags & _GLOB_ERR_BLOCK) != 0) { 1123 if (pglob->gl_errblk != NULL) 1124 rv = CALL_BLOCK((glob_b_block)pglob->gl_errblk, buf, 1125 errno); 1126 } else if (pglob->gl_errfunc != NULL) { 1127 rv = pglob->gl_errfunc(buf, errno); 1128 } 1129 /* GLOB_ERR is allowed to override the error callback function. */ 1130 if (rv != 0 || pglob->gl_flags & GLOB_ERR) { 1131 return (GLOB_ABORTED); 1132 } 1133 return (0); 1134 } 1135 1136 #ifdef DEBUG 1137 static void 1138 qprintf(const char *str, Char *s) 1139 { 1140 Char *p; 1141 1142 (void)printf("%s\n", str); 1143 if (s != NULL) { 1144 for (p = s; *p != EOS; p++) 1145 (void)printf("%c", (char)CHAR(*p)); 1146 (void)printf("\n"); 1147 for (p = s; *p != EOS; p++) 1148 (void)printf("%c", (isprot(*p) ? '\\' : ' ')); 1149 (void)printf("\n"); 1150 for (p = s; *p != EOS; p++) 1151 (void)printf("%c", (ismeta(*p) ? '_' : ' ')); 1152 (void)printf("\n"); 1153 } 1154 } 1155 #endif 1156