libregexp.c (113209B)
1 /* 2 * Regular Expression Engine 3 * 4 * Copyright (c) 2017-2018 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 #include <stdlib.h> 25 #include <stdio.h> 26 #include <stdarg.h> 27 #include <inttypes.h> 28 #include <string.h> 29 #include <assert.h> 30 31 #include "cutils.h" 32 #include "libregexp.h" 33 #include "libunicode.h" 34 35 /* 36 TODO: 37 - remove REOP_char_i and REOP_range_i by precomputing the case folding. 38 - add specific opcodes for simple unicode property tests so that the 39 generated bytecode is smaller. 40 - Add a lock step execution mode (=linear time execution guaranteed) 41 when the regular expression is "simple" i.e. no backreference nor 42 complicated lookahead. The opcodes are designed for this execution 43 model. 44 */ 45 46 #if defined(TEST) 47 #define DUMP_REOP 48 #endif 49 //#define DUMP_REOP 50 //#define DUMP_EXEC 51 52 typedef enum { 53 #define DEF(id, size) REOP_ ## id, 54 #include "libregexp-opcode.h" 55 #undef DEF 56 REOP_COUNT, 57 } REOPCodeEnum; 58 59 #define CAPTURE_COUNT_MAX 255 60 #define REGISTER_COUNT_MAX 255 61 /* must be large enough to have a negligible runtime cost and small 62 enough to call the interrupt callback often. */ 63 #define INTERRUPT_COUNTER_INIT 10000 64 65 /* unicode code points */ 66 #define CP_LS 0x2028 67 #define CP_PS 0x2029 68 69 #define TMP_BUF_SIZE 128 70 71 typedef struct { 72 DynBuf byte_code; 73 const uint8_t *buf_ptr; 74 const uint8_t *buf_end; 75 const uint8_t *buf_start; 76 int re_flags; 77 BOOL is_unicode; 78 BOOL unicode_sets; /* if set, is_unicode is also set */ 79 BOOL ignore_case; 80 BOOL multi_line; 81 BOOL dotall; 82 uint8_t group_name_scope; 83 int capture_count; 84 int total_capture_count; /* -1 = not computed yet */ 85 int has_named_captures; /* -1 = don't know, 0 = no, 1 = yes */ 86 void *opaque; 87 DynBuf group_names; 88 union { 89 char error_msg[TMP_BUF_SIZE]; 90 char tmp_buf[TMP_BUF_SIZE]; 91 } u; 92 } REParseState; 93 94 typedef struct { 95 #ifdef DUMP_REOP 96 const char *name; 97 #endif 98 uint8_t size; 99 } REOpCode; 100 101 static const REOpCode reopcode_info[REOP_COUNT] = { 102 #ifdef DUMP_REOP 103 #define DEF(id, size) { #id, size }, 104 #else 105 #define DEF(id, size) { size }, 106 #endif 107 #include "libregexp-opcode.h" 108 #undef DEF 109 }; 110 111 #define RE_HEADER_FLAGS 0 112 #define RE_HEADER_CAPTURE_COUNT 2 113 #define RE_HEADER_REGISTER_COUNT 3 114 #define RE_HEADER_BYTECODE_LEN 4 115 116 #define RE_HEADER_LEN 8 117 118 static inline int is_digit(int c) { 119 return c >= '0' && c <= '9'; 120 } 121 122 /* insert 'len' bytes at position 'pos'. Return < 0 if error. */ 123 static int dbuf_insert(DynBuf *s, int pos, int len) 124 { 125 if (dbuf_claim(s, len)) 126 return -1; 127 memmove(s->buf + pos + len, s->buf + pos, s->size - pos); 128 s->size += len; 129 return 0; 130 } 131 132 typedef struct REString { 133 struct REString *next; 134 uint32_t hash; 135 uint32_t len; 136 uint32_t buf[]; 137 } REString; 138 139 typedef struct { 140 /* the string list is the union of 'char_range' and of the strings 141 in hash_table[]. The strings in hash_table[] have a length != 142 1. */ 143 CharRange cr; 144 uint32_t n_strings; 145 uint32_t hash_size; 146 int hash_bits; 147 REString **hash_table; 148 } REStringList; 149 150 static uint32_t re_string_hash(int len, const uint32_t *buf) 151 { 152 int i; 153 uint32_t h; 154 h = 1; 155 for(i = 0; i < len; i++) 156 h = h * 263 + buf[i]; 157 return h * 0x61C88647; 158 } 159 160 static void re_string_list_init(REParseState *s1, REStringList *s) 161 { 162 cr_init(&s->cr, s1->opaque, lre_realloc); 163 s->n_strings = 0; 164 s->hash_size = 0; 165 s->hash_bits = 0; 166 s->hash_table = NULL; 167 } 168 169 static void re_string_list_free(REStringList *s) 170 { 171 REString *p, *p_next; 172 int i; 173 for(i = 0; i < s->hash_size; i++) { 174 for(p = s->hash_table[i]; p != NULL; p = p_next) { 175 p_next = p->next; 176 lre_realloc(s->cr.mem_opaque, p, 0); 177 } 178 } 179 lre_realloc(s->cr.mem_opaque, s->hash_table, 0); 180 181 cr_free(&s->cr); 182 } 183 184 static void lre_print_char(int c, BOOL is_range) 185 { 186 if (c == '\'' || c == '\\' || 187 (is_range && (c == '-' || c == ']'))) { 188 printf("\\%c", c); 189 } else if (c >= ' ' && c <= 126) { 190 printf("%c", c); 191 } else { 192 printf("\\u{%04x}", c); 193 } 194 } 195 196 static __maybe_unused void re_string_list_dump(const char *str, const REStringList *s) 197 { 198 REString *p; 199 const CharRange *cr; 200 int i, j, k; 201 202 printf("%s:\n", str); 203 printf(" ranges: ["); 204 cr = &s->cr; 205 for(i = 0; i < cr->len; i += 2) { 206 lre_print_char(cr->points[i], TRUE); 207 if (cr->points[i] != cr->points[i + 1] - 1) { 208 printf("-"); 209 lre_print_char(cr->points[i + 1] - 1, TRUE); 210 } 211 } 212 printf("]\n"); 213 214 j = 0; 215 for(i = 0; i < s->hash_size; i++) { 216 for(p = s->hash_table[i]; p != NULL; p = p->next) { 217 printf(" %d/%d: '", j, s->n_strings); 218 for(k = 0; k < p->len; k++) { 219 lre_print_char(p->buf[k], FALSE); 220 } 221 printf("'\n"); 222 j++; 223 } 224 } 225 } 226 227 static int re_string_find2(REStringList *s, int len, const uint32_t *buf, 228 uint32_t h0, BOOL add_flag) 229 { 230 uint32_t h = 0; /* avoid warning */ 231 REString *p; 232 if (s->n_strings != 0) { 233 h = h0 >> (32 - s->hash_bits); 234 for(p = s->hash_table[h]; p != NULL; p = p->next) { 235 if (p->hash == h0 && p->len == len && 236 !memcmp(p->buf, buf, len * sizeof(buf[0]))) { 237 return 1; 238 } 239 } 240 } 241 /* not found */ 242 if (!add_flag) 243 return 0; 244 /* increase the size of the hash table if needed */ 245 if (unlikely((s->n_strings + 1) > s->hash_size)) { 246 REString **new_hash_table, *p_next; 247 int new_hash_bits, i; 248 uint32_t new_hash_size; 249 new_hash_bits = max_int(s->hash_bits + 1, 4); 250 new_hash_size = 1 << new_hash_bits; 251 new_hash_table = lre_realloc(s->cr.mem_opaque, NULL, 252 sizeof(new_hash_table[0]) * new_hash_size); 253 if (!new_hash_table) 254 return -1; 255 memset(new_hash_table, 0, sizeof(new_hash_table[0]) * new_hash_size); 256 for(i = 0; i < s->hash_size; i++) { 257 for(p = s->hash_table[i]; p != NULL; p = p_next) { 258 p_next = p->next; 259 h = p->hash >> (32 - new_hash_bits); 260 p->next = new_hash_table[h]; 261 new_hash_table[h] = p; 262 } 263 } 264 lre_realloc(s->cr.mem_opaque, s->hash_table, 0); 265 s->hash_bits = new_hash_bits; 266 s->hash_size = new_hash_size; 267 s->hash_table = new_hash_table; 268 h = h0 >> (32 - s->hash_bits); 269 } 270 271 p = lre_realloc(s->cr.mem_opaque, NULL, sizeof(REString) + len * sizeof(buf[0])); 272 if (!p) 273 return -1; 274 p->next = s->hash_table[h]; 275 s->hash_table[h] = p; 276 s->n_strings++; 277 p->hash = h0; 278 p->len = len; 279 memcpy(p->buf, buf, sizeof(buf[0]) * len); 280 return 1; 281 } 282 283 static int re_string_find(REStringList *s, int len, const uint32_t *buf, 284 BOOL add_flag) 285 { 286 uint32_t h0; 287 h0 = re_string_hash(len, buf); 288 return re_string_find2(s, len, buf, h0, add_flag); 289 } 290 291 /* return -1 if memory error, 0 if OK */ 292 static int re_string_add(REStringList *s, int len, const uint32_t *buf) 293 { 294 if (len == 1) { 295 return cr_union_interval(&s->cr, buf[0], buf[0]); 296 } 297 if (re_string_find(s, len, buf, TRUE) < 0) 298 return -1; 299 return 0; 300 } 301 302 /* a = a op b */ 303 static int re_string_list_op(REStringList *a, REStringList *b, int op) 304 { 305 int i, ret; 306 REString *p, **pp; 307 308 if (cr_op1(&a->cr, b->cr.points, b->cr.len, op)) 309 return -1; 310 311 switch(op) { 312 case CR_OP_UNION: 313 if (b->n_strings != 0) { 314 for(i = 0; i < b->hash_size; i++) { 315 for(p = b->hash_table[i]; p != NULL; p = p->next) { 316 if (re_string_find2(a, p->len, p->buf, p->hash, TRUE) < 0) 317 return -1; 318 } 319 } 320 } 321 break; 322 case CR_OP_INTER: 323 case CR_OP_SUB: 324 for(i = 0; i < a->hash_size; i++) { 325 pp = &a->hash_table[i]; 326 for(;;) { 327 p = *pp; 328 if (p == NULL) 329 break; 330 ret = re_string_find2(b, p->len, p->buf, p->hash, FALSE); 331 if (op == CR_OP_SUB) 332 ret = !ret; 333 if (!ret) { 334 /* remove it */ 335 *pp = p->next; 336 a->n_strings--; 337 lre_realloc(a->cr.mem_opaque, p, 0); 338 } else { 339 /* keep it */ 340 pp = &p->next; 341 } 342 } 343 } 344 break; 345 default: 346 abort(); 347 } 348 return 0; 349 } 350 351 static int re_string_list_canonicalize(REParseState *s1, 352 REStringList *s, BOOL is_unicode) 353 { 354 if (cr_regexp_canonicalize(&s->cr, is_unicode)) 355 return -1; 356 if (s->n_strings != 0) { 357 REStringList a_s, *a = &a_s; 358 int i, j; 359 REString *p; 360 361 /* XXX: simplify */ 362 re_string_list_init(s1, a); 363 364 a->n_strings = s->n_strings; 365 a->hash_size = s->hash_size; 366 a->hash_bits = s->hash_bits; 367 a->hash_table = s->hash_table; 368 369 s->n_strings = 0; 370 s->hash_size = 0; 371 s->hash_bits = 0; 372 s->hash_table = NULL; 373 374 for(i = 0; i < a->hash_size; i++) { 375 for(p = a->hash_table[i]; p != NULL; p = p->next) { 376 for(j = 0; j < p->len; j++) { 377 p->buf[j] = lre_canonicalize(p->buf[j], is_unicode); 378 } 379 if (re_string_add(s, p->len, p->buf)) { 380 re_string_list_free(a); 381 return -1; 382 } 383 } 384 } 385 re_string_list_free(a); 386 } 387 return 0; 388 } 389 390 static const uint16_t char_range_d[] = { 391 1, 392 0x0030, 0x0039 + 1, 393 }; 394 395 /* code point ranges for Zs,Zl or Zp property */ 396 static const uint16_t char_range_s[] = { 397 10, 398 0x0009, 0x000D + 1, 399 0x0020, 0x0020 + 1, 400 0x00A0, 0x00A0 + 1, 401 0x1680, 0x1680 + 1, 402 0x2000, 0x200A + 1, 403 /* 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; */ 404 /* 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; */ 405 0x2028, 0x2029 + 1, 406 0x202F, 0x202F + 1, 407 0x205F, 0x205F + 1, 408 0x3000, 0x3000 + 1, 409 /* FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; */ 410 0xFEFF, 0xFEFF + 1, 411 }; 412 413 static const uint16_t char_range_w[] = { 414 4, 415 0x0030, 0x0039 + 1, 416 0x0041, 0x005A + 1, 417 0x005F, 0x005F + 1, 418 0x0061, 0x007A + 1, 419 }; 420 421 #define CLASS_RANGE_BASE 0x40000000 422 423 typedef enum { 424 CHAR_RANGE_d, 425 CHAR_RANGE_D, 426 CHAR_RANGE_s, 427 CHAR_RANGE_S, 428 CHAR_RANGE_w, 429 CHAR_RANGE_W, 430 } CharRangeEnum; 431 432 static const uint16_t * const char_range_table[] = { 433 char_range_d, 434 char_range_s, 435 char_range_w, 436 }; 437 438 static int cr_init_char_range(REParseState *s, REStringList *cr, uint32_t c) 439 { 440 BOOL invert; 441 const uint16_t *c_pt; 442 int len, i; 443 444 invert = c & 1; 445 c_pt = char_range_table[c >> 1]; 446 len = *c_pt++; 447 re_string_list_init(s, cr); 448 for(i = 0; i < len * 2; i++) { 449 if (cr_add_point(&cr->cr, c_pt[i])) 450 goto fail; 451 } 452 if (invert) { 453 if (cr_invert(&cr->cr)) 454 goto fail; 455 } 456 return 0; 457 fail: 458 re_string_list_free(cr); 459 return -1; 460 } 461 462 #ifdef DUMP_REOP 463 static __maybe_unused void lre_dump_bytecode(const uint8_t *buf, 464 int buf_len) 465 { 466 int pos, len, opcode, bc_len, re_flags, i; 467 uint32_t val, val2; 468 469 assert(buf_len >= RE_HEADER_LEN); 470 471 re_flags = lre_get_flags(buf); 472 bc_len = get_u32(buf + RE_HEADER_BYTECODE_LEN); 473 assert(bc_len + RE_HEADER_LEN <= buf_len); 474 printf("flags: 0x%x capture_count=%d reg_count=%d\n", 475 re_flags, buf[RE_HEADER_CAPTURE_COUNT], buf[RE_HEADER_REGISTER_COUNT]); 476 if (re_flags & LRE_FLAG_NAMED_GROUPS) { 477 const char *p; 478 p = (char *)buf + RE_HEADER_LEN + bc_len; 479 printf("named groups: "); 480 for(i = 1; i < buf[RE_HEADER_CAPTURE_COUNT]; i++) { 481 if (i != 1) 482 printf(","); 483 printf("<%s>", p); 484 p += strlen(p) + LRE_GROUP_NAME_TRAILER_LEN; 485 } 486 printf("\n"); 487 assert(p == (char *)(buf + buf_len)); 488 } 489 printf("bytecode_len=%d\n", bc_len); 490 491 buf += RE_HEADER_LEN; 492 pos = 0; 493 while (pos < bc_len) { 494 printf("%5u: ", pos); 495 opcode = buf[pos]; 496 len = reopcode_info[opcode].size; 497 if (opcode >= REOP_COUNT) { 498 printf(" invalid opcode=0x%02x\n", opcode); 499 break; 500 } 501 if ((pos + len) > bc_len) { 502 printf(" buffer overflow (opcode=0x%02x)\n", opcode); 503 break; 504 } 505 printf("%s", reopcode_info[opcode].name); 506 switch(opcode) { 507 case REOP_char: 508 case REOP_char_i: 509 val = get_u16(buf + pos + 1); 510 if (val >= ' ' && val <= 126) 511 printf(" '%c'", val); 512 else 513 printf(" 0x%04x", val); 514 break; 515 case REOP_char32: 516 case REOP_char32_i: 517 val = get_u32(buf + pos + 1); 518 if (val >= ' ' && val <= 126) 519 printf(" '%c'", val); 520 else 521 printf(" 0x%08x", val); 522 break; 523 case REOP_goto: 524 case REOP_split_goto_first: 525 case REOP_split_next_first: 526 case REOP_lookahead: 527 case REOP_negative_lookahead: 528 val = get_u32(buf + pos + 1); 529 val += (pos + 5); 530 printf(" %u", val); 531 break; 532 case REOP_loop: 533 val2 = buf[pos + 1]; 534 val = get_u32(buf + pos + 2); 535 val += (pos + 6); 536 printf(" r%u, %u", val2, val); 537 break; 538 case REOP_loop_split_goto_first: 539 case REOP_loop_split_next_first: 540 case REOP_loop_check_adv_split_goto_first: 541 case REOP_loop_check_adv_split_next_first: 542 { 543 uint32_t limit; 544 val2 = buf[pos + 1]; 545 limit = get_u32(buf + pos + 2); 546 val = get_u32(buf + pos + 6); 547 val += (pos + 10); 548 printf(" r%u, %u, %u", val2, limit, val); 549 } 550 break; 551 case REOP_save_start: 552 case REOP_save_end: 553 printf(" %u", buf[pos + 1]); 554 break; 555 case REOP_back_reference: 556 case REOP_back_reference_i: 557 case REOP_backward_back_reference: 558 case REOP_backward_back_reference_i: 559 { 560 int n, i; 561 n = buf[pos + 1]; 562 len += n; 563 for(i = 0; i < n; i++) { 564 if (i != 0) 565 printf(","); 566 printf(" %u", buf[pos + 2 + i]); 567 } 568 } 569 break; 570 case REOP_save_reset: 571 printf(" %u %u", buf[pos + 1], buf[pos + 2]); 572 break; 573 case REOP_set_i32: 574 val = buf[pos + 1]; 575 val2 = get_u32(buf + pos + 2); 576 printf(" r%u, %d", val, val2); 577 break; 578 case REOP_set_char_pos: 579 case REOP_check_advance: 580 val = buf[pos + 1]; 581 printf(" r%u", val); 582 break; 583 case REOP_range: 584 case REOP_range_i: 585 { 586 int n, i; 587 n = get_u16(buf + pos + 1); 588 len += n * 4; 589 for(i = 0; i < n * 2; i++) { 590 val = get_u16(buf + pos + 3 + i * 2); 591 printf(" 0x%04x", val); 592 } 593 } 594 break; 595 case REOP_range32: 596 case REOP_range32_i: 597 { 598 int n, i; 599 n = get_u16(buf + pos + 1); 600 len += n * 8; 601 for(i = 0; i < n * 2; i++) { 602 val = get_u32(buf + pos + 3 + i * 4); 603 printf(" 0x%08x", val); 604 } 605 } 606 break; 607 default: 608 break; 609 } 610 printf("\n"); 611 pos += len; 612 } 613 } 614 #endif 615 616 static void re_emit_op(REParseState *s, int op) 617 { 618 dbuf_putc(&s->byte_code, op); 619 } 620 621 /* return the offset of the u32 value */ 622 static int re_emit_op_u32(REParseState *s, int op, uint32_t val) 623 { 624 int pos; 625 dbuf_putc(&s->byte_code, op); 626 pos = s->byte_code.size; 627 dbuf_put_u32(&s->byte_code, val); 628 return pos; 629 } 630 631 static int re_emit_goto(REParseState *s, int op, uint32_t val) 632 { 633 int pos; 634 dbuf_putc(&s->byte_code, op); 635 pos = s->byte_code.size; 636 dbuf_put_u32(&s->byte_code, val - (pos + 4)); 637 return pos; 638 } 639 640 static int re_emit_goto_u8(REParseState *s, int op, uint32_t arg, uint32_t val) 641 { 642 int pos; 643 dbuf_putc(&s->byte_code, op); 644 dbuf_putc(&s->byte_code, arg); 645 pos = s->byte_code.size; 646 dbuf_put_u32(&s->byte_code, val - (pos + 4)); 647 return pos; 648 } 649 650 static int re_emit_goto_u8_u32(REParseState *s, int op, uint32_t arg0, uint32_t arg1, uint32_t val) 651 { 652 int pos; 653 dbuf_putc(&s->byte_code, op); 654 dbuf_putc(&s->byte_code, arg0); 655 dbuf_put_u32(&s->byte_code, arg1); 656 pos = s->byte_code.size; 657 dbuf_put_u32(&s->byte_code, val - (pos + 4)); 658 return pos; 659 } 660 661 static void re_emit_op_u8(REParseState *s, int op, uint32_t val) 662 { 663 dbuf_putc(&s->byte_code, op); 664 dbuf_putc(&s->byte_code, val); 665 } 666 667 static void re_emit_op_u16(REParseState *s, int op, uint32_t val) 668 { 669 dbuf_putc(&s->byte_code, op); 670 dbuf_put_u16(&s->byte_code, val); 671 } 672 673 static int __attribute__((format(printf, 2, 3))) re_parse_error(REParseState *s, const char *fmt, ...) 674 { 675 va_list ap; 676 va_start(ap, fmt); 677 vsnprintf(s->u.error_msg, sizeof(s->u.error_msg), fmt, ap); 678 va_end(ap); 679 return -1; 680 } 681 682 static int re_parse_out_of_memory(REParseState *s) 683 { 684 return re_parse_error(s, "out of memory"); 685 } 686 687 /* If allow_overflow is false, return -1 in case of 688 overflow. Otherwise return INT32_MAX. */ 689 static int parse_digits(const uint8_t **pp, BOOL allow_overflow) 690 { 691 const uint8_t *p; 692 uint64_t v; 693 int c; 694 695 p = *pp; 696 v = 0; 697 for(;;) { 698 c = *p; 699 if (c < '0' || c > '9') 700 break; 701 v = v * 10 + c - '0'; 702 if (v >= INT32_MAX) { 703 if (allow_overflow) 704 v = INT32_MAX; 705 else 706 return -1; 707 } 708 p++; 709 } 710 *pp = p; 711 return v; 712 } 713 714 static int re_parse_expect(REParseState *s, const uint8_t **pp, int c) 715 { 716 const uint8_t *p; 717 p = *pp; 718 if (*p != c) 719 return re_parse_error(s, "expecting '%c'", c); 720 p++; 721 *pp = p; 722 return 0; 723 } 724 725 /* Parse an escape sequence, *pp points after the '\': 726 allow_utf16 value: 727 0 : no UTF-16 escapes allowed 728 1 : UTF-16 escapes allowed 729 2 : UTF-16 escapes allowed and escapes of surrogate pairs are 730 converted to a unicode character (unicode regexp case). 731 732 Return the unicode char and update *pp if recognized, 733 return -1 if malformed escape, 734 return -2 otherwise. */ 735 int lre_parse_escape(const uint8_t **pp, int allow_utf16) 736 { 737 const uint8_t *p; 738 uint32_t c; 739 740 p = *pp; 741 c = *p++; 742 switch(c) { 743 case 'b': 744 c = '\b'; 745 break; 746 case 'f': 747 c = '\f'; 748 break; 749 case 'n': 750 c = '\n'; 751 break; 752 case 'r': 753 c = '\r'; 754 break; 755 case 't': 756 c = '\t'; 757 break; 758 case 'v': 759 c = '\v'; 760 break; 761 case 'x': 762 { 763 int h0, h1; 764 765 h0 = from_hex(*p++); 766 if (h0 < 0) 767 return -1; 768 h1 = from_hex(*p++); 769 if (h1 < 0) 770 return -1; 771 c = (h0 << 4) | h1; 772 } 773 break; 774 case 'u': 775 { 776 int h, i; 777 uint32_t c1; 778 779 if (*p == '{' && allow_utf16) { 780 p++; 781 c = 0; 782 for(;;) { 783 h = from_hex(*p++); 784 if (h < 0) 785 return -1; 786 c = (c << 4) | h; 787 if (c > 0x10FFFF) 788 return -1; 789 if (*p == '}') 790 break; 791 } 792 p++; 793 } else { 794 c = 0; 795 for(i = 0; i < 4; i++) { 796 h = from_hex(*p++); 797 if (h < 0) { 798 return -1; 799 } 800 c = (c << 4) | h; 801 } 802 if (is_hi_surrogate(c) && 803 allow_utf16 == 2 && p[0] == '\\' && p[1] == 'u') { 804 /* convert an escaped surrogate pair into a 805 unicode char */ 806 c1 = 0; 807 for(i = 0; i < 4; i++) { 808 h = from_hex(p[2 + i]); 809 if (h < 0) 810 break; 811 c1 = (c1 << 4) | h; 812 } 813 if (i == 4 && is_lo_surrogate(c1)) { 814 p += 6; 815 c = from_surrogate(c, c1); 816 } 817 } 818 } 819 } 820 break; 821 case '0': case '1': case '2': case '3': 822 case '4': case '5': case '6': case '7': 823 c -= '0'; 824 if (allow_utf16 == 2) { 825 /* only accept \0 not followed by digit */ 826 if (c != 0 || is_digit(*p)) 827 return -1; 828 } else { 829 /* parse a legacy octal sequence */ 830 uint32_t v; 831 v = *p - '0'; 832 if (v > 7) 833 break; 834 c = (c << 3) | v; 835 p++; 836 if (c >= 32) 837 break; 838 v = *p - '0'; 839 if (v > 7) 840 break; 841 c = (c << 3) | v; 842 p++; 843 } 844 break; 845 default: 846 return -2; 847 } 848 *pp = p; 849 return c; 850 } 851 852 #ifdef CONFIG_ALL_UNICODE 853 /* XXX: we use the same chars for name and value */ 854 static BOOL is_unicode_char(int c) 855 { 856 return ((c >= '0' && c <= '9') || 857 (c >= 'A' && c <= 'Z') || 858 (c >= 'a' && c <= 'z') || 859 (c == '_')); 860 } 861 862 /* XXX: memory error test */ 863 static void seq_prop_cb(void *opaque, const uint32_t *seq, int seq_len) 864 { 865 REStringList *sl = opaque; 866 re_string_add(sl, seq_len, seq); 867 } 868 869 static int parse_unicode_property(REParseState *s, REStringList *cr, 870 const uint8_t **pp, BOOL is_inv, 871 BOOL allow_sequence_prop) 872 { 873 const uint8_t *p; 874 char name[64], value[64]; 875 char *q; 876 BOOL script_ext; 877 int ret; 878 879 p = *pp; 880 if (*p != '{') 881 return re_parse_error(s, "expecting '{' after \\p"); 882 p++; 883 q = name; 884 while (is_unicode_char(*p)) { 885 if ((q - name) >= sizeof(name) - 1) 886 goto unknown_property_name; 887 *q++ = *p++; 888 } 889 *q = '\0'; 890 q = value; 891 if (*p == '=') { 892 p++; 893 while (is_unicode_char(*p)) { 894 if ((q - value) >= sizeof(value) - 1) 895 return re_parse_error(s, "unknown unicode property value"); 896 *q++ = *p++; 897 } 898 } 899 *q = '\0'; 900 if (*p != '}') 901 return re_parse_error(s, "expecting '}'"); 902 p++; 903 // printf("name=%s value=%s\n", name, value); 904 905 if (!strcmp(name, "Script") || !strcmp(name, "sc")) { 906 script_ext = FALSE; 907 goto do_script; 908 } else if (!strcmp(name, "Script_Extensions") || !strcmp(name, "scx")) { 909 script_ext = TRUE; 910 do_script: 911 re_string_list_init(s, cr); 912 ret = unicode_script(&cr->cr, value, script_ext); 913 if (ret) { 914 re_string_list_free(cr); 915 if (ret == -2) 916 return re_parse_error(s, "unknown unicode script"); 917 else 918 goto out_of_memory; 919 } 920 } else if (!strcmp(name, "General_Category") || !strcmp(name, "gc")) { 921 re_string_list_init(s, cr); 922 ret = unicode_general_category(&cr->cr, value); 923 if (ret) { 924 re_string_list_free(cr); 925 if (ret == -2) 926 return re_parse_error(s, "unknown unicode general category"); 927 else 928 goto out_of_memory; 929 } 930 } else if (value[0] == '\0') { 931 re_string_list_init(s, cr); 932 ret = unicode_general_category(&cr->cr, name); 933 if (ret == -1) { 934 re_string_list_free(cr); 935 goto out_of_memory; 936 } 937 if (ret < 0) { 938 ret = unicode_prop(&cr->cr, name); 939 if (ret == -1) { 940 re_string_list_free(cr); 941 goto out_of_memory; 942 } 943 } 944 if (ret < 0 && !is_inv && allow_sequence_prop) { 945 CharRange cr_tmp; 946 cr_init(&cr_tmp, s->opaque, lre_realloc); 947 ret = unicode_sequence_prop(name, seq_prop_cb, cr, &cr_tmp); 948 cr_free(&cr_tmp); 949 if (ret == -1) { 950 re_string_list_free(cr); 951 goto out_of_memory; 952 } 953 } 954 if (ret < 0) 955 goto unknown_property_name; 956 } else { 957 unknown_property_name: 958 return re_parse_error(s, "unknown unicode property name"); 959 } 960 961 /* the ordering of case folding and inversion differs with 962 unicode_sets. 'unicode_sets' ordering is more consistent */ 963 /* XXX: the spec seems incorrect, we do it as the other engines 964 seem to do it. */ 965 if (s->ignore_case && s->unicode_sets) { 966 if (re_string_list_canonicalize(s, cr, s->is_unicode)) { 967 re_string_list_free(cr); 968 goto out_of_memory; 969 } 970 } 971 if (is_inv) { 972 if (cr_invert(&cr->cr)) { 973 re_string_list_free(cr); 974 goto out_of_memory; 975 } 976 } 977 if (s->ignore_case && !s->unicode_sets) { 978 if (re_string_list_canonicalize(s, cr, s->is_unicode)) { 979 re_string_list_free(cr); 980 goto out_of_memory; 981 } 982 } 983 *pp = p; 984 return 0; 985 out_of_memory: 986 return re_parse_out_of_memory(s); 987 } 988 #endif /* CONFIG_ALL_UNICODE */ 989 990 static int get_class_atom(REParseState *s, REStringList *cr, 991 const uint8_t **pp, BOOL inclass); 992 993 static int parse_class_string_disjunction(REParseState *s, REStringList *cr, 994 const uint8_t **pp) 995 { 996 const uint8_t *p; 997 DynBuf str; 998 int c; 999 1000 p = *pp; 1001 if (*p != '{') 1002 return re_parse_error(s, "expecting '{' after \\q"); 1003 1004 dbuf_init2(&str, s->opaque, lre_realloc); 1005 re_string_list_init(s, cr); 1006 1007 p++; 1008 for(;;) { 1009 str.size = 0; 1010 while (*p != '}' && *p != '|') { 1011 c = get_class_atom(s, NULL, &p, FALSE); 1012 if (c < 0) 1013 goto fail; 1014 if (dbuf_put_u32(&str, c)) { 1015 re_parse_out_of_memory(s); 1016 goto fail; 1017 } 1018 } 1019 if (re_string_add(cr, str.size / 4, (uint32_t *)str.buf)) { 1020 re_parse_out_of_memory(s); 1021 goto fail; 1022 } 1023 if (*p == '}') 1024 break; 1025 p++; 1026 } 1027 if (s->ignore_case) { 1028 if (re_string_list_canonicalize(s, cr, TRUE)) 1029 goto fail; 1030 } 1031 p++; /* skip the '}' */ 1032 dbuf_free(&str); 1033 *pp = p; 1034 return 0; 1035 fail: 1036 dbuf_free(&str); 1037 re_string_list_free(cr); 1038 return -1; 1039 } 1040 1041 /* return -1 if error otherwise the character or a class range 1042 (CLASS_RANGE_BASE) if cr != NULL. In case of class range, 'cr' is 1043 initialized. Otherwise, it is ignored. */ 1044 static int get_class_atom(REParseState *s, REStringList *cr, 1045 const uint8_t **pp, BOOL inclass) 1046 { 1047 const uint8_t *p; 1048 uint32_t c; 1049 int ret; 1050 1051 p = *pp; 1052 1053 c = *p; 1054 switch(c) { 1055 case '\\': 1056 p++; 1057 if (p >= s->buf_end) 1058 goto unexpected_end; 1059 c = *p++; 1060 switch(c) { 1061 case 'd': 1062 c = CHAR_RANGE_d; 1063 goto class_range; 1064 case 'D': 1065 c = CHAR_RANGE_D; 1066 goto class_range; 1067 case 's': 1068 c = CHAR_RANGE_s; 1069 goto class_range; 1070 case 'S': 1071 c = CHAR_RANGE_S; 1072 goto class_range; 1073 case 'w': 1074 c = CHAR_RANGE_w; 1075 goto class_range; 1076 case 'W': 1077 c = CHAR_RANGE_W; 1078 class_range: 1079 if (!cr) 1080 goto default_escape; 1081 if (cr_init_char_range(s, cr, c)) 1082 return -1; 1083 c += CLASS_RANGE_BASE; 1084 break; 1085 case 'c': 1086 c = *p; 1087 if ((c >= 'a' && c <= 'z') || 1088 (c >= 'A' && c <= 'Z') || 1089 (((c >= '0' && c <= '9') || c == '_') && 1090 inclass && !s->is_unicode)) { /* Annex B.1.4 */ 1091 c &= 0x1f; 1092 p++; 1093 } else if (s->is_unicode) { 1094 goto invalid_escape; 1095 } else { 1096 /* otherwise return '\' and 'c' */ 1097 p--; 1098 c = '\\'; 1099 } 1100 break; 1101 case '-': 1102 if (!inclass && s->is_unicode) 1103 goto invalid_escape; 1104 break; 1105 case '^': 1106 case '$': 1107 case '\\': 1108 case '.': 1109 case '*': 1110 case '+': 1111 case '?': 1112 case '(': 1113 case ')': 1114 case '[': 1115 case ']': 1116 case '{': 1117 case '}': 1118 case '|': 1119 case '/': 1120 /* always valid to escape these characters */ 1121 break; 1122 #ifdef CONFIG_ALL_UNICODE 1123 case 'p': 1124 case 'P': 1125 if (s->is_unicode && cr) { 1126 if (parse_unicode_property(s, cr, &p, (c == 'P'), s->unicode_sets)) 1127 return -1; 1128 c = CLASS_RANGE_BASE; 1129 break; 1130 } 1131 goto default_escape; 1132 #endif 1133 case 'q': 1134 if (s->unicode_sets && cr && inclass) { 1135 if (parse_class_string_disjunction(s, cr, &p)) 1136 return -1; 1137 c = CLASS_RANGE_BASE; 1138 break; 1139 } 1140 goto default_escape; 1141 default: 1142 default_escape: 1143 p--; 1144 ret = lre_parse_escape(&p, s->is_unicode * 2); 1145 if (ret >= 0) { 1146 c = ret; 1147 } else { 1148 if (s->is_unicode) { 1149 invalid_escape: 1150 return re_parse_error(s, "invalid escape sequence in regular expression"); 1151 } else { 1152 /* just ignore the '\' */ 1153 goto normal_char; 1154 } 1155 } 1156 break; 1157 } 1158 break; 1159 case '\0': 1160 if (p >= s->buf_end) { 1161 unexpected_end: 1162 return re_parse_error(s, "unexpected end"); 1163 } 1164 /* fall thru */ 1165 goto normal_char; 1166 1167 case '&': 1168 case '!': 1169 case '#': 1170 case '$': 1171 case '%': 1172 case '*': 1173 case '+': 1174 case ',': 1175 case '.': 1176 case ':': 1177 case ';': 1178 case '<': 1179 case '=': 1180 case '>': 1181 case '?': 1182 case '@': 1183 case '^': 1184 case '`': 1185 case '~': 1186 if (s->unicode_sets && p[1] == c) { 1187 /* forbidden double characters */ 1188 return re_parse_error(s, "invalid class set operation in regular expression"); 1189 } 1190 goto normal_char; 1191 1192 case '(': 1193 case ')': 1194 case '[': 1195 case ']': 1196 case '{': 1197 case '}': 1198 case '/': 1199 case '-': 1200 case '|': 1201 if (s->unicode_sets) { 1202 /* invalid characters in unicode sets */ 1203 return re_parse_error(s, "invalid character in class in regular expression"); 1204 } 1205 goto normal_char; 1206 1207 default: 1208 normal_char: 1209 /* normal char */ 1210 if (c >= 128) { 1211 c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); 1212 if ((unsigned)c > 0xffff && !s->is_unicode) { 1213 /* XXX: should handle non BMP-1 code points */ 1214 return re_parse_error(s, "malformed unicode char"); 1215 } 1216 } else { 1217 p++; 1218 } 1219 break; 1220 } 1221 *pp = p; 1222 return c; 1223 } 1224 1225 static int re_emit_range(REParseState *s, const CharRange *cr) 1226 { 1227 int len, i; 1228 uint32_t high; 1229 1230 len = (unsigned)cr->len / 2; 1231 if (len >= 65535) 1232 return re_parse_error(s, "too many ranges"); 1233 if (len == 0) { 1234 re_emit_op_u32(s, REOP_char32, -1); 1235 } else { 1236 high = cr->points[cr->len - 1]; 1237 if (high == UINT32_MAX) 1238 high = cr->points[cr->len - 2]; 1239 if (high <= 0xffff) { 1240 /* can use 16 bit ranges with the conversion that 0xffff = 1241 infinity */ 1242 re_emit_op_u16(s, s->ignore_case ? REOP_range_i : REOP_range, len); 1243 for(i = 0; i < cr->len; i += 2) { 1244 dbuf_put_u16(&s->byte_code, cr->points[i]); 1245 high = cr->points[i + 1] - 1; 1246 if (high == UINT32_MAX - 1) 1247 high = 0xffff; 1248 dbuf_put_u16(&s->byte_code, high); 1249 } 1250 } else { 1251 re_emit_op_u16(s, s->ignore_case ? REOP_range32_i : REOP_range32, len); 1252 for(i = 0; i < cr->len; i += 2) { 1253 dbuf_put_u32(&s->byte_code, cr->points[i]); 1254 dbuf_put_u32(&s->byte_code, cr->points[i + 1] - 1); 1255 } 1256 } 1257 } 1258 return 0; 1259 } 1260 1261 static int re_string_cmp_len(const void *a, const void *b, void *arg) 1262 { 1263 REString *p1 = *(REString **)a; 1264 REString *p2 = *(REString **)b; 1265 return (p1->len < p2->len) - (p1->len > p2->len); 1266 } 1267 1268 static void re_emit_char(REParseState *s, int c) 1269 { 1270 if (c <= 0xffff) 1271 re_emit_op_u16(s, s->ignore_case ? REOP_char_i : REOP_char, c); 1272 else 1273 re_emit_op_u32(s, s->ignore_case ? REOP_char32_i : REOP_char32, c); 1274 } 1275 1276 static int re_emit_string_list(REParseState *s, const REStringList *sl) 1277 { 1278 REString **tab, *p; 1279 int i, j, split_pos, last_match_pos, n; 1280 BOOL has_empty_string, is_last; 1281 1282 // re_string_list_dump("sl", sl); 1283 if (sl->n_strings == 0) { 1284 /* simple case: only characters */ 1285 if (re_emit_range(s, &sl->cr)) 1286 return -1; 1287 } else { 1288 /* at least one string list is present : match the longest ones first */ 1289 /* XXX: add a new op_switch opcode to compile as a trie */ 1290 tab = lre_realloc(s->opaque, NULL, sizeof(tab[0]) * sl->n_strings); 1291 if (!tab) { 1292 re_parse_out_of_memory(s); 1293 return -1; 1294 } 1295 has_empty_string = FALSE; 1296 n = 0; 1297 for(i = 0; i < sl->hash_size; i++) { 1298 for(p = sl->hash_table[i]; p != NULL; p = p->next) { 1299 if (p->len == 0) { 1300 has_empty_string = TRUE; 1301 } else { 1302 tab[n++] = p; 1303 } 1304 } 1305 } 1306 assert(n <= sl->n_strings); 1307 1308 rqsort(tab, n, sizeof(tab[0]), re_string_cmp_len, NULL); 1309 1310 last_match_pos = -1; 1311 for(i = 0; i < n; i++) { 1312 p = tab[i]; 1313 is_last = !has_empty_string && sl->cr.len == 0 && i == (n - 1); 1314 if (!is_last) 1315 split_pos = re_emit_op_u32(s, REOP_split_next_first, 0); 1316 else 1317 split_pos = 0; 1318 for(j = 0; j < p->len; j++) { 1319 re_emit_char(s, p->buf[j]); 1320 } 1321 if (!is_last) { 1322 last_match_pos = re_emit_op_u32(s, REOP_goto, last_match_pos); 1323 put_u32(s->byte_code.buf + split_pos, s->byte_code.size - (split_pos + 4)); 1324 } 1325 } 1326 1327 if (sl->cr.len != 0) { 1328 /* char range */ 1329 is_last = !has_empty_string; 1330 if (!is_last) 1331 split_pos = re_emit_op_u32(s, REOP_split_next_first, 0); 1332 else 1333 split_pos = 0; /* not used */ 1334 if (re_emit_range(s, &sl->cr)) { 1335 lre_realloc(s->opaque, tab, 0); 1336 return -1; 1337 } 1338 if (!is_last) 1339 put_u32(s->byte_code.buf + split_pos, s->byte_code.size - (split_pos + 4)); 1340 } 1341 1342 /* patch the 'goto match' */ 1343 while (last_match_pos != -1) { 1344 int next_pos = get_u32(s->byte_code.buf + last_match_pos); 1345 put_u32(s->byte_code.buf + last_match_pos, s->byte_code.size - (last_match_pos + 4)); 1346 last_match_pos = next_pos; 1347 } 1348 1349 lre_realloc(s->opaque, tab, 0); 1350 } 1351 return 0; 1352 } 1353 1354 static int re_parse_nested_class(REParseState *s, REStringList *cr, const uint8_t **pp); 1355 1356 static int re_parse_class_set_operand(REParseState *s, REStringList *cr, const uint8_t **pp) 1357 { 1358 int c1; 1359 const uint8_t *p = *pp; 1360 1361 if (*p == '[') { 1362 if (re_parse_nested_class(s, cr, pp)) 1363 return -1; 1364 } else { 1365 c1 = get_class_atom(s, cr, pp, TRUE); 1366 if (c1 < 0) 1367 return -1; 1368 if (c1 < CLASS_RANGE_BASE) { 1369 /* create a range with a single character */ 1370 re_string_list_init(s, cr); 1371 if (s->ignore_case) 1372 c1 = lre_canonicalize(c1, s->is_unicode); 1373 if (cr_union_interval(&cr->cr, c1, c1)) { 1374 re_string_list_free(cr); 1375 return -1; 1376 } 1377 } 1378 } 1379 return 0; 1380 } 1381 1382 static int re_parse_nested_class(REParseState *s, REStringList *cr, const uint8_t **pp) 1383 { 1384 const uint8_t *p; 1385 uint32_t c1, c2; 1386 int ret; 1387 REStringList cr1_s, *cr1 = &cr1_s; 1388 BOOL invert, is_first; 1389 1390 if (lre_check_stack_overflow(s->opaque, 0)) 1391 return re_parse_error(s, "stack overflow"); 1392 1393 re_string_list_init(s, cr); 1394 p = *pp; 1395 p++; /* skip '[' */ 1396 1397 invert = FALSE; 1398 if (*p == '^') { 1399 p++; 1400 invert = TRUE; 1401 } 1402 1403 /* handle unions */ 1404 is_first = TRUE; 1405 for(;;) { 1406 if (*p == ']') 1407 break; 1408 if (*p == '[' && s->unicode_sets) { 1409 if (re_parse_nested_class(s, cr1, &p)) 1410 goto fail; 1411 goto class_union; 1412 } else { 1413 c1 = get_class_atom(s, cr1, &p, TRUE); 1414 if ((int)c1 < 0) 1415 goto fail; 1416 if (*p == '-' && p[1] != ']') { 1417 const uint8_t *p0 = p + 1; 1418 if (p[1] == '-' && s->unicode_sets && is_first) 1419 goto class_atom; /* first character class followed by '--' */ 1420 if (c1 >= CLASS_RANGE_BASE) { 1421 if (s->is_unicode) { 1422 re_string_list_free(cr1); 1423 goto invalid_class_range; 1424 } 1425 /* Annex B: match '-' character */ 1426 goto class_atom; 1427 } 1428 c2 = get_class_atom(s, cr1, &p0, TRUE); 1429 if ((int)c2 < 0) 1430 goto fail; 1431 if (c2 >= CLASS_RANGE_BASE) { 1432 re_string_list_free(cr1); 1433 if (s->is_unicode) { 1434 goto invalid_class_range; 1435 } 1436 /* Annex B: match '-' character */ 1437 goto class_atom; 1438 } 1439 p = p0; 1440 if (c2 < c1) { 1441 invalid_class_range: 1442 re_parse_error(s, "invalid class range"); 1443 goto fail; 1444 } 1445 if (s->ignore_case) { 1446 CharRange cr2_s, *cr2 = &cr2_s; 1447 cr_init(cr2, s->opaque, lre_realloc); 1448 if (cr_add_interval(cr2, c1, c2 + 1) || 1449 cr_regexp_canonicalize(cr2, s->is_unicode) || 1450 cr_op1(&cr->cr, cr2->points, cr2->len, CR_OP_UNION)) { 1451 cr_free(cr2); 1452 goto memory_error; 1453 } 1454 cr_free(cr2); 1455 } else { 1456 if (cr_union_interval(&cr->cr, c1, c2)) 1457 goto memory_error; 1458 } 1459 is_first = FALSE; /* union operation */ 1460 } else { 1461 class_atom: 1462 if (c1 >= CLASS_RANGE_BASE) { 1463 class_union: 1464 ret = re_string_list_op(cr, cr1, CR_OP_UNION); 1465 re_string_list_free(cr1); 1466 if (ret) 1467 goto memory_error; 1468 } else { 1469 if (s->ignore_case) 1470 c1 = lre_canonicalize(c1, s->is_unicode); 1471 if (cr_union_interval(&cr->cr, c1, c1)) 1472 goto memory_error; 1473 } 1474 } 1475 } 1476 if (s->unicode_sets && is_first) { 1477 if (*p == '&' && p[1] == '&' && p[2] != '&') { 1478 /* handle '&&' */ 1479 for(;;) { 1480 if (*p == ']') { 1481 break; 1482 } else if (*p == '&' && p[1] == '&' && p[2] != '&') { 1483 p += 2; 1484 } else { 1485 goto invalid_operation; 1486 } 1487 if (re_parse_class_set_operand(s, cr1, &p)) 1488 goto fail; 1489 ret = re_string_list_op(cr, cr1, CR_OP_INTER); 1490 re_string_list_free(cr1); 1491 if (ret) 1492 goto memory_error; 1493 } 1494 } else if (*p == '-' && p[1] == '-') { 1495 /* handle '--' */ 1496 for(;;) { 1497 if (*p == ']') { 1498 break; 1499 } else if (*p == '-' && p[1] == '-') { 1500 p += 2; 1501 } else { 1502 invalid_operation: 1503 re_parse_error(s, "invalid operation in regular expression"); 1504 goto fail; 1505 } 1506 if (re_parse_class_set_operand(s, cr1, &p)) 1507 goto fail; 1508 ret = re_string_list_op(cr, cr1, CR_OP_SUB); 1509 re_string_list_free(cr1); 1510 if (ret) 1511 goto memory_error; 1512 } 1513 } 1514 } 1515 is_first = FALSE; 1516 } 1517 1518 p++; /* skip ']' */ 1519 *pp = p; 1520 if (invert) { 1521 /* XXX: add may_contain_string syntax check to be fully 1522 compliant. The test here accepts more input than the 1523 spec. */ 1524 if (cr->n_strings != 0) { 1525 re_parse_error(s, "negated character class with strings in regular expression debugger eval code"); 1526 goto fail; 1527 } 1528 if (cr_invert(&cr->cr)) 1529 goto memory_error; 1530 } 1531 return 0; 1532 memory_error: 1533 re_parse_out_of_memory(s); 1534 fail: 1535 re_string_list_free(cr); 1536 return -1; 1537 } 1538 1539 static int re_parse_char_class(REParseState *s, const uint8_t **pp) 1540 { 1541 REStringList cr_s, *cr = &cr_s; 1542 1543 if (re_parse_nested_class(s, cr, pp)) 1544 return -1; 1545 if (re_emit_string_list(s, cr)) 1546 goto fail; 1547 re_string_list_free(cr); 1548 return 0; 1549 fail: 1550 re_string_list_free(cr); 1551 return -1; 1552 } 1553 1554 /* need_check_adv: false if the opcodes always advance the char pointer 1555 need_capture_init: true if all the captures in the atom are not set 1556 */ 1557 static BOOL re_need_check_adv_and_capture_init(BOOL *pneed_capture_init, 1558 const uint8_t *bc_buf, int bc_buf_len) 1559 { 1560 int pos, opcode, len; 1561 uint32_t val; 1562 BOOL need_check_adv, need_capture_init; 1563 1564 need_check_adv = TRUE; 1565 need_capture_init = FALSE; 1566 pos = 0; 1567 while (pos < bc_buf_len) { 1568 opcode = bc_buf[pos]; 1569 len = reopcode_info[opcode].size; 1570 switch(opcode) { 1571 case REOP_range: 1572 case REOP_range_i: 1573 val = get_u16(bc_buf + pos + 1); 1574 len += val * 4; 1575 need_check_adv = FALSE; 1576 break; 1577 case REOP_range32: 1578 case REOP_range32_i: 1579 val = get_u16(bc_buf + pos + 1); 1580 len += val * 8; 1581 need_check_adv = FALSE; 1582 break; 1583 case REOP_char: 1584 case REOP_char_i: 1585 case REOP_char32: 1586 case REOP_char32_i: 1587 case REOP_dot: 1588 case REOP_any: 1589 case REOP_space: 1590 case REOP_not_space: 1591 need_check_adv = FALSE; 1592 break; 1593 case REOP_line_start: 1594 case REOP_line_start_m: 1595 case REOP_line_end: 1596 case REOP_line_end_m: 1597 case REOP_set_i32: 1598 case REOP_set_char_pos: 1599 case REOP_word_boundary: 1600 case REOP_word_boundary_i: 1601 case REOP_not_word_boundary: 1602 case REOP_not_word_boundary_i: 1603 case REOP_prev: 1604 /* no effect */ 1605 break; 1606 case REOP_save_start: 1607 case REOP_save_end: 1608 case REOP_save_reset: 1609 break; 1610 case REOP_back_reference: 1611 case REOP_back_reference_i: 1612 case REOP_backward_back_reference: 1613 case REOP_backward_back_reference_i: 1614 val = bc_buf[pos + 1]; 1615 len += val; 1616 need_capture_init = TRUE; 1617 break; 1618 default: 1619 /* safe behavior: we cannot predict the outcome */ 1620 need_capture_init = TRUE; 1621 goto done; 1622 } 1623 pos += len; 1624 } 1625 done: 1626 *pneed_capture_init = need_capture_init; 1627 return need_check_adv; 1628 } 1629 1630 /* '*pp' is the first char after '<' */ 1631 static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp) 1632 { 1633 const uint8_t *p, *p1; 1634 uint32_t c, d; 1635 char *q; 1636 1637 p = *pp; 1638 q = buf; 1639 for(;;) { 1640 c = *p; 1641 if (c == '\\') { 1642 p++; 1643 if (*p != 'u') 1644 return -1; 1645 c = lre_parse_escape(&p, 2); // accept surrogate pairs 1646 } else if (c == '>') { 1647 break; 1648 } else if (c >= 128) { 1649 c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); 1650 if (is_hi_surrogate(c)) { 1651 d = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1); 1652 if (is_lo_surrogate(d)) { 1653 c = from_surrogate(c, d); 1654 p = p1; 1655 } 1656 } 1657 } else { 1658 p++; 1659 } 1660 if (c > 0x10FFFF) 1661 return -1; 1662 if (q == buf) { 1663 if (!lre_js_is_ident_first(c)) 1664 return -1; 1665 } else { 1666 if (!lre_js_is_ident_next(c)) 1667 return -1; 1668 } 1669 if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size) 1670 return -1; 1671 if (c < 128) { 1672 *q++ = c; 1673 } else { 1674 q += unicode_to_utf8((uint8_t*)q, c); 1675 } 1676 } 1677 if (q == buf) 1678 return -1; 1679 *q = '\0'; 1680 p++; 1681 *pp = p; 1682 return 0; 1683 } 1684 1685 /* if capture_name = NULL: return the number of captures + 1. 1686 Otherwise, return the number of matching capture groups */ 1687 static int re_parse_captures(REParseState *s, int *phas_named_captures, 1688 const char *capture_name, BOOL emit_group_index) 1689 { 1690 const uint8_t *p; 1691 int capture_index, n; 1692 char name[TMP_BUF_SIZE]; 1693 1694 capture_index = 1; 1695 n = 0; 1696 *phas_named_captures = 0; 1697 for (p = s->buf_start; p < s->buf_end; p++) { 1698 switch (*p) { 1699 case '(': 1700 if (p[1] == '?') { 1701 if (p[2] == '<' && p[3] != '=' && p[3] != '!') { 1702 *phas_named_captures = 1; 1703 /* potential named capture */ 1704 if (capture_name) { 1705 p += 3; 1706 if (re_parse_group_name(name, sizeof(name), &p) == 0) { 1707 if (!strcmp(name, capture_name)) { 1708 if (emit_group_index) 1709 dbuf_putc(&s->byte_code, capture_index); 1710 n++; 1711 } 1712 } 1713 } 1714 capture_index++; 1715 if (capture_index >= CAPTURE_COUNT_MAX) 1716 goto done; 1717 } 1718 } else { 1719 capture_index++; 1720 if (capture_index >= CAPTURE_COUNT_MAX) 1721 goto done; 1722 } 1723 break; 1724 case '\\': 1725 p++; 1726 break; 1727 case '[': 1728 for (p += 1 + (*p == ']'); p < s->buf_end && *p != ']'; p++) { 1729 if (*p == '\\') 1730 p++; 1731 } 1732 break; 1733 } 1734 } 1735 done: 1736 if (capture_name) { 1737 return n; 1738 } else { 1739 return capture_index; 1740 } 1741 } 1742 1743 static int re_count_captures(REParseState *s) 1744 { 1745 if (s->total_capture_count < 0) { 1746 s->total_capture_count = re_parse_captures(s, &s->has_named_captures, 1747 NULL, FALSE); 1748 } 1749 return s->total_capture_count; 1750 } 1751 1752 static BOOL re_has_named_captures(REParseState *s) 1753 { 1754 if (s->has_named_captures < 0) 1755 re_count_captures(s); 1756 return s->has_named_captures; 1757 } 1758 1759 static int find_group_name(REParseState *s, const char *name, BOOL emit_group_index) 1760 { 1761 const char *p, *buf_end; 1762 size_t len, name_len; 1763 int capture_index, n; 1764 1765 p = (char *)s->group_names.buf; 1766 if (!p) 1767 return 0; 1768 buf_end = (char *)s->group_names.buf + s->group_names.size; 1769 name_len = strlen(name); 1770 capture_index = 1; 1771 n = 0; 1772 while (p < buf_end) { 1773 len = strlen(p); 1774 if (len == name_len && memcmp(name, p, name_len) == 0) { 1775 if (emit_group_index) 1776 dbuf_putc(&s->byte_code, capture_index); 1777 n++; 1778 } 1779 p += len + LRE_GROUP_NAME_TRAILER_LEN; 1780 capture_index++; 1781 } 1782 return n; 1783 } 1784 1785 static BOOL is_duplicate_group_name(REParseState *s, const char *name, int scope) 1786 { 1787 const char *p, *buf_end; 1788 size_t len, name_len; 1789 int scope1; 1790 1791 p = (char *)s->group_names.buf; 1792 if (!p) 1793 return 0; 1794 buf_end = (char *)s->group_names.buf + s->group_names.size; 1795 name_len = strlen(name); 1796 while (p < buf_end) { 1797 len = strlen(p); 1798 if (len == name_len && memcmp(name, p, name_len) == 0) { 1799 scope1 = (uint8_t)p[len + 1]; 1800 if (scope == scope1) 1801 return TRUE; 1802 } 1803 p += len + LRE_GROUP_NAME_TRAILER_LEN; 1804 } 1805 return FALSE; 1806 } 1807 1808 static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir); 1809 1810 static int re_parse_modifiers(REParseState *s, const uint8_t **pp) 1811 { 1812 const uint8_t *p = *pp; 1813 int mask = 0; 1814 int val; 1815 1816 for(;;) { 1817 if (*p == 'i') { 1818 val = LRE_FLAG_IGNORECASE; 1819 } else if (*p == 'm') { 1820 val = LRE_FLAG_MULTILINE; 1821 } else if (*p == 's') { 1822 val = LRE_FLAG_DOTALL; 1823 } else { 1824 break; 1825 } 1826 if (mask & val) 1827 return re_parse_error(s, "duplicate modifier: '%c'", *p); 1828 mask |= val; 1829 p++; 1830 } 1831 *pp = p; 1832 return mask; 1833 } 1834 1835 static BOOL update_modifier(BOOL val, int add_mask, int remove_mask, 1836 int mask) 1837 { 1838 if (add_mask & mask) 1839 val = TRUE; 1840 if (remove_mask & mask) 1841 val = FALSE; 1842 return val; 1843 } 1844 1845 static int re_parse_term(REParseState *s, BOOL is_backward_dir) 1846 { 1847 const uint8_t *p; 1848 int c, last_atom_start, quant_min, quant_max, last_capture_count; 1849 BOOL greedy, is_neg, is_backward_lookahead; 1850 REStringList cr_s, *cr = &cr_s; 1851 1852 last_atom_start = -1; 1853 last_capture_count = 0; 1854 p = s->buf_ptr; 1855 c = *p; 1856 switch(c) { 1857 case '^': 1858 p++; 1859 re_emit_op(s, s->multi_line ? REOP_line_start_m : REOP_line_start); 1860 break; 1861 case '$': 1862 p++; 1863 re_emit_op(s, s->multi_line ? REOP_line_end_m : REOP_line_end); 1864 break; 1865 case '.': 1866 p++; 1867 last_atom_start = s->byte_code.size; 1868 last_capture_count = s->capture_count; 1869 if (is_backward_dir) 1870 re_emit_op(s, REOP_prev); 1871 re_emit_op(s, s->dotall ? REOP_any : REOP_dot); 1872 if (is_backward_dir) 1873 re_emit_op(s, REOP_prev); 1874 break; 1875 case '{': 1876 if (s->is_unicode) { 1877 return re_parse_error(s, "syntax error"); 1878 } else if (!is_digit(p[1])) { 1879 /* Annex B: we accept '{' not followed by digits as a 1880 normal atom */ 1881 goto parse_class_atom; 1882 } else { 1883 const uint8_t *p1 = p + 1; 1884 /* Annex B: error if it is like a repetition count */ 1885 parse_digits(&p1, TRUE); 1886 if (*p1 == ',') { 1887 p1++; 1888 if (is_digit(*p1)) { 1889 parse_digits(&p1, TRUE); 1890 } 1891 } 1892 if (*p1 != '}') { 1893 goto parse_class_atom; 1894 } 1895 } 1896 /* fall thru */ 1897 case '*': 1898 case '+': 1899 case '?': 1900 return re_parse_error(s, "nothing to repeat"); 1901 case '(': 1902 if (p[1] == '?') { 1903 if (p[2] == ':') { 1904 p += 3; 1905 last_atom_start = s->byte_code.size; 1906 last_capture_count = s->capture_count; 1907 s->buf_ptr = p; 1908 if (re_parse_disjunction(s, is_backward_dir)) 1909 return -1; 1910 p = s->buf_ptr; 1911 if (re_parse_expect(s, &p, ')')) 1912 return -1; 1913 } else if (p[2] == 'i' || p[2] == 'm' || p[2] == 's' || p[2] == '-') { 1914 BOOL saved_ignore_case, saved_multi_line, saved_dotall; 1915 int add_mask, remove_mask; 1916 p += 2; 1917 remove_mask = 0; 1918 add_mask = re_parse_modifiers(s, &p); 1919 if (add_mask < 0) 1920 return -1; 1921 if (*p == '-') { 1922 p++; 1923 remove_mask = re_parse_modifiers(s, &p); 1924 if (remove_mask < 0) 1925 return -1; 1926 } 1927 if ((add_mask == 0 && remove_mask == 0) || 1928 (add_mask & remove_mask) != 0) { 1929 return re_parse_error(s, "invalid modifiers"); 1930 } 1931 if (re_parse_expect(s, &p, ':')) 1932 return -1; 1933 saved_ignore_case = s->ignore_case; 1934 saved_multi_line = s->multi_line; 1935 saved_dotall = s->dotall; 1936 s->ignore_case = update_modifier(s->ignore_case, add_mask, remove_mask, LRE_FLAG_IGNORECASE); 1937 s->multi_line = update_modifier(s->multi_line, add_mask, remove_mask, LRE_FLAG_MULTILINE); 1938 s->dotall = update_modifier(s->dotall, add_mask, remove_mask, LRE_FLAG_DOTALL); 1939 1940 last_atom_start = s->byte_code.size; 1941 last_capture_count = s->capture_count; 1942 s->buf_ptr = p; 1943 if (re_parse_disjunction(s, is_backward_dir)) 1944 return -1; 1945 p = s->buf_ptr; 1946 if (re_parse_expect(s, &p, ')')) 1947 return -1; 1948 s->ignore_case = saved_ignore_case; 1949 s->multi_line = saved_multi_line; 1950 s->dotall = saved_dotall; 1951 } else if ((p[2] == '=' || p[2] == '!')) { 1952 is_neg = (p[2] == '!'); 1953 is_backward_lookahead = FALSE; 1954 p += 3; 1955 goto lookahead; 1956 } else if (p[2] == '<' && 1957 (p[3] == '=' || p[3] == '!')) { 1958 int pos; 1959 is_neg = (p[3] == '!'); 1960 is_backward_lookahead = TRUE; 1961 p += 4; 1962 /* lookahead */ 1963 lookahead: 1964 /* Annex B allows lookahead to be used as an atom for 1965 the quantifiers */ 1966 if (!s->is_unicode && !is_backward_lookahead) { 1967 last_atom_start = s->byte_code.size; 1968 last_capture_count = s->capture_count; 1969 } 1970 pos = re_emit_op_u32(s, REOP_lookahead + is_neg, 0); 1971 s->buf_ptr = p; 1972 if (re_parse_disjunction(s, is_backward_lookahead)) 1973 return -1; 1974 p = s->buf_ptr; 1975 if (re_parse_expect(s, &p, ')')) 1976 return -1; 1977 re_emit_op(s, REOP_lookahead_match + is_neg); 1978 /* jump after the 'match' after the lookahead is successful */ 1979 if (dbuf_error(&s->byte_code)) 1980 return -1; 1981 put_u32(s->byte_code.buf + pos, s->byte_code.size - (pos + 4)); 1982 } else if (p[2] == '<') { 1983 p += 3; 1984 if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), 1985 &p)) { 1986 return re_parse_error(s, "invalid group name"); 1987 } 1988 /* poor's man method to test duplicate group 1989 names. */ 1990 /* XXX: this method does not catch all the errors*/ 1991 if (is_duplicate_group_name(s, s->u.tmp_buf, s->group_name_scope)) { 1992 return re_parse_error(s, "duplicate group name"); 1993 } 1994 /* group name with a trailing zero */ 1995 dbuf_put(&s->group_names, (uint8_t *)s->u.tmp_buf, 1996 strlen(s->u.tmp_buf) + 1); 1997 dbuf_putc(&s->group_names, s->group_name_scope); 1998 s->has_named_captures = 1; 1999 goto parse_capture; 2000 } else { 2001 return re_parse_error(s, "invalid group"); 2002 } 2003 } else { 2004 int capture_index; 2005 p++; 2006 /* capture without group name */ 2007 dbuf_putc(&s->group_names, 0); 2008 dbuf_putc(&s->group_names, 0); 2009 parse_capture: 2010 if (s->capture_count >= CAPTURE_COUNT_MAX) 2011 return re_parse_error(s, "too many captures"); 2012 last_atom_start = s->byte_code.size; 2013 last_capture_count = s->capture_count; 2014 capture_index = s->capture_count++; 2015 re_emit_op_u8(s, REOP_save_start + is_backward_dir, 2016 capture_index); 2017 2018 s->buf_ptr = p; 2019 if (re_parse_disjunction(s, is_backward_dir)) 2020 return -1; 2021 p = s->buf_ptr; 2022 2023 re_emit_op_u8(s, REOP_save_start + 1 - is_backward_dir, 2024 capture_index); 2025 2026 if (re_parse_expect(s, &p, ')')) 2027 return -1; 2028 } 2029 break; 2030 case '\\': 2031 switch(p[1]) { 2032 case 'b': 2033 case 'B': 2034 if (p[1] != 'b') { 2035 re_emit_op(s, s->ignore_case && s->is_unicode ? REOP_not_word_boundary_i : REOP_not_word_boundary); 2036 } else { 2037 re_emit_op(s, s->ignore_case && s->is_unicode ? REOP_word_boundary_i : REOP_word_boundary); 2038 } 2039 p += 2; 2040 break; 2041 case 'k': 2042 { 2043 const uint8_t *p1; 2044 int dummy_res, n; 2045 BOOL is_forward; 2046 2047 p1 = p; 2048 if (p1[2] != '<') { 2049 /* annex B: we tolerate invalid group names in non 2050 unicode mode if there is no named capture 2051 definition */ 2052 if (s->is_unicode || re_has_named_captures(s)) 2053 return re_parse_error(s, "expecting group name"); 2054 else 2055 goto parse_class_atom; 2056 } 2057 p1 += 3; 2058 if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), 2059 &p1)) { 2060 if (s->is_unicode || re_has_named_captures(s)) 2061 return re_parse_error(s, "invalid group name"); 2062 else 2063 goto parse_class_atom; 2064 } 2065 is_forward = FALSE; 2066 n = find_group_name(s, s->u.tmp_buf, FALSE); 2067 if (n == 0) { 2068 /* no capture name parsed before, try to look 2069 after (inefficient, but hopefully not common */ 2070 n = re_parse_captures(s, &dummy_res, s->u.tmp_buf, FALSE); 2071 if (n == 0) { 2072 if (s->is_unicode || re_has_named_captures(s)) 2073 return re_parse_error(s, "group name not defined"); 2074 else 2075 goto parse_class_atom; 2076 } 2077 is_forward = TRUE; 2078 } 2079 last_atom_start = s->byte_code.size; 2080 last_capture_count = s->capture_count; 2081 2082 /* emit back references to all the captures indexes matching the group name */ 2083 re_emit_op_u8(s, REOP_back_reference + 2 * is_backward_dir + s->ignore_case, n); 2084 if (is_forward) { 2085 re_parse_captures(s, &dummy_res, s->u.tmp_buf, TRUE); 2086 } else { 2087 find_group_name(s, s->u.tmp_buf, TRUE); 2088 } 2089 p = p1; 2090 } 2091 break; 2092 case '0': 2093 p += 2; 2094 c = 0; 2095 if (s->is_unicode) { 2096 if (is_digit(*p)) { 2097 return re_parse_error(s, "invalid decimal escape in regular expression"); 2098 } 2099 } else { 2100 /* Annex B.1.4: accept legacy octal */ 2101 if (*p >= '0' && *p <= '7') { 2102 c = *p++ - '0'; 2103 if (*p >= '0' && *p <= '7') { 2104 c = (c << 3) + *p++ - '0'; 2105 } 2106 } 2107 } 2108 goto normal_char; 2109 case '1': case '2': case '3': case '4': 2110 case '5': case '6': case '7': case '8': 2111 case '9': 2112 { 2113 const uint8_t *q = ++p; 2114 2115 c = parse_digits(&p, FALSE); 2116 if (c < 0 || (c >= s->capture_count && c >= re_count_captures(s))) { 2117 if (!s->is_unicode) { 2118 /* Annex B.1.4: accept legacy octal */ 2119 p = q; 2120 if (*p <= '7') { 2121 c = 0; 2122 if (*p <= '3') 2123 c = *p++ - '0'; 2124 if (*p >= '0' && *p <= '7') { 2125 c = (c << 3) + *p++ - '0'; 2126 if (*p >= '0' && *p <= '7') { 2127 c = (c << 3) + *p++ - '0'; 2128 } 2129 } 2130 } else { 2131 c = *p++; 2132 } 2133 goto normal_char; 2134 } 2135 return re_parse_error(s, "back reference out of range in regular expression"); 2136 } 2137 last_atom_start = s->byte_code.size; 2138 last_capture_count = s->capture_count; 2139 2140 re_emit_op_u8(s, REOP_back_reference + 2 * is_backward_dir + s->ignore_case, 1); 2141 dbuf_putc(&s->byte_code, c); 2142 } 2143 break; 2144 default: 2145 goto parse_class_atom; 2146 } 2147 break; 2148 case '[': 2149 last_atom_start = s->byte_code.size; 2150 last_capture_count = s->capture_count; 2151 if (is_backward_dir) 2152 re_emit_op(s, REOP_prev); 2153 if (re_parse_char_class(s, &p)) 2154 return -1; 2155 if (is_backward_dir) 2156 re_emit_op(s, REOP_prev); 2157 break; 2158 case ']': 2159 case '}': 2160 if (s->is_unicode) 2161 return re_parse_error(s, "syntax error"); 2162 goto parse_class_atom; 2163 default: 2164 parse_class_atom: 2165 c = get_class_atom(s, cr, &p, FALSE); 2166 if ((int)c < 0) 2167 return -1; 2168 normal_char: 2169 last_atom_start = s->byte_code.size; 2170 last_capture_count = s->capture_count; 2171 if (is_backward_dir) 2172 re_emit_op(s, REOP_prev); 2173 if (c >= CLASS_RANGE_BASE) { 2174 int ret = 0; 2175 /* optimize the common 'space' tests */ 2176 if (c == (CLASS_RANGE_BASE + CHAR_RANGE_s)) { 2177 re_emit_op(s, REOP_space); 2178 } else if (c == (CLASS_RANGE_BASE + CHAR_RANGE_S)) { 2179 re_emit_op(s, REOP_not_space); 2180 } else { 2181 ret = re_emit_string_list(s, cr); 2182 } 2183 re_string_list_free(cr); 2184 if (ret) 2185 return -1; 2186 } else { 2187 if (s->ignore_case) 2188 c = lre_canonicalize(c, s->is_unicode); 2189 re_emit_char(s, c); 2190 } 2191 if (is_backward_dir) 2192 re_emit_op(s, REOP_prev); 2193 break; 2194 } 2195 2196 /* quantifier */ 2197 if (last_atom_start >= 0) { 2198 c = *p; 2199 switch(c) { 2200 case '*': 2201 p++; 2202 quant_min = 0; 2203 quant_max = INT32_MAX; 2204 goto quantifier; 2205 case '+': 2206 p++; 2207 quant_min = 1; 2208 quant_max = INT32_MAX; 2209 goto quantifier; 2210 case '?': 2211 p++; 2212 quant_min = 0; 2213 quant_max = 1; 2214 goto quantifier; 2215 case '{': 2216 { 2217 const uint8_t *p1 = p; 2218 /* As an extension (see ES6 annex B), we accept '{' not 2219 followed by digits as a normal atom */ 2220 if (!is_digit(p[1])) { 2221 if (s->is_unicode) 2222 goto invalid_quant_count; 2223 break; 2224 } 2225 p++; 2226 quant_min = parse_digits(&p, TRUE); 2227 quant_max = quant_min; 2228 if (*p == ',') { 2229 p++; 2230 if (is_digit(*p)) { 2231 quant_max = parse_digits(&p, TRUE); 2232 if (quant_max < quant_min) { 2233 invalid_quant_count: 2234 return re_parse_error(s, "invalid repetition count"); 2235 } 2236 } else { 2237 quant_max = INT32_MAX; /* infinity */ 2238 } 2239 } 2240 if (*p != '}' && !s->is_unicode) { 2241 /* Annex B: normal atom if invalid '{' syntax */ 2242 p = p1; 2243 break; 2244 } 2245 if (re_parse_expect(s, &p, '}')) 2246 return -1; 2247 } 2248 quantifier: 2249 greedy = TRUE; 2250 if (*p == '?') { 2251 p++; 2252 greedy = FALSE; 2253 } 2254 if (last_atom_start < 0) { 2255 return re_parse_error(s, "nothing to repeat"); 2256 } 2257 { 2258 BOOL need_capture_init, add_zero_advance_check; 2259 int len, pos; 2260 2261 /* the spec tells that if there is no advance when 2262 running the atom after the first quant_min times, 2263 then there is no match. We remove this test when we 2264 are sure the atom always advances the position. */ 2265 add_zero_advance_check = 2266 re_need_check_adv_and_capture_init(&need_capture_init, 2267 s->byte_code.buf + last_atom_start, 2268 s->byte_code.size - last_atom_start); 2269 2270 /* general case: need to reset the capture at each 2271 iteration. We don't do it if there are no captures 2272 in the atom or if we are sure all captures are 2273 initialized in the atom. If quant_min = 0, we still 2274 need to reset once the captures in case the atom 2275 does not match. */ 2276 if (need_capture_init && last_capture_count != s->capture_count) { 2277 if (dbuf_insert(&s->byte_code, last_atom_start, 3)) 2278 goto out_of_memory; 2279 int pos = last_atom_start; 2280 s->byte_code.buf[pos++] = REOP_save_reset; 2281 s->byte_code.buf[pos++] = last_capture_count; 2282 s->byte_code.buf[pos++] = s->capture_count - 1; 2283 } 2284 2285 len = s->byte_code.size - last_atom_start; 2286 if (quant_min == 0) { 2287 /* need to reset the capture in case the atom is 2288 not executed */ 2289 if (!need_capture_init && last_capture_count != s->capture_count) { 2290 if (dbuf_insert(&s->byte_code, last_atom_start, 3)) 2291 goto out_of_memory; 2292 s->byte_code.buf[last_atom_start++] = REOP_save_reset; 2293 s->byte_code.buf[last_atom_start++] = last_capture_count; 2294 s->byte_code.buf[last_atom_start++] = s->capture_count - 1; 2295 } 2296 if (quant_max == 0) { 2297 s->byte_code.size = last_atom_start; 2298 } else if (quant_max == 1 || quant_max == INT32_MAX) { 2299 BOOL has_goto = (quant_max == INT32_MAX); 2300 if (dbuf_insert(&s->byte_code, last_atom_start, 5 + add_zero_advance_check * 2)) 2301 goto out_of_memory; 2302 s->byte_code.buf[last_atom_start] = REOP_split_goto_first + 2303 greedy; 2304 put_u32(s->byte_code.buf + last_atom_start + 1, 2305 len + 5 * has_goto + add_zero_advance_check * 2 * 2); 2306 if (add_zero_advance_check) { 2307 s->byte_code.buf[last_atom_start + 1 + 4] = REOP_set_char_pos; 2308 s->byte_code.buf[last_atom_start + 1 + 4 + 1] = 0; 2309 re_emit_op_u8(s, REOP_check_advance, 0); 2310 } 2311 if (has_goto) 2312 re_emit_goto(s, REOP_goto, last_atom_start); 2313 } else { 2314 if (dbuf_insert(&s->byte_code, last_atom_start, 11 + add_zero_advance_check * 2)) 2315 goto out_of_memory; 2316 pos = last_atom_start; 2317 s->byte_code.buf[pos++] = REOP_split_goto_first + greedy; 2318 put_u32(s->byte_code.buf + pos, 6 + add_zero_advance_check * 2 + len + 10); 2319 pos += 4; 2320 2321 s->byte_code.buf[pos++] = REOP_set_i32; 2322 s->byte_code.buf[pos++] = 0; 2323 put_u32(s->byte_code.buf + pos, quant_max); 2324 pos += 4; 2325 last_atom_start = pos; 2326 if (add_zero_advance_check) { 2327 s->byte_code.buf[pos++] = REOP_set_char_pos; 2328 s->byte_code.buf[pos++] = 0; 2329 } 2330 re_emit_goto_u8_u32(s, (add_zero_advance_check ? REOP_loop_check_adv_split_next_first : REOP_loop_split_next_first) - greedy, 0, quant_max, last_atom_start); 2331 } 2332 } else if (quant_min == 1 && quant_max == INT32_MAX && 2333 !add_zero_advance_check) { 2334 re_emit_goto(s, REOP_split_next_first - greedy, 2335 last_atom_start); 2336 } else { 2337 if (quant_min == quant_max) 2338 add_zero_advance_check = FALSE; 2339 if (dbuf_insert(&s->byte_code, last_atom_start, 6 + add_zero_advance_check * 2)) 2340 goto out_of_memory; 2341 /* Note: we assume the string length is < INT32_MAX */ 2342 pos = last_atom_start; 2343 s->byte_code.buf[pos++] = REOP_set_i32; 2344 s->byte_code.buf[pos++] = 0; 2345 put_u32(s->byte_code.buf + pos, quant_max); 2346 pos += 4; 2347 last_atom_start = pos; 2348 if (add_zero_advance_check) { 2349 s->byte_code.buf[pos++] = REOP_set_char_pos; 2350 s->byte_code.buf[pos++] = 0; 2351 } 2352 if (quant_min == quant_max) { 2353 /* a simple loop is enough */ 2354 re_emit_goto_u8(s, REOP_loop, 0, last_atom_start); 2355 } else { 2356 re_emit_goto_u8_u32(s, (add_zero_advance_check ? REOP_loop_check_adv_split_next_first : REOP_loop_split_next_first) - greedy, 0, quant_max - quant_min, last_atom_start); 2357 } 2358 } 2359 last_atom_start = -1; 2360 } 2361 break; 2362 default: 2363 break; 2364 } 2365 } 2366 s->buf_ptr = p; 2367 return 0; 2368 out_of_memory: 2369 return re_parse_out_of_memory(s); 2370 } 2371 2372 static int re_parse_alternative(REParseState *s, BOOL is_backward_dir) 2373 { 2374 const uint8_t *p; 2375 int ret; 2376 size_t start, term_start, end, term_size; 2377 2378 start = s->byte_code.size; 2379 for(;;) { 2380 p = s->buf_ptr; 2381 if (p >= s->buf_end) 2382 break; 2383 if (*p == '|' || *p == ')') 2384 break; 2385 term_start = s->byte_code.size; 2386 ret = re_parse_term(s, is_backward_dir); 2387 if (ret) 2388 return ret; 2389 if (is_backward_dir) { 2390 /* reverse the order of the terms (XXX: inefficient, but 2391 speed is not really critical here) */ 2392 end = s->byte_code.size; 2393 term_size = end - term_start; 2394 if (dbuf_claim(&s->byte_code, term_size)) 2395 return -1; 2396 memmove(s->byte_code.buf + start + term_size, 2397 s->byte_code.buf + start, 2398 end - start); 2399 memcpy(s->byte_code.buf + start, s->byte_code.buf + end, 2400 term_size); 2401 } 2402 } 2403 return 0; 2404 } 2405 2406 static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir) 2407 { 2408 int start, len, pos; 2409 2410 if (lre_check_stack_overflow(s->opaque, 0)) 2411 return re_parse_error(s, "stack overflow"); 2412 2413 start = s->byte_code.size; 2414 if (re_parse_alternative(s, is_backward_dir)) 2415 return -1; 2416 while (*s->buf_ptr == '|') { 2417 s->buf_ptr++; 2418 2419 len = s->byte_code.size - start; 2420 2421 /* insert a split before the first alternative */ 2422 if (dbuf_insert(&s->byte_code, start, 5)) { 2423 return re_parse_out_of_memory(s); 2424 } 2425 s->byte_code.buf[start] = REOP_split_next_first; 2426 put_u32(s->byte_code.buf + start + 1, len + 5); 2427 2428 pos = re_emit_op_u32(s, REOP_goto, 0); 2429 2430 s->group_name_scope++; 2431 2432 if (re_parse_alternative(s, is_backward_dir)) 2433 return -1; 2434 2435 /* patch the goto */ 2436 len = s->byte_code.size - (pos + 4); 2437 put_u32(s->byte_code.buf + pos, len); 2438 } 2439 return 0; 2440 } 2441 2442 /* Allocate the registers as a stack. The control flow is recursive so 2443 the analysis can be linear. */ 2444 static int compute_register_count(uint8_t *bc_buf, int bc_buf_len) 2445 { 2446 int stack_size, stack_size_max, pos, opcode, len; 2447 uint32_t val; 2448 2449 stack_size = 0; 2450 stack_size_max = 0; 2451 bc_buf += RE_HEADER_LEN; 2452 bc_buf_len -= RE_HEADER_LEN; 2453 pos = 0; 2454 while (pos < bc_buf_len) { 2455 opcode = bc_buf[pos]; 2456 len = reopcode_info[opcode].size; 2457 assert(opcode < REOP_COUNT); 2458 assert((pos + len) <= bc_buf_len); 2459 switch(opcode) { 2460 case REOP_set_i32: 2461 case REOP_set_char_pos: 2462 bc_buf[pos + 1] = stack_size; 2463 stack_size++; 2464 if (stack_size > stack_size_max) { 2465 if (stack_size > REGISTER_COUNT_MAX) 2466 return -1; 2467 stack_size_max = stack_size; 2468 } 2469 break; 2470 case REOP_check_advance: 2471 case REOP_loop: 2472 case REOP_loop_split_goto_first: 2473 case REOP_loop_split_next_first: 2474 assert(stack_size > 0); 2475 stack_size--; 2476 bc_buf[pos + 1] = stack_size; 2477 break; 2478 case REOP_loop_check_adv_split_goto_first: 2479 case REOP_loop_check_adv_split_next_first: 2480 assert(stack_size >= 2); 2481 stack_size -= 2; 2482 bc_buf[pos + 1] = stack_size; 2483 break; 2484 case REOP_range: 2485 case REOP_range_i: 2486 val = get_u16(bc_buf + pos + 1); 2487 len += val * 4; 2488 break; 2489 case REOP_range32: 2490 case REOP_range32_i: 2491 val = get_u16(bc_buf + pos + 1); 2492 len += val * 8; 2493 break; 2494 case REOP_back_reference: 2495 case REOP_back_reference_i: 2496 case REOP_backward_back_reference: 2497 case REOP_backward_back_reference_i: 2498 val = bc_buf[pos + 1]; 2499 len += val; 2500 break; 2501 } 2502 pos += len; 2503 } 2504 return stack_size_max; 2505 } 2506 2507 static void *lre_bytecode_realloc(void *opaque, void *ptr, size_t size) 2508 { 2509 if (size > (INT32_MAX / 2)) { 2510 /* the bytecode cannot be larger than 2G. Leave some slack to 2511 avoid some overflows. */ 2512 return NULL; 2513 } else { 2514 return lre_realloc(opaque, ptr, size); 2515 } 2516 } 2517 2518 /* 'buf' must be a zero terminated UTF-8 string of length buf_len. 2519 Return NULL if error and allocate an error message in *perror_msg, 2520 otherwise the compiled bytecode and its length in plen. 2521 */ 2522 uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, 2523 const char *buf, size_t buf_len, int re_flags, 2524 void *opaque) 2525 { 2526 REParseState s_s, *s = &s_s; 2527 int register_count; 2528 BOOL is_sticky; 2529 2530 memset(s, 0, sizeof(*s)); 2531 s->opaque = opaque; 2532 s->buf_ptr = (const uint8_t *)buf; 2533 s->buf_end = s->buf_ptr + buf_len; 2534 s->buf_start = s->buf_ptr; 2535 s->re_flags = re_flags; 2536 s->is_unicode = ((re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0); 2537 is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0); 2538 s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0); 2539 s->multi_line = ((re_flags & LRE_FLAG_MULTILINE) != 0); 2540 s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0); 2541 s->unicode_sets = ((re_flags & LRE_FLAG_UNICODE_SETS) != 0); 2542 s->capture_count = 1; 2543 s->total_capture_count = -1; 2544 s->has_named_captures = -1; 2545 2546 dbuf_init2(&s->byte_code, opaque, lre_bytecode_realloc); 2547 dbuf_init2(&s->group_names, opaque, lre_realloc); 2548 2549 dbuf_put_u16(&s->byte_code, re_flags); /* first element is the flags */ 2550 dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */ 2551 dbuf_putc(&s->byte_code, 0); /* stack size */ 2552 dbuf_put_u32(&s->byte_code, 0); /* bytecode length */ 2553 2554 if (!is_sticky) { 2555 /* iterate thru all positions (about the same as .*?( ... ) ) 2556 . We do it without an explicit loop so that lock step 2557 thread execution will be possible in an optimized 2558 implementation */ 2559 re_emit_op_u32(s, REOP_split_goto_first, 1 + 5); 2560 re_emit_op(s, REOP_any); 2561 re_emit_op_u32(s, REOP_goto, -(5 + 1 + 5)); 2562 } 2563 re_emit_op_u8(s, REOP_save_start, 0); 2564 2565 if (re_parse_disjunction(s, FALSE)) { 2566 error: 2567 dbuf_free(&s->byte_code); 2568 dbuf_free(&s->group_names); 2569 pstrcpy(error_msg, error_msg_size, s->u.error_msg); 2570 *plen = 0; 2571 return NULL; 2572 } 2573 2574 re_emit_op_u8(s, REOP_save_end, 0); 2575 2576 re_emit_op(s, REOP_match); 2577 2578 if (*s->buf_ptr != '\0') { 2579 re_parse_error(s, "extraneous characters at the end"); 2580 goto error; 2581 } 2582 2583 if (dbuf_error(&s->byte_code)) { 2584 re_parse_out_of_memory(s); 2585 goto error; 2586 } 2587 2588 register_count = compute_register_count(s->byte_code.buf, s->byte_code.size); 2589 if (register_count < 0) { 2590 re_parse_error(s, "too many imbricated quantifiers"); 2591 goto error; 2592 } 2593 2594 s->byte_code.buf[RE_HEADER_CAPTURE_COUNT] = s->capture_count; 2595 s->byte_code.buf[RE_HEADER_REGISTER_COUNT] = register_count; 2596 put_u32(s->byte_code.buf + RE_HEADER_BYTECODE_LEN, 2597 s->byte_code.size - RE_HEADER_LEN); 2598 2599 /* add the named groups if needed */ 2600 if (s->group_names.size > (s->capture_count - 1) * LRE_GROUP_NAME_TRAILER_LEN) { 2601 dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size); 2602 put_u16(s->byte_code.buf + RE_HEADER_FLAGS, 2603 lre_get_flags(s->byte_code.buf) | LRE_FLAG_NAMED_GROUPS); 2604 } 2605 dbuf_free(&s->group_names); 2606 2607 #ifdef DUMP_REOP 2608 lre_dump_bytecode(s->byte_code.buf, s->byte_code.size); 2609 #endif 2610 2611 error_msg[0] = '\0'; 2612 *plen = s->byte_code.size; 2613 return s->byte_code.buf; 2614 } 2615 2616 static BOOL is_line_terminator(uint32_t c) 2617 { 2618 return (c == '\n' || c == '\r' || c == CP_LS || c == CP_PS); 2619 } 2620 2621 #define GET_CHAR(c, cptr, cbuf_end, cbuf_type) \ 2622 do { \ 2623 if (cbuf_type == 0) { \ 2624 c = *cptr++; \ 2625 } else { \ 2626 const uint16_t *_p = (const uint16_t *)cptr; \ 2627 const uint16_t *_end = (const uint16_t *)cbuf_end; \ 2628 c = *_p++; \ 2629 if (is_hi_surrogate(c) && cbuf_type == 2) { \ 2630 if (_p < _end && is_lo_surrogate(*_p)) { \ 2631 c = from_surrogate(c, *_p++); \ 2632 } \ 2633 } \ 2634 cptr = (const void *)_p; \ 2635 } \ 2636 } while (0) 2637 2638 #define PEEK_CHAR(c, cptr, cbuf_end, cbuf_type) \ 2639 do { \ 2640 if (cbuf_type == 0) { \ 2641 c = cptr[0]; \ 2642 } else { \ 2643 const uint16_t *_p = (const uint16_t *)cptr; \ 2644 const uint16_t *_end = (const uint16_t *)cbuf_end; \ 2645 c = *_p++; \ 2646 if (is_hi_surrogate(c) && cbuf_type == 2) { \ 2647 if (_p < _end && is_lo_surrogate(*_p)) { \ 2648 c = from_surrogate(c, *_p); \ 2649 } \ 2650 } \ 2651 } \ 2652 } while (0) 2653 2654 #define PEEK_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \ 2655 do { \ 2656 if (cbuf_type == 0) { \ 2657 c = cptr[-1]; \ 2658 } else { \ 2659 const uint16_t *_p = (const uint16_t *)cptr - 1; \ 2660 const uint16_t *_start = (const uint16_t *)cbuf_start; \ 2661 c = *_p; \ 2662 if (is_lo_surrogate(c) && cbuf_type == 2) { \ 2663 if (_p > _start && is_hi_surrogate(_p[-1])) { \ 2664 c = from_surrogate(*--_p, c); \ 2665 } \ 2666 } \ 2667 } \ 2668 } while (0) 2669 2670 #define GET_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \ 2671 do { \ 2672 if (cbuf_type == 0) { \ 2673 cptr--; \ 2674 c = cptr[0]; \ 2675 } else { \ 2676 const uint16_t *_p = (const uint16_t *)cptr - 1; \ 2677 const uint16_t *_start = (const uint16_t *)cbuf_start; \ 2678 c = *_p; \ 2679 if (is_lo_surrogate(c) && cbuf_type == 2) { \ 2680 if (_p > _start && is_hi_surrogate(_p[-1])) { \ 2681 c = from_surrogate(*--_p, c); \ 2682 } \ 2683 } \ 2684 cptr = (const void *)_p; \ 2685 } \ 2686 } while (0) 2687 2688 #define PREV_CHAR(cptr, cbuf_start, cbuf_type) \ 2689 do { \ 2690 if (cbuf_type == 0) { \ 2691 cptr--; \ 2692 } else { \ 2693 const uint16_t *_p = (const uint16_t *)cptr - 1; \ 2694 const uint16_t *_start = (const uint16_t *)cbuf_start; \ 2695 if (is_lo_surrogate(*_p) && cbuf_type == 2) { \ 2696 if (_p > _start && is_hi_surrogate(_p[-1])) { \ 2697 --_p; \ 2698 } \ 2699 } \ 2700 cptr = (const void *)_p; \ 2701 } \ 2702 } while (0) 2703 2704 typedef enum { 2705 RE_EXEC_STATE_SPLIT, 2706 RE_EXEC_STATE_LOOKAHEAD, 2707 RE_EXEC_STATE_NEGATIVE_LOOKAHEAD, 2708 } REExecStateEnum; 2709 2710 #if INTPTR_MAX >= INT64_MAX 2711 #define BP_TYPE_BITS 3 2712 #else 2713 #define BP_TYPE_BITS 2 2714 #endif 2715 2716 typedef union { 2717 uint8_t *ptr; 2718 intptr_t val; /* for bp, the low BP_SHIFT bits store REExecStateEnum */ 2719 struct { 2720 uintptr_t val : sizeof(uintptr_t) * 8 - BP_TYPE_BITS; 2721 uintptr_t type : BP_TYPE_BITS; 2722 } bp; 2723 } StackElem; 2724 2725 typedef struct { 2726 const uint8_t *cbuf; 2727 const uint8_t *cbuf_end; 2728 /* 0 = 8 bit chars, 1 = 16 bit chars, 2 = 16 bit chars, UTF-16 */ 2729 int cbuf_type; 2730 int capture_count; 2731 BOOL is_unicode; 2732 int interrupt_counter; 2733 void *opaque; /* used for stack overflow check */ 2734 2735 StackElem *stack_buf; 2736 size_t stack_size; 2737 StackElem static_stack_buf[32]; /* static stack to avoid allocation in most cases */ 2738 } REExecContext; 2739 2740 static int lre_poll_timeout(REExecContext *s) 2741 { 2742 if (unlikely(--s->interrupt_counter <= 0)) { 2743 s->interrupt_counter = INTERRUPT_COUNTER_INIT; 2744 if (lre_check_timeout(s->opaque)) 2745 return LRE_RET_TIMEOUT; 2746 } 2747 return 0; 2748 } 2749 2750 static no_inline int stack_realloc(REExecContext *s, size_t n) 2751 { 2752 StackElem *new_stack; 2753 size_t new_size; 2754 new_size = s->stack_size * 3 / 2; 2755 if (new_size < n) 2756 new_size = n; 2757 if (s->stack_buf == s->static_stack_buf) { 2758 new_stack = lre_realloc(s->opaque, NULL, new_size * sizeof(StackElem)); 2759 if (!new_stack) 2760 return -1; 2761 /* XXX: could use correct size */ 2762 memcpy(new_stack, s->stack_buf, s->stack_size * sizeof(StackElem)); 2763 } else { 2764 new_stack = lre_realloc(s->opaque, s->stack_buf, new_size * sizeof(StackElem)); 2765 if (!new_stack) 2766 return -1; 2767 } 2768 s->stack_size = new_size; 2769 s->stack_buf = new_stack; 2770 return 0; 2771 } 2772 2773 /* return 1 if match, 0 if not match or < 0 if error. */ 2774 static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture, 2775 const uint8_t *pc, const uint8_t *cptr) 2776 { 2777 int opcode; 2778 int cbuf_type; 2779 uint32_t val, c, idx; 2780 const uint8_t *cbuf_end; 2781 StackElem *sp, *bp, *stack_end; 2782 #ifdef DUMP_EXEC 2783 const uint8_t *pc_start = pc; /* TEST */ 2784 #endif 2785 cbuf_type = s->cbuf_type; 2786 cbuf_end = s->cbuf_end; 2787 2788 sp = s->stack_buf; 2789 bp = s->stack_buf; 2790 stack_end = s->stack_buf + s->stack_size; 2791 2792 #define CHECK_STACK_SPACE(n) \ 2793 if (unlikely((stack_end - sp) < (n))) { \ 2794 size_t saved_sp = sp - s->stack_buf; \ 2795 size_t saved_bp = bp - s->stack_buf; \ 2796 if (stack_realloc(s, sp - s->stack_buf + (n))) \ 2797 return LRE_RET_MEMORY_ERROR; \ 2798 stack_end = s->stack_buf + s->stack_size; \ 2799 sp = s->stack_buf + saved_sp; \ 2800 bp = s->stack_buf + saved_bp; \ 2801 } 2802 2803 /* XXX: could test if the value was saved to reduce the stack size 2804 but slower */ 2805 #define SAVE_CAPTURE(idx, value) \ 2806 { \ 2807 CHECK_STACK_SPACE(2); \ 2808 sp[0].val = idx; \ 2809 sp[1].ptr = capture[idx]; \ 2810 sp += 2; \ 2811 capture[idx] = (value); \ 2812 } 2813 2814 /* avoid saving the previous value if already saved */ 2815 #define SAVE_CAPTURE_CHECK(idx, value) \ 2816 { \ 2817 StackElem *sp1; \ 2818 sp1 = sp; \ 2819 for(;;) { \ 2820 if (sp1 > bp) { \ 2821 if (sp1[-2].val == idx) \ 2822 break; \ 2823 sp1 -= 2; \ 2824 } else { \ 2825 CHECK_STACK_SPACE(2); \ 2826 sp[0].val = idx; \ 2827 sp[1].ptr = capture[idx]; \ 2828 sp += 2; \ 2829 break; \ 2830 } \ 2831 } \ 2832 capture[idx] = (value); \ 2833 } 2834 2835 2836 #ifdef DUMP_EXEC 2837 printf("%5s %5s %5s %5s %s\n", "PC", "CP", "BP", "SP", "OPCODE"); 2838 #endif 2839 for(;;) { 2840 opcode = *pc++; 2841 #ifdef DUMP_EXEC 2842 printf("%5ld %5ld %5ld %5ld %s\n", 2843 pc - 1 - pc_start, 2844 cbuf_type == 0 ? cptr - s->cbuf : (cptr - s->cbuf) / 2, 2845 bp - s->stack_buf, 2846 sp - s->stack_buf, 2847 reopcode_info[opcode].name); 2848 #endif 2849 switch(opcode) { 2850 case REOP_match: 2851 return 1; 2852 no_match: 2853 for(;;) { 2854 REExecStateEnum type; 2855 if (bp == s->stack_buf) 2856 return 0; 2857 /* undo the modifications to capture[] */ 2858 while (sp > bp) { 2859 capture[sp[-2].val] = sp[-1].ptr; 2860 sp -= 2; 2861 } 2862 2863 pc = sp[-3].ptr; 2864 cptr = sp[-2].ptr; 2865 type = sp[-1].bp.type; 2866 bp = s->stack_buf + sp[-1].bp.val; 2867 sp -= 3; 2868 if (type != RE_EXEC_STATE_LOOKAHEAD) 2869 break; 2870 } 2871 if (lre_poll_timeout(s)) 2872 return LRE_RET_TIMEOUT; 2873 break; 2874 case REOP_lookahead_match: 2875 /* pop all the saved states until reaching the start of 2876 the lookahead and keep the updated captures and 2877 variables and the corresponding undo info. */ 2878 { 2879 StackElem *sp1, *sp_top, *next_sp; 2880 REExecStateEnum type; 2881 2882 sp_top = sp; 2883 for(;;) { 2884 sp1 = sp; 2885 sp = bp; 2886 pc = sp[-3].ptr; 2887 cptr = sp[-2].ptr; 2888 type = sp[-1].bp.type; 2889 bp = s->stack_buf + sp[-1].bp.val; 2890 sp[-1].ptr = (void *)sp1; /* save the next value for the copy step */ 2891 sp -= 3; 2892 if (type == RE_EXEC_STATE_LOOKAHEAD) 2893 break; 2894 } 2895 if (sp != s->stack_buf) { 2896 /* keep the undo info if there is a saved state */ 2897 sp1 = sp; 2898 while (sp1 < sp_top) { 2899 next_sp = (void *)sp1[2].ptr; 2900 sp1 += 3; 2901 while (sp1 < next_sp) 2902 *sp++ = *sp1++; 2903 } 2904 } 2905 } 2906 break; 2907 case REOP_negative_lookahead_match: 2908 /* pop all the saved states until reaching start of the negative lookahead */ 2909 for(;;) { 2910 REExecStateEnum type; 2911 type = bp[-1].bp.type; 2912 /* undo the modifications to capture[] */ 2913 while (sp > bp) { 2914 capture[sp[-2].val] = sp[-1].ptr; 2915 sp -= 2; 2916 } 2917 pc = sp[-3].ptr; 2918 cptr = sp[-2].ptr; 2919 type = sp[-1].bp.type; 2920 bp = s->stack_buf + sp[-1].bp.val; 2921 sp -= 3; 2922 if (type == RE_EXEC_STATE_NEGATIVE_LOOKAHEAD) 2923 break; 2924 } 2925 goto no_match; 2926 case REOP_char32: 2927 case REOP_char32_i: 2928 val = get_u32(pc); 2929 pc += 4; 2930 goto test_char; 2931 case REOP_char: 2932 case REOP_char_i: 2933 val = get_u16(pc); 2934 pc += 2; 2935 test_char: 2936 if (cptr >= cbuf_end) 2937 goto no_match; 2938 GET_CHAR(c, cptr, cbuf_end, cbuf_type); 2939 if (opcode == REOP_char_i || opcode == REOP_char32_i) { 2940 c = lre_canonicalize(c, s->is_unicode); 2941 } 2942 if (val != c) 2943 goto no_match; 2944 break; 2945 case REOP_split_goto_first: 2946 case REOP_split_next_first: 2947 { 2948 const uint8_t *pc1; 2949 2950 val = get_u32(pc); 2951 pc += 4; 2952 if (opcode == REOP_split_next_first) { 2953 pc1 = pc + (int)val; 2954 } else { 2955 pc1 = pc; 2956 pc = pc + (int)val; 2957 } 2958 CHECK_STACK_SPACE(3); 2959 sp[0].ptr = (uint8_t *)pc1; 2960 sp[1].ptr = (uint8_t *)cptr; 2961 sp[2].bp.val = bp - s->stack_buf; 2962 sp[2].bp.type = RE_EXEC_STATE_SPLIT; 2963 sp += 3; 2964 bp = sp; 2965 } 2966 break; 2967 case REOP_lookahead: 2968 case REOP_negative_lookahead: 2969 val = get_u32(pc); 2970 pc += 4; 2971 CHECK_STACK_SPACE(3); 2972 sp[0].ptr = (uint8_t *)(pc + (int)val); 2973 sp[1].ptr = (uint8_t *)cptr; 2974 sp[2].bp.val = bp - s->stack_buf; 2975 sp[2].bp.type = RE_EXEC_STATE_LOOKAHEAD + opcode - REOP_lookahead; 2976 sp += 3; 2977 bp = sp; 2978 break; 2979 case REOP_goto: 2980 val = get_u32(pc); 2981 pc += 4 + (int)val; 2982 if (lre_poll_timeout(s)) 2983 return LRE_RET_TIMEOUT; 2984 break; 2985 case REOP_line_start: 2986 case REOP_line_start_m: 2987 if (cptr == s->cbuf) 2988 break; 2989 if (opcode == REOP_line_start) 2990 goto no_match; 2991 PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type); 2992 if (!is_line_terminator(c)) 2993 goto no_match; 2994 break; 2995 case REOP_line_end: 2996 case REOP_line_end_m: 2997 if (cptr == cbuf_end) 2998 break; 2999 if (opcode == REOP_line_end) 3000 goto no_match; 3001 PEEK_CHAR(c, cptr, cbuf_end, cbuf_type); 3002 if (!is_line_terminator(c)) 3003 goto no_match; 3004 break; 3005 case REOP_dot: 3006 if (cptr == cbuf_end) 3007 goto no_match; 3008 GET_CHAR(c, cptr, cbuf_end, cbuf_type); 3009 if (is_line_terminator(c)) 3010 goto no_match; 3011 break; 3012 case REOP_any: 3013 if (cptr == cbuf_end) 3014 goto no_match; 3015 GET_CHAR(c, cptr, cbuf_end, cbuf_type); 3016 break; 3017 case REOP_space: 3018 if (cptr == cbuf_end) 3019 goto no_match; 3020 GET_CHAR(c, cptr, cbuf_end, cbuf_type); 3021 if (!lre_is_space(c)) 3022 goto no_match; 3023 break; 3024 case REOP_not_space: 3025 if (cptr == cbuf_end) 3026 goto no_match; 3027 GET_CHAR(c, cptr, cbuf_end, cbuf_type); 3028 if (lre_is_space(c)) 3029 goto no_match; 3030 break; 3031 case REOP_save_start: 3032 case REOP_save_end: 3033 val = *pc++; 3034 assert(val < s->capture_count); 3035 idx = 2 * val + opcode - REOP_save_start; 3036 SAVE_CAPTURE(idx, (uint8_t *)cptr); 3037 break; 3038 case REOP_save_reset: 3039 { 3040 uint32_t val2; 3041 val = pc[0]; 3042 val2 = pc[1]; 3043 pc += 2; 3044 assert(val2 < s->capture_count); 3045 CHECK_STACK_SPACE(2 * (val2 - val + 1)); 3046 while (val <= val2) { 3047 idx = 2 * val; 3048 SAVE_CAPTURE(idx, NULL); 3049 idx = 2 * val + 1; 3050 SAVE_CAPTURE(idx, NULL); 3051 val++; 3052 } 3053 } 3054 break; 3055 case REOP_set_i32: 3056 idx = 2 * s->capture_count + pc[0]; 3057 val = get_u32(pc + 1); 3058 pc += 5; 3059 SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val); 3060 break; 3061 case REOP_loop: 3062 { 3063 uint32_t val2; 3064 idx = 2 * s->capture_count + pc[0]; 3065 val = get_u32(pc + 1); 3066 pc += 5; 3067 3068 val2 = (uintptr_t)capture[idx] - 1; 3069 SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val2); 3070 if (val2 != 0) { 3071 pc += (int)val; 3072 if (lre_poll_timeout(s)) 3073 return LRE_RET_TIMEOUT; 3074 } 3075 } 3076 break; 3077 case REOP_loop_split_goto_first: 3078 case REOP_loop_split_next_first: 3079 case REOP_loop_check_adv_split_goto_first: 3080 case REOP_loop_check_adv_split_next_first: 3081 { 3082 const uint8_t *pc1; 3083 uint32_t val2, limit; 3084 idx = 2 * s->capture_count + pc[0]; 3085 limit = get_u32(pc + 1); 3086 val = get_u32(pc + 5); 3087 pc += 9; 3088 3089 /* decrement the counter */ 3090 val2 = (uintptr_t)capture[idx] - 1; 3091 SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val2); 3092 3093 if (val2 > limit) { 3094 /* normal loop if counter > limit */ 3095 pc += (int)val; 3096 if (lre_poll_timeout(s)) 3097 return LRE_RET_TIMEOUT; 3098 } else { 3099 /* check advance */ 3100 if ((opcode == REOP_loop_check_adv_split_goto_first || 3101 opcode == REOP_loop_check_adv_split_next_first) && 3102 capture[idx + 1] == cptr && 3103 val2 != limit) { 3104 goto no_match; 3105 } 3106 3107 /* otherwise conditional split */ 3108 if (val2 != 0) { 3109 if (opcode == REOP_loop_split_next_first || 3110 opcode == REOP_loop_check_adv_split_next_first) { 3111 pc1 = pc + (int)val; 3112 } else { 3113 pc1 = pc; 3114 pc = pc + (int)val; 3115 } 3116 CHECK_STACK_SPACE(3); 3117 sp[0].ptr = (uint8_t *)pc1; 3118 sp[1].ptr = (uint8_t *)cptr; 3119 sp[2].bp.val = bp - s->stack_buf; 3120 sp[2].bp.type = RE_EXEC_STATE_SPLIT; 3121 sp += 3; 3122 bp = sp; 3123 } 3124 } 3125 } 3126 break; 3127 case REOP_set_char_pos: 3128 idx = 2 * s->capture_count + pc[0]; 3129 pc++; 3130 SAVE_CAPTURE_CHECK(idx, (uint8_t *)cptr); 3131 break; 3132 case REOP_check_advance: 3133 idx = 2 * s->capture_count + pc[0]; 3134 pc++; 3135 if (capture[idx] == cptr) 3136 goto no_match; 3137 break; 3138 case REOP_word_boundary: 3139 case REOP_word_boundary_i: 3140 case REOP_not_word_boundary: 3141 case REOP_not_word_boundary_i: 3142 { 3143 BOOL v1, v2; 3144 int ignore_case = (opcode == REOP_word_boundary_i || opcode == REOP_not_word_boundary_i); 3145 BOOL is_boundary = (opcode == REOP_word_boundary || opcode == REOP_word_boundary_i); 3146 /* char before */ 3147 if (cptr == s->cbuf) { 3148 v1 = FALSE; 3149 } else { 3150 PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type); 3151 if (c < 256) { 3152 v1 = (lre_is_word_byte(c) != 0); 3153 } else { 3154 v1 = ignore_case && (c == 0x017f || c == 0x212a); 3155 } 3156 } 3157 /* current char */ 3158 if (cptr >= cbuf_end) { 3159 v2 = FALSE; 3160 } else { 3161 PEEK_CHAR(c, cptr, cbuf_end, cbuf_type); 3162 if (c < 256) { 3163 v2 = (lre_is_word_byte(c) != 0); 3164 } else { 3165 v2 = ignore_case && (c == 0x017f || c == 0x212a); 3166 } 3167 } 3168 if (v1 ^ v2 ^ is_boundary) 3169 goto no_match; 3170 } 3171 break; 3172 case REOP_back_reference: 3173 case REOP_back_reference_i: 3174 case REOP_backward_back_reference: 3175 case REOP_backward_back_reference_i: 3176 { 3177 const uint8_t *cptr1, *cptr1_end, *cptr1_start; 3178 const uint8_t *pc1; 3179 uint32_t c1, c2; 3180 int i, n; 3181 3182 n = *pc++; 3183 pc1 = pc; 3184 pc += n; 3185 3186 for(i = 0; i < n; i++) { 3187 val = pc1[i]; 3188 if (val >= s->capture_count) 3189 goto no_match; 3190 cptr1_start = capture[2 * val]; 3191 cptr1_end = capture[2 * val + 1]; 3192 /* test the first not empty capture */ 3193 if (cptr1_start && cptr1_end) { 3194 if (opcode == REOP_back_reference || 3195 opcode == REOP_back_reference_i) { 3196 cptr1 = cptr1_start; 3197 while (cptr1 < cptr1_end) { 3198 if (cptr >= cbuf_end) 3199 goto no_match; 3200 GET_CHAR(c1, cptr1, cptr1_end, cbuf_type); 3201 GET_CHAR(c2, cptr, cbuf_end, cbuf_type); 3202 if (opcode == REOP_back_reference_i) { 3203 c1 = lre_canonicalize(c1, s->is_unicode); 3204 c2 = lre_canonicalize(c2, s->is_unicode); 3205 } 3206 if (c1 != c2) 3207 goto no_match; 3208 } 3209 } else { 3210 cptr1 = cptr1_end; 3211 while (cptr1 > cptr1_start) { 3212 if (cptr == s->cbuf) 3213 goto no_match; 3214 GET_PREV_CHAR(c1, cptr1, cptr1_start, cbuf_type); 3215 GET_PREV_CHAR(c2, cptr, s->cbuf, cbuf_type); 3216 if (opcode == REOP_backward_back_reference_i) { 3217 c1 = lre_canonicalize(c1, s->is_unicode); 3218 c2 = lre_canonicalize(c2, s->is_unicode); 3219 } 3220 if (c1 != c2) 3221 goto no_match; 3222 } 3223 } 3224 break; 3225 } 3226 } 3227 } 3228 break; 3229 case REOP_range: 3230 case REOP_range_i: 3231 { 3232 int n; 3233 uint32_t low, high, idx_min, idx_max, idx; 3234 3235 n = get_u16(pc); /* n must be >= 1 */ 3236 pc += 2; 3237 if (cptr >= cbuf_end) 3238 goto no_match; 3239 GET_CHAR(c, cptr, cbuf_end, cbuf_type); 3240 if (opcode == REOP_range_i) { 3241 c = lre_canonicalize(c, s->is_unicode); 3242 } 3243 idx_min = 0; 3244 low = get_u16(pc + 0 * 4); 3245 if (c < low) 3246 goto no_match; 3247 idx_max = n - 1; 3248 high = get_u16(pc + idx_max * 4 + 2); 3249 /* 0xffff in for last value means +infinity */ 3250 if (unlikely(c >= 0xffff) && high == 0xffff) 3251 goto range_match; 3252 if (c > high) 3253 goto no_match; 3254 while (idx_min <= idx_max) { 3255 idx = (idx_min + idx_max) / 2; 3256 low = get_u16(pc + idx * 4); 3257 high = get_u16(pc + idx * 4 + 2); 3258 if (c < low) 3259 idx_max = idx - 1; 3260 else if (c > high) 3261 idx_min = idx + 1; 3262 else 3263 goto range_match; 3264 } 3265 goto no_match; 3266 range_match: 3267 pc += 4 * n; 3268 } 3269 break; 3270 case REOP_range32: 3271 case REOP_range32_i: 3272 { 3273 int n; 3274 uint32_t low, high, idx_min, idx_max, idx; 3275 3276 n = get_u16(pc); /* n must be >= 1 */ 3277 pc += 2; 3278 if (cptr >= cbuf_end) 3279 goto no_match; 3280 GET_CHAR(c, cptr, cbuf_end, cbuf_type); 3281 if (opcode == REOP_range32_i) { 3282 c = lre_canonicalize(c, s->is_unicode); 3283 } 3284 idx_min = 0; 3285 low = get_u32(pc + 0 * 8); 3286 if (c < low) 3287 goto no_match; 3288 idx_max = n - 1; 3289 high = get_u32(pc + idx_max * 8 + 4); 3290 if (c > high) 3291 goto no_match; 3292 while (idx_min <= idx_max) { 3293 idx = (idx_min + idx_max) / 2; 3294 low = get_u32(pc + idx * 8); 3295 high = get_u32(pc + idx * 8 + 4); 3296 if (c < low) 3297 idx_max = idx - 1; 3298 else if (c > high) 3299 idx_min = idx + 1; 3300 else 3301 goto range32_match; 3302 } 3303 goto no_match; 3304 range32_match: 3305 pc += 8 * n; 3306 } 3307 break; 3308 case REOP_prev: 3309 /* go to the previous char */ 3310 if (cptr == s->cbuf) 3311 goto no_match; 3312 PREV_CHAR(cptr, s->cbuf, cbuf_type); 3313 break; 3314 default: 3315 #ifdef DUMP_EXEC 3316 printf("unknown opcode pc=%ld\n", pc - 1 - pc_start); 3317 #endif 3318 abort(); 3319 } 3320 } 3321 } 3322 3323 /* Return 1 if match, 0 if not match or < 0 if error (see LRE_RET_x). cindex is the 3324 starting position of the match and must be such as 0 <= cindex <= 3325 clen. */ 3326 int lre_exec(uint8_t **capture, 3327 const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, 3328 int cbuf_type, void *opaque) 3329 { 3330 REExecContext s_s, *s = &s_s; 3331 int re_flags, i, ret; 3332 const uint8_t *cptr; 3333 3334 re_flags = lre_get_flags(bc_buf); 3335 s->is_unicode = (re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0; 3336 s->capture_count = bc_buf[RE_HEADER_CAPTURE_COUNT]; 3337 s->cbuf = cbuf; 3338 s->cbuf_end = cbuf + (clen << cbuf_type); 3339 s->cbuf_type = cbuf_type; 3340 if (s->cbuf_type == 1 && s->is_unicode) 3341 s->cbuf_type = 2; 3342 s->interrupt_counter = INTERRUPT_COUNTER_INIT; 3343 s->opaque = opaque; 3344 3345 s->stack_buf = s->static_stack_buf; 3346 s->stack_size = countof(s->static_stack_buf); 3347 3348 for(i = 0; i < s->capture_count * 2; i++) 3349 capture[i] = NULL; 3350 3351 cptr = cbuf + (cindex << cbuf_type); 3352 if (0 < cindex && cindex < clen && s->cbuf_type == 2) { 3353 const uint16_t *p = (const uint16_t *)cptr; 3354 if (is_lo_surrogate(*p) && is_hi_surrogate(p[-1])) { 3355 cptr = (const uint8_t *)(p - 1); 3356 } 3357 } 3358 3359 ret = lre_exec_backtrack(s, capture, bc_buf + RE_HEADER_LEN, cptr); 3360 3361 if (s->stack_buf != s->static_stack_buf) 3362 lre_realloc(s->opaque, s->stack_buf, 0); 3363 return ret; 3364 } 3365 3366 int lre_get_alloc_count(const uint8_t *bc_buf) 3367 { 3368 return bc_buf[RE_HEADER_CAPTURE_COUNT] * 2 + 3369 bc_buf[RE_HEADER_REGISTER_COUNT]; 3370 } 3371 3372 int lre_get_capture_count(const uint8_t *bc_buf) 3373 { 3374 return bc_buf[RE_HEADER_CAPTURE_COUNT]; 3375 } 3376 3377 int lre_get_flags(const uint8_t *bc_buf) 3378 { 3379 return get_u16(bc_buf + RE_HEADER_FLAGS); 3380 } 3381 3382 /* Return NULL if no group names. Otherwise, return a pointer to 3383 'capture_count - 1' zero terminated UTF-8 strings. */ 3384 const char *lre_get_groupnames(const uint8_t *bc_buf) 3385 { 3386 uint32_t re_bytecode_len; 3387 if ((lre_get_flags(bc_buf) & LRE_FLAG_NAMED_GROUPS) == 0) 3388 return NULL; 3389 re_bytecode_len = get_u32(bc_buf + RE_HEADER_BYTECODE_LEN); 3390 return (const char *)(bc_buf + RE_HEADER_LEN + re_bytecode_len); 3391 } 3392 3393 #ifdef TEST 3394 3395 BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size) 3396 { 3397 return FALSE; 3398 } 3399 3400 void *lre_realloc(void *opaque, void *ptr, size_t size) 3401 { 3402 return realloc(ptr, size); 3403 } 3404 3405 int main(int argc, char **argv) 3406 { 3407 int len, flags, ret, i; 3408 uint8_t *bc; 3409 char error_msg[64]; 3410 uint8_t *capture; 3411 const char *input; 3412 int input_len, capture_count; 3413 3414 if (argc < 4) { 3415 printf("usage: %s regexp flags input\n", argv[0]); 3416 return 1; 3417 } 3418 flags = atoi(argv[2]); 3419 bc = lre_compile(&len, error_msg, sizeof(error_msg), argv[1], 3420 strlen(argv[1]), flags, NULL); 3421 if (!bc) { 3422 fprintf(stderr, "error: %s\n", error_msg); 3423 exit(1); 3424 } 3425 3426 input = argv[3]; 3427 input_len = strlen(input); 3428 3429 capture = malloc(sizeof(capture[0]) * lre_get_alloc_count(bc)); 3430 ret = lre_exec(capture, bc, (uint8_t *)input, 0, input_len, 0, NULL); 3431 printf("ret=%d\n", ret); 3432 if (ret == 1) { 3433 capture_count = lre_get_capture_count(bc); 3434 for(i = 0; i < 2 * capture_count; i++) { 3435 uint8_t *ptr; 3436 ptr = capture[i]; 3437 printf("%d: ", i); 3438 if (!ptr) 3439 printf("<nil>"); 3440 else 3441 printf("%u", (int)(ptr - (uint8_t *)input)); 3442 printf("\n"); 3443 } 3444 } 3445 free(capture); 3446 return 0; 3447 } 3448 #endif