1 /* 2 * Copyright 2023 Bill Sommerfeld <sommerfeld@hamachi.org> 3 * Copyright 2013 Garrett D'Amore <garrett@damore.org> 4 * Copyright 2019 Nexenta by DDN, Inc. All rights reserved. 5 * Copyright 2012 Milan Jurik. All rights reserved. 6 * Copyright (c) 1992, 1993, 1994 Henry Spencer. 7 * Copyright (c) 1992, 1993, 1994 8 * The Regents of the University of California. All rights reserved. 9 * 10 * This code is derived from software contributed to Berkeley by 11 * Henry Spencer. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #include "lint.h" 39 #include "thr_uberdata.h" 40 #include "file64.h" 41 #include <sys/types.h> 42 #include <stdio.h> 43 #include <string.h> 44 #include <ctype.h> 45 #include <limits.h> 46 #include <regex.h> 47 #include <stdlib.h> 48 #include <stdbool.h> 49 #include <wchar.h> 50 #include <wctype.h> 51 52 #include "../locale/runetype.h" 53 #include "../locale/collate.h" 54 55 #include "utils.h" 56 #include "regex2.h" 57 58 #include "cname.h" 59 #include "../locale/mblocal.h" 60 61 /* 62 * Branching context, used to keep track of branch state for all of the branch- 63 * aware functions. In addition to keeping track of branch positions for the 64 * p_branch_* functions, we use this to simplify some clumsiness in BREs for 65 * detection of whether ^ is acting as an anchor or being used erroneously and 66 * also for whether we're in a sub-expression or not. 67 */ 68 struct branchc { 69 sopno start; 70 sopno back; 71 sopno fwd; 72 73 int nbranch; 74 int nchain; 75 bool outer; 76 bool terminate; 77 }; 78 79 /* 80 * parse structure, passed up and down to avoid global variables and 81 * other clumsinesses 82 */ 83 struct parse { 84 const char *next; /* next character in RE */ 85 const char *end; /* end of string (-> NUL normally) */ 86 int error; /* has an error been seen? */ 87 sop *strip; /* malloced strip */ 88 sopno ssize; /* malloced strip size (allocated) */ 89 sopno slen; /* malloced strip length (used) */ 90 int ncsalloc; /* number of csets allocated */ 91 wint_t nc; /* size of small-char bitmap in cset */ 92 struct re_guts *g; 93 #define NPAREN 10 /* we need to remember () 1-9 for back refs */ 94 sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ 95 sopno pend[NPAREN]; /* -> ) ([0] unused) */ 96 bool allowbranch; /* can this expression branch? */ 97 bool bre; /* convenience; is this a BRE? */ 98 bool (*parse_expr)(struct parse *, struct branchc *); 99 void (*pre_parse)(struct parse *, struct branchc *); 100 void (*post_parse)(struct parse *, struct branchc *); 101 }; 102 103 /* ========= begin header generated by ./mkh ========= */ 104 #ifdef __cplusplus 105 extern "C" { 106 #endif 107 108 /* === regcomp.c === */ 109 static bool p_ere_exp(struct parse *p, struct branchc *bc); 110 static void p_str(struct parse *p); 111 static int p_branch_eat_delim(struct parse *p, struct branchc *bc); 112 static void p_branch_ins_offset(struct parse *p, struct branchc *bc); 113 static void p_branch_fix_tail(struct parse *p, struct branchc *bc); 114 static bool p_branch_empty(struct parse *p, struct branchc *bc); 115 static bool p_branch_do(struct parse *p, struct branchc *bc); 116 static void p_bre_pre_parse(struct parse *p, struct branchc *bc); 117 static void p_bre_post_parse(struct parse *p, struct branchc *bc); 118 static void p_re(struct parse *p, int end1, int end2); 119 static bool p_simp_re(struct parse *p, struct branchc *bc); 120 static int p_count(struct parse *p); 121 static void p_bracket(struct parse *p); 122 static void p_b_term(struct parse *p, cset *cs); 123 static void p_b_cclass(struct parse *p, cset *cs); 124 static void p_b_eclass(struct parse *p, cset *cs); 125 static wint_t p_b_symbol(struct parse *p); 126 static wint_t p_b_coll_elem(struct parse *p, wint_t endc); 127 static wint_t othercase(wint_t ch); 128 static void bothcases(struct parse *p, wint_t ch); 129 static void ordinary(struct parse *p, wint_t ch); 130 static void nonnewline(struct parse *p); 131 static void repeat(struct parse *p, sopno start, int from, int to); 132 static int seterr(struct parse *p, int e); 133 static cset *allocset(struct parse *p); 134 static void freeset(struct parse *p, cset *cs); 135 static void CHadd(struct parse *p, cset *cs, wint_t ch); 136 static void CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max); 137 static void CHaddtype(struct parse *p, cset *cs, wctype_t wct); 138 static wint_t singleton(struct parse *p, cset *cs); 139 static sopno dupl(struct parse *p, sopno start, sopno finish); 140 static void doemit(struct parse *p, sop op, size_t opnd); 141 static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos); 142 static void dofwd(struct parse *p, sopno pos, sop value); 143 static int enlarge(struct parse *p, sopno size); 144 static void stripsnug(struct parse *p, struct re_guts *g); 145 static void findmust(struct parse *p, struct re_guts *g); 146 static int altoffset(sop *scan, int offset); 147 static void computejumps(struct parse *p, struct re_guts *g); 148 static void computematchjumps(struct parse *p, struct re_guts *g); 149 static sopno pluscount(struct parse *p, struct re_guts *g); 150 static wint_t wgetnext(struct parse *p); 151 152 #ifdef __cplusplus 153 } 154 #endif 155 /* ========= end header generated by ./mkh ========= */ 156 157 static char nuls[10]; /* place to point scanner in event of error */ 158 159 /* 160 * macros for use with parse structure 161 * BEWARE: these know that the parse structure is named `p' !!! 162 */ 163 #define PEEK() (*p->next) 164 #define PEEK2() (*(p->next+1)) 165 #define MORE() (p->next < p->end) 166 #define MORE2() (p->next+1 < p->end) 167 #define SEE(c) (MORE() && PEEK() == (c)) 168 #define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b)) 169 #define SEESPEC(a) (p->bre ? SEETWO('\\', a) : SEE(a)) 170 #define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0) 171 #define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0) 172 #define NEXT() (p->next++) 173 #define NEXT2() (p->next += 2) 174 #define NEXTn(n) (p->next += (n)) 175 #define GETNEXT() (*p->next++) 176 #define WGETNEXT() wgetnext(p) 177 #define SETERROR(e) ((void)seterr(p, (e))) 178 #define REQUIRE(co, e) ((co) || seterr(p, e)) 179 #define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e)) 180 #define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e)) 181 #define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e)) 182 #define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd)) 183 #define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos) 184 #define AHEAD(pos) dofwd(p, pos, HERE()-(pos)) 185 #define ASTERN(sop, pos) EMIT(sop, HERE()-pos) 186 #define HERE() (p->slen) 187 #define THERE() (p->slen - 1) 188 #define THERETHERE() (p->slen - 2) 189 #define DROP(n) (p->slen -= (n)) 190 191 #ifndef NDEBUG 192 static int never = 0; /* for use in asserts; shuts lint up */ 193 #else 194 #define never 0 /* some <assert.h>s have bugs too */ 195 #endif 196 197 /* 198 * regcomp - interface for parser and compilation 199 */ 200 int /* 0 success, otherwise REG_something */ 201 regcomp(regex_t *_RESTRICT_KYWD preg, const char *_RESTRICT_KYWD pattern, 202 int cflags) 203 { 204 struct parse pa; 205 struct re_guts *g; 206 struct parse *p = &pa; 207 int i; 208 size_t len; 209 size_t maxlen; 210 #ifdef REDEBUG 211 #define GOODFLAGS(f) (f) 212 #else 213 #define GOODFLAGS(f) ((f)&~REG_DUMP) 214 #endif 215 216 /* 217 * Which character values are kept in cset bitmaps? 218 * 219 * Character sets store their members as a bitmap (for low-codepoint 220 * characters) or as elements of an array; pa.nc sets the dividing 221 * point between them. 222 * 223 * The value of MB_CUR_MAX depends on the current locale; fetching the 224 * current locale can be expensive, so we pick a value now and stick 225 * with it for the lifetime of the compiled regex. 226 */ 227 pa.nc = ((MB_CUR_MAX) == 1 ? (NC_MAX) : (NC_WIDE)); 228 229 /* We had REG_INVARG, but we don't have that on Solaris. */ 230 cflags = GOODFLAGS(cflags); 231 if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) 232 return (REG_EFATAL); 233 234 if (cflags®_PEND) { 235 if (preg->re_endp < pattern) 236 return (REG_EFATAL); 237 len = preg->re_endp - pattern; 238 } else 239 len = strlen(pattern); 240 241 /* do the mallocs early so failure handling is easy */ 242 g = (struct re_guts *)malloc(sizeof (struct re_guts)); 243 if (g == NULL) 244 return (REG_ESPACE); 245 g->mb_cur_max = MB_CUR_MAX; 246 /* 247 * Limit the pattern space to avoid a 32-bit overflow on buffer 248 * extension. Also avoid any signed overflow in case of conversion 249 * so make the real limit based on a 31-bit overflow. 250 * 251 * Likely not applicable on 64-bit systems but handle the case 252 * generically (who are we to stop people from using ~715MB+ 253 * patterns?). 254 */ 255 maxlen = ((size_t)-1 >> 1) / sizeof (sop) * 2 / 3; 256 if (len >= maxlen) { 257 free((char *)g); 258 return (REG_ESPACE); 259 } 260 p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ 261 assert(p->ssize >= len); 262 263 p->strip = (sop *)malloc(p->ssize * sizeof (sop)); 264 p->slen = 0; 265 if (p->strip == NULL) { 266 free((char *)g); 267 return (REG_ESPACE); 268 } 269 270 /* set things up */ 271 p->g = g; 272 p->next = pattern; /* convenience; we do not modify it */ 273 p->end = p->next + len; 274 p->error = 0; 275 p->ncsalloc = 0; 276 for (i = 0; i < NPAREN; i++) { 277 p->pbegin[i] = 0; 278 p->pend[i] = 0; 279 } 280 if (cflags & REG_EXTENDED) { 281 p->allowbranch = true; 282 p->bre = false; 283 p->parse_expr = p_ere_exp; 284 p->pre_parse = NULL; 285 p->post_parse = NULL; 286 } else { 287 p->allowbranch = false; 288 p->bre = true; 289 p->parse_expr = p_simp_re; 290 p->pre_parse = p_bre_pre_parse; 291 p->post_parse = p_bre_post_parse; 292 } 293 g->sets = NULL; 294 g->ncsets = 0; 295 g->cflags = cflags; 296 g->iflags = 0; 297 g->nbol = 0; 298 g->neol = 0; 299 g->must = NULL; 300 g->moffset = -1; 301 g->charjump = NULL; 302 g->matchjump = NULL; 303 g->mlen = 0; 304 g->nsub = 0; 305 g->backrefs = 0; 306 307 /* do it */ 308 EMIT(OEND, 0); 309 g->firststate = THERE(); 310 if (cflags & REG_NOSPEC) 311 p_str(p); 312 else 313 p_re(p, OUT, OUT); 314 EMIT(OEND, 0); 315 g->laststate = THERE(); 316 317 /* tidy up loose ends and fill things in */ 318 stripsnug(p, g); 319 findmust(p, g); 320 /* 321 * only use Boyer-Moore algorithm if the pattern is bigger 322 * than three characters 323 */ 324 if (g->mlen > 3) { 325 computejumps(p, g); 326 computematchjumps(p, g); 327 if (g->matchjump == NULL && g->charjump != NULL) { 328 free(g->charjump); 329 g->charjump = NULL; 330 } 331 } 332 g->nplus = pluscount(p, g); 333 g->magic = MAGIC2; 334 preg->re_nsub = g->nsub; 335 preg->re_g = g; 336 preg->re_magic = MAGIC1; 337 #ifndef REDEBUG 338 /* not debugging, so can't rely on the assert() in regexec() */ 339 if (g->iflags&BAD) 340 SETERROR(REG_EFATAL); 341 #endif 342 343 /* win or lose, we're done */ 344 if (p->error != 0) /* lose */ 345 regfree(preg); 346 return (p->error); 347 } 348 349 /* 350 * Parse one subERE, an atom possibly followed by a repetition op, 351 * return whether we should terminate or not. 352 */ 353 static bool 354 p_ere_exp(struct parse *p, struct branchc *bc) 355 { 356 char c; 357 wint_t wc; 358 sopno pos; 359 int count; 360 int count2; 361 sopno subno; 362 int wascaret = 0; 363 364 (void) bc; 365 assert(MORE()); /* caller should have ensured this */ 366 c = GETNEXT(); 367 368 pos = HERE(); 369 switch (c) { 370 case '(': 371 (void) REQUIRE(MORE(), REG_EPAREN); 372 p->g->nsub++; 373 subno = p->g->nsub; 374 if (subno < NPAREN) 375 p->pbegin[subno] = HERE(); 376 EMIT(OLPAREN, subno); 377 if (!SEE(')')) 378 p_re(p, ')', IGN); 379 if (subno < NPAREN) { 380 p->pend[subno] = HERE(); 381 assert(p->pend[subno] != 0); 382 } 383 EMIT(ORPAREN, subno); 384 (void) MUSTEAT(')', REG_EPAREN); 385 break; 386 #ifndef POSIX_MISTAKE 387 case ')': /* happens only if no current unmatched ( */ 388 /* 389 * You may ask, why the ifndef? Because I didn't notice 390 * this until slightly too late for 1003.2, and none of the 391 * other 1003.2 regular-expression reviewers noticed it at 392 * all. So an unmatched ) is legal POSIX, at least until 393 * we can get it fixed. 394 */ 395 SETERROR(REG_EPAREN); 396 break; 397 #endif 398 case '^': 399 EMIT(OBOL, 0); 400 p->g->iflags |= USEBOL; 401 p->g->nbol++; 402 wascaret = 1; 403 break; 404 case '$': 405 EMIT(OEOL, 0); 406 p->g->iflags |= USEEOL; 407 p->g->neol++; 408 break; 409 case '|': 410 SETERROR(REG_BADPAT); 411 break; 412 case '*': 413 case '+': 414 case '?': 415 case '{': 416 SETERROR(REG_BADRPT); 417 break; 418 case '.': 419 if (p->g->cflags®_NEWLINE) 420 nonnewline(p); 421 else 422 EMIT(OANY, 0); 423 break; 424 case '[': 425 p_bracket(p); 426 break; 427 case '\\': 428 (void) REQUIRE(MORE(), REG_EESCAPE); 429 wc = WGETNEXT(); 430 switch (wc) { 431 case '<': 432 EMIT(OBOW, 0); 433 break; 434 case '>': 435 EMIT(OEOW, 0); 436 break; 437 default: 438 ordinary(p, wc); 439 break; 440 } 441 break; 442 default: 443 if (p->error != 0) 444 return (false); 445 p->next--; 446 wc = WGETNEXT(); 447 ordinary(p, wc); 448 break; 449 } 450 451 if (!MORE()) 452 return (false); 453 c = PEEK(); 454 /* we call { a repetition if followed by a digit */ 455 if (!(c == '*' || c == '+' || c == '?' || c == '{')) 456 return (false); /* no repetition, we're done */ 457 else if (c == '{') 458 (void) REQUIRE(MORE2() && \ 459 (isdigit((uch)PEEK2()) || PEEK2() == ','), REG_BADRPT); 460 NEXT(); 461 462 (void) REQUIRE(!wascaret, REG_BADRPT); 463 switch (c) { 464 case '*': /* implemented as +? */ 465 /* this case does not require the (y|) trick, noKLUDGE */ 466 INSERT(OPLUS_, pos); 467 ASTERN(O_PLUS, pos); 468 INSERT(OQUEST_, pos); 469 ASTERN(O_QUEST, pos); 470 break; 471 case '+': 472 INSERT(OPLUS_, pos); 473 ASTERN(O_PLUS, pos); 474 break; 475 case '?': 476 /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ 477 INSERT(OCH_, pos); /* offset slightly wrong */ 478 ASTERN(OOR1, pos); /* this one's right */ 479 AHEAD(pos); /* fix the OCH_ */ 480 EMIT(OOR2, 0); /* offset very wrong... */ 481 AHEAD(THERE()); /* ...so fix it */ 482 ASTERN(O_CH, THERETHERE()); 483 break; 484 case '{': 485 count = p_count(p); 486 if (EAT(',')) { 487 if (isdigit((uch)PEEK())) { 488 count2 = p_count(p); 489 (void) REQUIRE(count <= count2, REG_BADBR); 490 } else /* single number with comma */ 491 count2 = INFINITY; 492 } else /* just a single number */ 493 count2 = count; 494 repeat(p, pos, count, count2); 495 if (!EAT('}')) { /* error heuristics */ 496 while (MORE() && PEEK() != '}') 497 NEXT(); 498 (void) REQUIRE(MORE(), REG_EBRACE); 499 SETERROR(REG_BADBR); 500 } 501 break; 502 } 503 504 if (!MORE()) 505 return (false); 506 c = PEEK(); 507 if (!(c == '*' || c == '+' || c == '?' || 508 (c == '{' && MORE2() && isdigit((uch)PEEK2())))) 509 return (false); 510 SETERROR(REG_BADRPT); 511 return (false); 512 } 513 514 /* 515 * p_str - string (no metacharacters) "parser" 516 */ 517 static void 518 p_str(struct parse *p) 519 { 520 (void) REQUIRE(MORE(), REG_BADPAT); 521 while (MORE()) 522 ordinary(p, WGETNEXT()); 523 } 524 525 /* 526 * Eat consecutive branch delimiters for the kind of expression that we are 527 * parsing, return the number of delimiters that we ate. 528 */ 529 static int 530 p_branch_eat_delim(struct parse *p, struct branchc *bc) 531 { 532 int nskip; 533 534 (void) bc; 535 nskip = 0; 536 while (EAT('|')) 537 ++nskip; 538 return (nskip); 539 } 540 541 /* 542 * Insert necessary branch book-keeping operations. This emits a 543 * bogus 'next' offset, since we still have more to parse 544 */ 545 static void 546 p_branch_ins_offset(struct parse *p, struct branchc *bc) 547 { 548 if (bc->nbranch == 0) { 549 INSERT(OCH_, bc->start); /* offset is wrong */ 550 bc->fwd = bc->start; 551 bc->back = bc->start; 552 } 553 554 ASTERN(OOR1, bc->back); 555 bc->back = THERE(); 556 AHEAD(bc->fwd); /* fix previous offset */ 557 bc->fwd = HERE(); 558 EMIT(OOR2, 0); /* offset is very wrong */ 559 ++bc->nbranch; 560 } 561 562 /* 563 * Fix the offset of the tail branch, if we actually had any branches. 564 * This is to correct the bogus placeholder offset that we use. 565 */ 566 static void 567 p_branch_fix_tail(struct parse *p, struct branchc *bc) 568 { 569 /* Fix bogus offset at the tail if we actually have branches */ 570 if (bc->nbranch > 0) { 571 AHEAD(bc->fwd); 572 ASTERN(O_CH, bc->back); 573 } 574 } 575 576 /* 577 * Signal to the parser that an empty branch has been encountered; this will, 578 * in the future, be used to allow for more permissive behavior with empty 579 * branches. The return value should indicate whether parsing may continue 580 * or not. 581 */ 582 static bool 583 p_branch_empty(struct parse *p, struct branchc *bc) 584 { 585 (void) bc; 586 SETERROR(REG_BADPAT); 587 return (false); 588 } 589 590 /* 591 * Take care of any branching requirements. This includes inserting the 592 * appropriate branching instructions as well as eating all of the branch 593 * delimiters until we either run out of pattern or need to parse more pattern. 594 */ 595 static bool 596 p_branch_do(struct parse *p, struct branchc *bc) 597 { 598 int ate = 0; 599 600 ate = p_branch_eat_delim(p, bc); 601 if (ate == 0) 602 return (false); 603 else if ((ate > 1 || (bc->outer && !MORE())) && !p_branch_empty(p, bc)) 604 /* 605 * Halt parsing only if we have an empty branch and 606 * p_branch_empty indicates that we must not continue. 607 * In the future, this will not necessarily be an error. 608 */ 609 return (false); 610 p_branch_ins_offset(p, bc); 611 612 return (true); 613 } 614 615 static void 616 p_bre_pre_parse(struct parse *p, struct branchc *bc) 617 { 618 (void) bc; 619 /* 620 * Does not move cleanly into expression parser because of 621 * ordinary interpration of * at the beginning position of 622 * an expression. 623 */ 624 if (EAT('^')) { 625 EMIT(OBOL, 0); 626 p->g->iflags |= USEBOL; 627 p->g->nbol++; 628 } 629 } 630 631 static void 632 p_bre_post_parse(struct parse *p, struct branchc *bc) 633 { 634 /* Expression is terminating due to EOL token */ 635 if (bc->terminate) { 636 DROP(1); 637 EMIT(OEOL, 0); 638 p->g->iflags |= USEEOL; 639 p->g->neol++; 640 } 641 } 642 643 /* 644 * Top level parser, concatenation and BRE anchoring. 645 * Giving end1 as OUT essentially eliminates the end1/end2 check. 646 * 647 * This implementation is a bit of a kludge, in that a trailing $ is first 648 * taken as an ordinary character and then revised to be an anchor. 649 * The amount of lookahead needed to avoid this kludge is excessive. 650 */ 651 static void 652 p_re(struct parse *p, 653 int end1, /* first terminating character */ 654 int end2) /* second terminating character; ignored for EREs */ 655 { 656 struct branchc bc; 657 658 bc.nbranch = 0; 659 if (end1 == OUT && end2 == OUT) 660 bc.outer = true; 661 else 662 bc.outer = false; 663 #define SEEEND() (!p->bre ? SEE(end1) : SEETWO(end1, end2)) 664 for (;;) { 665 bc.start = HERE(); 666 bc.nchain = 0; 667 bc.terminate = false; 668 if (p->pre_parse != NULL) 669 p->pre_parse(p, &bc); 670 while (MORE() && (!p->allowbranch || !SEESPEC('|')) && 671 !SEEEND()) { 672 bc.terminate = p->parse_expr(p, &bc); 673 ++bc.nchain; 674 } 675 if (p->post_parse != NULL) 676 p->post_parse(p, &bc); 677 (void) REQUIRE(HERE() != bc.start, REG_BADPAT); 678 if (!p->allowbranch) 679 break; 680 /* 681 * p_branch_do's return value indicates whether we should 682 * continue parsing or not. This is both for correctness and 683 * a slight optimization, because it will check if we've 684 * encountered an empty branch or the end of the string 685 * immediately following a branch delimiter. 686 */ 687 if (!p_branch_do(p, &bc)) 688 break; 689 } 690 #undef SEE_END 691 if (p->allowbranch) 692 p_branch_fix_tail(p, &bc); 693 assert(!MORE() || SEE(end1)); 694 } 695 696 /* 697 * p_simp_re - parse a simple RE, an atom possibly followed by a repetition 698 */ 699 static bool /* was the simple RE an unbackslashed $? */ 700 p_simp_re(struct parse *p, struct branchc *bc) 701 { 702 int c; 703 int count; 704 int count2; 705 sopno pos; 706 int i; 707 wint_t wc; 708 sopno subno; 709 #define BACKSL (1<<CHAR_BIT) 710 711 pos = HERE(); /* repetition op, if any, covers from here */ 712 713 assert(MORE()); /* caller should have ensured this */ 714 c = GETNEXT(); 715 if (c == '\\') { 716 (void) REQUIRE(MORE(), REG_EESCAPE); 717 c = BACKSL | GETNEXT(); 718 } 719 switch (c) { 720 case '.': 721 if (p->g->cflags®_NEWLINE) 722 nonnewline(p); 723 else 724 EMIT(OANY, 0); 725 break; 726 case '[': 727 p_bracket(p); 728 break; 729 case BACKSL|'<': 730 EMIT(OBOW, 0); 731 break; 732 case BACKSL|'>': 733 EMIT(OEOW, 0); 734 break; 735 case BACKSL|'{': 736 SETERROR(REG_BADRPT); 737 break; 738 case BACKSL|'(': 739 p->g->nsub++; 740 subno = p->g->nsub; 741 if (subno < NPAREN) 742 p->pbegin[subno] = HERE(); 743 EMIT(OLPAREN, subno); 744 /* the MORE here is an error heuristic */ 745 if (MORE() && !SEETWO('\\', ')')) 746 p_re(p, '\\', ')'); 747 if (subno < NPAREN) { 748 p->pend[subno] = HERE(); 749 assert(p->pend[subno] != 0); 750 } 751 EMIT(ORPAREN, subno); 752 (void) REQUIRE(EATTWO('\\', ')'), REG_EPAREN); 753 break; 754 case BACKSL|')': /* should not get here -- must be user */ 755 SETERROR(REG_EPAREN); 756 break; 757 case BACKSL|'1': 758 case BACKSL|'2': 759 case BACKSL|'3': 760 case BACKSL|'4': 761 case BACKSL|'5': 762 case BACKSL|'6': 763 case BACKSL|'7': 764 case BACKSL|'8': 765 case BACKSL|'9': 766 i = (c&~BACKSL) - '0'; 767 assert(i < NPAREN); 768 if (p->pend[i] != 0) { 769 assert(i <= p->g->nsub); 770 EMIT(OBACK_, i); 771 assert(p->pbegin[i] != 0); 772 assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); 773 assert(OP(p->strip[p->pend[i]]) == ORPAREN); 774 (void) dupl(p, p->pbegin[i]+1, p->pend[i]); 775 EMIT(O_BACK, i); 776 } else 777 SETERROR(REG_ESUBREG); 778 p->g->backrefs = 1; 779 break; 780 case '*': 781 /* 782 * Ordinary if used as the first character beyond BOL anchor of 783 * a (sub-)expression, counts as a bad repetition operator if it 784 * appears otherwise. 785 */ 786 (void) REQUIRE(bc->nchain == 0, REG_BADRPT); 787 /* FALLTHROUGH */ 788 default: 789 if (p->error != 0) 790 return (false); /* Definitely not $... */ 791 p->next--; 792 wc = WGETNEXT(); 793 ordinary(p, wc); 794 break; 795 } 796 797 if (EAT('*')) { /* implemented as +? */ 798 /* this case does not require the (y|) trick, noKLUDGE */ 799 INSERT(OPLUS_, pos); 800 ASTERN(O_PLUS, pos); 801 INSERT(OQUEST_, pos); 802 ASTERN(O_QUEST, pos); 803 } else if (EATTWO('\\', '{')) { 804 count = p_count(p); 805 if (EAT(',')) { 806 if (MORE() && isdigit((uch)PEEK())) { 807 count2 = p_count(p); 808 (void) REQUIRE(count <= count2, REG_BADBR); 809 } else /* single number with comma */ 810 count2 = INFINITY; 811 } else /* just a single number */ 812 count2 = count; 813 repeat(p, pos, count, count2); 814 if (!EATTWO('\\', '}')) { /* error heuristics */ 815 while (MORE() && !SEETWO('\\', '}')) 816 NEXT(); 817 (void) REQUIRE(MORE(), REG_EBRACE); 818 SETERROR(REG_BADBR); 819 } 820 } else if (c == '$') /* $ (but not \$) ends it */ 821 return (true); 822 823 return (false); 824 } 825 826 /* 827 * p_count - parse a repetition count 828 */ 829 static int /* the value */ 830 p_count(struct parse *p) 831 { 832 int count = 0; 833 int ndigits = 0; 834 835 while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) { 836 count = count*10 + (GETNEXT() - '0'); 837 ndigits++; 838 } 839 840 (void) REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); 841 return (count); 842 } 843 844 /* 845 * p_bracket - parse a bracketed character list 846 */ 847 static void 848 p_bracket(struct parse *p) 849 { 850 cset *cs; 851 wint_t ch; 852 853 /* Dept of Truly Sickening Special-Case Kludges */ 854 if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) { 855 EMIT(OBOW, 0); 856 NEXTn(6); 857 return; 858 } 859 if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) { 860 EMIT(OEOW, 0); 861 NEXTn(6); 862 return; 863 } 864 865 if ((cs = allocset(p)) == NULL) 866 return; 867 868 if (p->g->cflags®_ICASE) 869 cs->icase = 1; 870 if (EAT('^')) 871 cs->invert = 1; 872 if (EAT(']')) 873 CHadd(p, cs, ']'); 874 else if (EAT('-')) 875 CHadd(p, cs, '-'); 876 while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) 877 p_b_term(p, cs); 878 if (EAT('-')) 879 CHadd(p, cs, '-'); 880 (void) MUSTEAT(']', REG_EBRACK); 881 882 if (p->error != 0) /* don't mess things up further */ 883 return; 884 885 if (cs->invert && p->g->cflags®_NEWLINE) 886 cs->bmp['\n' >> 3] |= 1 << ('\n' & 7); 887 888 if ((ch = singleton(p, cs)) != OUT) { /* optimize singleton sets */ 889 ordinary(p, ch); 890 freeset(p, cs); 891 } else 892 EMIT(OANYOF, (int)(cs - p->g->sets)); 893 } 894 895 /* 896 * p_b_term - parse one term of a bracketed character list 897 */ 898 static void 899 p_b_term(struct parse *p, cset *cs) 900 { 901 char c; 902 wint_t start, finish; 903 wint_t i; 904 locale_t loc = __curlocale(); 905 906 /* classify what we've got */ 907 switch ((MORE()) ? PEEK() : '\0') { 908 case '[': 909 c = (MORE2()) ? PEEK2() : '\0'; 910 break; 911 case '-': 912 SETERROR(REG_ERANGE); 913 return; /* NOTE RETURN */ 914 default: 915 c = '\0'; 916 break; 917 } 918 919 switch (c) { 920 case ':': /* character class */ 921 NEXT2(); 922 (void) REQUIRE(MORE(), REG_EBRACK); 923 c = PEEK(); 924 (void) REQUIRE(c != '-' && c != ']', REG_ECTYPE); 925 p_b_cclass(p, cs); 926 (void) REQUIRE(MORE(), REG_EBRACK); 927 (void) REQUIRE(EATTWO(':', ']'), REG_ECTYPE); 928 break; 929 case '=': /* equivalence class */ 930 NEXT2(); 931 (void) REQUIRE(MORE(), REG_EBRACK); 932 c = PEEK(); 933 (void) REQUIRE(c != '-' && c != ']', REG_ECOLLATE); 934 p_b_eclass(p, cs); 935 (void) REQUIRE(MORE(), REG_EBRACK); 936 (void) REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); 937 break; 938 default: /* symbol, ordinary character, or range */ 939 start = p_b_symbol(p); 940 if (SEE('-') && MORE2() && PEEK2() != ']') { 941 /* range */ 942 NEXT(); 943 if (EAT('-')) 944 finish = '-'; 945 else 946 finish = p_b_symbol(p); 947 } else 948 finish = start; 949 if (start == finish) 950 CHadd(p, cs, start); 951 else { 952 if (loc->collate->lc_is_posix) { 953 (void) REQUIRE((uch)start <= (uch)finish, 954 REG_ERANGE); 955 CHaddrange(p, cs, start, finish); 956 } else { 957 (void) REQUIRE(_collate_range_cmp(start, 958 finish, loc) <= 0, REG_ERANGE); 959 for (i = 0; i <= UCHAR_MAX; i++) { 960 if (_collate_range_cmp(start, i, loc) 961 <= 0 && 962 _collate_range_cmp(i, finish, loc) 963 <= 0) 964 CHadd(p, cs, i); 965 } 966 } 967 } 968 break; 969 } 970 } 971 972 /* 973 * p_b_cclass - parse a character-class name and deal with it 974 */ 975 static void 976 p_b_cclass(struct parse *p, cset *cs) 977 { 978 const char *sp = p->next; 979 size_t len; 980 wctype_t wct; 981 char clname[16]; 982 983 while (MORE() && isalpha((uch)PEEK())) 984 NEXT(); 985 len = p->next - sp; 986 if (len >= sizeof (clname) - 1) { 987 SETERROR(REG_ECTYPE); 988 return; 989 } 990 (void) memcpy(clname, sp, len); 991 clname[len] = '\0'; 992 if ((wct = wctype(clname)) == 0) { 993 SETERROR(REG_ECTYPE); 994 return; 995 } 996 CHaddtype(p, cs, wct); 997 } 998 999 /* 1000 * p_b_eclass - parse an equivalence-class name and deal with it 1001 * 1002 * This implementation is incomplete. xxx 1003 */ 1004 static void 1005 p_b_eclass(struct parse *p, cset *cs) 1006 { 1007 wint_t c; 1008 1009 c = p_b_coll_elem(p, '='); 1010 CHadd(p, cs, c); 1011 } 1012 1013 /* 1014 * p_b_symbol - parse a character or [..]ed multicharacter collating symbol 1015 */ 1016 static wint_t /* value of symbol */ 1017 p_b_symbol(struct parse *p) 1018 { 1019 wint_t value; 1020 1021 (void) REQUIRE(MORE(), REG_EBRACK); 1022 if (!EATTWO('[', '.')) 1023 return (WGETNEXT()); 1024 1025 /* collating symbol */ 1026 value = p_b_coll_elem(p, '.'); 1027 (void) REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); 1028 return (value); 1029 } 1030 1031 /* 1032 * p_b_coll_elem - parse a collating-element name and look it up 1033 */ 1034 static wint_t /* value of collating element */ 1035 p_b_coll_elem(struct parse *p, 1036 wint_t endc) /* name ended by endc,']' */ 1037 { 1038 const char *sp = p->next; 1039 struct cname *cp; 1040 mbstate_t mbs; 1041 wchar_t wc; 1042 size_t clen, len; 1043 1044 while (MORE() && !SEETWO(endc, ']')) 1045 NEXT(); 1046 if (!MORE()) { 1047 SETERROR(REG_EBRACK); 1048 return (0); 1049 } 1050 len = p->next - sp; 1051 for (cp = cnames; cp->name != NULL; cp++) 1052 if (strncmp(cp->name, sp, len) == 0 && strlen(cp->name) == len) 1053 return (cp->code); /* known name */ 1054 (void) memset(&mbs, 0, sizeof (mbs)); 1055 if ((clen = mbrtowc(&wc, sp, len, &mbs)) == len) 1056 return (wc); /* single character */ 1057 else if (clen == (size_t)-1 || clen == (size_t)-2) 1058 SETERROR(REG_ECHAR); 1059 else 1060 SETERROR(REG_ECOLLATE); /* neither */ 1061 return (0); 1062 } 1063 1064 /* 1065 * othercase - return the case counterpart of an alphabetic 1066 */ 1067 static wint_t /* if no counterpart, return ch */ 1068 othercase(wint_t ch) 1069 { 1070 assert(iswalpha(ch)); 1071 if (iswupper(ch)) 1072 return (towlower(ch)); 1073 else if (iswlower(ch)) 1074 return (towupper(ch)); 1075 else /* peculiar, but could happen */ 1076 return (ch); 1077 } 1078 1079 /* 1080 * bothcases - emit a dualcase version of a two-case character 1081 * 1082 * Boy, is this implementation ever a kludge... 1083 */ 1084 static void 1085 bothcases(struct parse *p, wint_t ch) 1086 { 1087 const char *oldnext = p->next; 1088 const char *oldend = p->end; 1089 char bracket[3 + MB_LEN_MAX]; 1090 size_t n; 1091 mbstate_t mbs; 1092 1093 assert(othercase(ch) != ch); /* p_bracket() would recurse */ 1094 p->next = bracket; 1095 (void) memset(&mbs, 0, sizeof (mbs)); 1096 n = wcrtomb(bracket, ch, &mbs); 1097 assert(n != (size_t)-1); 1098 bracket[n] = ']'; 1099 bracket[n + 1] = '\0'; 1100 p->end = bracket+n+1; 1101 p_bracket(p); 1102 assert(p->next == p->end); 1103 p->next = oldnext; 1104 p->end = oldend; 1105 } 1106 1107 /* 1108 * ordinary - emit an ordinary character 1109 */ 1110 static void 1111 ordinary(struct parse *p, wint_t ch) 1112 { 1113 cset *cs; 1114 1115 if ((p->g->cflags®_ICASE) && iswalpha(ch) && othercase(ch) != ch) 1116 bothcases(p, ch); 1117 else if ((ch & OPDMASK) == ch) 1118 EMIT(OCHAR, ch); 1119 else { 1120 /* 1121 * Kludge: character is too big to fit into an OCHAR operand. 1122 * Emit a singleton set. 1123 */ 1124 if ((cs = allocset(p)) == NULL) 1125 return; 1126 CHadd(p, cs, ch); 1127 EMIT(OANYOF, (int)(cs - p->g->sets)); 1128 } 1129 } 1130 1131 /* 1132 * nonnewline - emit REG_NEWLINE version of OANY 1133 * 1134 * Boy, is this implementation ever a kludge... 1135 */ 1136 static void 1137 nonnewline(struct parse *p) 1138 { 1139 const char *oldnext = p->next; 1140 const char *oldend = p->end; 1141 char bracket[4]; 1142 1143 p->next = bracket; 1144 p->end = bracket+3; 1145 bracket[0] = '^'; 1146 bracket[1] = '\n'; 1147 bracket[2] = ']'; 1148 bracket[3] = '\0'; 1149 p_bracket(p); 1150 assert(p->next == bracket+3); 1151 p->next = oldnext; 1152 p->end = oldend; 1153 } 1154 1155 /* 1156 * repeat - generate code for a bounded repetition, recursively if needed 1157 */ 1158 static void 1159 repeat(struct parse *p, 1160 sopno start, /* operand from here to end of strip */ 1161 int from, /* repeated from this number */ 1162 int to) /* to this number of times (maybe INFINITY) */ 1163 { 1164 sopno finish = HERE(); 1165 #define N 2 1166 #define INF 3 1167 #define REP(f, t) ((f)*8 + (t)) 1168 #define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) 1169 sopno copy; 1170 1171 if (p->error != 0) /* head off possible runaway recursion */ 1172 return; 1173 1174 assert(from <= to); 1175 1176 switch (REP(MAP(from), MAP(to))) { 1177 case REP(0, 0): /* must be user doing this */ 1178 DROP(finish-start); /* drop the operand */ 1179 break; 1180 case REP(0, 1): /* as x{1,1}? */ 1181 case REP(0, N): /* as x{1,n}? */ 1182 case REP(0, INF): /* as x{1,}? */ 1183 /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ 1184 INSERT(OCH_, start); /* offset is wrong... */ 1185 repeat(p, start+1, 1, to); 1186 ASTERN(OOR1, start); 1187 AHEAD(start); /* ... fix it */ 1188 EMIT(OOR2, 0); 1189 AHEAD(THERE()); 1190 ASTERN(O_CH, THERETHERE()); 1191 break; 1192 case REP(1, 1): /* trivial case */ 1193 /* done */ 1194 break; 1195 case REP(1, N): /* as x?x{1,n-1} */ 1196 /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ 1197 INSERT(OCH_, start); 1198 ASTERN(OOR1, start); 1199 AHEAD(start); 1200 EMIT(OOR2, 0); /* offset very wrong... */ 1201 AHEAD(THERE()); /* ...so fix it */ 1202 ASTERN(O_CH, THERETHERE()); 1203 copy = dupl(p, start+1, finish+1); 1204 assert(copy == finish+4); 1205 repeat(p, copy, 1, to-1); 1206 break; 1207 case REP(1, INF): /* as x+ */ 1208 INSERT(OPLUS_, start); 1209 ASTERN(O_PLUS, start); 1210 break; 1211 case REP(N, N): /* as xx{m-1,n-1} */ 1212 copy = dupl(p, start, finish); 1213 repeat(p, copy, from-1, to-1); 1214 break; 1215 case REP(N, INF): /* as xx{n-1,INF} */ 1216 copy = dupl(p, start, finish); 1217 repeat(p, copy, from-1, to); 1218 break; 1219 default: /* "can't happen" */ 1220 SETERROR(REG_EFATAL); /* just in case */ 1221 break; 1222 } 1223 } 1224 1225 /* 1226 * wgetnext - helper function for WGETNEXT() macro. Gets the next wide 1227 * character from the parse struct, signals a REG_ILLSEQ error if the 1228 * character can't be converted. Returns the number of bytes consumed. 1229 */ 1230 static wint_t 1231 wgetnext(struct parse *p) 1232 { 1233 mbstate_t mbs; 1234 wchar_t wc; 1235 size_t n; 1236 1237 (void) memset(&mbs, 0, sizeof (mbs)); 1238 n = mbrtowc(&wc, p->next, p->end - p->next, &mbs); 1239 if (n == (size_t)-1 || n == (size_t)-2) { 1240 SETERROR(REG_ECHAR); 1241 return (0); 1242 } 1243 if (n == 0) 1244 n = 1; 1245 p->next += n; 1246 return (wc); 1247 } 1248 1249 /* 1250 * seterr - set an error condition 1251 */ 1252 static int /* useless but makes type checking happy */ 1253 seterr(struct parse *p, int e) 1254 { 1255 if (p->error == 0) /* keep earliest error condition */ 1256 p->error = e; 1257 p->next = nuls; /* try to bring things to a halt */ 1258 p->end = nuls; 1259 return (0); /* make the return value well-defined */ 1260 } 1261 1262 /* 1263 * allocset - allocate a set of characters for [] 1264 */ 1265 static cset * 1266 allocset(struct parse *p) 1267 { 1268 cset *cs, *ncs; 1269 1270 ncs = realloc(p->g->sets, (p->g->ncsets + 1) * sizeof (*ncs)); 1271 if (ncs == NULL) { 1272 SETERROR(REG_ESPACE); 1273 return (NULL); 1274 } 1275 p->g->sets = ncs; 1276 cs = &p->g->sets[p->g->ncsets++]; 1277 (void) memset(cs, 0, sizeof (*cs)); 1278 1279 return (cs); 1280 } 1281 1282 /* 1283 * freeset - free a now-unused set 1284 */ 1285 static void 1286 freeset(struct parse *p, cset *cs) 1287 { 1288 cset *top = &p->g->sets[p->g->ncsets]; 1289 1290 free(cs->wides); 1291 free(cs->ranges); 1292 free(cs->types); 1293 (void) memset(cs, 0, sizeof (*cs)); 1294 if (cs == top-1) /* recover only the easy case */ 1295 p->g->ncsets--; 1296 } 1297 1298 /* 1299 * singleton - Determine whether a set contains only one character, 1300 * returning it if so, otherwise returning OUT. 1301 */ 1302 static wint_t 1303 singleton(struct parse *p, cset *cs) 1304 { 1305 wint_t i, s, n; 1306 1307 /* Exclude the complicated cases we don't want to deal with */ 1308 if (cs->nranges != 0 || cs->ntypes != 0 || cs->icase != 0) 1309 return (OUT); 1310 1311 if (cs->nwides > 1) 1312 return (OUT); 1313 1314 /* Count the number of characters present in the bitmap */ 1315 for (i = n = 0; i < p->nc; i++) 1316 if (CHIN(p->nc, cs, i)) { 1317 n++; 1318 s = i; 1319 } 1320 1321 if (n > 1) 1322 return (OUT); 1323 1324 if (n == 1) { 1325 if (cs->nwides == 0) 1326 return (s); 1327 else 1328 return (OUT); 1329 } 1330 if (cs->nwides == 1) 1331 return (cs->wides[0]); 1332 1333 return (OUT); 1334 } 1335 1336 /* 1337 * CHadd - add character to character set. 1338 */ 1339 static void 1340 CHadd(struct parse *p, cset *cs, wint_t ch) 1341 { 1342 wint_t nch, *newwides; 1343 assert(ch >= 0); 1344 if (ch < p->nc) 1345 cs->bmp[ch >> 3] |= 1 << (ch & 7); 1346 else { 1347 newwides = realloc(cs->wides, (cs->nwides + 1) * 1348 sizeof (*cs->wides)); 1349 if (newwides == NULL) { 1350 SETERROR(REG_ESPACE); 1351 return; 1352 } 1353 cs->wides = newwides; 1354 cs->wides[cs->nwides++] = ch; 1355 } 1356 if (cs->icase) { 1357 if ((nch = towlower(ch)) < p->nc) 1358 cs->bmp[nch >> 3] |= 1 << (nch & 7); 1359 if ((nch = towupper(ch)) < p->nc) 1360 cs->bmp[nch >> 3] |= 1 << (nch & 7); 1361 } 1362 } 1363 1364 /* 1365 * CHaddrange - add all characters in the range [min,max] to a character set. 1366 */ 1367 static void 1368 CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max) 1369 { 1370 crange *newranges; 1371 1372 for (; min < p->nc && min <= max; min++) 1373 CHadd(p, cs, min); 1374 if (min >= max) 1375 return; 1376 newranges = realloc(cs->ranges, (cs->nranges + 1) * 1377 sizeof (*cs->ranges)); 1378 if (newranges == NULL) { 1379 SETERROR(REG_ESPACE); 1380 return; 1381 } 1382 cs->ranges = newranges; 1383 cs->ranges[cs->nranges].min = min; 1384 cs->ranges[cs->nranges].max = max; 1385 cs->nranges++; 1386 } 1387 1388 /* 1389 * CHaddtype - add all characters of a certain type to a character set. 1390 */ 1391 static void 1392 CHaddtype(struct parse *p, cset *cs, wctype_t wct) 1393 { 1394 wint_t i; 1395 wctype_t *newtypes; 1396 1397 for (i = 0; i < p->nc; i++) 1398 if (iswctype(i, wct)) 1399 CHadd(p, cs, i); 1400 newtypes = realloc(cs->types, (cs->ntypes + 1) * 1401 sizeof (*cs->types)); 1402 if (newtypes == NULL) { 1403 SETERROR(REG_ESPACE); 1404 return; 1405 } 1406 cs->types = newtypes; 1407 cs->types[cs->ntypes++] = wct; 1408 } 1409 1410 /* 1411 * dupl - emit a duplicate of a bunch of sops 1412 */ 1413 static sopno /* start of duplicate */ 1414 dupl(struct parse *p, 1415 sopno start, /* from here */ 1416 sopno finish) /* to this less one */ 1417 { 1418 sopno ret = HERE(); 1419 sopno len = finish - start; 1420 1421 assert(finish >= start); 1422 if (len == 0) 1423 return (ret); 1424 if (!enlarge(p, p->ssize + len)) /* this many unexpected additions */ 1425 return (ret); 1426 assert(p->ssize >= p->slen + len); 1427 (void) memcpy((char *)(p->strip + p->slen), 1428 (char *)(p->strip + start), (size_t)len*sizeof (sop)); 1429 p->slen += len; 1430 return (ret); 1431 } 1432 1433 /* 1434 * doemit - emit a strip operator 1435 * 1436 * It might seem better to implement this as a macro with a function as 1437 * hard-case backup, but it's just too big and messy unless there are 1438 * some changes to the data structures. Maybe later. 1439 */ 1440 static void 1441 doemit(struct parse *p, sop op, size_t opnd) 1442 { 1443 /* avoid making error situations worse */ 1444 if (p->error != 0) 1445 return; 1446 1447 /* deal with oversize operands ("can't happen", more or less) */ 1448 assert(opnd < 1<<OPSHIFT); 1449 1450 /* deal with undersized strip */ 1451 if (p->slen >= p->ssize) 1452 if (!enlarge(p, (p->ssize+1) / 2 * 3)) /* +50% */ 1453 return; 1454 1455 /* finally, it's all reduced to the easy case */ 1456 p->strip[p->slen++] = SOP(op, opnd); 1457 } 1458 1459 /* 1460 * doinsert - insert a sop into the strip 1461 */ 1462 static void 1463 doinsert(struct parse *p, sop op, size_t opnd, sopno pos) 1464 { 1465 sopno sn; 1466 sop s; 1467 int i; 1468 1469 /* avoid making error situations worse */ 1470 if (p->error != 0) 1471 return; 1472 1473 sn = HERE(); 1474 EMIT(op, opnd); /* do checks, ensure space */ 1475 assert(HERE() == sn+1); 1476 s = p->strip[sn]; 1477 1478 /* adjust paren pointers */ 1479 assert(pos > 0); 1480 for (i = 1; i < NPAREN; i++) { 1481 if (p->pbegin[i] >= pos) { 1482 p->pbegin[i]++; 1483 } 1484 if (p->pend[i] >= pos) { 1485 p->pend[i]++; 1486 } 1487 } 1488 1489 (void) memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], 1490 (HERE()-pos-1)*sizeof (sop)); 1491 p->strip[pos] = s; 1492 } 1493 1494 /* 1495 * dofwd - complete a forward reference 1496 */ 1497 static void 1498 dofwd(struct parse *p, sopno pos, sop value) 1499 { 1500 /* avoid making error situations worse */ 1501 if (p->error != 0) 1502 return; 1503 1504 assert(value < 1<<OPSHIFT); 1505 p->strip[pos] = OP(p->strip[pos]) | value; 1506 } 1507 1508 /* 1509 * enlarge - enlarge the strip 1510 */ 1511 static int 1512 enlarge(struct parse *p, sopno size) 1513 { 1514 sop *sp; 1515 1516 if (p->ssize >= size) 1517 return (1); 1518 1519 sp = (sop *)realloc(p->strip, size*sizeof (sop)); 1520 if (sp == NULL) { 1521 SETERROR(REG_ESPACE); 1522 return (0); 1523 } 1524 p->strip = sp; 1525 p->ssize = size; 1526 return (1); 1527 } 1528 1529 /* 1530 * stripsnug - compact the strip 1531 */ 1532 static void 1533 stripsnug(struct parse *p, struct re_guts *g) 1534 { 1535 g->nstates = p->slen; 1536 g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof (sop)); 1537 if (g->strip == NULL) { 1538 SETERROR(REG_ESPACE); 1539 g->strip = p->strip; 1540 } 1541 } 1542 1543 /* 1544 * findmust - fill in must and mlen with longest mandatory literal string 1545 * 1546 * This algorithm could do fancy things like analyzing the operands of | 1547 * for common subsequences. Someday. This code is simple and finds most 1548 * of the interesting cases. 1549 * 1550 * Note that must and mlen got initialized during setup. 1551 */ 1552 static void 1553 findmust(struct parse *p, struct re_guts *g) 1554 { 1555 sop *scan; 1556 sop *start = NULL; 1557 sop *newstart = NULL; 1558 sopno newlen; 1559 sop s; 1560 char *cp; 1561 int offset; 1562 char buf[MB_LEN_MAX]; 1563 size_t clen; 1564 mbstate_t mbs; 1565 locale_t loc = __curlocale(); 1566 1567 /* avoid making error situations worse */ 1568 if (p->error != 0) 1569 return; 1570 1571 /* 1572 * It's not generally safe to do a ``char'' substring search on 1573 * multibyte character strings, but it's safe for at least 1574 * UTF-8 (see RFC 3629). 1575 */ 1576 if (g->mb_cur_max > 1 && 1577 strcmp(loc->runelocale->__encoding, "UTF-8") != 0) 1578 return; 1579 1580 /* find the longest OCHAR sequence in strip */ 1581 newlen = 0; 1582 offset = 0; 1583 g->moffset = 0; 1584 scan = g->strip + 1; 1585 do { 1586 s = *scan++; 1587 switch (OP(s)) { 1588 case OCHAR: /* sequence member */ 1589 if (newlen == 0) { /* new sequence */ 1590 (void) memset(&mbs, 0, sizeof (mbs)); 1591 newstart = scan - 1; 1592 } 1593 clen = wcrtomb(buf, OPND(s), &mbs); 1594 if (clen == (size_t)-1) 1595 goto toohard; 1596 newlen += clen; 1597 break; 1598 case OPLUS_: /* things that don't break one */ 1599 case OLPAREN: 1600 case ORPAREN: 1601 break; 1602 case OQUEST_: /* things that must be skipped */ 1603 case OCH_: 1604 offset = altoffset(scan, offset); 1605 scan--; 1606 do { 1607 scan += OPND(s); 1608 s = *scan; 1609 /* assert() interferes w debug printouts */ 1610 if (OP(s) != (sop)O_QUEST && 1611 OP(s) != (sop)O_CH && OP(s) != (sop)OOR2) { 1612 g->iflags |= BAD; 1613 return; 1614 } 1615 } while (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH); 1616 /* FALLTHROUGH */ 1617 case OBOW: /* things that break a sequence */ 1618 case OEOW: 1619 case OBOL: 1620 case OEOL: 1621 case O_QUEST: 1622 case O_CH: 1623 case OEND: 1624 if (newlen > (sopno)g->mlen) { /* ends one */ 1625 start = newstart; 1626 g->mlen = newlen; 1627 if (offset > -1) { 1628 g->moffset += offset; 1629 offset = newlen; 1630 } else 1631 g->moffset = offset; 1632 } else { 1633 if (offset > -1) 1634 offset += newlen; 1635 } 1636 newlen = 0; 1637 break; 1638 case OANY: 1639 if (newlen > (sopno)g->mlen) { /* ends one */ 1640 start = newstart; 1641 g->mlen = newlen; 1642 if (offset > -1) { 1643 g->moffset += offset; 1644 offset = newlen; 1645 } else 1646 g->moffset = offset; 1647 } else { 1648 if (offset > -1) 1649 offset += newlen; 1650 } 1651 if (offset > -1) 1652 offset++; 1653 newlen = 0; 1654 break; 1655 case OANYOF: /* may or may not invalidate offset */ 1656 /* First, everything as OANY */ 1657 if (newlen > (sopno)g->mlen) { /* ends one */ 1658 start = newstart; 1659 g->mlen = newlen; 1660 if (offset > -1) { 1661 g->moffset += offset; 1662 offset = newlen; 1663 } else 1664 g->moffset = offset; 1665 } else { 1666 if (offset > -1) 1667 offset += newlen; 1668 } 1669 if (offset > -1) 1670 offset++; 1671 newlen = 0; 1672 break; 1673 toohard: 1674 default: 1675 /* 1676 * Anything here makes it impossible or too hard 1677 * to calculate the offset -- so we give up; 1678 * save the last known good offset, in case the 1679 * must sequence doesn't occur later. 1680 */ 1681 if (newlen > (sopno)g->mlen) { /* ends one */ 1682 start = newstart; 1683 g->mlen = newlen; 1684 if (offset > -1) 1685 g->moffset += offset; 1686 else 1687 g->moffset = offset; 1688 } 1689 offset = -1; 1690 newlen = 0; 1691 break; 1692 } 1693 } while (OP(s) != OEND); 1694 1695 if (g->mlen == 0) { /* there isn't one */ 1696 g->moffset = -1; 1697 return; 1698 } 1699 1700 /* turn it into a character string */ 1701 g->must = malloc((size_t)g->mlen + 1); 1702 if (g->must == NULL) { /* argh; just forget it */ 1703 g->mlen = 0; 1704 g->moffset = -1; 1705 return; 1706 } 1707 cp = g->must; 1708 scan = start; 1709 (void) memset(&mbs, 0, sizeof (mbs)); 1710 while (cp < g->must + g->mlen) { 1711 while (OP(s = *scan++) != OCHAR) 1712 continue; 1713 clen = wcrtomb(cp, OPND(s), &mbs); 1714 assert(clen != (size_t)-1); 1715 cp += clen; 1716 } 1717 assert(cp == g->must + g->mlen); 1718 *cp++ = '\0'; /* just on general principles */ 1719 } 1720 1721 /* 1722 * altoffset - choose biggest offset among multiple choices 1723 * 1724 * Compute, recursively if necessary, the largest offset among multiple 1725 * re paths. 1726 */ 1727 static int 1728 altoffset(sop *scan, int offset) 1729 { 1730 int largest; 1731 int try; 1732 sop s; 1733 1734 /* If we gave up already on offsets, return */ 1735 if (offset == -1) 1736 return (-1); 1737 1738 largest = 0; 1739 try = 0; 1740 s = *scan++; 1741 while (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH) { 1742 switch (OP(s)) { 1743 case OOR1: 1744 if (try > largest) 1745 largest = try; 1746 try = 0; 1747 break; 1748 case OQUEST_: 1749 case OCH_: 1750 try = altoffset(scan, try); 1751 if (try == -1) 1752 return (-1); 1753 scan--; 1754 do { 1755 scan += OPND(s); 1756 s = *scan; 1757 if (OP(s) != (sop)O_QUEST && 1758 OP(s) != (sop)O_CH && OP(s) != (sop)OOR2) 1759 return (-1); 1760 } while (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH); 1761 /* 1762 * We must skip to the next position, or we'll 1763 * leave altoffset() too early. 1764 */ 1765 scan++; 1766 break; 1767 case OANYOF: 1768 case OCHAR: 1769 case OANY: 1770 try++; 1771 /*FALLTHRU*/ 1772 case OBOW: 1773 case OEOW: 1774 case OLPAREN: 1775 case ORPAREN: 1776 case OOR2: 1777 break; 1778 default: 1779 try = -1; 1780 break; 1781 } 1782 if (try == -1) 1783 return (-1); 1784 s = *scan++; 1785 } 1786 1787 if (try > largest) 1788 largest = try; 1789 1790 return (largest+offset); 1791 } 1792 1793 /* 1794 * computejumps - compute char jumps for BM scan 1795 * 1796 * This algorithm assumes g->must exists and is has size greater than 1797 * zero. It's based on the algorithm found on Computer Algorithms by 1798 * Sara Baase. 1799 * 1800 * A char jump is the number of characters one needs to jump based on 1801 * the value of the character from the text that was mismatched. 1802 */ 1803 static void 1804 computejumps(struct parse *p, struct re_guts *g) 1805 { 1806 int ch; 1807 int mindex; 1808 1809 /* Avoid making errors worse */ 1810 if (p->error != 0) 1811 return; 1812 1813 g->charjump = (int *)malloc((NC_MAX + 1) * sizeof (int)); 1814 if (g->charjump == NULL) /* Not a fatal error */ 1815 return; 1816 /* Adjust for signed chars, if necessary */ 1817 g->charjump = &g->charjump[-(CHAR_MIN)]; 1818 1819 /* 1820 * If the character does not exist in the pattern, the jump 1821 * is equal to the number of characters in the pattern. 1822 */ 1823 for (ch = CHAR_MIN; ch < (CHAR_MAX + 1); ch++) 1824 g->charjump[ch] = g->mlen; 1825 1826 /* 1827 * If the character does exist, compute the jump that would 1828 * take us to the last character in the pattern equal to it 1829 * (notice that we match right to left, so that last character 1830 * is the first one that would be matched). 1831 */ 1832 for (mindex = 0; mindex < g->mlen; mindex++) 1833 g->charjump[(int)g->must[mindex]] = g->mlen - mindex - 1; 1834 } 1835 1836 /* 1837 * computematchjumps - compute match jumps for BM scan 1838 * 1839 * This algorithm assumes g->must exists and is has size greater than 1840 * zero. It's based on the algorithm found on Computer Algorithms by 1841 * Sara Baase. 1842 * 1843 * A match jump is the number of characters one needs to advance based 1844 * on the already-matched suffix. 1845 * Notice that all values here are minus (g->mlen-1), because of the way 1846 * the search algorithm works. 1847 */ 1848 static void 1849 computematchjumps(struct parse *p, struct re_guts *g) 1850 { 1851 int mindex; /* General "must" iterator */ 1852 int suffix; /* Keeps track of matching suffix */ 1853 int ssuffix; /* Keeps track of suffixes' suffix */ 1854 int *pmatches; 1855 /* 1856 * pmatches[k] points to the next i 1857 * such that i+1...mlen is a substring 1858 * of k+1...k+mlen-i-1 1859 */ 1860 1861 /* calm static analyzer, see comment above */ 1862 if (g->mlen < 1) 1863 return; 1864 1865 /* Avoid making errors worse */ 1866 if (p->error != 0) 1867 return; 1868 1869 pmatches = (int *)malloc(g->mlen * sizeof (unsigned int)); 1870 if (pmatches == NULL) { 1871 g->matchjump = NULL; 1872 return; 1873 } 1874 1875 g->matchjump = (int *)malloc(g->mlen * sizeof (unsigned int)); 1876 if (g->matchjump == NULL) { /* Not a fatal error */ 1877 free(pmatches); 1878 return; 1879 } 1880 1881 /* Set maximum possible jump for each character in the pattern */ 1882 for (mindex = 0; mindex < g->mlen; mindex++) 1883 g->matchjump[mindex] = 2*g->mlen - mindex - 1; 1884 1885 /* Compute pmatches[] */ 1886 for (mindex = g->mlen - 1, suffix = g->mlen; mindex >= 0; 1887 mindex--, suffix--) { 1888 pmatches[mindex] = suffix; 1889 1890 /* 1891 * If a mismatch is found, interrupting the substring, 1892 * compute the matchjump for that position. If no 1893 * mismatch is found, then a text substring mismatched 1894 * against the suffix will also mismatch against the 1895 * substring. 1896 */ 1897 while (suffix < g->mlen && g->must[mindex] != g->must[suffix]) { 1898 g->matchjump[suffix] = MIN(g->matchjump[suffix], 1899 g->mlen - mindex - 1); 1900 suffix = pmatches[suffix]; 1901 } 1902 } 1903 1904 /* 1905 * Compute the matchjump up to the last substring found to jump 1906 * to the beginning of the largest must pattern prefix matching 1907 * it's own suffix. 1908 */ 1909 for (mindex = 0; mindex <= suffix; mindex++) 1910 g->matchjump[mindex] = MIN(g->matchjump[mindex], 1911 g->mlen + suffix - mindex); 1912 1913 ssuffix = pmatches[suffix]; 1914 while (suffix < g->mlen) { 1915 while (suffix <= ssuffix && suffix < g->mlen) { 1916 g->matchjump[suffix] = MIN(g->matchjump[suffix], 1917 g->mlen + ssuffix - suffix); 1918 suffix++; 1919 } 1920 if (suffix < g->mlen) 1921 ssuffix = pmatches[ssuffix]; 1922 } 1923 1924 free(pmatches); 1925 } 1926 1927 /* 1928 * pluscount - count + nesting 1929 */ 1930 static sopno /* nesting depth */ 1931 pluscount(struct parse *p, struct re_guts *g) 1932 { 1933 sop *scan; 1934 sop s; 1935 sopno plusnest = 0; 1936 sopno maxnest = 0; 1937 1938 if (p->error != 0) 1939 return (0); /* there may not be an OEND */ 1940 1941 scan = g->strip + 1; 1942 do { 1943 s = *scan++; 1944 switch (OP(s)) { 1945 case OPLUS_: 1946 plusnest++; 1947 break; 1948 case O_PLUS: 1949 if (plusnest > maxnest) 1950 maxnest = plusnest; 1951 plusnest--; 1952 break; 1953 } 1954 } while (OP(s) != OEND); 1955 if (plusnest != 0) 1956 g->iflags |= BAD; 1957 return (maxnest); 1958 } 1959