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