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