1 : /**********************************************************************
2 : regparse.c - Oniguruma (regular expression library)
3 : **********************************************************************/
4 : /*-
5 : * Copyright (c) 2002-2009 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
6 : * All rights reserved.
7 : *
8 : * Redistribution and use in source and binary forms, with or without
9 : * modification, are permitted provided that the following conditions
10 : * are met:
11 : * 1. Redistributions of source code must retain the above copyright
12 : * notice, this list of conditions and the following disclaimer.
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 : * SUCH DAMAGE.
28 : */
29 :
30 : #include "regparse.h"
31 :
32 : #define WARN_BUFSIZE 256
33 :
34 : OnigSyntaxType OnigSyntaxRuby = {
35 : (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
36 : ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
37 : ONIG_SYN_OP_ESC_X_BRACE_HEX8 | ONIG_SYN_OP_ESC_CONTROL_CHARS |
38 : ONIG_SYN_OP_ESC_C_CONTROL )
39 : & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END )
40 : , ( ONIG_SYN_OP2_QMARK_GROUP_EFFECT |
41 : ONIG_SYN_OP2_OPTION_RUBY |
42 : ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP | ONIG_SYN_OP2_ESC_K_NAMED_BACKREF |
43 : ONIG_SYN_OP2_ESC_G_SUBEXP_CALL |
44 : ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT |
45 : ONIG_SYN_OP2_CCLASS_SET_OP | ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL |
46 : ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META | ONIG_SYN_OP2_ESC_V_VTAB |
47 : ONIG_SYN_OP2_ESC_H_XDIGIT )
48 : , ( SYN_GNU_REGEX_BV |
49 : ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV |
50 : ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND |
51 : ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP |
52 : ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME |
53 : ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY |
54 : ONIG_SYN_WARN_CC_OP_NOT_ESCAPED |
55 : ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT )
56 : , ONIG_OPTION_NONE
57 : };
58 :
59 : OnigSyntaxType* OnigDefaultSyntax = ONIG_SYNTAX_RUBY;
60 :
61 0 : extern void onig_null_warn(const char* s) { }
62 :
63 : #ifdef RUBY_PLATFORM
64 : extern void
65 : onig_rb_warn(const char* s)
66 : {
67 : rb_warn(s);
68 : }
69 :
70 : extern void
71 : onig_rb_warning(const char* s)
72 : {
73 : rb_warning(s);
74 : }
75 : #endif
76 :
77 : #ifdef DEFAULT_WARN_FUNCTION
78 : static OnigWarnFunc onig_warn = (OnigWarnFunc )DEFAULT_WARN_FUNCTION;
79 : #else
80 : static OnigWarnFunc onig_warn = onig_null_warn;
81 : #endif
82 :
83 : #ifdef DEFAULT_VERB_WARN_FUNCTION
84 : static OnigWarnFunc onig_verb_warn = (OnigWarnFunc )DEFAULT_VERB_WARN_FUNCTION;
85 : #else
86 : static OnigWarnFunc onig_verb_warn = onig_null_warn;
87 : #endif
88 :
89 : extern void onig_set_warn_func(OnigWarnFunc f)
90 0 : {
91 0 : onig_warn = f;
92 0 : }
93 :
94 : extern void onig_set_verb_warn_func(OnigWarnFunc f)
95 0 : {
96 0 : onig_verb_warn = f;
97 0 : }
98 :
99 : static void
100 : bbuf_free(BBuf* bbuf)
101 42 : {
102 42 : if (IS_NOT_NULL(bbuf)) {
103 42 : if (IS_NOT_NULL(bbuf->p)) xfree(bbuf->p);
104 42 : xfree(bbuf);
105 : }
106 42 : }
107 :
108 : static int
109 : bbuf_clone(BBuf** rto, BBuf* from)
110 0 : {
111 : int r;
112 : BBuf *to;
113 :
114 0 : *rto = to = (BBuf* )xmalloc(sizeof(BBuf));
115 0 : CHECK_NULL_RETURN_VAL(to, ONIGERR_MEMORY);
116 0 : r = BBUF_INIT(to, from->alloc);
117 0 : if (r != 0) return r;
118 0 : to->used = from->used;
119 0 : xmemcpy(to->p, from->p, from->used);
120 0 : return 0;
121 : }
122 :
123 : #define ONOFF(v,f,negative) (negative) ? ((v) &= ~(f)) : ((v) |= (f))
124 :
125 : #define MBCODE_START_POS(enc) \
126 : (OnigCodePoint )(ONIGENC_MBC_MINLEN(enc) > 1 ? 0 : 0x80)
127 :
128 : #define SET_ALL_MULTI_BYTE_RANGE(enc, pbuf) \
129 : add_code_range_to_buf(pbuf, MBCODE_START_POS(enc), ~((OnigCodePoint )0))
130 :
131 : #define ADD_ALL_MULTI_BYTE_RANGE(enc, mbuf) do {\
132 : if (! ONIGENC_IS_SINGLEBYTE(enc)) {\
133 : r = SET_ALL_MULTI_BYTE_RANGE(enc, &(mbuf));\
134 : if (r) return r;\
135 : }\
136 : } while (0)
137 :
138 :
139 : #define BITSET_IS_EMPTY(bs,empty) do {\
140 : int i;\
141 : empty = 1;\
142 : for (i = 0; i < BITSET_SIZE; i++) {\
143 : if ((bs)[i] != 0) {\
144 : empty = 0; break;\
145 : }\
146 : }\
147 : } while (0)
148 :
149 : static void
150 : bitset_set_range(BitSetRef bs, int from, int to)
151 34 : {
152 : int i;
153 744 : for (i = from; i <= to && i < SINGLE_BYTE_SIZE; i++) {
154 710 : BITSET_SET_BIT(bs, i);
155 : }
156 34 : }
157 :
158 : #if 0
159 : static void
160 : bitset_set_all(BitSetRef bs)
161 : {
162 : int i;
163 : for (i = 0; i < BITSET_SIZE; i++) {
164 : bs[i] = ~((Bits )0);
165 : }
166 : }
167 : #endif
168 :
169 : static void
170 : bitset_invert(BitSetRef bs)
171 0 : {
172 : int i;
173 0 : for (i = 0; i < BITSET_SIZE; i++) {
174 0 : bs[i] = ~(bs[i]);
175 : }
176 0 : }
177 :
178 : static void
179 : bitset_invert_to(BitSetRef from, BitSetRef to)
180 0 : {
181 : int i;
182 0 : for (i = 0; i < BITSET_SIZE; i++) {
183 0 : to[i] = ~(from[i]);
184 : }
185 0 : }
186 :
187 : static void
188 : bitset_and(BitSetRef dest, BitSetRef bs)
189 0 : {
190 : int i;
191 0 : for (i = 0; i < BITSET_SIZE; i++) {
192 0 : dest[i] &= bs[i];
193 : }
194 0 : }
195 :
196 : static void
197 : bitset_or(BitSetRef dest, BitSetRef bs)
198 0 : {
199 : int i;
200 0 : for (i = 0; i < BITSET_SIZE; i++) {
201 0 : dest[i] |= bs[i];
202 : }
203 0 : }
204 :
205 : static void
206 : bitset_copy(BitSetRef dest, BitSetRef bs)
207 0 : {
208 : int i;
209 0 : for (i = 0; i < BITSET_SIZE; i++) {
210 0 : dest[i] = bs[i];
211 : }
212 0 : }
213 :
214 : extern int
215 : onig_strncmp(const UChar* s1, const UChar* s2, int n)
216 0 : {
217 : int x;
218 :
219 0 : while (n-- > 0) {
220 0 : x = *s2++ - *s1++;
221 0 : if (x) return x;
222 : }
223 0 : return 0;
224 : }
225 :
226 : static void
227 : k_strcpy(UChar* dest, const UChar* src, const UChar* end)
228 355 : {
229 355 : int len = end - src;
230 355 : if (len > 0) {
231 355 : xmemcpy(dest, src, len);
232 355 : dest[len] = (UChar )0;
233 : }
234 355 : }
235 :
236 : static UChar*
237 : strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
238 0 : {
239 : int slen, term_len, i;
240 : UChar *r;
241 :
242 0 : slen = end - s;
243 0 : term_len = ONIGENC_MBC_MINLEN(enc);
244 :
245 0 : r = (UChar* )xmalloc(slen + term_len);
246 0 : CHECK_NULL_RETURN(r);
247 0 : xmemcpy(r, s, slen);
248 :
249 0 : for (i = 0; i < term_len; i++)
250 0 : r[slen + i] = (UChar )0;
251 :
252 0 : return r;
253 : }
254 :
255 :
256 : /* scan pattern methods */
257 : #define PEND_VALUE 0
258 :
259 : #define PFETCH_READY UChar* pfetch_prev
260 : #define PEND (p < end ? 0 : 1)
261 : #define PUNFETCH p = pfetch_prev
262 : #define PINC do { \
263 : pfetch_prev = p; \
264 : p += ONIGENC_MBC_ENC_LEN(enc, p); \
265 : } while (0)
266 : #define PFETCH(c) do { \
267 : c = ONIGENC_MBC_TO_CODE(enc, p, end); \
268 : pfetch_prev = p; \
269 : p += ONIGENC_MBC_ENC_LEN(enc, p); \
270 : } while (0)
271 :
272 : #define PPEEK (p < end ? ONIGENC_MBC_TO_CODE(enc, p, end) : PEND_VALUE)
273 : #define PPEEK_IS(c) (PPEEK == (OnigCodePoint )c)
274 :
275 : static UChar*
276 : k_strcat_capa(UChar* dest, UChar* dest_end, const UChar* src, const UChar* src_end,
277 : int capa)
278 0 : {
279 : UChar* r;
280 :
281 0 : if (dest)
282 0 : r = (UChar* )xrealloc(dest, capa + 1);
283 : else
284 0 : r = (UChar* )xmalloc(capa + 1);
285 :
286 0 : CHECK_NULL_RETURN(r);
287 0 : k_strcpy(r + (dest_end - dest), src, src_end);
288 0 : return r;
289 : }
290 :
291 : /* dest on static area */
292 : static UChar*
293 : strcat_capa_from_static(UChar* dest, UChar* dest_end,
294 : const UChar* src, const UChar* src_end, int capa)
295 0 : {
296 : UChar* r;
297 :
298 0 : r = (UChar* )xmalloc(capa + 1);
299 0 : CHECK_NULL_RETURN(r);
300 0 : k_strcpy(r, dest, dest_end);
301 0 : k_strcpy(r + (dest_end - dest), src, src_end);
302 0 : return r;
303 : }
304 :
305 : #ifdef USE_NAMED_GROUP
306 :
307 : #define INIT_NAME_BACKREFS_ALLOC_NUM 8
308 :
309 : typedef struct {
310 : UChar* name;
311 : int name_len; /* byte length */
312 : int back_num; /* number of backrefs */
313 : int back_alloc;
314 : int back_ref1;
315 : int* back_refs;
316 : } NameEntry;
317 :
318 : #ifdef USE_ST_HASH_TABLE
319 :
320 : #include "st.h"
321 :
322 : typedef struct {
323 : unsigned char* s;
324 : unsigned char* end;
325 : } st_strend_key;
326 :
327 : static int strend_cmp(st_strend_key*, st_strend_key*);
328 : static int strend_hash(st_strend_key*);
329 :
330 : static struct st_hash_type type_strend_hash = {
331 : strend_cmp,
332 : strend_hash,
333 : };
334 :
335 : static st_table*
336 : onig_st_init_strend_table_with_size(int size)
337 0 : {
338 0 : return onig_st_init_table_with_size(&type_strend_hash, size);
339 : }
340 :
341 : static int
342 : onig_st_lookup_strend(st_table *table, const UChar* str_key, const UChar* end_key, st_data_t *value)
343 0 : {
344 : st_strend_key key;
345 :
346 0 : key.s = (unsigned char* )str_key;
347 0 : key.end = (unsigned char* )end_key;
348 :
349 0 : return onig_st_lookup(table, (st_data_t )(&key), value);
350 : }
351 :
352 : static int
353 : onig_st_insert_strend(st_table *table, const UChar* str_key, const UChar* end_key, st_data_t value)
354 0 : {
355 : st_strend_key* key;
356 : int result;
357 :
358 0 : key = (st_strend_key* )xmalloc(sizeof(st_strend_key));
359 0 : key->s = (unsigned char* )str_key;
360 0 : key->end = (unsigned char* )end_key;
361 0 : result = onig_st_insert(table, (st_data_t )key, value);
362 0 : if (result) {
363 0 : xfree(key);
364 : }
365 0 : return result;
366 : }
367 :
368 : static int
369 : strend_cmp(st_strend_key* x, st_strend_key* y)
370 0 : {
371 : unsigned char *p, *q;
372 : int c;
373 :
374 0 : if ((x->end - x->s) != (y->end - y->s))
375 0 : return 1;
376 :
377 0 : p = x->s;
378 0 : q = y->s;
379 0 : while (p < x->end) {
380 0 : c = (int )*p - (int )*q;
381 0 : if (c != 0) return c;
382 :
383 0 : p++; q++;
384 : }
385 :
386 0 : return 0;
387 : }
388 :
389 : static int
390 : strend_hash(st_strend_key* x)
391 0 : {
392 : int val;
393 : unsigned char *p;
394 :
395 0 : val = 0;
396 0 : p = x->s;
397 0 : while (p < x->end) {
398 0 : val = val * 997 + (int )*p++;
399 : }
400 :
401 0 : return val + (val >> 5);
402 : }
403 :
404 : typedef st_table NameTable;
405 : typedef st_data_t HashDataType; /* 1.6 st.h doesn't define st_data_t type */
406 :
407 : #define NAMEBUF_SIZE 24
408 : #define NAMEBUF_SIZE_1 25
409 :
410 : #ifdef ONIG_DEBUG
411 : static int
412 : i_print_name_entry(UChar* key, NameEntry* e, void* arg)
413 : {
414 : int i;
415 : FILE* fp = (FILE* )arg;
416 :
417 : fprintf(fp, "%s: ", e->name);
418 : if (e->back_num == 0)
419 : fputs("-", fp);
420 : else if (e->back_num == 1)
421 : fprintf(fp, "%d", e->back_ref1);
422 : else {
423 : for (i = 0; i < e->back_num; i++) {
424 : if (i > 0) fprintf(fp, ", ");
425 : fprintf(fp, "%d", e->back_refs[i]);
426 : }
427 : }
428 : fputs("\n", fp);
429 : return ST_CONTINUE;
430 : }
431 :
432 : extern int
433 : onig_print_names(FILE* fp, regex_t* reg)
434 : {
435 : NameTable* t = (NameTable* )reg->name_table;
436 :
437 : if (IS_NOT_NULL(t)) {
438 : fprintf(fp, "name table\n");
439 : onig_st_foreach(t, i_print_name_entry, (HashDataType )fp);
440 : fputs("\n", fp);
441 : }
442 : return 0;
443 : }
444 : #endif
445 :
446 : static int
447 : i_free_name_entry(UChar* key, NameEntry* e, void* arg)
448 0 : {
449 0 : xfree(e->name);
450 0 : if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
451 0 : xfree(key);
452 0 : xfree(e);
453 0 : return ST_DELETE;
454 : }
455 :
456 : static int
457 : names_clear(regex_t* reg)
458 290 : {
459 290 : NameTable* t = (NameTable* )reg->name_table;
460 :
461 290 : if (IS_NOT_NULL(t)) {
462 0 : onig_st_foreach(t, i_free_name_entry, 0);
463 : }
464 290 : return 0;
465 : }
466 :
467 : extern int
468 : onig_names_free(regex_t* reg)
469 145 : {
470 : int r;
471 : NameTable* t;
472 :
473 145 : r = names_clear(reg);
474 145 : if (r) return r;
475 :
476 145 : t = (NameTable* )reg->name_table;
477 145 : if (IS_NOT_NULL(t)) onig_st_free_table(t);
478 145 : reg->name_table = (void* )NULL;
479 145 : return 0;
480 : }
481 :
482 : static NameEntry*
483 : name_find(regex_t* reg, const UChar* name, const UChar* name_end)
484 0 : {
485 : NameEntry* e;
486 0 : NameTable* t = (NameTable* )reg->name_table;
487 :
488 0 : e = (NameEntry* )NULL;
489 0 : if (IS_NOT_NULL(t)) {
490 0 : onig_st_lookup_strend(t, name, name_end, (HashDataType* )((void* )(&e)));
491 : }
492 0 : return e;
493 : }
494 :
495 : typedef struct {
496 : int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*);
497 : regex_t* reg;
498 : void* arg;
499 : int ret;
500 : OnigEncoding enc;
501 : } INamesArg;
502 :
503 : static int
504 : i_names(UChar* key, NameEntry* e, INamesArg* arg)
505 0 : {
506 : int r = (*(arg->func))(e->name,
507 : /*e->name + onigenc_str_bytelen_null(arg->enc, e->name), */
508 : e->name + e->name_len,
509 : e->back_num,
510 : (e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
511 0 : arg->reg, arg->arg);
512 0 : if (r != 0) {
513 0 : arg->ret = r;
514 0 : return ST_STOP;
515 : }
516 0 : return ST_CONTINUE;
517 : }
518 :
519 : extern int
520 : onig_foreach_name(regex_t* reg,
521 : int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*),
522 : void* arg)
523 0 : {
524 : INamesArg narg;
525 0 : NameTable* t = (NameTable* )reg->name_table;
526 :
527 0 : narg.ret = 0;
528 0 : if (IS_NOT_NULL(t)) {
529 0 : narg.func = func;
530 0 : narg.reg = reg;
531 0 : narg.arg = arg;
532 0 : narg.enc = reg->enc; /* should be pattern encoding. */
533 0 : onig_st_foreach(t, i_names, (HashDataType )&narg);
534 : }
535 0 : return narg.ret;
536 : }
537 :
538 : static int
539 : i_renumber_name(UChar* key, NameEntry* e, GroupNumRemap* map)
540 0 : {
541 : int i;
542 :
543 0 : if (e->back_num > 1) {
544 0 : for (i = 0; i < e->back_num; i++) {
545 0 : e->back_refs[i] = map[e->back_refs[i]].new_val;
546 : }
547 : }
548 0 : else if (e->back_num == 1) {
549 0 : e->back_ref1 = map[e->back_ref1].new_val;
550 : }
551 :
552 0 : return ST_CONTINUE;
553 : }
554 :
555 : extern int
556 : onig_renumber_name_table(regex_t* reg, GroupNumRemap* map)
557 0 : {
558 0 : NameTable* t = (NameTable* )reg->name_table;
559 :
560 0 : if (IS_NOT_NULL(t)) {
561 0 : onig_st_foreach(t, i_renumber_name, (HashDataType )map);
562 : }
563 0 : return 0;
564 : }
565 :
566 :
567 : extern int
568 : onig_number_of_names(regex_t* reg)
569 0 : {
570 0 : NameTable* t = (NameTable* )reg->name_table;
571 :
572 0 : if (IS_NOT_NULL(t))
573 0 : return t->num_entries;
574 : else
575 0 : return 0;
576 : }
577 :
578 : #else /* USE_ST_HASH_TABLE */
579 :
580 : #define INIT_NAMES_ALLOC_NUM 8
581 :
582 : typedef struct {
583 : NameEntry* e;
584 : int num;
585 : int alloc;
586 : } NameTable;
587 :
588 :
589 : #ifdef ONIG_DEBUG
590 : extern int
591 : onig_print_names(FILE* fp, regex_t* reg)
592 : {
593 : int i, j;
594 : NameEntry* e;
595 : NameTable* t = (NameTable* )reg->name_table;
596 :
597 : if (IS_NOT_NULL(t) && t->num > 0) {
598 : fprintf(fp, "name table\n");
599 : for (i = 0; i < t->num; i++) {
600 : e = &(t->e[i]);
601 : fprintf(fp, "%s: ", e->name);
602 : if (e->back_num == 0) {
603 : fputs("-", fp);
604 : }
605 : else if (e->back_num == 1) {
606 : fprintf(fp, "%d", e->back_ref1);
607 : }
608 : else {
609 : for (j = 0; j < e->back_num; j++) {
610 : if (j > 0) fprintf(fp, ", ");
611 : fprintf(fp, "%d", e->back_refs[j]);
612 : }
613 : }
614 : fputs("\n", fp);
615 : }
616 : fputs("\n", fp);
617 : }
618 : return 0;
619 : }
620 : #endif
621 :
622 : static int
623 : names_clear(regex_t* reg)
624 : {
625 : int i;
626 : NameEntry* e;
627 : NameTable* t = (NameTable* )reg->name_table;
628 :
629 : if (IS_NOT_NULL(t)) {
630 : for (i = 0; i < t->num; i++) {
631 : e = &(t->e[i]);
632 : if (IS_NOT_NULL(e->name)) {
633 : xfree(e->name);
634 : e->name = NULL;
635 : e->name_len = 0;
636 : e->back_num = 0;
637 : e->back_alloc = 0;
638 : if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
639 : e->back_refs = (int* )NULL;
640 : }
641 : }
642 : if (IS_NOT_NULL(t->e)) {
643 : xfree(t->e);
644 : t->e = NULL;
645 : }
646 : t->num = 0;
647 : }
648 : return 0;
649 : }
650 :
651 : extern int
652 : onig_names_free(regex_t* reg)
653 : {
654 : int r;
655 : NameTable* t;
656 :
657 : r = names_clear(reg);
658 : if (r) return r;
659 :
660 : t = (NameTable* )reg->name_table;
661 : if (IS_NOT_NULL(t)) xfree(t);
662 : reg->name_table = NULL;
663 : return 0;
664 : }
665 :
666 : static NameEntry*
667 : name_find(regex_t* reg, UChar* name, UChar* name_end)
668 : {
669 : int i, len;
670 : NameEntry* e;
671 : NameTable* t = (NameTable* )reg->name_table;
672 :
673 : if (IS_NOT_NULL(t)) {
674 : len = name_end - name;
675 : for (i = 0; i < t->num; i++) {
676 : e = &(t->e[i]);
677 : if (len == e->name_len && onig_strncmp(name, e->name, len) == 0)
678 : return e;
679 : }
680 : }
681 : return (NameEntry* )NULL;
682 : }
683 :
684 : extern int
685 : onig_foreach_name(regex_t* reg,
686 : int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*),
687 : void* arg)
688 : {
689 : int i, r;
690 : NameEntry* e;
691 : NameTable* t = (NameTable* )reg->name_table;
692 :
693 : if (IS_NOT_NULL(t)) {
694 : for (i = 0; i < t->num; i++) {
695 : e = &(t->e[i]);
696 : r = (*func)(e->name, e->name + e->name_len, e->back_num,
697 : (e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
698 : reg, arg);
699 : if (r != 0) return r;
700 : }
701 : }
702 : return 0;
703 : }
704 :
705 : extern int
706 : onig_number_of_names(regex_t* reg)
707 : {
708 : NameTable* t = (NameTable* )reg->name_table;
709 :
710 : if (IS_NOT_NULL(t))
711 : return t->num;
712 : else
713 : return 0;
714 : }
715 :
716 : #endif /* else USE_ST_HASH_TABLE */
717 :
718 : static int
719 : name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
720 0 : {
721 : int alloc;
722 : NameEntry* e;
723 0 : NameTable* t = (NameTable* )reg->name_table;
724 :
725 0 : if (name_end - name <= 0)
726 0 : return ONIGERR_EMPTY_GROUP_NAME;
727 :
728 0 : e = name_find(reg, name, name_end);
729 0 : if (IS_NULL(e)) {
730 : #ifdef USE_ST_HASH_TABLE
731 0 : if (IS_NULL(t)) {
732 0 : t = onig_st_init_strend_table_with_size(5);
733 0 : reg->name_table = (void* )t;
734 : }
735 0 : e = (NameEntry* )xmalloc(sizeof(NameEntry));
736 0 : CHECK_NULL_RETURN_VAL(e, ONIGERR_MEMORY);
737 :
738 0 : e->name = strdup_with_null(reg->enc, name, name_end);
739 0 : if (IS_NULL(e->name)) return ONIGERR_MEMORY;
740 0 : onig_st_insert_strend(t, e->name, (e->name + (name_end - name)),
741 : (HashDataType )e);
742 :
743 0 : e->name_len = name_end - name;
744 0 : e->back_num = 0;
745 0 : e->back_alloc = 0;
746 0 : e->back_refs = (int* )NULL;
747 :
748 : #else
749 :
750 : if (IS_NULL(t)) {
751 : alloc = INIT_NAMES_ALLOC_NUM;
752 : t = (NameTable* )xmalloc(sizeof(NameTable));
753 : CHECK_NULL_RETURN_VAL(t, ONIGERR_MEMORY);
754 : t->e = NULL;
755 : t->alloc = 0;
756 : t->num = 0;
757 :
758 : t->e = (NameEntry* )xmalloc(sizeof(NameEntry) * alloc);
759 : if (IS_NULL(t->e)) {
760 : xfree(t);
761 : return ONIGERR_MEMORY;
762 : }
763 : t->alloc = alloc;
764 : reg->name_table = t;
765 : goto clear;
766 : }
767 : else if (t->num == t->alloc) {
768 : int i;
769 :
770 : alloc = t->alloc * 2;
771 : t->e = (NameEntry* )xrealloc(t->e, sizeof(NameEntry) * alloc);
772 : CHECK_NULL_RETURN_VAL(t->e, ONIGERR_MEMORY);
773 : t->alloc = alloc;
774 :
775 : clear:
776 : for (i = t->num; i < t->alloc; i++) {
777 : t->e[i].name = NULL;
778 : t->e[i].name_len = 0;
779 : t->e[i].back_num = 0;
780 : t->e[i].back_alloc = 0;
781 : t->e[i].back_refs = (int* )NULL;
782 : }
783 : }
784 : e = &(t->e[t->num]);
785 : t->num++;
786 : e->name = strdup_with_null(reg->enc, name, name_end);
787 : e->name_len = name_end - name;
788 : #endif
789 : }
790 :
791 0 : if (e->back_num >= 1 &&
792 : ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME)) {
793 0 : onig_scan_env_set_error_string(env, ONIGERR_MULTIPLEX_DEFINED_NAME,
794 : name, name_end);
795 0 : return ONIGERR_MULTIPLEX_DEFINED_NAME;
796 : }
797 :
798 0 : e->back_num++;
799 0 : if (e->back_num == 1) {
800 0 : e->back_ref1 = backref;
801 : }
802 : else {
803 0 : if (e->back_num == 2) {
804 0 : alloc = INIT_NAME_BACKREFS_ALLOC_NUM;
805 0 : e->back_refs = (int* )xmalloc(sizeof(int) * alloc);
806 0 : CHECK_NULL_RETURN_VAL(e->back_refs, ONIGERR_MEMORY);
807 0 : e->back_alloc = alloc;
808 0 : e->back_refs[0] = e->back_ref1;
809 0 : e->back_refs[1] = backref;
810 : }
811 : else {
812 0 : if (e->back_num > e->back_alloc) {
813 0 : alloc = e->back_alloc * 2;
814 0 : e->back_refs = (int* )xrealloc(e->back_refs, sizeof(int) * alloc);
815 0 : CHECK_NULL_RETURN_VAL(e->back_refs, ONIGERR_MEMORY);
816 0 : e->back_alloc = alloc;
817 : }
818 0 : e->back_refs[e->back_num - 1] = backref;
819 : }
820 : }
821 :
822 0 : return 0;
823 : }
824 :
825 : extern int
826 : onig_name_to_group_numbers(regex_t* reg, const UChar* name,
827 : const UChar* name_end, int** nums)
828 0 : {
829 : NameEntry* e;
830 :
831 0 : e = name_find(reg, name, name_end);
832 0 : if (IS_NULL(e)) return ONIGERR_UNDEFINED_NAME_REFERENCE;
833 :
834 0 : switch (e->back_num) {
835 : case 0:
836 0 : break;
837 : case 1:
838 0 : *nums = &(e->back_ref1);
839 0 : break;
840 : default:
841 0 : *nums = e->back_refs;
842 : break;
843 : }
844 0 : return e->back_num;
845 : }
846 :
847 : extern int
848 : onig_name_to_backref_number(regex_t* reg, const UChar* name,
849 : const UChar* name_end, OnigRegion *region)
850 0 : {
851 : int i, n, *nums;
852 :
853 0 : n = onig_name_to_group_numbers(reg, name, name_end, &nums);
854 0 : if (n < 0)
855 0 : return n;
856 0 : else if (n == 0)
857 0 : return ONIGERR_PARSER_BUG;
858 0 : else if (n == 1)
859 0 : return nums[0];
860 : else {
861 0 : if (IS_NOT_NULL(region)) {
862 0 : for (i = n - 1; i >= 0; i--) {
863 0 : if (region->beg[nums[i]] != ONIG_REGION_NOTPOS)
864 0 : return nums[i];
865 : }
866 : }
867 0 : return nums[n - 1];
868 : }
869 : }
870 :
871 : #else /* USE_NAMED_GROUP */
872 :
873 : extern int
874 : onig_name_to_group_numbers(regex_t* reg, const UChar* name,
875 : const UChar* name_end, int** nums)
876 : {
877 : return ONIG_NO_SUPPORT_CONFIG;
878 : }
879 :
880 : extern int
881 : onig_name_to_backref_number(regex_t* reg, const UChar* name,
882 : const UChar* name_end, OnigRegion* region)
883 : {
884 : return ONIG_NO_SUPPORT_CONFIG;
885 : }
886 :
887 : extern int
888 : onig_foreach_name(regex_t* reg,
889 : int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*),
890 : void* arg)
891 : {
892 : return ONIG_NO_SUPPORT_CONFIG;
893 : }
894 :
895 : extern int
896 : onig_number_of_names(regex_t* reg)
897 : {
898 : return 0;
899 : }
900 : #endif /* else USE_NAMED_GROUP */
901 :
902 : extern int
903 : onig_noname_group_capture_is_active(regex_t* reg)
904 0 : {
905 0 : if (ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_DONT_CAPTURE_GROUP))
906 0 : return 0;
907 :
908 : #ifdef USE_NAMED_GROUP
909 0 : if (onig_number_of_names(reg) > 0 &&
910 : IS_SYNTAX_BV(reg->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
911 : !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
912 0 : return 0;
913 : }
914 : #endif
915 :
916 0 : return 1;
917 : }
918 :
919 :
920 : #define INIT_SCANENV_MEMNODES_ALLOC_SIZE 16
921 :
922 : static void
923 : scan_env_clear(ScanEnv* env)
924 145 : {
925 : int i;
926 :
927 145 : BIT_STATUS_CLEAR(env->capture_history);
928 145 : BIT_STATUS_CLEAR(env->bt_mem_start);
929 145 : BIT_STATUS_CLEAR(env->bt_mem_end);
930 145 : BIT_STATUS_CLEAR(env->backrefed_mem);
931 145 : env->error = (UChar* )NULL;
932 145 : env->error_end = (UChar* )NULL;
933 145 : env->num_call = 0;
934 145 : env->num_mem = 0;
935 : #ifdef USE_NAMED_GROUP
936 145 : env->num_named = 0;
937 : #endif
938 145 : env->mem_alloc = 0;
939 145 : env->mem_nodes_dynamic = (Node** )NULL;
940 :
941 1305 : for (i = 0; i < SCANENV_MEMNODES_SIZE; i++)
942 1160 : env->mem_nodes_static[i] = NULL_NODE;
943 :
944 : #ifdef USE_COMBINATION_EXPLOSION_CHECK
945 145 : env->num_comb_exp_check = 0;
946 145 : env->comb_exp_max_regnum = 0;
947 145 : env->curr_max_regnum = 0;
948 145 : env->has_recursion = 0;
949 : #endif
950 145 : }
951 :
952 : static int
953 : scan_env_add_mem_entry(ScanEnv* env)
954 61 : {
955 : int i, need, alloc;
956 : Node** p;
957 :
958 61 : need = env->num_mem + 1;
959 61 : if (need >= SCANENV_MEMNODES_SIZE) {
960 0 : if (env->mem_alloc <= need) {
961 0 : if (IS_NULL(env->mem_nodes_dynamic)) {
962 0 : alloc = INIT_SCANENV_MEMNODES_ALLOC_SIZE;
963 0 : p = (Node** )xmalloc(sizeof(Node*) * alloc);
964 0 : xmemcpy(p, env->mem_nodes_static,
965 : sizeof(Node*) * SCANENV_MEMNODES_SIZE);
966 : }
967 : else {
968 0 : alloc = env->mem_alloc * 2;
969 0 : p = (Node** )xrealloc(env->mem_nodes_dynamic, sizeof(Node*) * alloc);
970 : }
971 0 : CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
972 :
973 0 : for (i = env->num_mem + 1; i < alloc; i++)
974 0 : p[i] = NULL_NODE;
975 :
976 0 : env->mem_nodes_dynamic = p;
977 0 : env->mem_alloc = alloc;
978 : }
979 : }
980 :
981 61 : env->num_mem++;
982 61 : return env->num_mem;
983 : }
984 :
985 : static int
986 : scan_env_set_mem_node(ScanEnv* env, int num, Node* node)
987 61 : {
988 61 : if (env->num_mem >= num)
989 61 : SCANENV_MEM_NODES(env)[num] = node;
990 : else
991 0 : return ONIGERR_PARSER_BUG;
992 61 : return 0;
993 : }
994 :
995 :
996 : #ifdef USE_RECYCLE_NODE
997 : typedef struct _FreeNode {
998 : struct _FreeNode* next;
999 : } FreeNode;
1000 :
1001 : static FreeNode* FreeNodeList = (FreeNode* )NULL;
1002 : #endif
1003 :
1004 : extern void
1005 : onig_node_free(Node* node)
1006 781 : {
1007 781 : start:
1008 781 : if (IS_NULL(node)) return ;
1009 :
1010 717 : switch (NTYPE(node)) {
1011 : case N_STRING:
1012 151 : if (IS_NOT_NULL(NSTRING(node).s) && NSTRING(node).s != NSTRING(node).buf) {
1013 0 : xfree(NSTRING(node).s);
1014 : }
1015 151 : break;
1016 :
1017 : case N_LIST:
1018 : case N_ALT:
1019 217 : onig_node_free(NCONS(node).left);
1020 : /* onig_node_free(NCONS(node).right); */
1021 : {
1022 217 : Node* next_node = NCONS(node).right;
1023 :
1024 : #ifdef USE_RECYCLE_NODE
1025 : {
1026 217 : FreeNode* n = (FreeNode* )node;
1027 :
1028 : THREAD_ATOMIC_START;
1029 217 : n->next = FreeNodeList;
1030 217 : FreeNodeList = n;
1031 : THREAD_ATOMIC_END;
1032 : }
1033 : #else
1034 : xfree(node);
1035 : #endif
1036 :
1037 217 : node = next_node;
1038 217 : goto start;
1039 : }
1040 : break;
1041 :
1042 : case N_CCLASS:
1043 : {
1044 99 : CClassNode* cc = &(NCCLASS(node));
1045 :
1046 99 : if (IS_CCLASS_SHARE(cc))
1047 6 : return ;
1048 :
1049 93 : if (cc->mbuf)
1050 42 : bbuf_free(cc->mbuf);
1051 : }
1052 93 : break;
1053 :
1054 : case N_QUALIFIER:
1055 126 : if (NQUALIFIER(node).target)
1056 126 : onig_node_free(NQUALIFIER(node).target);
1057 126 : break;
1058 :
1059 : case N_EFFECT:
1060 76 : if (NEFFECT(node).target)
1061 76 : onig_node_free(NEFFECT(node).target);
1062 76 : break;
1063 :
1064 : case N_BACKREF:
1065 0 : if (IS_NOT_NULL(NBACKREF(node).back_dynamic))
1066 0 : xfree(NBACKREF(node).back_dynamic);
1067 0 : break;
1068 :
1069 : case N_ANCHOR:
1070 18 : if (NANCHOR(node).target)
1071 0 : onig_node_free(NANCHOR(node).target);
1072 : break;
1073 : }
1074 :
1075 : #ifdef USE_RECYCLE_NODE
1076 : {
1077 494 : FreeNode* n = (FreeNode* )node;
1078 :
1079 : THREAD_ATOMIC_START;
1080 494 : n->next = FreeNodeList;
1081 494 : FreeNodeList = n;
1082 : THREAD_ATOMIC_END;
1083 : }
1084 : #else
1085 : xfree(node);
1086 : #endif
1087 : }
1088 :
1089 : #ifdef USE_RECYCLE_NODE
1090 : extern int
1091 : onig_free_node_list()
1092 13597 : {
1093 : FreeNode* n;
1094 :
1095 : /* THREAD_ATOMIC_START; */
1096 27453 : while (IS_NOT_NULL(FreeNodeList)) {
1097 259 : n = FreeNodeList;
1098 259 : FreeNodeList = FreeNodeList->next;
1099 259 : xfree(n);
1100 : }
1101 : /* THREAD_ATOMIC_END; */
1102 13597 : return 0;
1103 : }
1104 : #endif
1105 :
1106 : static Node*
1107 : node_new()
1108 717 : {
1109 : Node* node;
1110 :
1111 : #ifdef USE_RECYCLE_NODE
1112 : THREAD_ATOMIC_START;
1113 717 : if (IS_NOT_NULL(FreeNodeList)) {
1114 452 : node = (Node* )FreeNodeList;
1115 452 : FreeNodeList = FreeNodeList->next;
1116 : THREAD_ATOMIC_END;
1117 452 : return node;
1118 : }
1119 : THREAD_ATOMIC_END;
1120 : #endif
1121 :
1122 265 : node = (Node* )xmalloc(sizeof(Node));
1123 265 : return node;
1124 : }
1125 :
1126 :
1127 : static void
1128 : initialize_cclass(CClassNode* cc)
1129 93 : {
1130 93 : BITSET_CLEAR(cc->bs);
1131 93 : cc->flags = 0;
1132 93 : cc->mbuf = NULL;
1133 93 : }
1134 :
1135 : static Node*
1136 : node_new_cclass()
1137 93 : {
1138 93 : Node* node = node_new();
1139 93 : CHECK_NULL_RETURN(node);
1140 93 : node->type = N_CCLASS;
1141 :
1142 93 : initialize_cclass(&(NCCLASS(node)));
1143 93 : return node;
1144 : }
1145 :
1146 : static Node*
1147 : node_new_cclass_by_codepoint_range(int not,
1148 : const OnigCodePoint sbr[], const OnigCodePoint mbr[])
1149 6 : {
1150 : CClassNode* cc;
1151 : int n, i, j;
1152 :
1153 6 : Node* node = node_new();
1154 6 : CHECK_NULL_RETURN(node);
1155 6 : node->type = N_CCLASS;
1156 :
1157 6 : cc = &(NCCLASS(node));
1158 6 : cc->flags = 0;
1159 6 : if (not != 0) CCLASS_SET_NOT(cc);
1160 :
1161 6 : BITSET_CLEAR(cc->bs);
1162 6 : if (IS_NOT_NULL(sbr)) {
1163 6 : n = ONIGENC_CODE_RANGE_NUM(sbr);
1164 16 : for (i = 0; i < n; i++) {
1165 10 : for (j = ONIGENC_CODE_RANGE_FROM(sbr, i);
1166 54 : j <= (int )ONIGENC_CODE_RANGE_TO(sbr, i); j++) {
1167 44 : BITSET_SET_BIT(cc->bs, j);
1168 : }
1169 : }
1170 : }
1171 :
1172 6 : if (IS_NULL(mbr)) {
1173 0 : is_null:
1174 0 : cc->mbuf = NULL;
1175 : }
1176 : else {
1177 : BBuf* bbuf;
1178 :
1179 6 : n = ONIGENC_CODE_RANGE_NUM(mbr);
1180 6 : if (n == 0) goto is_null;
1181 :
1182 6 : bbuf = (BBuf* )xmalloc(sizeof(BBuf));
1183 6 : CHECK_NULL_RETURN_VAL(bbuf, NULL);
1184 6 : bbuf->alloc = n + 1;
1185 6 : bbuf->used = n + 1;
1186 6 : bbuf->p = (UChar* )((void* )mbr);
1187 :
1188 6 : cc->mbuf = bbuf;
1189 : }
1190 :
1191 6 : return node;
1192 : }
1193 :
1194 : static Node*
1195 : node_new_ctype(int type)
1196 4 : {
1197 4 : Node* node = node_new();
1198 4 : CHECK_NULL_RETURN(node);
1199 4 : node->type = N_CTYPE;
1200 4 : NCTYPE(node).type = type;
1201 4 : return node;
1202 : }
1203 :
1204 : static Node*
1205 : node_new_anychar()
1206 26 : {
1207 26 : Node* node = node_new();
1208 26 : CHECK_NULL_RETURN(node);
1209 26 : node->type = N_ANYCHAR;
1210 26 : return node;
1211 : }
1212 :
1213 : static Node*
1214 : node_new_list(Node* left, Node* right)
1215 213 : {
1216 213 : Node* node = node_new();
1217 213 : CHECK_NULL_RETURN(node);
1218 213 : node->type = N_LIST;
1219 213 : NCONS(node).left = left;
1220 213 : NCONS(node).right = right;
1221 213 : return node;
1222 : }
1223 :
1224 : extern Node*
1225 : onig_node_new_list(Node* left, Node* right)
1226 0 : {
1227 0 : return node_new_list(left, right);
1228 : }
1229 :
1230 : static Node*
1231 : node_new_alt(Node* left, Node* right)
1232 4 : {
1233 4 : Node* node = node_new();
1234 4 : CHECK_NULL_RETURN(node);
1235 4 : node->type = N_ALT;
1236 4 : NCONS(node).left = left;
1237 4 : NCONS(node).right = right;
1238 4 : return node;
1239 : }
1240 :
1241 : extern Node*
1242 : onig_node_new_anchor(int type)
1243 18 : {
1244 18 : Node* node = node_new();
1245 18 : CHECK_NULL_RETURN(node);
1246 18 : node->type = N_ANCHOR;
1247 18 : NANCHOR(node).type = type;
1248 18 : NANCHOR(node).target = NULL;
1249 18 : NANCHOR(node).char_len = -1;
1250 18 : return node;
1251 : }
1252 :
1253 : static Node*
1254 : node_new_backref(int back_num, int* backrefs, int by_name,
1255 : #ifdef USE_BACKREF_AT_LEVEL
1256 : int exist_level, int nest_level,
1257 : #endif
1258 : ScanEnv* env)
1259 0 : {
1260 : int i;
1261 0 : Node* node = node_new();
1262 :
1263 0 : CHECK_NULL_RETURN(node);
1264 0 : node->type = N_BACKREF;
1265 0 : NBACKREF(node).state = 0;
1266 0 : NBACKREF(node).back_num = back_num;
1267 0 : NBACKREF(node).back_dynamic = (int* )NULL;
1268 0 : if (by_name != 0)
1269 0 : NBACKREF(node).state |= NST_NAME_REF;
1270 :
1271 : #ifdef USE_BACKREF_AT_LEVEL
1272 0 : if (exist_level != 0) {
1273 0 : NBACKREF(node).state |= NST_NEST_LEVEL;
1274 0 : NBACKREF(node).nest_level = nest_level;
1275 : }
1276 : #endif
1277 :
1278 0 : for (i = 0; i < back_num; i++) {
1279 0 : if (backrefs[i] <= env->num_mem &&
1280 : IS_NULL(SCANENV_MEM_NODES(env)[backrefs[i]])) {
1281 0 : NBACKREF(node).state |= NST_RECURSION; /* /...(\1).../ */
1282 0 : break;
1283 : }
1284 : }
1285 :
1286 0 : if (back_num <= NODE_BACKREFS_SIZE) {
1287 0 : for (i = 0; i < back_num; i++)
1288 0 : NBACKREF(node).back_static[i] = backrefs[i];
1289 : }
1290 : else {
1291 0 : int* p = (int* )xmalloc(sizeof(int) * back_num);
1292 0 : if (IS_NULL(p)) {
1293 0 : onig_node_free(node);
1294 0 : return NULL;
1295 : }
1296 0 : NBACKREF(node).back_dynamic = p;
1297 0 : for (i = 0; i < back_num; i++)
1298 0 : p[i] = backrefs[i];
1299 : }
1300 0 : return node;
1301 : }
1302 :
1303 : #ifdef USE_SUBEXP_CALL
1304 : static Node*
1305 : node_new_call(UChar* name, UChar* name_end)
1306 0 : {
1307 0 : Node* node = node_new();
1308 0 : CHECK_NULL_RETURN(node);
1309 :
1310 0 : node->type = N_CALL;
1311 0 : NCALL(node).state = 0;
1312 0 : NCALL(node).ref_num = CALLNODE_REFNUM_UNDEF;
1313 0 : NCALL(node).target = NULL_NODE;
1314 0 : NCALL(node).name = name;
1315 0 : NCALL(node).name_end = name_end;
1316 0 : return node;
1317 : }
1318 : #endif
1319 :
1320 : static Node*
1321 : node_new_qualifier(int lower, int upper, int by_number)
1322 126 : {
1323 126 : Node* node = node_new();
1324 126 : CHECK_NULL_RETURN(node);
1325 126 : node->type = N_QUALIFIER;
1326 126 : NQUALIFIER(node).state = 0;
1327 126 : NQUALIFIER(node).target = NULL;
1328 126 : NQUALIFIER(node).lower = lower;
1329 126 : NQUALIFIER(node).upper = upper;
1330 126 : NQUALIFIER(node).greedy = 1;
1331 126 : NQUALIFIER(node).target_empty_info = NQ_TARGET_ISNOT_EMPTY;
1332 126 : NQUALIFIER(node).head_exact = NULL_NODE;
1333 126 : NQUALIFIER(node).next_head_exact = NULL_NODE;
1334 126 : NQUALIFIER(node).is_refered = 0;
1335 126 : if (by_number != 0)
1336 4 : NQUALIFIER(node).state |= NST_BY_NUMBER;
1337 :
1338 : #ifdef USE_COMBINATION_EXPLOSION_CHECK
1339 126 : NQUALIFIER(node).comb_exp_check_num = 0;
1340 : #endif
1341 :
1342 126 : return node;
1343 : }
1344 :
1345 : static Node*
1346 : node_new_effect(int type)
1347 76 : {
1348 76 : Node* node = node_new();
1349 76 : CHECK_NULL_RETURN(node);
1350 76 : node->type = N_EFFECT;
1351 76 : NEFFECT(node).type = type;
1352 76 : NEFFECT(node).state = 0;
1353 76 : NEFFECT(node).regnum = 0;
1354 76 : NEFFECT(node).option = 0;
1355 76 : NEFFECT(node).target = NULL;
1356 76 : NEFFECT(node).call_addr = -1;
1357 76 : NEFFECT(node).opt_count = 0;
1358 76 : return node;
1359 : }
1360 :
1361 : extern Node*
1362 : onig_node_new_effect(int type)
1363 15 : {
1364 15 : return node_new_effect(type);
1365 : }
1366 :
1367 : static Node*
1368 : node_new_effect_memory(OnigOptionType option, int is_named)
1369 61 : {
1370 61 : Node* node = node_new_effect(EFFECT_MEMORY);
1371 61 : CHECK_NULL_RETURN(node);
1372 61 : if (is_named != 0)
1373 0 : SET_EFFECT_STATUS(node, NST_NAMED_GROUP);
1374 :
1375 : #ifdef USE_SUBEXP_CALL
1376 61 : NEFFECT(node).option = option;
1377 : #endif
1378 61 : return node;
1379 : }
1380 :
1381 : static Node*
1382 : node_new_option(OnigOptionType option)
1383 0 : {
1384 0 : Node* node = node_new_effect(EFFECT_OPTION);
1385 0 : CHECK_NULL_RETURN(node);
1386 0 : NEFFECT(node).option = option;
1387 0 : return node;
1388 : }
1389 :
1390 : extern int
1391 : onig_node_str_cat(Node* node, const UChar* s, const UChar* end)
1392 357 : {
1393 357 : int addlen = end - s;
1394 :
1395 357 : if (addlen > 0) {
1396 355 : int len = NSTRING(node).end - NSTRING(node).s;
1397 :
1398 355 : if (NSTRING(node).capa > 0 || (len + addlen > NODE_STR_BUF_SIZE - 1)) {
1399 : UChar* p;
1400 0 : int capa = len + addlen + NODE_STR_MARGIN;
1401 :
1402 0 : if (capa <= NSTRING(node).capa) {
1403 0 : k_strcpy(NSTRING(node).s + len, s, end);
1404 : }
1405 : else {
1406 0 : if (NSTRING(node).s == NSTRING(node).buf)
1407 0 : p = strcat_capa_from_static(NSTRING(node).s, NSTRING(node).end,
1408 : s, end, capa);
1409 : else
1410 0 : p = k_strcat_capa(NSTRING(node).s, NSTRING(node).end, s, end, capa);
1411 :
1412 0 : CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
1413 0 : NSTRING(node).s = p;
1414 0 : NSTRING(node).capa = capa;
1415 : }
1416 : }
1417 : else {
1418 355 : k_strcpy(NSTRING(node).s + len, s, end);
1419 : }
1420 355 : NSTRING(node).end = NSTRING(node).s + len + addlen;
1421 : }
1422 :
1423 357 : return 0;
1424 : }
1425 :
1426 : static int
1427 : node_str_cat_char(Node* node, UChar c)
1428 0 : {
1429 : UChar s[1];
1430 :
1431 0 : s[0] = c;
1432 0 : return onig_node_str_cat(node, s, s + 1);
1433 : }
1434 :
1435 : extern void
1436 : onig_node_conv_to_str_node(Node* node, int flag)
1437 0 : {
1438 0 : node->type = N_STRING;
1439 :
1440 0 : NSTRING(node).flag = flag;
1441 0 : NSTRING(node).capa = 0;
1442 0 : NSTRING(node).s = NSTRING(node).buf;
1443 0 : NSTRING(node).end = NSTRING(node).buf;
1444 0 : }
1445 :
1446 : extern void
1447 : onig_node_str_clear(Node* node)
1448 0 : {
1449 0 : if (NSTRING(node).capa != 0 &&
1450 : IS_NOT_NULL(NSTRING(node).s) && NSTRING(node).s != NSTRING(node).buf) {
1451 0 : xfree(NSTRING(node).s);
1452 : }
1453 :
1454 0 : NSTRING(node).capa = 0;
1455 0 : NSTRING(node).flag = 0;
1456 0 : NSTRING(node).s = NSTRING(node).buf;
1457 0 : NSTRING(node).end = NSTRING(node).buf;
1458 0 : }
1459 :
1460 : static Node*
1461 : node_new_str(const UChar* s, const UChar* end)
1462 151 : {
1463 151 : Node* node = node_new();
1464 151 : CHECK_NULL_RETURN(node);
1465 :
1466 151 : node->type = N_STRING;
1467 151 : NSTRING(node).capa = 0;
1468 151 : NSTRING(node).flag = 0;
1469 151 : NSTRING(node).s = NSTRING(node).buf;
1470 151 : NSTRING(node).end = NSTRING(node).buf;
1471 151 : if (onig_node_str_cat(node, s, end)) {
1472 0 : onig_node_free(node);
1473 0 : return NULL;
1474 : }
1475 151 : return node;
1476 : }
1477 :
1478 : extern Node*
1479 : onig_node_new_str(const UChar* s, const UChar* end)
1480 0 : {
1481 0 : return node_new_str(s, end);
1482 : }
1483 :
1484 : static Node*
1485 : node_new_str_raw(UChar* s, UChar* end)
1486 0 : {
1487 0 : Node* node = node_new_str(s, end);
1488 0 : NSTRING_SET_RAW(node);
1489 0 : return node;
1490 : }
1491 :
1492 : static Node*
1493 : node_new_empty()
1494 2 : {
1495 2 : return node_new_str(NULL, NULL);
1496 : }
1497 :
1498 : static Node*
1499 : node_new_str_raw_char(UChar c)
1500 0 : {
1501 : UChar p[1];
1502 :
1503 0 : p[0] = c;
1504 0 : return node_new_str_raw(p, p + 1);
1505 : }
1506 :
1507 : static Node*
1508 : str_node_split_last_char(StrNode* sn, OnigEncoding enc)
1509 9 : {
1510 : const UChar *p;
1511 9 : Node* n = NULL_NODE;
1512 :
1513 9 : if (sn->end > sn->s) {
1514 9 : p = onigenc_get_prev_char_head(enc, sn->s, sn->end);
1515 9 : if (p && p > sn->s) { /* can be splitted. */
1516 9 : n = node_new_str(p, sn->end);
1517 9 : if ((sn->flag & NSTR_RAW) != 0)
1518 0 : NSTRING_SET_RAW(n);
1519 9 : sn->end = (UChar* )p;
1520 : }
1521 : }
1522 9 : return n;
1523 : }
1524 :
1525 : static int
1526 : str_node_can_be_split(StrNode* sn, OnigEncoding enc)
1527 23 : {
1528 23 : if (sn->end > sn->s) {
1529 23 : return ((enc_len(enc, sn->s) < sn->end - sn->s) ? 1 : 0);
1530 : }
1531 0 : return 0;
1532 : }
1533 :
1534 : extern int
1535 : onig_scan_unsigned_number(UChar** src, const UChar* end, OnigEncoding enc)
1536 5 : {
1537 : unsigned int num, val;
1538 : OnigCodePoint c;
1539 5 : UChar* p = *src;
1540 : PFETCH_READY;
1541 :
1542 5 : num = 0;
1543 15 : while (!PEND) {
1544 10 : PFETCH(c);
1545 10 : if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
1546 5 : val = (unsigned int )DIGITVAL(c);
1547 5 : if ((INT_MAX_LIMIT - val) / 10UL < num)
1548 0 : return -1; /* overflow */
1549 :
1550 5 : num = num * 10 + val;
1551 : }
1552 : else {
1553 5 : PUNFETCH;
1554 5 : break;
1555 : }
1556 : }
1557 5 : *src = p;
1558 5 : return num;
1559 : }
1560 :
1561 : static int
1562 : scan_unsigned_hexadecimal_number(UChar** src, UChar* end, int maxlen,
1563 : OnigEncoding enc)
1564 0 : {
1565 : OnigCodePoint c;
1566 : unsigned int num, val;
1567 0 : UChar* p = *src;
1568 : PFETCH_READY;
1569 :
1570 0 : num = 0;
1571 0 : while (!PEND && maxlen-- != 0) {
1572 0 : PFETCH(c);
1573 0 : if (ONIGENC_IS_CODE_XDIGIT(enc, c)) {
1574 0 : val = (unsigned int )XDIGITVAL(enc,c);
1575 0 : if ((INT_MAX_LIMIT - val) / 16UL < num)
1576 0 : return -1; /* overflow */
1577 :
1578 0 : num = (num << 4) + XDIGITVAL(enc,c);
1579 : }
1580 : else {
1581 0 : PUNFETCH;
1582 0 : break;
1583 : }
1584 : }
1585 0 : *src = p;
1586 0 : return num;
1587 : }
1588 :
1589 : static int
1590 : scan_unsigned_octal_number(UChar** src, UChar* end, int maxlen,
1591 : OnigEncoding enc)
1592 0 : {
1593 : OnigCodePoint c;
1594 : unsigned int num, val;
1595 0 : UChar* p = *src;
1596 : PFETCH_READY;
1597 :
1598 0 : num = 0;
1599 0 : while (!PEND && maxlen-- != 0) {
1600 0 : PFETCH(c);
1601 0 : if (ONIGENC_IS_CODE_DIGIT(enc, c) && c < '8') {
1602 0 : val = ODIGITVAL(c);
1603 0 : if ((INT_MAX_LIMIT - val) / 8UL < num)
1604 0 : return -1; /* overflow */
1605 :
1606 0 : num = (num << 3) + val;
1607 : }
1608 : else {
1609 0 : PUNFETCH;
1610 0 : break;
1611 : }
1612 : }
1613 0 : *src = p;
1614 0 : return num;
1615 : }
1616 :
1617 :
1618 : #define BBUF_WRITE_CODE_POINT(bbuf,pos,code) \
1619 : BBUF_WRITE(bbuf, pos, &(code), SIZE_CODE_POINT)
1620 :
1621 : /* data format:
1622 : [n][from-1][to-1][from-2][to-2] ... [from-n][to-n]
1623 : (all data size is OnigCodePoint)
1624 : */
1625 : static int
1626 : new_code_range(BBuf** pbuf)
1627 42 : {
1628 : #define INIT_MULTI_BYTE_RANGE_SIZE (SIZE_CODE_POINT * 5)
1629 : int r;
1630 : OnigCodePoint n;
1631 : BBuf* bbuf;
1632 :
1633 42 : bbuf = *pbuf = (BBuf* )xmalloc(sizeof(BBuf));
1634 42 : CHECK_NULL_RETURN_VAL(*pbuf, ONIGERR_MEMORY);
1635 42 : r = BBUF_INIT(*pbuf, INIT_MULTI_BYTE_RANGE_SIZE);
1636 42 : if (r) return r;
1637 :
1638 42 : n = 0;
1639 42 : BBUF_WRITE_CODE_POINT(bbuf, 0, n);
1640 42 : return 0;
1641 : }
1642 :
1643 : static int
1644 : add_code_range_to_buf(BBuf** pbuf, OnigCodePoint from, OnigCodePoint to)
1645 5466 : {
1646 : int r, inc_n, pos;
1647 : int low, high, bound, x;
1648 : OnigCodePoint n, *data;
1649 : BBuf* bbuf;
1650 :
1651 5466 : if (from > to) {
1652 0 : n = from; from = to; to = n;
1653 : }
1654 :
1655 5466 : if (IS_NULL(*pbuf)) {
1656 42 : r = new_code_range(pbuf);
1657 42 : if (r) return r;
1658 42 : bbuf = *pbuf;
1659 42 : n = 0;
1660 : }
1661 : else {
1662 5424 : bbuf = *pbuf;
1663 5424 : GET_CODE_POINT(n, bbuf->p);
1664 : }
1665 5466 : data = (OnigCodePoint* )(bbuf->p);
1666 5466 : data++;
1667 :
1668 46336 : for (low = 0, bound = n; low < bound; ) {
1669 35404 : x = (low + bound) >> 1;
1670 35404 : if (from > data[x*2 + 1])
1671 35325 : low = x + 1;
1672 : else
1673 79 : bound = x;
1674 : }
1675 :
1676 11052 : for (high = low, bound = n; high < bound; ) {
1677 120 : x = (high + bound) >> 1;
1678 120 : if (to >= data[x*2] - 1)
1679 5 : high = x + 1;
1680 : else
1681 115 : bound = x;
1682 : }
1683 :
1684 5466 : inc_n = low + 1 - high;
1685 5466 : if (n + inc_n > ONIG_MAX_MULTI_BYTE_RANGES_NUM)
1686 0 : return ONIGERR_TOO_MANY_MULTI_BYTE_RANGES;
1687 :
1688 5466 : if (inc_n != 1) {
1689 5 : if (from > data[low*2])
1690 0 : from = data[low*2];
1691 5 : if (to < data[(high - 1)*2 + 1])
1692 5 : to = data[(high - 1)*2 + 1];
1693 : }
1694 :
1695 5466 : if (inc_n != 0 && (OnigCodePoint )high < n) {
1696 17 : int from_pos = SIZE_CODE_POINT * (1 + high * 2);
1697 17 : int to_pos = SIZE_CODE_POINT * (1 + (low + 1) * 2);
1698 17 : int size = (n - high) * 2 * SIZE_CODE_POINT;
1699 :
1700 17 : if (inc_n > 0) {
1701 17 : BBUF_MOVE_RIGHT(bbuf, from_pos, to_pos, size);
1702 : }
1703 : else {
1704 0 : BBUF_MOVE_LEFT_REDUCE(bbuf, from_pos, to_pos);
1705 : }
1706 : }
1707 :
1708 5466 : pos = SIZE_CODE_POINT * (1 + low * 2);
1709 5466 : BBUF_ENSURE_SIZE(bbuf, pos + SIZE_CODE_POINT * 2);
1710 5466 : BBUF_WRITE_CODE_POINT(bbuf, pos, from);
1711 5466 : BBUF_WRITE_CODE_POINT(bbuf, pos + SIZE_CODE_POINT, to);
1712 5466 : n += inc_n;
1713 5466 : BBUF_WRITE_CODE_POINT(bbuf, 0, n);
1714 :
1715 5466 : return 0;
1716 : }
1717 :
1718 : static int
1719 : add_code_range(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to)
1720 14 : {
1721 14 : if (from > to) {
1722 0 : if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
1723 0 : return 0;
1724 : else
1725 0 : return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
1726 : }
1727 :
1728 14 : return add_code_range_to_buf(pbuf, from, to);
1729 : }
1730 :
1731 : static int
1732 : not_code_range_buf(OnigEncoding enc, BBuf* bbuf, BBuf** pbuf)
1733 0 : {
1734 : int r, i, n;
1735 0 : OnigCodePoint pre, from, *data, to = 0;
1736 :
1737 0 : *pbuf = (BBuf* )NULL;
1738 0 : if (IS_NULL(bbuf)) {
1739 0 : set_all:
1740 0 : return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
1741 : }
1742 :
1743 0 : data = (OnigCodePoint* )(bbuf->p);
1744 0 : GET_CODE_POINT(n, data);
1745 0 : data++;
1746 0 : if (n <= 0) goto set_all;
1747 :
1748 0 : r = 0;
1749 0 : pre = MBCODE_START_POS(enc);
1750 0 : for (i = 0; i < n; i++) {
1751 0 : from = data[i*2];
1752 0 : to = data[i*2+1];
1753 0 : if (pre <= from - 1) {
1754 0 : r = add_code_range_to_buf(pbuf, pre, from - 1);
1755 0 : if (r != 0) return r;
1756 : }
1757 0 : if (to == ~((OnigCodePoint )0)) break;
1758 0 : pre = to + 1;
1759 : }
1760 0 : if (to < ~((OnigCodePoint )0)) {
1761 0 : r = add_code_range_to_buf(pbuf, to + 1, ~((OnigCodePoint )0));
1762 : }
1763 0 : return r;
1764 : }
1765 :
1766 : #define SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2) do {\
1767 : BBuf *tbuf; \
1768 : int tnot; \
1769 : tnot = not1; not1 = not2; not2 = tnot; \
1770 : tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf; \
1771 : } while (0)
1772 :
1773 : static int
1774 : or_code_range_buf(OnigEncoding enc, BBuf* bbuf1, int not1,
1775 : BBuf* bbuf2, int not2, BBuf** pbuf)
1776 0 : {
1777 : int r;
1778 : OnigCodePoint i, n1, *data1;
1779 : OnigCodePoint from, to;
1780 :
1781 0 : *pbuf = (BBuf* )NULL;
1782 0 : if (IS_NULL(bbuf1) && IS_NULL(bbuf2)) {
1783 0 : if (not1 != 0 || not2 != 0)
1784 0 : return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
1785 0 : return 0;
1786 : }
1787 :
1788 0 : r = 0;
1789 0 : if (IS_NULL(bbuf2))
1790 0 : SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
1791 :
1792 0 : if (IS_NULL(bbuf1)) {
1793 0 : if (not1 != 0) {
1794 0 : return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
1795 : }
1796 : else {
1797 0 : if (not2 == 0) {
1798 0 : return bbuf_clone(pbuf, bbuf2);
1799 : }
1800 : else {
1801 0 : return not_code_range_buf(enc, bbuf2, pbuf);
1802 : }
1803 : }
1804 : }
1805 :
1806 0 : if (not1 != 0)
1807 0 : SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
1808 :
1809 0 : data1 = (OnigCodePoint* )(bbuf1->p);
1810 0 : GET_CODE_POINT(n1, data1);
1811 0 : data1++;
1812 :
1813 0 : if (not2 == 0 && not1 == 0) { /* 1 OR 2 */
1814 0 : r = bbuf_clone(pbuf, bbuf2);
1815 : }
1816 0 : else if (not1 == 0) { /* 1 OR (not 2) */
1817 0 : r = not_code_range_buf(enc, bbuf2, pbuf);
1818 : }
1819 0 : if (r != 0) return r;
1820 :
1821 0 : for (i = 0; i < n1; i++) {
1822 0 : from = data1[i*2];
1823 0 : to = data1[i*2+1];
1824 0 : r = add_code_range_to_buf(pbuf, from, to);
1825 0 : if (r != 0) return r;
1826 : }
1827 0 : return 0;
1828 : }
1829 :
1830 : static int
1831 : and_code_range1(BBuf** pbuf, OnigCodePoint from1, OnigCodePoint to1,
1832 : OnigCodePoint* data, int n)
1833 0 : {
1834 : int i, r;
1835 : OnigCodePoint from2, to2;
1836 :
1837 0 : for (i = 0; i < n; i++) {
1838 0 : from2 = data[i*2];
1839 0 : to2 = data[i*2+1];
1840 0 : if (from2 < from1) {
1841 0 : if (to2 < from1) continue;
1842 : else {
1843 0 : from1 = to2 + 1;
1844 : }
1845 : }
1846 0 : else if (from2 <= to1) {
1847 0 : if (to2 < to1) {
1848 0 : if (from1 <= from2 - 1) {
1849 0 : r = add_code_range_to_buf(pbuf, from1, from2-1);
1850 0 : if (r != 0) return r;
1851 : }
1852 0 : from1 = to2 + 1;
1853 : }
1854 : else {
1855 0 : to1 = from2 - 1;
1856 : }
1857 : }
1858 : else {
1859 0 : from1 = from2;
1860 : }
1861 0 : if (from1 > to1) break;
1862 : }
1863 0 : if (from1 <= to1) {
1864 0 : r = add_code_range_to_buf(pbuf, from1, to1);
1865 0 : if (r != 0) return r;
1866 : }
1867 0 : return 0;
1868 : }
1869 :
1870 : static int
1871 : and_code_range_buf(BBuf* bbuf1, int not1, BBuf* bbuf2, int not2, BBuf** pbuf)
1872 0 : {
1873 : int r;
1874 : OnigCodePoint i, j, n1, n2, *data1, *data2;
1875 : OnigCodePoint from, to, from1, to1, from2, to2;
1876 :
1877 0 : *pbuf = (BBuf* )NULL;
1878 0 : if (IS_NULL(bbuf1)) {
1879 0 : if (not1 != 0 && IS_NOT_NULL(bbuf2)) /* not1 != 0 -> not2 == 0 */
1880 0 : return bbuf_clone(pbuf, bbuf2);
1881 0 : return 0;
1882 : }
1883 0 : else if (IS_NULL(bbuf2)) {
1884 0 : if (not2 != 0)
1885 0 : return bbuf_clone(pbuf, bbuf1);
1886 0 : return 0;
1887 : }
1888 :
1889 0 : if (not1 != 0)
1890 0 : SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
1891 :
1892 0 : data1 = (OnigCodePoint* )(bbuf1->p);
1893 0 : data2 = (OnigCodePoint* )(bbuf2->p);
1894 0 : GET_CODE_POINT(n1, data1);
1895 0 : GET_CODE_POINT(n2, data2);
1896 0 : data1++;
1897 0 : data2++;
1898 :
1899 0 : if (not2 == 0 && not1 == 0) { /* 1 AND 2 */
1900 0 : for (i = 0; i < n1; i++) {
1901 0 : from1 = data1[i*2];
1902 0 : to1 = data1[i*2+1];
1903 0 : for (j = 0; j < n2; j++) {
1904 0 : from2 = data2[j*2];
1905 0 : to2 = data2[j*2+1];
1906 0 : if (from2 > to1) break;
1907 0 : if (to2 < from1) continue;
1908 0 : from = MAX(from1, from2);
1909 0 : to = MIN(to1, to2);
1910 0 : r = add_code_range_to_buf(pbuf, from, to);
1911 0 : if (r != 0) return r;
1912 : }
1913 : }
1914 : }
1915 0 : else if (not1 == 0) { /* 1 AND (not 2) */
1916 0 : for (i = 0; i < n1; i++) {
1917 0 : from1 = data1[i*2];
1918 0 : to1 = data1[i*2+1];
1919 0 : r = and_code_range1(pbuf, from1, to1, data2, n2);
1920 0 : if (r != 0) return r;
1921 : }
1922 : }
1923 :
1924 0 : return 0;
1925 : }
1926 :
1927 : static int
1928 : clear_not_flag_cclass(CClassNode* cc, OnigEncoding enc)
1929 0 : {
1930 : BBuf *tbuf;
1931 : int r;
1932 :
1933 0 : if (IS_CCLASS_NOT(cc)) {
1934 0 : bitset_invert(cc->bs);
1935 :
1936 0 : if (! ONIGENC_IS_SINGLEBYTE(enc)) {
1937 0 : r = not_code_range_buf(enc, cc->mbuf, &tbuf);
1938 0 : if (r != 0) return r;
1939 :
1940 0 : bbuf_free(cc->mbuf);
1941 0 : cc->mbuf = tbuf;
1942 : }
1943 :
1944 0 : CCLASS_CLEAR_NOT(cc);
1945 : }
1946 :
1947 0 : return 0;
1948 : }
1949 :
1950 : static int
1951 : and_cclass(CClassNode* dest, CClassNode* cc, OnigEncoding enc)
1952 0 : {
1953 : int r, not1, not2;
1954 : BBuf *buf1, *buf2, *pbuf;
1955 : BitSetRef bsr1, bsr2;
1956 : BitSet bs1, bs2;
1957 :
1958 0 : not1 = IS_CCLASS_NOT(dest);
1959 0 : bsr1 = dest->bs;
1960 0 : buf1 = dest->mbuf;
1961 0 : not2 = IS_CCLASS_NOT(cc);
1962 0 : bsr2 = cc->bs;
1963 0 : buf2 = cc->mbuf;
1964 :
1965 0 : if (not1 != 0) {
1966 0 : bitset_invert_to(bsr1, bs1);
1967 0 : bsr1 = bs1;
1968 : }
1969 0 : if (not2 != 0) {
1970 0 : bitset_invert_to(bsr2, bs2);
1971 0 : bsr2 = bs2;
1972 : }
1973 0 : bitset_and(bsr1, bsr2);
1974 0 : if (bsr1 != dest->bs) {
1975 0 : bitset_copy(dest->bs, bsr1);
1976 0 : bsr1 = dest->bs;
1977 : }
1978 0 : if (not1 != 0) {
1979 0 : bitset_invert(dest->bs);
1980 : }
1981 :
1982 0 : if (! ONIGENC_IS_SINGLEBYTE(enc)) {
1983 0 : if (not1 != 0 && not2 != 0) {
1984 0 : r = or_code_range_buf(enc, buf1, 0, buf2, 0, &pbuf);
1985 : }
1986 : else {
1987 0 : r = and_code_range_buf(buf1, not1, buf2, not2, &pbuf);
1988 0 : if (r == 0 && not1 != 0) {
1989 : BBuf *tbuf;
1990 0 : r = not_code_range_buf(enc, pbuf, &tbuf);
1991 0 : if (r != 0) {
1992 0 : bbuf_free(pbuf);
1993 0 : return r;
1994 : }
1995 0 : bbuf_free(pbuf);
1996 0 : pbuf = tbuf;
1997 : }
1998 : }
1999 0 : if (r != 0) return r;
2000 :
2001 0 : dest->mbuf = pbuf;
2002 0 : bbuf_free(buf1);
2003 0 : return r;
2004 : }
2005 0 : return 0;
2006 : }
2007 :
2008 : static int
2009 : or_cclass(CClassNode* dest, CClassNode* cc, OnigEncoding enc)
2010 0 : {
2011 : int r, not1, not2;
2012 : BBuf *buf1, *buf2, *pbuf;
2013 : BitSetRef bsr1, bsr2;
2014 : BitSet bs1, bs2;
2015 :
2016 0 : not1 = IS_CCLASS_NOT(dest);
2017 0 : bsr1 = dest->bs;
2018 0 : buf1 = dest->mbuf;
2019 0 : not2 = IS_CCLASS_NOT(cc);
2020 0 : bsr2 = cc->bs;
2021 0 : buf2 = cc->mbuf;
2022 :
2023 0 : if (not1 != 0) {
2024 0 : bitset_invert_to(bsr1, bs1);
2025 0 : bsr1 = bs1;
2026 : }
2027 0 : if (not2 != 0) {
2028 0 : bitset_invert_to(bsr2, bs2);
2029 0 : bsr2 = bs2;
2030 : }
2031 0 : bitset_or(bsr1, bsr2);
2032 0 : if (bsr1 != dest->bs) {
2033 0 : bitset_copy(dest->bs, bsr1);
2034 0 : bsr1 = dest->bs;
2035 : }
2036 0 : if (not1 != 0) {
2037 0 : bitset_invert(dest->bs);
2038 : }
2039 :
2040 0 : if (! ONIGENC_IS_SINGLEBYTE(enc)) {
2041 0 : if (not1 != 0 && not2 != 0) {
2042 0 : r = and_code_range_buf(buf1, 0, buf2, 0, &pbuf);
2043 : }
2044 : else {
2045 0 : r = or_code_range_buf(enc, buf1, not1, buf2, not2, &pbuf);
2046 0 : if (r == 0 && not1 != 0) {
2047 : BBuf *tbuf;
2048 0 : r = not_code_range_buf(enc, pbuf, &tbuf);
2049 0 : if (r != 0) {
2050 0 : bbuf_free(pbuf);
2051 0 : return r;
2052 : }
2053 0 : bbuf_free(pbuf);
2054 0 : pbuf = tbuf;
2055 : }
2056 : }
2057 0 : if (r != 0) return r;
2058 :
2059 0 : dest->mbuf = pbuf;
2060 0 : bbuf_free(buf1);
2061 0 : return r;
2062 : }
2063 : else
2064 0 : return 0;
2065 : }
2066 :
2067 : static int
2068 : conv_backslash_value(int c, ScanEnv* env)
2069 5 : {
2070 5 : if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_CONTROL_CHARS)) {
2071 5 : switch (c) {
2072 0 : case 'n': return '\n';
2073 0 : case 't': return '\t';
2074 0 : case 'r': return '\r';
2075 0 : case 'f': return '\f';
2076 0 : case 'a': return '\007';
2077 0 : case 'b': return '\010';
2078 0 : case 'e': return '\033';
2079 : case 'v':
2080 0 : if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_V_VTAB))
2081 0 : return '\v';
2082 : break;
2083 :
2084 : default:
2085 : break;
2086 : }
2087 : }
2088 5 : return c;
2089 : }
2090 :
2091 : static int
2092 : is_invalid_qualifier_target(Node* node)
2093 126 : {
2094 126 : switch (NTYPE(node)) {
2095 : case N_ANCHOR:
2096 0 : return 1;
2097 : break;
2098 :
2099 : case N_EFFECT:
2100 5 : if (NEFFECT(node).type == EFFECT_OPTION)
2101 0 : return is_invalid_qualifier_target(NEFFECT(node).target);
2102 5 : break;
2103 :
2104 : case N_LIST: /* ex. (?:\G\A)* */
2105 : do {
2106 0 : if (! is_invalid_qualifier_target(NCONS(node).left)) return 0;
2107 0 : } while (IS_NOT_NULL(node = NCONS(node).right));
2108 0 : return 0;
2109 : break;
2110 :
2111 : case N_ALT: /* ex. (?:abc|\A)* */
2112 : do {
2113 0 : if (is_invalid_qualifier_target(NCONS(node).left)) return 1;
2114 0 : } while (IS_NOT_NULL(node = NCONS(node).right));
2115 : break;
2116 :
2117 : default:
2118 : break;
2119 : }
2120 126 : return 0;
2121 : }
2122 :
2123 : /* ?:0, *:1, +:2, ??:3, *?:4, +?:5 */
2124 : static int
2125 : popular_qualifier_num(QualifierNode* qf)
2126 0 : {
2127 0 : if (qf->greedy) {
2128 0 : if (qf->lower == 0) {
2129 0 : if (qf->upper == 1) return 0;
2130 0 : else if (IS_REPEAT_INFINITE(qf->upper)) return 1;
2131 : }
2132 0 : else if (qf->lower == 1) {
2133 0 : if (IS_REPEAT_INFINITE(qf->upper)) return 2;
2134 : }
2135 : }
2136 : else {
2137 0 : if (qf->lower == 0) {
2138 0 : if (qf->upper == 1) return 3;
2139 0 : else if (IS_REPEAT_INFINITE(qf->upper)) return 4;
2140 : }
2141 0 : else if (qf->lower == 1) {
2142 0 : if (IS_REPEAT_INFINITE(qf->upper)) return 5;
2143 : }
2144 : }
2145 0 : return -1;
2146 : }
2147 :
2148 :
2149 : enum ReduceType {
2150 : RQ_ASIS = 0, /* as is */
2151 : RQ_DEL = 1, /* delete parent */
2152 : RQ_A, /* to '*' */
2153 : RQ_AQ, /* to '*?' */
2154 : RQ_QQ, /* to '??' */
2155 : RQ_P_QQ, /* to '+)??' */
2156 : RQ_PQ_Q /* to '+?)?' */
2157 : };
2158 :
2159 : static enum ReduceType ReduceTypeTable[6][6] = {
2160 : {RQ_DEL, RQ_A, RQ_A, RQ_QQ, RQ_AQ, RQ_ASIS}, /* '?' */
2161 : {RQ_DEL, RQ_DEL, RQ_DEL, RQ_P_QQ, RQ_P_QQ, RQ_DEL}, /* '*' */
2162 : {RQ_A, RQ_A, RQ_DEL, RQ_ASIS, RQ_P_QQ, RQ_DEL}, /* '+' */
2163 : {RQ_DEL, RQ_AQ, RQ_AQ, RQ_DEL, RQ_AQ, RQ_AQ}, /* '??' */
2164 : {RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL, RQ_DEL}, /* '*?' */
2165 : {RQ_ASIS, RQ_PQ_Q, RQ_DEL, RQ_AQ, RQ_AQ, RQ_DEL} /* '+?' */
2166 : };
2167 :
2168 : extern void
2169 : onig_reduce_nested_qualifier(Node* pnode, Node* cnode)
2170 0 : {
2171 : int pnum, cnum;
2172 : QualifierNode *p, *c;
2173 :
2174 0 : p = &(NQUALIFIER(pnode));
2175 0 : c = &(NQUALIFIER(cnode));
2176 0 : pnum = popular_qualifier_num(p);
2177 0 : cnum = popular_qualifier_num(c);
2178 :
2179 0 : switch(ReduceTypeTable[cnum][pnum]) {
2180 : case RQ_DEL:
2181 0 : *p = *c;
2182 0 : break;
2183 : case RQ_A:
2184 0 : p->target = c->target;
2185 0 : p->lower = 0; p->upper = REPEAT_INFINITE; p->greedy = 1;
2186 0 : break;
2187 : case RQ_AQ:
2188 0 : p->target = c->target;
2189 0 : p->lower = 0; p->upper = REPEAT_INFINITE; p->greedy = 0;
2190 0 : break;
2191 : case RQ_QQ:
2192 0 : p->target = c->target;
2193 0 : p->lower = 0; p->upper = 1; p->greedy = 0;
2194 0 : break;
2195 : case RQ_P_QQ:
2196 0 : p->target = cnode;
2197 0 : p->lower = 0; p->upper = 1; p->greedy = 0;
2198 0 : c->lower = 1; c->upper = REPEAT_INFINITE; c->greedy = 1;
2199 0 : return ;
2200 : break;
2201 : case RQ_PQ_Q:
2202 0 : p->target = cnode;
2203 0 : p->lower = 0; p->upper = 1; p->greedy = 1;
2204 0 : c->lower = 1; c->upper = REPEAT_INFINITE; c->greedy = 0;
2205 0 : return ;
2206 : break;
2207 : case RQ_ASIS:
2208 0 : p->target = cnode;
2209 0 : return ;
2210 : break;
2211 : }
2212 :
2213 0 : c->target = NULL_NODE;
2214 0 : onig_node_free(cnode);
2215 : }
2216 :
2217 :
2218 : enum TokenSyms {
2219 : TK_EOT = 0, /* end of token */
2220 : TK_RAW_BYTE = 1,
2221 : TK_CHAR,
2222 : TK_STRING,
2223 : TK_CODE_POINT,
2224 : TK_ANYCHAR,
2225 : TK_CHAR_TYPE,
2226 : TK_BACKREF,
2227 : TK_CALL,
2228 : TK_ANCHOR,
2229 : TK_OP_REPEAT,
2230 : TK_INTERVAL,
2231 : TK_ANYCHAR_ANYTIME, /* SQL '%' == .* */
2232 : TK_ALT,
2233 : TK_SUBEXP_OPEN,
2234 : TK_SUBEXP_CLOSE,
2235 : TK_CC_OPEN,
2236 : TK_QUOTE_OPEN,
2237 : TK_CHAR_PROPERTY, /* \p{...}, \P{...} */
2238 : /* in cc */
2239 : TK_CC_CLOSE,
2240 : TK_CC_RANGE,
2241 : TK_POSIX_BRACKET_OPEN,
2242 : TK_CC_AND, /* && */
2243 : TK_CC_CC_OPEN /* [ */
2244 : };
2245 :
2246 : typedef struct {
2247 : enum TokenSyms type;
2248 : int escaped;
2249 : int base; /* is number: 8, 16 (used in [....]) */
2250 : UChar* backp;
2251 : union {
2252 : UChar* s;
2253 : int c;
2254 : OnigCodePoint code;
2255 : int anchor;
2256 : int subtype;
2257 : struct {
2258 : int lower;
2259 : int upper;
2260 : int greedy;
2261 : int possessive;
2262 : } repeat;
2263 : struct {
2264 : int num;
2265 : int ref1;
2266 : int* refs;
2267 : int by_name;
2268 : #ifdef USE_BACKREF_AT_LEVEL
2269 : int exist_level;
2270 : int level; /* \k<name+n> */
2271 : #endif
2272 : } backref;
2273 : struct {
2274 : UChar* name;
2275 : UChar* name_end;
2276 : } call;
2277 : struct {
2278 : int not;
2279 : } prop;
2280 : } u;
2281 : } OnigToken;
2282 :
2283 :
2284 : static int
2285 : fetch_range_qualifier(UChar** src, UChar* end, OnigToken* tok, ScanEnv* env)
2286 4 : {
2287 4 : int low, up, syn_allow, non_low = 0;
2288 4 : int r = 0;
2289 : OnigCodePoint c;
2290 4 : OnigEncoding enc = env->enc;
2291 4 : UChar* p = *src;
2292 : PFETCH_READY;
2293 :
2294 4 : syn_allow = IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INVALID_INTERVAL);
2295 :
2296 4 : if (PEND) {
2297 0 : if (syn_allow)
2298 0 : return 1; /* "....{" : OK! */
2299 : else
2300 0 : return ONIGERR_END_PATTERN_AT_LEFT_BRACE; /* "....{" syntax error */
2301 : }
2302 :
2303 4 : if (! syn_allow) {
2304 0 : c = PPEEK;
2305 0 : if (c == ')' || c == '(' || c == '|') {
2306 0 : return ONIGERR_END_PATTERN_AT_LEFT_BRACE;
2307 : }
2308 : }
2309 :
2310 4 : low = onig_scan_unsigned_number(&p, end, env->enc);
2311 4 : if (low < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
2312 4 : if (low > ONIG_MAX_REPEAT_NUM)
2313 0 : return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
2314 :
2315 4 : if (p == *src) { /* can't read low */
2316 0 : if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV)) {
2317 : /* allow {,n} as {0,n} */
2318 0 : low = 0;
2319 0 : non_low = 1;
2320 : }
2321 : else
2322 0 : goto invalid;
2323 : }
2324 :
2325 4 : if (PEND) goto invalid;
2326 4 : PFETCH(c);
2327 4 : if (c == ',') {
2328 1 : UChar* prev = p;
2329 1 : up = onig_scan_unsigned_number(&p, end, env->enc);
2330 1 : if (up < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
2331 1 : if (up > ONIG_MAX_REPEAT_NUM)
2332 0 : return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
2333 :
2334 1 : if (p == prev) {
2335 0 : if (non_low != 0)
2336 0 : goto invalid;
2337 0 : up = REPEAT_INFINITE; /* {n,} : {n,infinite} */
2338 : }
2339 : }
2340 : else {
2341 3 : if (non_low != 0)
2342 0 : goto invalid;
2343 :
2344 3 : PUNFETCH;
2345 3 : up = low; /* {n} : exact n times */
2346 3 : r = 2; /* fixed */
2347 : }
2348 :
2349 4 : if (PEND) goto invalid;
2350 4 : PFETCH(c);
2351 4 : if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) {
2352 0 : if (c != MC_ESC(enc)) goto invalid;
2353 0 : PFETCH(c);
2354 : }
2355 4 : if (c != '}') goto invalid;
2356 :
2357 4 : if (!IS_REPEAT_INFINITE(up) && low > up) {
2358 0 : return ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE;
2359 : }
2360 :
2361 4 : tok->type = TK_INTERVAL;
2362 4 : tok->u.repeat.lower = low;
2363 4 : tok->u.repeat.upper = up;
2364 4 : *src = p;
2365 4 : return r; /* 0: normal {n,m}, 2: fixed {n} */
2366 :
2367 0 : invalid:
2368 0 : if (syn_allow)
2369 0 : return 1; /* OK */
2370 : else
2371 0 : return ONIGERR_INVALID_REPEAT_RANGE_PATTERN;
2372 : }
2373 :
2374 : /* \M-, \C-, \c, or \... */
2375 : static int
2376 : fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env)
2377 5 : {
2378 : int v;
2379 : OnigCodePoint c;
2380 5 : OnigEncoding enc = env->enc;
2381 5 : UChar* p = *src;
2382 : PFETCH_READY;
2383 :
2384 5 : if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
2385 :
2386 5 : PFETCH(c);
2387 5 : switch (c) {
2388 : case 'M':
2389 0 : if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META)) {
2390 0 : if (PEND) return ONIGERR_END_PATTERN_AT_META;
2391 0 : PFETCH(c);
2392 0 : if (c != '-') return ONIGERR_META_CODE_SYNTAX;
2393 0 : if (PEND) return ONIGERR_END_PATTERN_AT_META;
2394 0 : PFETCH(c);
2395 0 : if (c == MC_ESC(enc)) {
2396 0 : v = fetch_escaped_value(&p, end, env);
2397 0 : if (v < 0) return v;
2398 0 : c = (OnigCodePoint )v;
2399 : }
2400 0 : c = ((c & 0xff) | 0x80);
2401 : }
2402 : else
2403 0 : goto backslash;
2404 0 : break;
2405 :
2406 : case 'C':
2407 0 : if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL)) {
2408 0 : if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL;
2409 0 : PFETCH(c);
2410 0 : if (c != '-') return ONIGERR_CONTROL_CODE_SYNTAX;
2411 0 : goto control;
2412 : }
2413 : else
2414 0 : goto backslash;
2415 :
2416 : case 'c':
2417 0 : if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_C_CONTROL)) {
2418 0 : control:
2419 0 : if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL;
2420 0 : PFETCH(c);
2421 0 : if (c == '?') {
2422 0 : c = 0177;
2423 : }
2424 : else {
2425 0 : if (c == MC_ESC(enc)) {
2426 0 : v = fetch_escaped_value(&p, end, env);
2427 0 : if (v < 0) return v;
2428 0 : c = (OnigCodePoint )v;
2429 : }
2430 0 : c &= 0x9f;
2431 : }
2432 0 : break;
2433 : }
2434 : /* fall through */
2435 :
2436 : default:
2437 : {
2438 5 : backslash:
2439 5 : c = conv_backslash_value(c, env);
2440 : }
2441 : break;
2442 : }
2443 :
2444 5 : *src = p;
2445 5 : return c;
2446 : }
2447 :
2448 : static int fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env);
2449 :
2450 : #ifdef USE_NAMED_GROUP
2451 : #ifdef USE_BACKREF_AT_LEVEL
2452 : /*
2453 : \k<name+n>, \k<name-n>
2454 : */
2455 : static int
2456 : fetch_name_with_level(UChar** src, UChar* end, UChar** rname_end
2457 : , ScanEnv* env, int* level)
2458 0 : {
2459 0 : int r, exist_level = 0;
2460 0 : OnigCodePoint c = 0;
2461 : OnigCodePoint first_code;
2462 0 : OnigEncoding enc = env->enc;
2463 : UChar *name_end;
2464 0 : UChar *p = *src;
2465 : PFETCH_READY;
2466 :
2467 0 : name_end = end;
2468 0 : r = 0;
2469 0 : if (PEND) {
2470 0 : return ONIGERR_EMPTY_GROUP_NAME;
2471 : }
2472 : else {
2473 0 : PFETCH(c);
2474 0 : first_code = c;
2475 0 : if (c == '>')
2476 0 : return ONIGERR_EMPTY_GROUP_NAME;
2477 :
2478 0 : if (!ONIGENC_IS_CODE_WORD(enc, c)) {
2479 0 : r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2480 : }
2481 : }
2482 :
2483 0 : while (!PEND) {
2484 0 : name_end = p;
2485 0 : PFETCH(c);
2486 0 : if (c == '>' || c == ')' || c == '+' || c == '-') break;
2487 :
2488 0 : if (!ONIGENC_IS_CODE_WORD(enc, c)) {
2489 0 : r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2490 : }
2491 : }
2492 :
2493 0 : if (c != '>') {
2494 0 : if (c == '+' || c == '-') {
2495 : int num;
2496 0 : int flag = (c == '-' ? -1 : 1);
2497 :
2498 0 : PFETCH(c);
2499 0 : if (! ONIGENC_IS_CODE_DIGIT(enc, c)) goto err;
2500 0 : PUNFETCH;
2501 0 : num = onig_scan_unsigned_number(&p, end, enc);
2502 0 : if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
2503 0 : *level = (num * flag);
2504 0 : exist_level = 1;
2505 :
2506 0 : PFETCH(c);
2507 0 : if (c == '>')
2508 0 : goto first_check;
2509 : }
2510 :
2511 0 : err:
2512 0 : r = ONIGERR_INVALID_GROUP_NAME;
2513 0 : name_end = end;
2514 : }
2515 : else {
2516 0 : first_check:
2517 0 : if (ONIGENC_IS_CODE_ASCII(first_code) &&
2518 : ONIGENC_IS_CODE_UPPER(enc, first_code))
2519 0 : r = ONIGERR_INVALID_GROUP_NAME;
2520 : }
2521 :
2522 0 : if (r == 0) {
2523 0 : *rname_end = name_end;
2524 0 : *src = p;
2525 0 : return (exist_level ? 1 : 0);
2526 : }
2527 : else {
2528 0 : onig_scan_env_set_error_string(env, r, *src, name_end);
2529 0 : return r;
2530 : }
2531 : }
2532 : #endif /* USE_BACKREF_AT_LEVEL */
2533 :
2534 : /*
2535 : def: 0 -> define name (don't allow number name)
2536 : 1 -> reference name (allow number name)
2537 : */
2538 : static int
2539 : fetch_name(UChar** src, UChar* end, UChar** rname_end, ScanEnv* env, int ref)
2540 0 : {
2541 : int r, is_num;
2542 0 : OnigCodePoint c = 0;
2543 : OnigCodePoint first_code;
2544 0 : OnigEncoding enc = env->enc;
2545 : UChar *name_end;
2546 0 : UChar *p = *src;
2547 : PFETCH_READY;
2548 :
2549 0 : name_end = end;
2550 0 : r = 0;
2551 0 : is_num = 0;
2552 0 : if (PEND) {
2553 0 : return ONIGERR_EMPTY_GROUP_NAME;
2554 : }
2555 : else {
2556 0 : PFETCH(c);
2557 0 : first_code = c;
2558 0 : if (c == '>')
2559 0 : return ONIGERR_EMPTY_GROUP_NAME;
2560 :
2561 0 : if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
2562 0 : if (ref == 1)
2563 0 : is_num = 1;
2564 : else {
2565 0 : r = ONIGERR_INVALID_GROUP_NAME;
2566 : }
2567 : }
2568 0 : else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
2569 0 : r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2570 : }
2571 : }
2572 :
2573 0 : while (!PEND) {
2574 0 : name_end = p;
2575 0 : PFETCH(c);
2576 0 : if (c == '>' || c == ')') break;
2577 :
2578 0 : if (is_num == 1) {
2579 0 : if (! ONIGENC_IS_CODE_DIGIT(enc, c)) {
2580 0 : if (!ONIGENC_IS_CODE_WORD(enc, c))
2581 0 : r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2582 : else
2583 0 : r = ONIGERR_INVALID_GROUP_NAME;
2584 : }
2585 : }
2586 : else {
2587 0 : if (!ONIGENC_IS_CODE_WORD(enc, c)) {
2588 0 : r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2589 : }
2590 : }
2591 : }
2592 :
2593 0 : if (c != '>') {
2594 0 : r = ONIGERR_INVALID_GROUP_NAME;
2595 0 : name_end = end;
2596 : }
2597 : else {
2598 0 : if (ONIGENC_IS_CODE_ASCII(first_code) &&
2599 : ONIGENC_IS_CODE_UPPER(enc, first_code))
2600 0 : r = ONIGERR_INVALID_GROUP_NAME;
2601 : }
2602 :
2603 0 : if (r == 0) {
2604 0 : *rname_end = name_end;
2605 0 : *src = p;
2606 0 : return 0;
2607 : }
2608 : else {
2609 0 : onig_scan_env_set_error_string(env, r, *src, name_end);
2610 0 : return r;
2611 : }
2612 : }
2613 : #else
2614 : static int
2615 : fetch_name(UChar** src, UChar* end, UChar** rname_end, ScanEnv* env, int ref)
2616 : {
2617 : int r, len;
2618 : OnigCodePoint c = 0;
2619 : UChar *name_end;
2620 : OnigEncoding enc = env->enc;
2621 : UChar *p = *src;
2622 : PFETCH_READY;
2623 :
2624 : r = 0;
2625 : while (!PEND) {
2626 : name_end = p;
2627 : if (enc_len(enc, p) > 1)
2628 : r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2629 :
2630 : PFETCH(c);
2631 : if (c == '>' || c == ')') break;
2632 : if (! ONIGENC_IS_CODE_DIGIT(enc, c))
2633 : r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
2634 : }
2635 : if (c != '>') {
2636 : r = ONIGERR_INVALID_GROUP_NAME;
2637 : name_end = end;
2638 : }
2639 :
2640 : if (r == 0) {
2641 : *rname_end = name_end;
2642 : *src = p;
2643 : return 0;
2644 : }
2645 : else {
2646 : err:
2647 : onig_scan_env_set_error_string(env, r, *src, name_end);
2648 : return r;
2649 : }
2650 : }
2651 : #endif
2652 :
2653 : static void
2654 : CC_ESC_WARN(ScanEnv* env, UChar *c)
2655 0 : {
2656 0 : if (onig_warn == onig_null_warn) return ;
2657 :
2658 0 : if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED) &&
2659 : IS_SYNTAX_BV(env->syntax, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC)) {
2660 : UChar buf[WARN_BUFSIZE];
2661 0 : onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
2662 : env->pattern, env->pattern_end,
2663 : (UChar* )"character class has '%s' without escape", c);
2664 0 : (*onig_warn)((char* )buf);
2665 : }
2666 : }
2667 :
2668 : static void
2669 : CCEND_ESC_WARN(ScanEnv* env, UChar* c)
2670 0 : {
2671 0 : if (onig_warn == onig_null_warn) return ;
2672 :
2673 0 : if (IS_SYNTAX_BV((env)->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED)) {
2674 : UChar buf[WARN_BUFSIZE];
2675 0 : onig_snprintf_with_pattern(buf, WARN_BUFSIZE, (env)->enc,
2676 : (env)->pattern, (env)->pattern_end,
2677 : (UChar* )"regular expression has '%s' without escape", c);
2678 0 : (*onig_warn)((char* )buf);
2679 : }
2680 : }
2681 :
2682 : static UChar*
2683 : find_str_position(OnigCodePoint s[], int n, UChar* from, UChar* to,
2684 : UChar **next, OnigEncoding enc)
2685 0 : {
2686 : int i;
2687 : OnigCodePoint x;
2688 : UChar *q;
2689 0 : UChar *p = from;
2690 :
2691 0 : while (p < to) {
2692 0 : x = ONIGENC_MBC_TO_CODE(enc, p, to);
2693 0 : q = p + enc_len(enc, p);
2694 0 : if (x == s[0]) {
2695 0 : for (i = 1; i < n && q < to; i++) {
2696 0 : x = ONIGENC_MBC_TO_CODE(enc, q, to);
2697 0 : if (x != s[i]) break;
2698 0 : q += enc_len(enc, q);
2699 : }
2700 0 : if (i >= n) {
2701 0 : if (IS_NOT_NULL(next))
2702 0 : *next = q;
2703 0 : return p;
2704 : }
2705 : }
2706 0 : p = q;
2707 : }
2708 0 : return NULL_UCHARP;
2709 : }
2710 :
2711 : static int
2712 : str_exist_check_with_esc(OnigCodePoint s[], int n, UChar* from, UChar* to,
2713 : OnigCodePoint bad, OnigEncoding enc)
2714 41 : {
2715 : int i, in_esc;
2716 : OnigCodePoint x;
2717 : UChar *q;
2718 41 : UChar *p = from;
2719 :
2720 41 : in_esc = 0;
2721 289 : while (p < to) {
2722 248 : if (in_esc) {
2723 0 : in_esc = 0;
2724 0 : p += enc_len(enc, p);
2725 : }
2726 : else {
2727 248 : x = ONIGENC_MBC_TO_CODE(enc, p, to);
2728 248 : q = p + enc_len(enc, p);
2729 248 : if (x == s[0]) {
2730 82 : for (i = 1; i < n && q < to; i++) {
2731 41 : x = ONIGENC_MBC_TO_CODE(enc, q, to);
2732 41 : if (x != s[i]) break;
2733 41 : q += enc_len(enc, q);
2734 : }
2735 41 : if (i >= n) return 1;
2736 0 : p += enc_len(enc, p);
2737 : }
2738 : else {
2739 207 : x = ONIGENC_MBC_TO_CODE(enc, p, to);
2740 207 : if (x == bad) return 0;
2741 207 : else if (x == MC_ESC(enc)) in_esc = 1;
2742 207 : p = q;
2743 : }
2744 : }
2745 : }
2746 0 : return 0;
2747 : }
2748 :
2749 : static int
2750 : fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
2751 298 : {
2752 : int num;
2753 : OnigCodePoint c, c2;
2754 298 : OnigSyntaxType* syn = env->syntax;
2755 298 : OnigEncoding enc = env->enc;
2756 : UChar* prev;
2757 298 : UChar* p = *src;
2758 : PFETCH_READY;
2759 :
2760 298 : if (PEND) {
2761 0 : tok->type = TK_EOT;
2762 0 : return tok->type;
2763 : }
2764 :
2765 298 : PFETCH(c);
2766 298 : tok->type = TK_CHAR;
2767 298 : tok->base = 0;
2768 298 : tok->u.c = c;
2769 298 : tok->escaped = 0;
2770 :
2771 298 : if (c == ']') {
2772 93 : tok->type = TK_CC_CLOSE;
2773 : }
2774 205 : else if (c == '-') {
2775 49 : tok->type = TK_CC_RANGE;
2776 : }
2777 156 : else if (c == MC_ESC(enc)) {
2778 1 : if (! IS_SYNTAX_BV(syn, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC))
2779 0 : goto end;
2780 :
2781 1 : if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
2782 :
2783 1 : PFETCH(c);
2784 1 : tok->escaped = 1;
2785 1 : tok->u.c = c;
2786 1 : switch (c) {
2787 : case 'w':
2788 0 : tok->type = TK_CHAR_TYPE;
2789 0 : tok->u.subtype = CTYPE_WORD;
2790 0 : break;
2791 : case 'W':
2792 0 : tok->type = TK_CHAR_TYPE;
2793 0 : tok->u.subtype = CTYPE_NOT_WORD;
2794 0 : break;
2795 : case 'd':
2796 0 : tok->type = TK_CHAR_TYPE;
2797 0 : tok->u.subtype = CTYPE_DIGIT;
2798 0 : break;
2799 : case 'D':
2800 0 : tok->type = TK_CHAR_TYPE;
2801 0 : tok->u.subtype = CTYPE_NOT_DIGIT;
2802 0 : break;
2803 : case 's':
2804 1 : tok->type = TK_CHAR_TYPE;
2805 1 : tok->u.subtype = CTYPE_WHITE_SPACE;
2806 1 : break;
2807 : case 'S':
2808 0 : tok->type = TK_CHAR_TYPE;
2809 0 : tok->u.subtype = CTYPE_NOT_WHITE_SPACE;
2810 0 : break;
2811 : case 'h':
2812 0 : if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
2813 0 : tok->type = TK_CHAR_TYPE;
2814 0 : tok->u.subtype = CTYPE_XDIGIT;
2815 0 : break;
2816 : case 'H':
2817 0 : if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
2818 0 : tok->type = TK_CHAR_TYPE;
2819 0 : tok->u.subtype = CTYPE_NOT_XDIGIT;
2820 0 : break;
2821 :
2822 : case 'p':
2823 : case 'P':
2824 0 : c2 = PPEEK;
2825 0 : if (c2 == '{' &&
2826 : IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) {
2827 0 : PINC;
2828 0 : tok->type = TK_CHAR_PROPERTY;
2829 0 : tok->u.prop.not = (c == 'P' ? 1 : 0);
2830 :
2831 0 : if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
2832 0 : PFETCH(c2);
2833 0 : if (c2 == '^') {
2834 0 : tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
2835 : }
2836 : else
2837 0 : PUNFETCH;
2838 : }
2839 : }
2840 0 : break;
2841 :
2842 : case 'x':
2843 0 : if (PEND) break;
2844 :
2845 0 : prev = p;
2846 0 : if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) {
2847 0 : PINC;
2848 0 : num = scan_unsigned_hexadecimal_number(&p, end, 8, enc);
2849 0 : if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
2850 0 : if (!PEND) {
2851 0 : c2 = PPEEK;
2852 0 : if (ONIGENC_IS_CODE_XDIGIT(enc, c2))
2853 0 : return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
2854 : }
2855 :
2856 0 : if (p > prev + enc_len(enc, prev) && !PEND && (PPEEK_IS('}'))) {
2857 0 : PINC;
2858 0 : tok->type = TK_CODE_POINT;
2859 0 : tok->base = 16;
2860 0 : tok->u.code = (OnigCodePoint )num;
2861 : }
2862 : else {
2863 : /* can't read nothing or invalid format */
2864 0 : p = prev;
2865 : }
2866 : }
2867 0 : else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) {
2868 0 : num = scan_unsigned_hexadecimal_number(&p, end, 2, enc);
2869 0 : if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
2870 0 : if (p == prev) { /* can't read nothing. */
2871 0 : num = 0; /* but, it's not error */
2872 : }
2873 0 : tok->type = TK_RAW_BYTE;
2874 0 : tok->base = 16;
2875 0 : tok->u.c = num;
2876 : }
2877 0 : break;
2878 :
2879 : case 'u':
2880 0 : if (PEND) break;
2881 :
2882 0 : prev = p;
2883 0 : if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) {
2884 0 : num = scan_unsigned_hexadecimal_number(&p, end, 4, enc);
2885 0 : if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
2886 0 : if (p == prev) { /* can't read nothing. */
2887 0 : num = 0; /* but, it's not error */
2888 : }
2889 0 : tok->type = TK_CODE_POINT;
2890 0 : tok->base = 16;
2891 0 : tok->u.code = (OnigCodePoint )num;
2892 : }
2893 0 : break;
2894 :
2895 : case '0':
2896 : case '1': case '2': case '3': case '4': case '5': case '6': case '7':
2897 0 : if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
2898 0 : PUNFETCH;
2899 0 : prev = p;
2900 0 : num = scan_unsigned_octal_number(&p, end, 3, enc);
2901 0 : if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
2902 0 : if (p == prev) { /* can't read nothing. */
2903 0 : num = 0; /* but, it's not error */
2904 : }
2905 0 : tok->type = TK_RAW_BYTE;
2906 0 : tok->base = 8;
2907 0 : tok->u.c = num;
2908 : }
2909 0 : break;
2910 :
2911 : default:
2912 0 : PUNFETCH;
2913 0 : num = fetch_escaped_value(&p, end, env);
2914 0 : if (num < 0) return num;
2915 0 : if (tok->u.c != num) {
2916 0 : tok->u.code = (OnigCodePoint )num;
2917 0 : tok->type = TK_CODE_POINT;
2918 : }
2919 : break;
2920 : }
2921 : }
2922 155 : else if (c == '[') {
2923 82 : if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_POSIX_BRACKET) && (PPEEK_IS(':'))) {
2924 41 : OnigCodePoint send[] = { (OnigCodePoint )':', (OnigCodePoint )']' };
2925 41 : tok->backp = p; /* point at '[' is readed */
2926 41 : PINC;
2927 41 : if (str_exist_check_with_esc(send, 2, p, end,
2928 : (OnigCodePoint )']', enc)) {
2929 41 : tok->type = TK_POSIX_BRACKET_OPEN;
2930 : }
2931 : else {
2932 0 : PUNFETCH;
2933 0 : goto cc_in_cc;
2934 : }
2935 : }
2936 : else {
2937 0 : cc_in_cc:
2938 0 : if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP)) {
2939 0 : tok->type = TK_CC_CC_OPEN;
2940 : }
2941 : else {
2942 0 : CC_ESC_WARN(env, (UChar* )"[");
2943 : }
2944 : }
2945 : }
2946 114 : else if (c == '&') {
2947 0 : if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP) &&
2948 : !PEND && (PPEEK_IS('&'))) {
2949 0 : PINC;
2950 0 : tok->type = TK_CC_AND;
2951 : }
2952 : }
2953 :
2954 298 : end:
2955 298 : *src = p;
2956 298 : return tok->type;
2957 : }
2958 :
2959 : static int
2960 : fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
2961 888 : {
2962 : int r, num;
2963 : OnigCodePoint c;
2964 888 : OnigEncoding enc = env->enc;
2965 888 : OnigSyntaxType* syn = env->syntax;
2966 : UChar* prev;
2967 888 : UChar* p = *src;
2968 : PFETCH_READY;
2969 :
2970 893 : start:
2971 893 : if (PEND) {
2972 145 : tok->type = TK_EOT;
2973 145 : return tok->type;
2974 : }
2975 :
2976 748 : tok->type = TK_STRING;
2977 748 : tok->base = 0;
2978 748 : tok->backp = p;
2979 :
2980 748 : PFETCH(c);
2981 892 : if (IS_MC_ESC_CODE(c, enc, syn)) {
2982 18 : if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
2983 :
2984 18 : tok->backp = p;
2985 18 : PFETCH(c);
2986 :
2987 18 : tok->u.c = c;
2988 18 : tok->escaped = 1;
2989 18 : switch (c) {
2990 : case '*':
2991 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF)) break;
2992 0 : tok->type = TK_OP_REPEAT;
2993 0 : tok->u.repeat.lower = 0;
2994 0 : tok->u.repeat.upper = REPEAT_INFINITE;
2995 0 : goto greedy_check;
2996 : break;
2997 :
2998 : case '+':
2999 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_PLUS_ONE_INF)) break;
3000 0 : tok->type = TK_OP_REPEAT;
3001 0 : tok->u.repeat.lower = 1;
3002 0 : tok->u.repeat.upper = REPEAT_INFINITE;
3003 0 : goto greedy_check;
3004 : break;
3005 :
3006 : case '?':
3007 1 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_QMARK_ZERO_ONE)) break;
3008 0 : tok->type = TK_OP_REPEAT;
3009 0 : tok->u.repeat.lower = 0;
3010 0 : tok->u.repeat.upper = 1;
3011 123 : greedy_check:
3012 126 : if (!PEND && PPEEK_IS('?') &&
3013 : IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_NON_GREEDY)) {
3014 3 : PFETCH(c);
3015 3 : tok->u.repeat.greedy = 0;
3016 3 : tok->u.repeat.possessive = 0;
3017 : }
3018 : else {
3019 123 : possessive_check:
3020 123 : if (!PEND && PPEEK_IS('+') &&
3021 : ((IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT) &&
3022 : tok->type != TK_INTERVAL) ||
3023 : (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL) &&
3024 : tok->type == TK_INTERVAL))) {
3025 0 : PFETCH(c);
3026 0 : tok->u.repeat.greedy = 1;
3027 0 : tok->u.repeat.possessive = 1;
3028 : }
3029 : else {
3030 123 : tok->u.repeat.greedy = 1;
3031 123 : tok->u.repeat.possessive = 0;
3032 : }
3033 : }
3034 126 : break;
3035 :
3036 : case '{':
3037 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) break;
3038 0 : r = fetch_range_qualifier(&p, end, tok, env);
3039 0 : if (r < 0) return r; /* error */
3040 0 : if (r == 0) goto greedy_check;
3041 0 : else if (r == 2) { /* {n} */
3042 0 : if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY))
3043 0 : goto possessive_check;
3044 :
3045 0 : goto greedy_check;
3046 : }
3047 : /* r == 1 : normal char */
3048 0 : break;
3049 :
3050 : case '|':
3051 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_VBAR_ALT)) break;
3052 0 : tok->type = TK_ALT;
3053 0 : break;
3054 :
3055 : case '(':
3056 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break;
3057 0 : tok->type = TK_SUBEXP_OPEN;
3058 0 : break;
3059 :
3060 : case ')':
3061 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break;
3062 0 : tok->type = TK_SUBEXP_CLOSE;
3063 0 : break;
3064 :
3065 : case 'w':
3066 3 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
3067 3 : tok->type = TK_CHAR_TYPE;
3068 3 : tok->u.subtype = CTYPE_WORD;
3069 3 : break;
3070 :
3071 : case 'W':
3072 1 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
3073 1 : tok->type = TK_CHAR_TYPE;
3074 1 : tok->u.subtype = CTYPE_NOT_WORD;
3075 1 : break;
3076 :
3077 : case 'b':
3078 1 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
3079 1 : tok->type = TK_ANCHOR;
3080 1 : tok->u.anchor = ANCHOR_WORD_BOUND;
3081 1 : break;
3082 :
3083 : case 'B':
3084 1 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
3085 1 : tok->type = TK_ANCHOR;
3086 1 : tok->u.anchor = ANCHOR_NOT_WORD_BOUND;
3087 1 : break;
3088 :
3089 : #ifdef USE_WORD_BEGIN_END
3090 : case '<':
3091 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
3092 0 : tok->type = TK_ANCHOR;
3093 0 : tok->u.anchor = ANCHOR_WORD_BEGIN;
3094 0 : break;
3095 :
3096 : case '>':
3097 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
3098 0 : tok->type = TK_ANCHOR;
3099 0 : tok->u.anchor = ANCHOR_WORD_END;
3100 0 : break;
3101 : #endif
3102 :
3103 : case 's':
3104 3 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
3105 3 : tok->type = TK_CHAR_TYPE;
3106 3 : tok->u.subtype = CTYPE_WHITE_SPACE;
3107 3 : break;
3108 :
3109 : case 'S':
3110 1 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
3111 1 : tok->type = TK_CHAR_TYPE;
3112 1 : tok->u.subtype = CTYPE_NOT_WHITE_SPACE;
3113 1 : break;
3114 :
3115 : case 'd':
3116 1 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
3117 1 : tok->type = TK_CHAR_TYPE;
3118 1 : tok->u.subtype = CTYPE_DIGIT;
3119 1 : break;
3120 :
3121 : case 'D':
3122 1 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
3123 1 : tok->type = TK_CHAR_TYPE;
3124 1 : tok->u.subtype = CTYPE_NOT_DIGIT;
3125 1 : break;
3126 :
3127 : case 'h':
3128 0 : if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
3129 0 : tok->type = TK_CHAR_TYPE;
3130 0 : tok->u.subtype = CTYPE_XDIGIT;
3131 0 : break;
3132 :
3133 : case 'H':
3134 0 : if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
3135 0 : tok->type = TK_CHAR_TYPE;
3136 0 : tok->u.subtype = CTYPE_NOT_XDIGIT;
3137 0 : break;
3138 :
3139 : case 'A':
3140 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
3141 0 : begin_buf:
3142 0 : tok->type = TK_ANCHOR;
3143 0 : tok->u.subtype = ANCHOR_BEGIN_BUF;
3144 0 : break;
3145 :
3146 : case 'Z':
3147 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
3148 0 : tok->type = TK_ANCHOR;
3149 0 : tok->u.subtype = ANCHOR_SEMI_END_BUF;
3150 0 : break;
3151 :
3152 : case 'z':
3153 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
3154 0 : end_buf:
3155 0 : tok->type = TK_ANCHOR;
3156 0 : tok->u.subtype = ANCHOR_END_BUF;
3157 0 : break;
3158 :
3159 : case 'G':
3160 0 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR)) break;
3161 0 : tok->type = TK_ANCHOR;
3162 0 : tok->u.subtype = ANCHOR_BEGIN_POSITION;
3163 0 : break;
3164 :
3165 : case '`':
3166 0 : if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break;
3167 0 : goto begin_buf;
3168 : break;
3169 :
3170 : case '\'':
3171 0 : if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break;
3172 0 : goto end_buf;
3173 : break;
3174 :
3175 : case 'x':
3176 0 : if (PEND) break;
3177 :
3178 0 : prev = p;
3179 0 : if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) {
3180 0 : PINC;
3181 0 : num = scan_unsigned_hexadecimal_number(&p, end, 8, enc);
3182 0 : if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
3183 0 : if (!PEND) {
3184 0 : if (ONIGENC_IS_CODE_XDIGIT(enc, PPEEK))
3185 0 : return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
3186 : }
3187 :
3188 0 : if ((p > prev + enc_len(enc, prev)) && !PEND && PPEEK_IS('}')) {
3189 0 : PINC;
3190 0 : tok->type = TK_CODE_POINT;
3191 0 : tok->u.code = (OnigCodePoint )num;
3192 : }
3193 : else {
3194 : /* can't read nothing or invalid format */
3195 0 : p = prev;
3196 : }
3197 : }
3198 0 : else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) {
3199 0 : num = scan_unsigned_hexadecimal_number(&p, end, 2, enc);
3200 0 : if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
3201 0 : if (p == prev) { /* can't read nothing. */
3202 0 : num = 0; /* but, it's not error */
3203 : }
3204 0 : tok->type = TK_RAW_BYTE;
3205 0 : tok->base = 16;
3206 0 : tok->u.c = num;
3207 : }
3208 0 : break;
3209 :
3210 : case 'u':
3211 0 : if (PEND) break;
3212 :
3213 0 : prev = p;
3214 0 : if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) {
3215 0 : num = scan_unsigned_hexadecimal_number(&p, end, 4, enc);
3216 0 : if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
3217 0 : if (p == prev) { /* can't read nothing. */
3218 0 : num = 0; /* but, it's not error */
3219 : }
3220 0 : tok->type = TK_CODE_POINT;
3221 0 : tok->base = 16;
3222 0 : tok->u.code = (OnigCodePoint )num;
3223 : }
3224 0 : break;
3225 :
3226 : case '1': case '2': case '3': case '4':
3227 : case '5': case '6': case '7': case '8': case '9':
3228 0 : PUNFETCH;
3229 0 : prev = p;
3230 0 : num = onig_scan_unsigned_number(&p, end, enc);
3231 0 : if (num < 0 || num > ONIG_MAX_BACKREF_NUM) {
3232 : goto skip_backref;
3233 : }
3234 :
3235 0 : if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_DECIMAL_BACKREF) &&
3236 : (num <= env->num_mem || num <= 9)) { /* This spec. from GNU regex */
3237 0 : if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
3238 0 : if (num > env->num_mem || IS_NULL(SCANENV_MEM_NODES(env)[num]))
3239 0 : return ONIGERR_INVALID_BACKREF;
3240 : }
3241 :
3242 0 : tok->type = TK_BACKREF;
3243 0 : tok->u.backref.num = 1;
3244 0 : tok->u.backref.ref1 = num;
3245 0 : tok->u.backref.by_name = 0;
3246 : #ifdef USE_BACKREF_AT_LEVEL
3247 0 : tok->u.backref.exist_level = 0;
3248 : #endif
3249 0 : break;
3250 : }
3251 :
3252 0 : skip_backref:
3253 0 : if (c == '8' || c == '9') {
3254 : /* normal char */
3255 0 : p = prev; PINC;
3256 0 : break;
3257 : }
3258 :
3259 0 : p = prev;
3260 : /* fall through */
3261 : case '0':
3262 0 : if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
3263 0 : prev = p;
3264 0 : num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc);
3265 0 : if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
3266 0 : if (p == prev) { /* can't read nothing. */
3267 0 : num = 0; /* but, it's not error */
3268 : }
3269 0 : tok->type = TK_RAW_BYTE;
3270 0 : tok->base = 8;
3271 0 : tok->u.c = num;
3272 : }
3273 0 : else if (c != '0') {
3274 0 : PINC;
3275 : }
3276 0 : break;
3277 :
3278 : #ifdef USE_NAMED_GROUP
3279 : case 'k':
3280 0 : if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_K_NAMED_BACKREF)) {
3281 0 : PFETCH(c);
3282 0 : if (c == '<') {
3283 : UChar* name_end;
3284 : int* backs;
3285 :
3286 0 : prev = p;
3287 :
3288 : #ifdef USE_BACKREF_AT_LEVEL
3289 0 : name_end = NULL_UCHARP; /* no need. escape gcc warning. */
3290 0 : r = fetch_name_with_level(&p, end, &name_end, env, &tok->u.backref.level);
3291 0 : if (r == 1) tok->u.backref.exist_level = 1;
3292 0 : else tok->u.backref.exist_level = 0;
3293 : #else
3294 : r = fetch_name(&p, end, &name_end, env, 1);
3295 : #endif
3296 0 : if (r < 0) return r;
3297 :
3298 0 : num = onig_name_to_group_numbers(env->reg, prev, name_end, &backs);
3299 0 : if (num <= 0) {
3300 0 : onig_scan_env_set_error_string(env,
3301 : ONIGERR_UNDEFINED_NAME_REFERENCE, prev, name_end);
3302 0 : return ONIGERR_UNDEFINED_NAME_REFERENCE;
3303 : }
3304 0 : if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
3305 : int i;
3306 0 : for (i = 0; i < num; i++) {
3307 0 : if (backs[i] > env->num_mem ||
3308 : IS_NULL(SCANENV_MEM_NODES(env)[backs[i]]))
3309 0 : return ONIGERR_INVALID_BACKREF;
3310 : }
3311 : }
3312 :
3313 0 : tok->type = TK_BACKREF;
3314 0 : tok->u.backref.by_name = 1;
3315 0 : if (num == 1) {
3316 0 : tok->u.backref.num = 1;
3317 0 : tok->u.backref.ref1 = backs[0];
3318 : }
3319 : else {
3320 0 : tok->u.backref.num = num;
3321 0 : tok->u.backref.refs = backs;
3322 : }
3323 : }
3324 : else
3325 0 : PUNFETCH;
3326 : }
3327 0 : break;
3328 : #endif
3329 :
3330 : #ifdef USE_SUBEXP_CALL
3331 : case 'g':
3332 0 : if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_SUBEXP_CALL)) {
3333 0 : PFETCH(c);
3334 0 : if (c == '<') {
3335 : UChar* name_end;
3336 :
3337 0 : prev = p;
3338 0 : r = fetch_name(&p, end, &name_end, env, 1);
3339 0 : if (r < 0) return r;
3340 :
3341 0 : tok->type = TK_CALL;
3342 0 : tok->u.call.name = prev;
3343 0 : tok->u.call.name_end = name_end;
3344 : }
3345 : else
3346 0 : PUNFETCH;
3347 : }
3348 0 : break;
3349 : #endif
3350 :
3351 : case 'Q':
3352 0 : if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE)) {
3353 0 : tok->type = TK_QUOTE_OPEN;
3354 : }
3355 0 : break;
3356 :
3357 : case 'p':
3358 : case 'P':
3359 0 : if (PPEEK_IS('{') &&
3360 : IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) {
3361 0 : PINC;
3362 0 : tok->type = TK_CHAR_PROPERTY;
3363 0 : tok->u.prop.not = (c == 'P' ? 1 : 0);
3364 :
3365 0 : if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
3366 0 : PFETCH(c);
3367 0 : if (c == '^') {
3368 0 : tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
3369 : }
3370 : else
3371 0 : PUNFETCH;
3372 : }
3373 : }
3374 0 : break;
3375 :
3376 : default:
3377 5 : PUNFETCH;
3378 5 : num = fetch_escaped_value(&p, end, env);
3379 5 : if (num < 0) return num;
3380 : /* set_raw: */
3381 5 : if (tok->u.c != num) {
3382 0 : tok->type = TK_CODE_POINT;
3383 0 : tok->u.code = (OnigCodePoint )num;
3384 : }
3385 : else { /* string */
3386 5 : p = tok->backp + enc_len(enc, tok->backp);
3387 : }
3388 : break;
3389 : }
3390 : }
3391 : else {
3392 730 : tok->u.c = c;
3393 730 : tok->escaped = 0;
3394 :
3395 : #ifdef USE_VARIABLE_META_CHARS
3396 730 : if ((c != ONIG_INEFFECTIVE_META_CHAR) &&
3397 : IS_SYNTAX_OP(syn, ONIG_SYN_OP_VARIABLE_META_CHARACTERS)) {
3398 0 : if (c == MC_ANYCHAR(enc))
3399 0 : goto any_char;
3400 0 : else if (c == MC_ANYTIME(enc))
3401 0 : goto anytime;
3402 0 : else if (c == MC_ZERO_OR_ONE_TIME(enc))
3403 0 : goto zero_or_one_time;
3404 0 : else if (c == MC_ONE_OR_MORE_TIME(enc))
3405 0 : goto one_or_more_time;
3406 0 : else if (c == MC_ANYCHAR_ANYTIME(enc)) {
3407 0 : tok->type = TK_ANYCHAR_ANYTIME;
3408 0 : goto out;
3409 : }
3410 : }
3411 : #endif
3412 :
3413 730 : switch (c) {
3414 : case '.':
3415 26 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_DOT_ANYCHAR)) break;
3416 : #ifdef USE_VARIABLE_META_CHARS
3417 26 : any_char:
3418 : #endif
3419 26 : tok->type = TK_ANYCHAR;
3420 26 : break;
3421 :
3422 : case '*':
3423 26 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ASTERISK_ZERO_INF)) break;
3424 : #ifdef USE_VARIABLE_META_CHARS
3425 26 : anytime:
3426 : #endif
3427 26 : tok->type = TK_OP_REPEAT;
3428 26 : tok->u.repeat.lower = 0;
3429 26 : tok->u.repeat.upper = REPEAT_INFINITE;
3430 26 : goto greedy_check;
3431 : break;
3432 :
3433 : case '+':
3434 75 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_PLUS_ONE_INF)) break;
3435 : #ifdef USE_VARIABLE_META_CHARS
3436 75 : one_or_more_time:
3437 : #endif
3438 75 : tok->type = TK_OP_REPEAT;
3439 75 : tok->u.repeat.lower = 1;
3440 75 : tok->u.repeat.upper = REPEAT_INFINITE;
3441 75 : goto greedy_check;
3442 : break;
3443 :
3444 : case '?':
3445 21 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_ZERO_ONE)) break;
3446 : #ifdef USE_VARIABLE_META_CHARS
3447 21 : zero_or_one_time:
3448 : #endif
3449 21 : tok->type = TK_OP_REPEAT;
3450 21 : tok->u.repeat.lower = 0;
3451 21 : tok->u.repeat.upper = 1;
3452 21 : goto greedy_check;
3453 : break;
3454 :
3455 : case '{':
3456 4 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACE_INTERVAL)) break;
3457 4 : r = fetch_range_qualifier(&p, end, tok, env);
3458 4 : if (r < 0) return r; /* error */
3459 4 : if (r == 0) goto greedy_check;
3460 3 : else if (r == 2) { /* {n} */
3461 3 : if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY))
3462 3 : goto possessive_check;
3463 :
3464 0 : goto greedy_check;
3465 : }
3466 : /* r == 1 : normal char */
3467 0 : break;
3468 :
3469 : case '|':
3470 2 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_VBAR_ALT)) break;
3471 2 : tok->type = TK_ALT;
3472 2 : break;
3473 :
3474 : case '(':
3475 61 : if (PPEEK_IS('?') &&
3476 : IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
3477 0 : PINC;
3478 0 : if (PPEEK_IS('#')) {
3479 0 : PFETCH(c);
3480 : while (1) {
3481 0 : if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
3482 0 : PFETCH(c);
3483 0 : if (c == MC_ESC(enc)) {
3484 0 : if (!PEND) PFETCH(c);
3485 : }
3486 : else {
3487 0 : if (c == ')') break;
3488 : }
3489 0 : }
3490 0 : goto start;
3491 : }
3492 0 : PUNFETCH;
3493 : }
3494 :
3495 61 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break;
3496 61 : tok->type = TK_SUBEXP_OPEN;
3497 61 : break;
3498 :
3499 : case ')':
3500 61 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break;
3501 61 : tok->type = TK_SUBEXP_CLOSE;
3502 61 : break;
3503 :
3504 : case '^':
3505 4 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
3506 4 : tok->type = TK_ANCHOR;
3507 4 : tok->u.subtype = (IS_SINGLELINE(env->option)
3508 : ? ANCHOR_BEGIN_BUF : ANCHOR_BEGIN_LINE);
3509 4 : break;
3510 :
3511 : case '$':
3512 12 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
3513 12 : tok->type = TK_ANCHOR;
3514 12 : tok->u.subtype = (IS_SINGLELINE(env->option)
3515 : ? ANCHOR_END_BUF : ANCHOR_END_LINE);
3516 12 : break;
3517 :
3518 : case '[':
3519 93 : if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACKET_CC)) break;
3520 93 : tok->type = TK_CC_OPEN;
3521 93 : break;
3522 :
3523 : case ']':
3524 0 : if (*src > env->pattern) /* /].../ is allowed. */
3525 0 : CCEND_ESC_WARN(env, (UChar* )"]");
3526 0 : break;
3527 :
3528 : case '#':
3529 1 : if (IS_EXTEND(env->option)) {
3530 0 : while (!PEND) {
3531 0 : PFETCH(c);
3532 0 : if (ONIGENC_IS_CODE_NEWLINE(enc, c))
3533 0 : break;
3534 : }
3535 0 : goto start;
3536 : break;
3537 : }
3538 1 : break;
3539 :
3540 : case ' ': case '\t': case '\n': case '\r': case '\f':
3541 39 : if (IS_EXTEND(env->option))
3542 5 : goto start;
3543 : break;
3544 :
3545 : default:
3546 : /* string */
3547 : break;
3548 : }
3549 : }
3550 :
3551 : #ifdef USE_VARIABLE_META_CHARS
3552 743 : out:
3553 : #endif
3554 743 : *src = p;
3555 743 : return tok->type;
3556 : }
3557 :
3558 : static int
3559 : add_ctype_to_cc_by_range(CClassNode* cc, int ctype, int not, OnigEncoding enc,
3560 : const OnigCodePoint sbr[], const OnigCodePoint mbr[])
3561 34 : {
3562 : int i, r;
3563 : OnigCodePoint j;
3564 :
3565 34 : int nsb = ONIGENC_CODE_RANGE_NUM(sbr);
3566 34 : int nmb = ONIGENC_CODE_RANGE_NUM(mbr);
3567 :
3568 34 : if (not == 0) {
3569 130 : for (i = 0; i < nsb; i++) {
3570 96 : for (j = ONIGENC_CODE_RANGE_FROM(sbr, i);
3571 1332 : j <= ONIGENC_CODE_RANGE_TO(sbr, i); j++) {
3572 1236 : BITSET_SET_BIT(cc->bs, j);
3573 : }
3574 : }
3575 :
3576 5486 : for (i = 0; i < nmb; i++) {
3577 5452 : r = add_code_range_to_buf(&(cc->mbuf),
3578 : ONIGENC_CODE_RANGE_FROM(mbr, i),
3579 : ONIGENC_CODE_RANGE_TO(mbr, i));
3580 5452 : if (r != 0) return r;
3581 : }
3582 : }
3583 : else {
3584 0 : OnigCodePoint prev = 0;
3585 :
3586 0 : if (ONIGENC_MBC_MINLEN(enc) == 1) {
3587 0 : for (i = 0; i < nsb; i++) {
3588 0 : for (j = prev;
3589 0 : j < ONIGENC_CODE_RANGE_FROM(sbr, i); j++) {
3590 0 : BITSET_SET_BIT(cc->bs, j);
3591 : }
3592 0 : prev = ONIGENC_CODE_RANGE_TO(sbr, i) + 1;
3593 : }
3594 0 : if (prev < 0x7f) {
3595 0 : for (j = prev; j < 0x7f; j++) {
3596 0 : BITSET_SET_BIT(cc->bs, j);
3597 : }
3598 : }
3599 :
3600 0 : prev = 0x80;
3601 : }
3602 :
3603 0 : for (i = 0; i < nmb; i++) {
3604 0 : if (prev < ONIGENC_CODE_RANGE_FROM(mbr, i)) {
3605 0 : r = add_code_range_to_buf(&(cc->mbuf), prev,
3606 : ONIGENC_CODE_RANGE_FROM(mbr, i) - 1);
3607 0 : if (r != 0) return r;
3608 : }
3609 0 : prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1;
3610 : }
3611 0 : if (prev < 0x7fffffff) {
3612 0 : r = add_code_range_to_buf(&(cc->mbuf), prev, 0x7fffffff);
3613 0 : if (r != 0) return r;
3614 : }
3615 : }
3616 :
3617 34 : return 0;
3618 : }
3619 :
3620 : static int
3621 : add_ctype_to_cc(CClassNode* cc, int ctype, int not, ScanEnv* env)
3622 42 : {
3623 : int c, r;
3624 : const OnigCodePoint *sbr, *mbr;
3625 42 : OnigEncoding enc = env->enc;
3626 :
3627 42 : r = ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, &sbr, &mbr);
3628 42 : if (r == 0) {
3629 34 : return add_ctype_to_cc_by_range(cc, ctype, not, env->enc, sbr, mbr);
3630 : }
3631 8 : else if (r != ONIG_NO_SUPPORT_CONFIG) {
3632 0 : return r;
3633 : }
3634 :
3635 8 : r = 0;
3636 8 : switch (ctype) {
3637 : case ONIGENC_CTYPE_ALPHA:
3638 : case ONIGENC_CTYPE_BLANK:
3639 : case ONIGENC_CTYPE_CNTRL:
3640 : case ONIGENC_CTYPE_DIGIT:
3641 : case ONIGENC_CTYPE_LOWER:
3642 : case ONIGENC_CTYPE_PUNCT:
3643 : case ONIGENC_CTYPE_SPACE:
3644 : case ONIGENC_CTYPE_UPPER:
3645 : case ONIGENC_CTYPE_XDIGIT:
3646 : case ONIGENC_CTYPE_ASCII:
3647 : case ONIGENC_CTYPE_ALNUM:
3648 8 : if (not != 0) {
3649 0 : for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
3650 0 : if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
3651 0 : BITSET_SET_BIT(cc->bs, c);
3652 : }
3653 0 : ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
3654 : }
3655 : else {
3656 2056 : for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
3657 2048 : if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
3658 49 : BITSET_SET_BIT(cc->bs, c);
3659 : }
3660 : }
3661 8 : break;
3662 :
3663 : case ONIGENC_CTYPE_GRAPH:
3664 : case ONIGENC_CTYPE_PRINT:
3665 0 : if (not != 0) {
3666 0 : for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
3667 0 : if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
3668 0 : BITSET_SET_BIT(cc->bs, c);
3669 : }
3670 : }
3671 : else {
3672 0 : for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
3673 0 : if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
3674 0 : BITSET_SET_BIT(cc->bs, c);
3675 : }
3676 0 : ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
3677 : }
3678 0 : break;
3679 :
3680 : case ONIGENC_CTYPE_WORD:
3681 0 : if (not == 0) {
3682 0 : for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
3683 0 : if (ONIGENC_IS_CODE_SB_WORD(enc, c)) BITSET_SET_BIT(cc->bs, c);
3684 : }
3685 0 : ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
3686 : }
3687 : else {
3688 0 : for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
3689 0 : if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0) /* 0: invalid code point */
3690 : && ! ONIGENC_IS_CODE_WORD(enc, c))
3691 0 : BITSET_SET_BIT(cc->bs, c);
3692 : }
3693 : }
3694 0 : break;
3695 :
3696 : default:
3697 0 : return ONIGERR_PARSER_BUG;
3698 : break;
3699 : }
3700 :
3701 8 : return r;
3702 : }
3703 :
3704 : static int
3705 : parse_ctype_to_enc_ctype(int pctype, int* not)
3706 7 : {
3707 : int ctype;
3708 :
3709 7 : switch (pctype) {
3710 : case CTYPE_WORD:
3711 0 : ctype = ONIGENC_CTYPE_WORD;
3712 0 : *not = 0;
3713 0 : break;
3714 : case CTYPE_NOT_WORD:
3715 0 : ctype = ONIGENC_CTYPE_WORD;
3716 0 : *not = 1;
3717 0 : break;
3718 : case CTYPE_WHITE_SPACE:
3719 4 : ctype = ONIGENC_CTYPE_SPACE;
3720 4 : *not = 0;
3721 4 : break;
3722 : case CTYPE_NOT_WHITE_SPACE:
3723 1 : ctype = ONIGENC_CTYPE_SPACE;
3724 1 : *not = 1;
3725 1 : break;
3726 : case CTYPE_DIGIT:
3727 1 : ctype = ONIGENC_CTYPE_DIGIT;
3728 1 : *not = 0;
3729 1 : break;
3730 : case CTYPE_NOT_DIGIT:
3731 1 : ctype = ONIGENC_CTYPE_DIGIT;
3732 1 : *not = 1;
3733 1 : break;
3734 : case CTYPE_XDIGIT:
3735 0 : ctype = ONIGENC_CTYPE_XDIGIT;
3736 0 : *not = 0;
3737 0 : break;
3738 : case CTYPE_NOT_XDIGIT:
3739 0 : ctype = ONIGENC_CTYPE_XDIGIT;
3740 0 : *not = 1;
3741 0 : break;
3742 : default:
3743 0 : return ONIGERR_PARSER_BUG;
3744 : break;
3745 : }
3746 7 : return ctype;
3747 : }
3748 :
3749 : typedef struct {
3750 : UChar *name;
3751 : int ctype;
3752 : short int len;
3753 : } PosixBracketEntryType;
3754 :
3755 : static int
3756 : parse_posix_bracket(CClassNode* cc, UChar** src, UChar* end, ScanEnv* env)
3757 41 : {
3758 : #define POSIX_BRACKET_CHECK_LIMIT_LENGTH 20
3759 : #define POSIX_BRACKET_NAME_MAX_LEN 6
3760 :
3761 : static PosixBracketEntryType PBS[] = {
3762 : { (UChar* )"alnum", ONIGENC_CTYPE_ALNUM, 5 },
3763 : { (UChar* )"alpha", ONIGENC_CTYPE_ALPHA, 5 },
3764 : { (UChar* )"blank", ONIGENC_CTYPE_BLANK, 5 },
3765 : { (UChar* )"cntrl", ONIGENC_CTYPE_CNTRL, 5 },
3766 : { (UChar* )"digit", ONIGENC_CTYPE_DIGIT, 5 },
3767 : { (UChar* )"graph", ONIGENC_CTYPE_GRAPH, 5 },
3768 : { (UChar* )"lower", ONIGENC_CTYPE_LOWER, 5 },
3769 : { (UChar* )"print", ONIGENC_CTYPE_PRINT, 5 },
3770 : { (UChar* )"punct", ONIGENC_CTYPE_PUNCT, 5 },
3771 : { (UChar* )"space", ONIGENC_CTYPE_SPACE, 5 },
3772 : { (UChar* )"upper", ONIGENC_CTYPE_UPPER, 5 },
3773 : { (UChar* )"xdigit", ONIGENC_CTYPE_XDIGIT, 6 },
3774 : { (UChar* )"ascii", ONIGENC_CTYPE_ASCII, 5 },
3775 : { (UChar* )NULL, -1, 0 }
3776 : };
3777 :
3778 : PosixBracketEntryType *pb;
3779 : int not, i, r;
3780 : OnigCodePoint c;
3781 41 : OnigEncoding enc = env->enc;
3782 41 : UChar *p = *src;
3783 : PFETCH_READY;
3784 :
3785 41 : if (PPEEK_IS('^')) {
3786 0 : PINC;
3787 0 : not = 1;
3788 : }
3789 : else
3790 41 : not = 0;
3791 :
3792 41 : if (onigenc_strlen(enc, p, end) < POSIX_BRACKET_NAME_MAX_LEN + 2)
3793 0 : goto not_posix_bracket;
3794 :
3795 316 : for (pb = PBS; IS_NOT_NULL(pb->name); pb++) {
3796 316 : if (onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0) {
3797 41 : p = (UChar* )onigenc_step(enc, p, end, pb->len);
3798 41 : if (onigenc_with_ascii_strncmp(enc, p, end, (UChar* )":]", 2) != 0)
3799 0 : return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
3800 :
3801 41 : r = add_ctype_to_cc(cc, pb->ctype, not, env);
3802 41 : if (r != 0) return r;
3803 :
3804 41 : PINC; PINC;
3805 41 : *src = p;
3806 41 : return 0;
3807 : }
3808 : }
3809 :
3810 0 : not_posix_bracket:
3811 0 : c = 0;
3812 0 : i = 0;
3813 0 : while (!PEND && ((c = PPEEK) != ':') && c != ']') {
3814 0 : PINC;
3815 0 : if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
3816 : }
3817 0 : if (c == ':' && ! PEND) {
3818 0 : PINC;
3819 0 : if (! PEND) {
3820 0 : PFETCH(c);
3821 0 : if (c == ']')
3822 0 : return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
3823 : }
3824 : }
3825 :
3826 0 : return 1; /* 1: is not POSIX bracket, but no error. */
3827 : }
3828 :
3829 : static int
3830 : property_name_to_ctype(UChar* p, UChar* end, OnigEncoding enc)
3831 0 : {
3832 : static PosixBracketEntryType PBS[] = {
3833 : { (UChar* )"Alnum", ONIGENC_CTYPE_ALNUM, 5 },
3834 : { (UChar* )"Alpha", ONIGENC_CTYPE_ALPHA, 5 },
3835 : { (UChar* )"Blank", ONIGENC_CTYPE_BLANK, 5 },
3836 : { (UChar* )"Cntrl", ONIGENC_CTYPE_CNTRL, 5 },
3837 : { (UChar* )"Digit", ONIGENC_CTYPE_DIGIT, 5 },
3838 : { (UChar* )"Graph", ONIGENC_CTYPE_GRAPH, 5 },
3839 : { (UChar* )"Lower", ONIGENC_CTYPE_LOWER, 5 },
3840 : { (UChar* )"Print", ONIGENC_CTYPE_PRINT, 5 },
3841 : { (UChar* )"Punct", ONIGENC_CTYPE_PUNCT, 5 },
3842 : { (UChar* )"Space", ONIGENC_CTYPE_SPACE, 5 },
3843 : { (UChar* )"Upper", ONIGENC_CTYPE_UPPER, 5 },
3844 : { (UChar* )"XDigit", ONIGENC_CTYPE_XDIGIT, 6 },
3845 : { (UChar* )"ASCII", ONIGENC_CTYPE_ASCII, 5 },
3846 : { (UChar* )NULL, -1, 0 }
3847 : };
3848 :
3849 : PosixBracketEntryType *pb;
3850 : int len;
3851 :
3852 0 : len = onigenc_strlen(enc, p, end);
3853 0 : for (pb = PBS; IS_NOT_NULL(pb->name); pb++) {
3854 0 : if (len == pb->len &&
3855 : onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0)
3856 0 : return pb->ctype;
3857 : }
3858 :
3859 0 : return -1;
3860 : }
3861 :
3862 : static int
3863 : fetch_char_property_to_ctype(UChar** src, UChar* end, ScanEnv* env)
3864 0 : {
3865 : int ctype;
3866 : OnigCodePoint c;
3867 0 : OnigEncoding enc = env->enc;
3868 0 : UChar *prev, *start, *p = *src;
3869 : PFETCH_READY;
3870 :
3871 : /* 'IsXXXX' => 'XXXX' */
3872 0 : if (!PEND &&
3873 : IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS)) {
3874 0 : c = PPEEK;
3875 0 : if (c == 'I') {
3876 0 : PINC;
3877 0 : if (! PEND) {
3878 0 : c = PPEEK;
3879 0 : if (c == 's')
3880 0 : PINC;
3881 : else
3882 0 : PUNFETCH;
3883 : }
3884 : }
3885 : }
3886 :
3887 0 : start = prev = p;
3888 :
3889 0 : while (!PEND) {
3890 0 : prev = p;
3891 0 : PFETCH(c);
3892 0 : if (c == '}') {
3893 0 : ctype = property_name_to_ctype(start, prev, enc);
3894 0 : if (ctype < 0) break;
3895 :
3896 0 : *src = p;
3897 0 : return ctype;
3898 : }
3899 0 : else if (c == '(' || c == ')' || c == '{' || c == '|')
3900 : break;
3901 : }
3902 :
3903 0 : onig_scan_env_set_error_string(env, ONIGERR_INVALID_CHAR_PROPERTY_NAME,
3904 : *src, prev);
3905 0 : return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
3906 : }
3907 :
3908 : static int
3909 : parse_char_property(Node** np, OnigToken* tok, UChar** src, UChar* end,
3910 : ScanEnv* env)
3911 0 : {
3912 : int r, ctype;
3913 : CClassNode* cc;
3914 :
3915 0 : ctype = fetch_char_property_to_ctype(src, end, env);
3916 0 : if (ctype < 0) return ctype;
3917 :
3918 0 : *np = node_new_cclass();
3919 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
3920 0 : cc = &(NCCLASS(*np));
3921 0 : r = add_ctype_to_cc(cc, ctype, 0, env);
3922 0 : if (r != 0) return r;
3923 0 : if (tok->u.prop.not != 0) CCLASS_SET_NOT(cc);
3924 :
3925 0 : return 0;
3926 : }
3927 :
3928 :
3929 : enum CCSTATE {
3930 : CCS_VALUE,
3931 : CCS_RANGE,
3932 : CCS_COMPLETE,
3933 : CCS_START
3934 : };
3935 :
3936 : enum CCVALTYPE {
3937 : CCV_SB,
3938 : CCV_CODE_POINT,
3939 : CCV_CLASS
3940 : };
3941 :
3942 : static int
3943 : next_state_class(CClassNode* cc, OnigCodePoint* vs, enum CCVALTYPE* type,
3944 : enum CCSTATE* state, ScanEnv* env)
3945 42 : {
3946 : int r;
3947 :
3948 42 : if (*state == CCS_RANGE)
3949 0 : return ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE;
3950 :
3951 42 : if (*state == CCS_VALUE && *type != CCV_CLASS) {
3952 0 : if (*type == CCV_SB)
3953 0 : BITSET_SET_BIT(cc->bs, (int )(*vs));
3954 0 : else if (*type == CCV_CODE_POINT) {
3955 0 : r = add_code_range(&(cc->mbuf), env, *vs, *vs);
3956 0 : if (r < 0) return r;
3957 : }
3958 : }
3959 :
3960 42 : *state = CCS_VALUE;
3961 42 : *type = CCV_CLASS;
3962 42 : return 0;
3963 : }
3964 :
3965 : static int
3966 : next_state_val(CClassNode* cc, OnigCodePoint *vs, OnigCodePoint v,
3967 : int* vs_israw, int v_israw,
3968 : enum CCVALTYPE intype, enum CCVALTYPE* type,
3969 : enum CCSTATE* state, ScanEnv* env)
3970 160 : {
3971 : int r;
3972 :
3973 160 : switch (*state) {
3974 : case CCS_VALUE:
3975 59 : if (*type == CCV_SB)
3976 18 : BITSET_SET_BIT(cc->bs, (int )(*vs));
3977 41 : else if (*type == CCV_CODE_POINT) {
3978 0 : r = add_code_range(&(cc->mbuf), env, *vs, *vs);
3979 0 : if (r < 0) return r;
3980 : }
3981 59 : break;
3982 :
3983 : case CCS_RANGE:
3984 48 : if (intype == *type) {
3985 48 : if (intype == CCV_SB) {
3986 34 : if (*vs > 0xff || v > 0xff)
3987 0 : return ONIGERR_INVALID_WIDE_CHAR_VALUE;
3988 :
3989 34 : if (*vs > v) {
3990 0 : if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
3991 0 : goto ccs_range_end;
3992 : else
3993 0 : return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
3994 : }
3995 34 : bitset_set_range(cc->bs, (int )*vs, (int )v);
3996 : }
3997 : else {
3998 14 : r = add_code_range(&(cc->mbuf), env, *vs, v);
3999 14 : if (r < 0) return r;
4000 : }
4001 : }
4002 : else {
4003 : #if 0
4004 : if (intype == CCV_CODE_POINT && *type == CCV_SB) {
4005 : #endif
4006 0 : if (*vs > v) {
4007 0 : if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
4008 0 : goto ccs_range_end;
4009 : else
4010 0 : return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
4011 : }
4012 0 : bitset_set_range(cc->bs, (int )*vs, (int )(v < 0xff ? v : 0xff));
4013 0 : r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*vs, v);
4014 0 : if (r < 0) return r;
4015 : #if 0
4016 : }
4017 : else
4018 : return ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE;
4019 : #endif
4020 : }
4021 48 : ccs_range_end:
4022 48 : *state = CCS_COMPLETE;
4023 48 : break;
4024 :
4025 : case CCS_COMPLETE:
4026 : case CCS_START:
4027 53 : *state = CCS_VALUE;
4028 : break;
4029 :
4030 : default:
4031 : break;
4032 : }
4033 :
4034 160 : *vs_israw = v_israw;
4035 160 : *vs = v;
4036 160 : *type = intype;
4037 160 : return 0;
4038 : }
4039 :
4040 : static int
4041 : code_exist_check(OnigCodePoint c, UChar* from, UChar* end, int ignore_escaped,
4042 : OnigEncoding enc)
4043 0 : {
4044 : int in_esc;
4045 : OnigCodePoint code;
4046 0 : UChar* p = from;
4047 : PFETCH_READY;
4048 :
4049 0 : in_esc = 0;
4050 0 : while (! PEND) {
4051 0 : if (ignore_escaped && in_esc) {
4052 0 : in_esc = 0;
4053 : }
4054 : else {
4055 0 : PFETCH(code);
4056 0 : if (code == c) return 1;
4057 0 : if (code == MC_ESC(enc)) in_esc = 1;
4058 : }
4059 : }
4060 0 : return 0;
4061 : }
4062 :
4063 : static int
4064 : parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
4065 : ScanEnv* env)
4066 93 : {
4067 : int r, neg, len, fetched, and_start;
4068 : OnigCodePoint v, vs;
4069 : UChar *p;
4070 : Node* node;
4071 : CClassNode *cc, *prev_cc;
4072 : CClassNode work_cc;
4073 :
4074 : enum CCSTATE state;
4075 : enum CCVALTYPE val_type, in_type;
4076 : int val_israw, in_israw;
4077 :
4078 93 : prev_cc = (CClassNode* )NULL;
4079 93 : *np = NULL_NODE;
4080 93 : r = fetch_token_in_cc(tok, src, end, env);
4081 94 : if (r == TK_CHAR && tok->u.c == '^' && tok->escaped == 0) {
4082 1 : neg = 1;
4083 1 : r = fetch_token_in_cc(tok, src, end, env);
4084 : }
4085 : else {
4086 92 : neg = 0;
4087 : }
4088 :
4089 93 : if (r < 0) return r;
4090 93 : if (r == TK_CC_CLOSE) {
4091 0 : if (! code_exist_check((OnigCodePoint )']',
4092 : *src, env->pattern_end, 1, env->enc))
4093 0 : return ONIGERR_EMPTY_CHAR_CLASS;
4094 :
4095 0 : CC_ESC_WARN(env, (UChar* )"]");
4096 0 : r = tok->type = TK_CHAR; /* allow []...] */
4097 : }
4098 :
4099 93 : *np = node = node_new_cclass();
4100 93 : CHECK_NULL_RETURN_VAL(node, ONIGERR_MEMORY);
4101 93 : cc = &(NCCLASS(node));
4102 :
4103 93 : and_start = 0;
4104 93 : state = CCS_START;
4105 93 : p = *src;
4106 390 : while (r != TK_CC_CLOSE) {
4107 204 : fetched = 0;
4108 204 : switch (r) {
4109 : case TK_CHAR:
4110 113 : len = ONIGENC_CODE_TO_MBCLEN(env->enc, tok->u.c);
4111 113 : if (len > 1) {
4112 28 : in_type = CCV_CODE_POINT;
4113 : }
4114 : else {
4115 85 : sb_char:
4116 85 : in_type = CCV_SB;
4117 : }
4118 113 : v = (OnigCodePoint )tok->u.c;
4119 113 : in_israw = 0;
4120 113 : goto val_entry2;
4121 : break;
4122 :
4123 : case TK_RAW_BYTE:
4124 : /* tok->base != 0 : octal or hexadec. */
4125 0 : if (! ONIGENC_IS_SINGLEBYTE(env->enc) && tok->base != 0) {
4126 : UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
4127 0 : UChar* bufe = buf + ONIGENC_CODE_TO_MBC_MAXLEN;
4128 0 : UChar* psave = p;
4129 0 : int i, base = tok->base;
4130 :
4131 0 : buf[0] = tok->u.c;
4132 0 : for (i = 1; i < ONIGENC_MBC_MAXLEN(env->enc); i++) {
4133 0 : r = fetch_token_in_cc(tok, &p, end, env);
4134 0 : if (r < 0) goto err;
4135 0 : if (r != TK_RAW_BYTE || tok->base != base) {
4136 0 : fetched = 1;
4137 0 : break;
4138 : }
4139 0 : buf[i] = tok->u.c;
4140 : }
4141 :
4142 0 : if (i < ONIGENC_MBC_MINLEN(env->enc)) {
4143 0 : r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
4144 0 : goto err;
4145 : }
4146 :
4147 0 : len = enc_len(env->enc, buf);
4148 0 : if (i < len) {
4149 0 : r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
4150 0 : goto err;
4151 : }
4152 0 : else if (i > len) { /* fetch back */
4153 0 : p = psave;
4154 0 : for (i = 1; i < len; i++) {
4155 0 : r = fetch_token_in_cc(tok, &p, end, env);
4156 : }
4157 0 : fetched = 0;
4158 : }
4159 :
4160 0 : if (i == 1) {
4161 0 : v = (OnigCodePoint )buf[0];
4162 0 : goto raw_single;
4163 : }
4164 : else {
4165 0 : v = ONIGENC_MBC_TO_CODE(env->enc, buf, bufe);
4166 0 : in_type = CCV_CODE_POINT;
4167 : }
4168 : }
4169 : else {
4170 0 : v = (OnigCodePoint )tok->u.c;
4171 0 : raw_single:
4172 0 : in_type = CCV_SB;
4173 : }
4174 0 : in_israw = 1;
4175 0 : goto val_entry2;
4176 : break;
4177 :
4178 : case TK_CODE_POINT:
4179 0 : v = tok->u.code;
4180 0 : in_israw = 1;
4181 1 : val_entry:
4182 1 : len = ONIGENC_CODE_TO_MBCLEN(env->enc, v);
4183 1 : if (len < 0) {
4184 0 : r = len;
4185 0 : goto err;
4186 : }
4187 1 : in_type = (len == 1 ? CCV_SB : CCV_CODE_POINT);
4188 114 : val_entry2:
4189 114 : r = next_state_val(cc, &vs, v, &val_israw, in_israw, in_type, &val_type,
4190 : &state, env);
4191 114 : if (r != 0) goto err;
4192 114 : break;
4193 :
4194 : case TK_POSIX_BRACKET_OPEN:
4195 41 : r = parse_posix_bracket(cc, &p, end, env);
4196 41 : if (r < 0) goto err;
4197 41 : if (r == 1) { /* is not POSIX bracket */
4198 0 : CC_ESC_WARN(env, (UChar* )"[");
4199 0 : p = tok->backp;
4200 0 : v = (OnigCodePoint )tok->u.c;
4201 0 : in_israw = 0;
4202 0 : goto val_entry;
4203 : }
4204 41 : goto next_class;
4205 : break;
4206 :
4207 : case TK_CHAR_TYPE:
4208 : {
4209 : int ctype, not;
4210 1 : ctype = parse_ctype_to_enc_ctype(tok->u.subtype, ¬);
4211 1 : r = add_ctype_to_cc(cc, ctype, not, env);
4212 1 : if (r != 0) return r;
4213 : }
4214 :
4215 42 : next_class:
4216 42 : r = next_state_class(cc, &vs, &val_type, &state, env);
4217 42 : if (r != 0) goto err;
4218 42 : break;
4219 :
4220 : case TK_CHAR_PROPERTY:
4221 : {
4222 : int ctype;
4223 :
4224 0 : ctype = fetch_char_property_to_ctype(&p, end, env);
4225 0 : if (ctype < 0) return ctype;
4226 0 : r = add_ctype_to_cc(cc, ctype, tok->u.prop.not, env);
4227 0 : if (r != 0) return r;
4228 0 : goto next_class;
4229 : }
4230 : break;
4231 :
4232 : case TK_CC_RANGE:
4233 49 : if (state == CCS_VALUE) {
4234 48 : r = fetch_token_in_cc(tok, &p, end, env);
4235 48 : if (r < 0) goto err;
4236 48 : fetched = 1;
4237 48 : if (r == TK_CC_CLOSE) { /* allow [x-] */
4238 0 : range_end_val:
4239 0 : v = (OnigCodePoint )'-';
4240 0 : in_israw = 0;
4241 0 : goto val_entry;
4242 : }
4243 48 : else if (r == TK_CC_AND) {
4244 0 : CC_ESC_WARN(env, (UChar* )"-");
4245 0 : goto range_end_val;
4246 : }
4247 48 : state = CCS_RANGE;
4248 : }
4249 1 : else if (state == CCS_START) {
4250 : /* [-xa] is allowed */
4251 1 : v = (OnigCodePoint )tok->u.c;
4252 1 : in_israw = 0;
4253 :
4254 1 : r = fetch_token_in_cc(tok, &p, end, env);
4255 1 : if (r < 0) goto err;
4256 1 : fetched = 1;
4257 : /* [--x] or [a&&-x] is warned. */
4258 1 : if (r == TK_CC_RANGE || and_start != 0)
4259 0 : CC_ESC_WARN(env, (UChar* )"-");
4260 :
4261 1 : goto val_entry;
4262 : }
4263 0 : else if (state == CCS_RANGE) {
4264 0 : CC_ESC_WARN(env, (UChar* )"-");
4265 0 : goto sb_char; /* [!--x] is allowed */
4266 : }
4267 : else { /* CCS_COMPLETE */
4268 0 : r = fetch_token_in_cc(tok, &p, end, env);
4269 0 : if (r < 0) goto err;
4270 0 : fetched = 1;
4271 0 : if (r == TK_CC_CLOSE) goto range_end_val; /* allow [a-b-] */
4272 0 : else if (r == TK_CC_AND) {
4273 0 : CC_ESC_WARN(env, (UChar* )"-");
4274 0 : goto range_end_val;
4275 : }
4276 :
4277 0 : if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC)) {
4278 0 : CC_ESC_WARN(env, (UChar* )"-");
4279 0 : goto sb_char; /* [0-9-a] is allowed as [0-9\-a] */
4280 : }
4281 0 : r = ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS;
4282 0 : goto err;
4283 : }
4284 48 : break;
4285 :
4286 : case TK_CC_CC_OPEN: /* [ */
4287 : {
4288 : Node *anode;
4289 : CClassNode* acc;
4290 :
4291 0 : r = parse_char_class(&anode, tok, &p, end, env);
4292 0 : if (r != 0) goto cc_open_err;
4293 0 : acc = &(NCCLASS(anode));
4294 0 : r = or_cclass(cc, acc, env->enc);
4295 :
4296 0 : onig_node_free(anode);
4297 0 : cc_open_err:
4298 0 : if (r != 0) goto err;
4299 : }
4300 0 : break;
4301 :
4302 : case TK_CC_AND: /* && */
4303 : {
4304 0 : if (state == CCS_VALUE) {
4305 0 : r = next_state_val(cc, &vs, 0, &val_israw, 0, val_type,
4306 : &val_type, &state, env);
4307 0 : if (r != 0) goto err;
4308 : }
4309 : /* initialize local variables */
4310 0 : and_start = 1;
4311 0 : state = CCS_START;
4312 :
4313 0 : if (IS_NOT_NULL(prev_cc)) {
4314 0 : r = and_cclass(prev_cc, cc, env->enc);
4315 0 : if (r != 0) goto err;
4316 0 : bbuf_free(cc->mbuf);
4317 : }
4318 : else {
4319 0 : prev_cc = cc;
4320 0 : cc = &work_cc;
4321 : }
4322 0 : initialize_cclass(cc);
4323 : }
4324 0 : break;
4325 :
4326 : case TK_EOT:
4327 0 : r = ONIGERR_PREMATURE_END_OF_CHAR_CLASS;
4328 0 : goto err;
4329 : break;
4330 : default:
4331 0 : r = ONIGERR_PARSER_BUG;
4332 0 : goto err;
4333 : break;
4334 : }
4335 :
4336 204 : if (fetched)
4337 49 : r = tok->type;
4338 : else {
4339 155 : r = fetch_token_in_cc(tok, &p, end, env);
4340 155 : if (r < 0) goto err;
4341 : }
4342 : }
4343 :
4344 93 : if (state == CCS_VALUE) {
4345 46 : r = next_state_val(cc, &vs, 0, &val_israw, 0, val_type,
4346 : &val_type, &state, env);
4347 46 : if (r != 0) goto err;
4348 : }
4349 :
4350 93 : if (IS_NOT_NULL(prev_cc)) {
4351 0 : r = and_cclass(prev_cc, cc, env->enc);
4352 0 : if (r != 0) goto err;
4353 0 : bbuf_free(cc->mbuf);
4354 0 : cc = prev_cc;
4355 : }
4356 :
4357 93 : if (neg != 0)
4358 1 : CCLASS_SET_NOT(cc);
4359 : else
4360 92 : CCLASS_CLEAR_NOT(cc);
4361 93 : if (IS_CCLASS_NOT(cc) &&
4362 : IS_SYNTAX_BV(env->syntax, ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC)) {
4363 : int is_empty;
4364 :
4365 0 : is_empty = (IS_NULL(cc->mbuf) ? 1 : 0);
4366 0 : if (is_empty != 0)
4367 0 : BITSET_IS_EMPTY(cc->bs, is_empty);
4368 :
4369 0 : if (is_empty == 0) {
4370 : #define NEWLINE_CODE 0x0a
4371 :
4372 0 : if (ONIGENC_IS_CODE_NEWLINE(env->enc, NEWLINE_CODE)) {
4373 0 : if (ONIGENC_CODE_TO_MBCLEN(env->enc, NEWLINE_CODE) == 1)
4374 0 : BITSET_SET_BIT(cc->bs, NEWLINE_CODE);
4375 : else
4376 0 : add_code_range(&(cc->mbuf), env, NEWLINE_CODE, NEWLINE_CODE);
4377 : }
4378 : }
4379 : }
4380 93 : *src = p;
4381 93 : return 0;
4382 :
4383 0 : err:
4384 0 : if (cc != &(NCCLASS(*np)))
4385 0 : bbuf_free(cc->mbuf);
4386 0 : onig_node_free(*np);
4387 0 : return r;
4388 : }
4389 :
4390 : static int parse_subexp(Node** top, OnigToken* tok, int term,
4391 : UChar** src, UChar* end, ScanEnv* env);
4392 :
4393 : static int
4394 : parse_effect(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
4395 : ScanEnv* env)
4396 61 : {
4397 : int r, num;
4398 : int list_capture;
4399 : Node *target;
4400 : OnigOptionType option;
4401 61 : OnigEncoding enc = env->enc;
4402 : OnigCodePoint c;
4403 61 : UChar* p = *src;
4404 : PFETCH_READY;
4405 :
4406 61 : *np = NULL;
4407 61 : if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
4408 :
4409 61 : option = env->option;
4410 61 : if (PPEEK_IS('?') &&
4411 : IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
4412 0 : PINC;
4413 0 : if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
4414 :
4415 0 : PFETCH(c);
4416 0 : switch (c) {
4417 : case ':': /* (?:...) grouping only */
4418 0 : group:
4419 0 : r = fetch_token(tok, &p, end, env);
4420 0 : if (r < 0) return r;
4421 0 : r = parse_subexp(np, tok, term, &p, end, env);
4422 0 : if (r < 0) return r;
4423 0 : *src = p;
4424 0 : return 1; /* group */
4425 : break;
4426 :
4427 : case '=':
4428 0 : *np = onig_node_new_anchor(ANCHOR_PREC_READ);
4429 0 : break;
4430 : case '!': /* preceding read */
4431 0 : *np = onig_node_new_anchor(ANCHOR_PREC_READ_NOT);
4432 0 : break;
4433 : case '>': /* (?>...) stop backtrack */
4434 0 : *np = node_new_effect(EFFECT_STOP_BACKTRACK);
4435 0 : break;
4436 :
4437 : case '<': /* look behind (?<=...), (?<!...) */
4438 0 : PFETCH(c);
4439 0 : if (c == '=')
4440 0 : *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND);
4441 0 : else if (c == '!')
4442 0 : *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND_NOT);
4443 : #ifdef USE_NAMED_GROUP
4444 0 : else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
4445 : UChar *name;
4446 : UChar *name_end;
4447 :
4448 0 : PUNFETCH;
4449 0 : list_capture = 0;
4450 :
4451 0 : named_group:
4452 0 : name = p;
4453 0 : r = fetch_name(&p, end, &name_end, env, 0);
4454 0 : if (r < 0) return r;
4455 :
4456 0 : num = scan_env_add_mem_entry(env);
4457 0 : if (num < 0) return num;
4458 0 : if (list_capture != 0 && num >= BIT_STATUS_BITS_NUM)
4459 0 : return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
4460 :
4461 0 : r = name_add(env->reg, name, name_end, num, env);
4462 0 : if (r != 0) return r;
4463 0 : *np = node_new_effect_memory(env->option, 1);
4464 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4465 0 : NEFFECT(*np).regnum = num;
4466 0 : if (list_capture != 0)
4467 0 : BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
4468 0 : env->num_named++;
4469 : }
4470 : #endif
4471 : else
4472 0 : return ONIGERR_UNDEFINED_GROUP_OPTION;
4473 0 : break;
4474 :
4475 : case '@':
4476 0 : if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY)) {
4477 : #ifdef USE_NAMED_GROUP
4478 0 : if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
4479 0 : PFETCH(c);
4480 0 : if (c == '<') {
4481 0 : list_capture = 1;
4482 0 : goto named_group; /* (?@<name>...) */
4483 : }
4484 0 : PUNFETCH;
4485 : }
4486 : #endif
4487 0 : *np = node_new_effect_memory(env->option, 0);
4488 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4489 0 : num = scan_env_add_mem_entry(env);
4490 0 : if (num < 0) {
4491 0 : onig_node_free(*np);
4492 0 : return num;
4493 : }
4494 0 : else if (num >= BIT_STATUS_BITS_NUM) {
4495 0 : onig_node_free(*np);
4496 0 : return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
4497 : }
4498 0 : NEFFECT(*np).regnum = num;
4499 0 : BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
4500 : }
4501 : else {
4502 0 : return ONIGERR_UNDEFINED_GROUP_OPTION;
4503 : }
4504 0 : break;
4505 :
4506 : #ifdef USE_POSIXLINE_OPTION
4507 : case 'p':
4508 : #endif
4509 : case '-': case 'i': case 'm': case 's': case 'x':
4510 : {
4511 0 : int neg = 0;
4512 :
4513 : while (1) {
4514 0 : switch (c) {
4515 : case ':':
4516 : case ')':
4517 0 : break;
4518 :
4519 0 : case '-': neg = 1; break;
4520 0 : case 'x': ONOFF(option, ONIG_OPTION_EXTEND, neg); break;
4521 0 : case 'i': ONOFF(option, ONIG_OPTION_IGNORECASE, neg); break;
4522 : case 's':
4523 0 : if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
4524 0 : ONOFF(option, ONIG_OPTION_MULTILINE, neg);
4525 : }
4526 : else
4527 0 : return ONIGERR_UNDEFINED_GROUP_OPTION;
4528 0 : break;
4529 :
4530 : case 'm':
4531 0 : if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
4532 0 : ONOFF(option, ONIG_OPTION_SINGLELINE, (neg == 0 ? 1 : 0));
4533 : }
4534 0 : else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
4535 0 : ONOFF(option, ONIG_OPTION_MULTILINE, neg);
4536 : }
4537 : else
4538 0 : return ONIGERR_UNDEFINED_GROUP_OPTION;
4539 0 : break;
4540 : #ifdef USE_POSIXLINE_OPTION
4541 : case 'p':
4542 : ONOFF(option, ONIG_OPTION_MULTILINE|ONIG_OPTION_SINGLELINE, neg);
4543 : break;
4544 : #endif
4545 : default:
4546 0 : return ONIGERR_UNDEFINED_GROUP_OPTION;
4547 : }
4548 :
4549 0 : if (c == ')') {
4550 0 : *np = node_new_option(option);
4551 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4552 0 : *src = p;
4553 0 : return 2; /* option only */
4554 : }
4555 0 : else if (c == ':') {
4556 0 : OnigOptionType prev = env->option;
4557 :
4558 0 : env->option = option;
4559 0 : r = fetch_token(tok, &p, end, env);
4560 0 : if (r < 0) return r;
4561 0 : r = parse_subexp(&target, tok, term, &p, end, env);
4562 0 : env->option = prev;
4563 0 : if (r < 0) return r;
4564 0 : *np = node_new_option(option);
4565 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4566 0 : NEFFECT(*np).target = target;
4567 0 : *src = p;
4568 0 : return 0;
4569 : }
4570 :
4571 0 : if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
4572 0 : PFETCH(c);
4573 0 : }
4574 : }
4575 : break;
4576 :
4577 : default:
4578 0 : return ONIGERR_UNDEFINED_GROUP_OPTION;
4579 : }
4580 : }
4581 : else {
4582 61 : if (ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_DONT_CAPTURE_GROUP))
4583 0 : goto group;
4584 :
4585 61 : *np = node_new_effect_memory(env->option, 0);
4586 61 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4587 61 : num = scan_env_add_mem_entry(env);
4588 61 : if (num < 0) return num;
4589 61 : NEFFECT(*np).regnum = num;
4590 : }
4591 :
4592 61 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4593 61 : r = fetch_token(tok, &p, end, env);
4594 61 : if (r < 0) return r;
4595 61 : r = parse_subexp(&target, tok, term, &p, end, env);
4596 61 : if (r < 0) return r;
4597 :
4598 61 : if (NTYPE(*np) == N_ANCHOR)
4599 0 : NANCHOR(*np).target = target;
4600 : else {
4601 61 : NEFFECT(*np).target = target;
4602 61 : if (NEFFECT(*np).type == EFFECT_MEMORY) {
4603 : /* Don't move this to previous of parse_subexp() */
4604 61 : r = scan_env_set_mem_node(env, NEFFECT(*np).regnum, *np);
4605 61 : if (r != 0) return r;
4606 : }
4607 : }
4608 :
4609 61 : *src = p;
4610 61 : return 0;
4611 : }
4612 :
4613 : static const char* PopularQStr[] = {
4614 : "?", "*", "+", "??", "*?", "+?"
4615 : };
4616 :
4617 : static const char* ReduceQStr[] = {
4618 : "", "", "*", "*?", "??", "+ and ??", "+? and ?"
4619 : };
4620 :
4621 : static int
4622 : set_qualifier(Node* qnode, Node* target, int group, ScanEnv* env)
4623 126 : {
4624 : QualifierNode* qn;
4625 :
4626 126 : qn = &(NQUALIFIER(qnode));
4627 126 : if (qn->lower == 1 && qn->upper == 1) {
4628 0 : return 1;
4629 : }
4630 :
4631 126 : switch (NTYPE(target)) {
4632 : case N_STRING:
4633 23 : if (! group) {
4634 23 : StrNode* sn = &(NSTRING(target));
4635 23 : if (str_node_can_be_split(sn, env->enc)) {
4636 9 : Node* n = str_node_split_last_char(sn, env->enc);
4637 9 : if (IS_NOT_NULL(n)) {
4638 9 : qn->target = n;
4639 9 : return 2;
4640 : }
4641 : }
4642 : }
4643 14 : break;
4644 :
4645 : case N_QUALIFIER:
4646 : { /* check redundant double repeat. */
4647 : /* verbose warn (?:.?)? etc... but not warn (.?)? etc... */
4648 0 : QualifierNode* qnt = &(NQUALIFIER(target));
4649 0 : int nestq_num = popular_qualifier_num(qn);
4650 0 : int targetq_num = popular_qualifier_num(qnt);
4651 :
4652 : #ifdef USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
4653 0 : if (!IS_QUALIFIER_BY_NUMBER(qn) && !IS_QUALIFIER_BY_NUMBER(qnt) &&
4654 : IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT)) {
4655 : UChar buf[WARN_BUFSIZE];
4656 :
4657 0 : switch(ReduceTypeTable[targetq_num][nestq_num]) {
4658 : case RQ_ASIS:
4659 0 : break;
4660 :
4661 : case RQ_DEL:
4662 0 : if (onig_verb_warn != onig_null_warn) {
4663 0 : onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
4664 : env->pattern, env->pattern_end,
4665 : (UChar* )"redundant nested repeat operator");
4666 0 : (*onig_verb_warn)((char* )buf);
4667 : }
4668 0 : goto warn_exit;
4669 : break;
4670 :
4671 : default:
4672 0 : if (onig_verb_warn != onig_null_warn) {
4673 0 : onig_snprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
4674 : env->pattern, env->pattern_end,
4675 : (UChar* )"nested repeat operator %s and %s was replaced with '%s'",
4676 : PopularQStr[targetq_num], PopularQStr[nestq_num],
4677 : ReduceQStr[ReduceTypeTable[targetq_num][nestq_num]]);
4678 0 : (*onig_verb_warn)((char* )buf);
4679 : }
4680 0 : goto warn_exit;
4681 : break;
4682 : }
4683 : }
4684 :
4685 0 : warn_exit:
4686 : #endif
4687 0 : if (targetq_num >= 0) {
4688 0 : if (nestq_num >= 0) {
4689 0 : onig_reduce_nested_qualifier(qnode, target);
4690 0 : goto q_exit;
4691 : }
4692 0 : else if (targetq_num == 1 || targetq_num == 2) { /* * or + */
4693 : /* (?:a*){n,m}, (?:a+){n,m} => (?:a*){n,n}, (?:a+){n,n} */
4694 0 : if (! IS_REPEAT_INFINITE(qn->upper) && qn->upper > 1 && qn->greedy) {
4695 0 : qn->upper = (qn->lower == 0 ? 1 : qn->lower);
4696 : }
4697 : }
4698 : }
4699 : }
4700 : break;
4701 :
4702 : default:
4703 : break;
4704 : }
4705 :
4706 117 : qn->target = target;
4707 117 : q_exit:
4708 117 : return 0;
4709 : }
4710 :
4711 : static int
4712 : make_compound_alt_node_from_cc(OnigAmbigType ambig_flag, OnigEncoding enc,
4713 : CClassNode* cc, Node** root)
4714 0 : {
4715 : int r, i, j, k, clen, len, ncode, n;
4716 : UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
4717 0 : Node **ptail, *snode = NULL_NODE;
4718 : const OnigCompAmbigCodes* ccs;
4719 : const OnigCompAmbigCodeItem* ci;
4720 : OnigAmbigType amb;
4721 :
4722 0 : n = 0;
4723 0 : *root = NULL_NODE;
4724 0 : ptail = root;
4725 :
4726 :
4727 0 : for (amb = 0x01; amb <= ONIGENC_AMBIGUOUS_MATCH_LIMIT; amb <<= 1) {
4728 0 : if ((amb & ambig_flag) == 0) continue;
4729 :
4730 0 : ncode = ONIGENC_GET_ALL_COMP_AMBIG_CODES(enc, amb, &ccs);
4731 0 : for (i = 0; i < ncode; i++) {
4732 0 : if (onig_is_code_in_cc(enc, ccs[i].code, cc)) {
4733 0 : for (j = 0; j < ccs[i].n; j++) {
4734 0 : ci = &(ccs[i].items[j]);
4735 0 : if (ci->len > 1) { /* compound only */
4736 0 : if (IS_CCLASS_NOT(cc)) clear_not_flag_cclass(cc, enc);
4737 :
4738 0 : clen = ci->len;
4739 0 : for (k = 0; k < clen; k++) {
4740 0 : len = ONIGENC_CODE_TO_MBC(enc, ci->code[k], buf);
4741 :
4742 0 : if (k == 0) {
4743 0 : snode = node_new_str_raw(buf, buf + len);
4744 0 : CHECK_NULL_RETURN_VAL(snode, ONIGERR_MEMORY);
4745 : }
4746 : else {
4747 0 : r = onig_node_str_cat(snode, buf, buf + len);
4748 0 : if (r < 0) return r;
4749 : }
4750 : }
4751 :
4752 0 : *ptail = node_new_alt(snode, NULL_NODE);
4753 0 : CHECK_NULL_RETURN_VAL(*ptail, ONIGERR_MEMORY);
4754 0 : ptail = &(NCONS(*ptail).right);
4755 0 : n++;
4756 : }
4757 : }
4758 : }
4759 : }
4760 : }
4761 :
4762 0 : return n;
4763 : }
4764 :
4765 :
4766 : #ifdef USE_SHARED_CCLASS_TABLE
4767 :
4768 : #define THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS 8
4769 :
4770 : /* for ctype node hash table */
4771 :
4772 : typedef struct {
4773 : OnigEncoding enc;
4774 : int not;
4775 : int type;
4776 : } type_cclass_key;
4777 :
4778 : static int type_cclass_cmp(type_cclass_key* x, type_cclass_key* y)
4779 0 : {
4780 0 : if (x->type != y->type) return 1;
4781 0 : if (x->enc != y->enc) return 1;
4782 0 : if (x->not != y->not) return 1;
4783 0 : return 0;
4784 : }
4785 :
4786 : static int type_cclass_hash(type_cclass_key* key)
4787 10 : {
4788 : int i, val;
4789 : unsigned char *p;
4790 :
4791 10 : val = 0;
4792 :
4793 10 : p = (unsigned char* )&(key->enc);
4794 50 : for (i = 0; i < sizeof(key->enc); i++) {
4795 40 : val = val * 997 + (int )*p++;
4796 : }
4797 :
4798 10 : p = (unsigned char* )(&key->type);
4799 50 : for (i = 0; i < sizeof(key->type); i++) {
4800 40 : val = val * 997 + (int )*p++;
4801 : }
4802 :
4803 10 : val += key->not;
4804 10 : return val + (val >> 5);
4805 : }
4806 :
4807 : static struct st_hash_type type_type_cclass_hash = {
4808 : type_cclass_cmp,
4809 : type_cclass_hash,
4810 : };
4811 :
4812 : static st_table* OnigTypeCClassTable;
4813 :
4814 :
4815 : static int
4816 : i_free_shared_class(type_cclass_key* key, Node* node, void* arg)
4817 6 : {
4818 6 : if (IS_NOT_NULL(node)) {
4819 6 : CClassNode* cc = &(NCCLASS(node));
4820 6 : if (IS_NOT_NULL(cc->mbuf)) xfree(cc->mbuf);
4821 6 : xfree(node);
4822 : }
4823 :
4824 6 : if (IS_NOT_NULL(key)) xfree(key);
4825 6 : return ST_DELETE;
4826 : }
4827 :
4828 : extern int
4829 : onig_free_shared_cclass_table()
4830 13597 : {
4831 13597 : if (IS_NOT_NULL(OnigTypeCClassTable)) {
4832 2 : onig_st_foreach(OnigTypeCClassTable, i_free_shared_class, 0);
4833 2 : xfree(OnigTypeCClassTable);
4834 2 : OnigTypeCClassTable = NULL;
4835 : }
4836 :
4837 13597 : return 0;
4838 : }
4839 :
4840 : #endif /* USE_SHARED_CCLASS_TABLE */
4841 :
4842 :
4843 : static int
4844 : parse_exp(Node** np, OnigToken* tok, int term,
4845 : UChar** src, UChar* end, ScanEnv* env)
4846 350 : {
4847 350 : int r, len, group = 0;
4848 : Node* qn;
4849 : Node** targetp;
4850 :
4851 350 : *np = NULL;
4852 350 : if (tok->type == term)
4853 2 : goto end_of_token;
4854 :
4855 348 : switch (tok->type) {
4856 : case TK_ALT:
4857 : case TK_EOT:
4858 2 : end_of_token:
4859 2 : *np = node_new_empty();
4860 2 : return tok->type;
4861 : break;
4862 :
4863 : case TK_SUBEXP_OPEN:
4864 61 : r = parse_effect(np, tok, TK_SUBEXP_CLOSE, src, end, env);
4865 61 : if (r < 0) return r;
4866 61 : if (r == 1) group = 1;
4867 61 : else if (r == 2) { /* option only */
4868 : Node* target;
4869 0 : OnigOptionType prev = env->option;
4870 :
4871 0 : env->option = NEFFECT(*np).option;
4872 0 : r = fetch_token(tok, src, end, env);
4873 0 : if (r < 0) return r;
4874 0 : r = parse_subexp(&target, tok, term, src, end, env);
4875 0 : env->option = prev;
4876 0 : if (r < 0) return r;
4877 0 : NEFFECT(*np).target = target;
4878 0 : return tok->type;
4879 : }
4880 61 : break;
4881 :
4882 : case TK_SUBEXP_CLOSE:
4883 0 : if (! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP))
4884 0 : return ONIGERR_UNMATCHED_CLOSE_PARENTHESIS;
4885 :
4886 0 : if (tok->escaped) goto tk_raw_byte;
4887 0 : else goto tk_byte;
4888 : break;
4889 :
4890 : case TK_STRING:
4891 140 : tk_byte:
4892 : {
4893 140 : *np = node_new_str(tok->backp, *src);
4894 140 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4895 :
4896 : while (1) {
4897 346 : r = fetch_token(tok, src, end, env);
4898 346 : if (r < 0) return r;
4899 346 : if (r != TK_STRING) break;
4900 :
4901 206 : r = onig_node_str_cat(*np, tok->backp, *src);
4902 206 : if (r < 0) return r;
4903 206 : }
4904 :
4905 140 : string_end:
4906 140 : targetp = np;
4907 140 : goto repeat;
4908 : }
4909 : break;
4910 :
4911 : case TK_RAW_BYTE:
4912 0 : tk_raw_byte:
4913 : {
4914 0 : *np = node_new_str_raw_char((UChar )tok->u.c);
4915 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4916 0 : len = 1;
4917 : while (1) {
4918 0 : r = fetch_token(tok, src, end, env);
4919 0 : if (r < 0) return r;
4920 0 : if (r != TK_RAW_BYTE) {
4921 : #ifndef NUMBERED_CHAR_IS_NOT_CASE_AMBIG
4922 0 : if (len >= enc_len(env->enc, NSTRING(*np).s)) {
4923 0 : NSTRING_CLEAR_RAW(*np);
4924 : }
4925 : #endif
4926 0 : goto string_end;
4927 : }
4928 :
4929 0 : r = node_str_cat_char(*np, (UChar )tok->u.c);
4930 0 : if (r < 0) return r;
4931 0 : len++;
4932 0 : }
4933 : }
4934 : break;
4935 :
4936 : case TK_CODE_POINT:
4937 : {
4938 : UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
4939 0 : int num = ONIGENC_CODE_TO_MBC(env->enc, tok->u.code, buf);
4940 0 : if (num < 0) return num;
4941 : #ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG
4942 : *np = node_new_str_raw(buf, buf + num);
4943 : #else
4944 0 : *np = node_new_str(buf, buf + num);
4945 : #endif
4946 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4947 : }
4948 0 : break;
4949 :
4950 : case TK_QUOTE_OPEN:
4951 : {
4952 : OnigCodePoint end_op[2];
4953 : UChar *qstart, *qend, *nextp;
4954 :
4955 0 : end_op[0] = (OnigCodePoint )MC_ESC(env->enc);
4956 0 : end_op[1] = (OnigCodePoint )'E';
4957 0 : qstart = *src;
4958 0 : qend = find_str_position(end_op, 2, qstart, end, &nextp, env->enc);
4959 0 : if (IS_NULL(qend)) {
4960 0 : nextp = qend = end;
4961 : }
4962 0 : *np = node_new_str(qstart, qend);
4963 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4964 0 : *src = nextp;
4965 : }
4966 0 : break;
4967 :
4968 : case TK_CHAR_TYPE:
4969 : {
4970 10 : switch (tok->u.subtype) {
4971 : case CTYPE_WORD:
4972 : case CTYPE_NOT_WORD:
4973 4 : *np = node_new_ctype(tok->u.subtype);
4974 4 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
4975 4 : break;
4976 :
4977 : case CTYPE_WHITE_SPACE:
4978 : case CTYPE_NOT_WHITE_SPACE:
4979 : case CTYPE_DIGIT:
4980 : case CTYPE_NOT_DIGIT:
4981 : case CTYPE_XDIGIT:
4982 : case CTYPE_NOT_XDIGIT:
4983 : {
4984 : CClassNode* cc;
4985 : int ctype, not;
4986 :
4987 : #ifdef USE_SHARED_CCLASS_TABLE
4988 : const OnigCodePoint *sbr, *mbr;
4989 :
4990 6 : ctype = parse_ctype_to_enc_ctype(tok->u.subtype, ¬);
4991 6 : r = ONIGENC_GET_CTYPE_CODE_RANGE(env->enc, ctype, &sbr, &mbr);
4992 12 : if (r == 0 &&
4993 : ONIGENC_CODE_RANGE_NUM(mbr)
4994 : >= THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS) {
4995 : type_cclass_key key;
4996 : type_cclass_key* new_key;
4997 :
4998 6 : key.enc = env->enc;
4999 6 : key.not = not;
5000 6 : key.type = ctype;
5001 :
5002 : THREAD_ATOMIC_START;
5003 :
5004 6 : if (IS_NULL(OnigTypeCClassTable)) {
5005 2 : OnigTypeCClassTable
5006 : = onig_st_init_table_with_size(&type_type_cclass_hash, 10);
5007 2 : if (IS_NULL(OnigTypeCClassTable)) {
5008 : THREAD_ATOMIC_END;
5009 0 : return ONIGERR_MEMORY;
5010 : }
5011 : }
5012 : else {
5013 4 : if (onig_st_lookup(OnigTypeCClassTable, (st_data_t )&key,
5014 : (st_data_t* )np)) {
5015 : THREAD_ATOMIC_END;
5016 0 : break;
5017 : }
5018 : }
5019 :
5020 6 : *np = node_new_cclass_by_codepoint_range(not, sbr, mbr);
5021 6 : if (IS_NULL(*np)) {
5022 : THREAD_ATOMIC_END;
5023 0 : return ONIGERR_MEMORY;
5024 : }
5025 :
5026 6 : CCLASS_SET_SHARE(&(NCCLASS(*np)));
5027 6 : new_key = (type_cclass_key* )xmalloc(sizeof(type_cclass_key));
5028 6 : onig_st_add_direct(OnigTypeCClassTable, (st_data_t )new_key,
5029 : (st_data_t )*np);
5030 :
5031 : THREAD_ATOMIC_END;
5032 : }
5033 : else {
5034 : #endif
5035 0 : ctype = parse_ctype_to_enc_ctype(tok->u.subtype, ¬);
5036 0 : *np = node_new_cclass();
5037 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
5038 0 : cc = &(NCCLASS(*np));
5039 0 : add_ctype_to_cc(cc, ctype, 0, env);
5040 0 : if (not != 0) CCLASS_SET_NOT(cc);
5041 : #ifdef USE_SHARED_CCLASS_TABLE
5042 : }
5043 : #endif
5044 : }
5045 6 : break;
5046 :
5047 : default:
5048 0 : return ONIGERR_PARSER_BUG;
5049 : break;
5050 : }
5051 : }
5052 10 : break;
5053 :
5054 : case TK_CHAR_PROPERTY:
5055 0 : r = parse_char_property(np, tok, src, end, env);
5056 0 : if (r != 0) return r;
5057 0 : break;
5058 :
5059 : case TK_CC_OPEN:
5060 : {
5061 : CClassNode* cc;
5062 :
5063 93 : r = parse_char_class(np, tok, src, end, env);
5064 93 : if (r != 0) return r;
5065 :
5066 93 : cc = &(NCCLASS(*np));
5067 :
5068 93 : if (IS_IGNORECASE(env->option)) {
5069 : int i, n, in_cc;
5070 : const OnigPairAmbigCodes* ccs;
5071 1 : BitSetRef bs = cc->bs;
5072 : OnigAmbigType amb;
5073 :
5074 3 : for (amb = 0x01; amb <= ONIGENC_AMBIGUOUS_MATCH_LIMIT; amb <<= 1) {
5075 2 : if ((amb & env->ambig_flag) == 0) continue;
5076 :
5077 2 : n = ONIGENC_GET_ALL_PAIR_AMBIG_CODES(env->enc, amb, &ccs);
5078 114 : for (i = 0; i < n; i++) {
5079 112 : in_cc = onig_is_code_in_cc(env->enc, ccs[i].from, cc);
5080 :
5081 112 : if ((in_cc != 0 && !IS_CCLASS_NOT(cc)) ||
5082 : (in_cc == 0 && IS_CCLASS_NOT(cc))) {
5083 0 : if (ONIGENC_MBC_MINLEN(env->enc) > 1 ||
5084 : ccs[i].from >= SINGLE_BYTE_SIZE) {
5085 : /* if (cc->not) clear_not_flag_cclass(cc, env->enc); */
5086 0 : add_code_range(&(cc->mbuf), env, ccs[i].to, ccs[i].to);
5087 : }
5088 : else {
5089 0 : if (BITSET_AT(bs, ccs[i].from)) {
5090 : /* /(?i:[^A-C])/.match("a") ==> fail. */
5091 0 : BITSET_SET_BIT(bs, ccs[i].to);
5092 : }
5093 0 : if (BITSET_AT(bs, ccs[i].to)) {
5094 0 : BITSET_SET_BIT(bs, ccs[i].from);
5095 : }
5096 : }
5097 : }
5098 : }
5099 : }
5100 : }
5101 :
5102 93 : if (IS_IGNORECASE(env->option) &&
5103 : (env->ambig_flag & ONIGENC_AMBIGUOUS_MATCH_COMPOUND) != 0) {
5104 : int res;
5105 : Node *alt_root, *work;
5106 :
5107 0 : res = make_compound_alt_node_from_cc(env->ambig_flag, env->enc,
5108 : cc, &alt_root);
5109 0 : if (res < 0) return res;
5110 0 : if (res > 0) {
5111 0 : work = node_new_alt(*np, alt_root);
5112 0 : if (IS_NULL(work)) {
5113 0 : onig_node_free(alt_root);
5114 0 : return ONIGERR_MEMORY;
5115 : }
5116 0 : *np = work;
5117 : }
5118 : }
5119 : }
5120 93 : break;
5121 :
5122 : case TK_ANYCHAR:
5123 26 : *np = node_new_anychar();
5124 26 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
5125 26 : break;
5126 :
5127 : case TK_ANYCHAR_ANYTIME:
5128 0 : *np = node_new_anychar();
5129 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
5130 0 : qn = node_new_qualifier(0, REPEAT_INFINITE, 0);
5131 0 : CHECK_NULL_RETURN_VAL(qn, ONIGERR_MEMORY);
5132 0 : NQUALIFIER(qn).target = *np;
5133 0 : *np = qn;
5134 0 : break;
5135 :
5136 : case TK_BACKREF:
5137 0 : len = tok->u.backref.num;
5138 0 : *np = node_new_backref(len,
5139 : (len > 1 ? tok->u.backref.refs : &(tok->u.backref.ref1)),
5140 : tok->u.backref.by_name,
5141 : #ifdef USE_BACKREF_AT_LEVEL
5142 : tok->u.backref.exist_level,
5143 : tok->u.backref.level,
5144 : #endif
5145 : env);
5146 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
5147 0 : break;
5148 :
5149 : #ifdef USE_SUBEXP_CALL
5150 : case TK_CALL:
5151 0 : *np = node_new_call(tok->u.call.name, tok->u.call.name_end);
5152 0 : CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
5153 0 : env->num_call++;
5154 0 : break;
5155 : #endif
5156 :
5157 : case TK_ANCHOR:
5158 18 : *np = onig_node_new_anchor(tok->u.anchor);
5159 18 : break;
5160 :
5161 : case TK_OP_REPEAT:
5162 : case TK_INTERVAL:
5163 0 : if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS)) {
5164 0 : if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS))
5165 0 : return ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED;
5166 : else
5167 0 : *np = node_new_empty();
5168 : }
5169 : else {
5170 0 : goto tk_byte;
5171 : }
5172 0 : break;
5173 :
5174 : default:
5175 0 : return ONIGERR_PARSER_BUG;
5176 : break;
5177 : }
5178 :
5179 : {
5180 208 : targetp = np;
5181 :
5182 334 : re_entry:
5183 334 : r = fetch_token(tok, src, end, env);
5184 334 : if (r < 0) return r;
5185 :
5186 474 : repeat:
5187 474 : if (r == TK_OP_REPEAT || r == TK_INTERVAL) {
5188 126 : if (is_invalid_qualifier_target(*targetp))
5189 0 : return ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID;
5190 :
5191 126 : qn = node_new_qualifier(tok->u.repeat.lower, tok->u.repeat.upper,
5192 : (r == TK_INTERVAL ? 1 : 0));
5193 126 : CHECK_NULL_RETURN_VAL(qn, ONIGERR_MEMORY);
5194 126 : NQUALIFIER(qn).greedy = tok->u.repeat.greedy;
5195 126 : r = set_qualifier(qn, *targetp, group, env);
5196 126 : if (r < 0) return r;
5197 :
5198 126 : if (tok->u.repeat.possessive != 0) {
5199 : Node* en;
5200 0 : en = node_new_effect(EFFECT_STOP_BACKTRACK);
5201 0 : CHECK_NULL_RETURN_VAL(en, ONIGERR_MEMORY);
5202 0 : NEFFECT(en).target = qn;
5203 0 : qn = en;
5204 : }
5205 :
5206 126 : if (r == 0) {
5207 117 : *targetp = qn;
5208 : }
5209 9 : else if (r == 2) { /* split case: /abc+/ */
5210 : Node *tmp;
5211 :
5212 9 : *targetp = node_new_list(*targetp, NULL);
5213 9 : CHECK_NULL_RETURN_VAL(*targetp, ONIGERR_MEMORY);
5214 9 : tmp = NCONS(*targetp).right = node_new_list(qn, NULL);
5215 9 : CHECK_NULL_RETURN_VAL(tmp, ONIGERR_MEMORY);
5216 9 : targetp = &(NCONS(tmp).left);
5217 : }
5218 126 : goto re_entry;
5219 : }
5220 : }
5221 :
5222 348 : return r;
5223 : }
5224 :
5225 : static int
5226 : parse_branch(Node** top, OnigToken* tok, int term,
5227 : UChar** src, UChar* end, ScanEnv* env)
5228 208 : {
5229 : int r;
5230 : Node *node, **headp;
5231 :
5232 208 : *top = NULL;
5233 208 : r = parse_exp(&node, tok, term, src, end, env);
5234 208 : if (r < 0) return r;
5235 :
5236 354 : if (r == TK_EOT || r == term || r == TK_ALT) {
5237 146 : *top = node;
5238 : }
5239 : else {
5240 62 : *top = node_new_list(node, NULL);
5241 62 : headp = &(NCONS(*top).right);
5242 266 : while (r != TK_EOT && r != term && r != TK_ALT) {
5243 142 : r = parse_exp(&node, tok, term, src, end, env);
5244 142 : if (r < 0) return r;
5245 :
5246 142 : if (NTYPE(node) == N_LIST) {
5247 9 : *headp = node;
5248 9 : while (IS_NOT_NULL(NCONS(node).right)) node = NCONS(node).right;
5249 9 : headp = &(NCONS(node).right);
5250 : }
5251 : else {
5252 133 : *headp = node_new_list(node, NULL);
5253 133 : headp = &(NCONS(*headp).right);
5254 : }
5255 : }
5256 : }
5257 :
5258 208 : return r;
5259 : }
5260 :
5261 : /* term_tok: TK_EOT or TK_SUBEXP_CLOSE */
5262 : static int
5263 : parse_subexp(Node** top, OnigToken* tok, int term,
5264 : UChar** src, UChar* end, ScanEnv* env)
5265 206 : {
5266 : int r;
5267 : Node *node, **headp;
5268 :
5269 206 : *top = NULL;
5270 206 : r = parse_branch(&node, tok, term, src, end, env);
5271 206 : if (r < 0) {
5272 0 : onig_node_free(node);
5273 0 : return r;
5274 : }
5275 :
5276 206 : if (r == term) {
5277 204 : *top = node;
5278 : }
5279 2 : else if (r == TK_ALT) {
5280 2 : *top = node_new_alt(node, NULL);
5281 2 : headp = &(NCONS(*top).right);
5282 6 : while (r == TK_ALT) {
5283 2 : r = fetch_token(tok, src, end, env);
5284 2 : if (r < 0) return r;
5285 2 : r = parse_branch(&node, tok, term, src, end, env);
5286 2 : if (r < 0) return r;
5287 :
5288 2 : *headp = node_new_alt(node, NULL);
5289 2 : headp = &(NCONS(*headp).right);
5290 : }
5291 :
5292 2 : if (tok->type != term)
5293 0 : goto err;
5294 : }
5295 : else {
5296 0 : err:
5297 0 : if (term == TK_SUBEXP_CLOSE)
5298 0 : return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
5299 : else
5300 0 : return ONIGERR_PARSER_BUG;
5301 : }
5302 :
5303 206 : return r;
5304 : }
5305 :
5306 : static int
5307 : parse_regexp(Node** top, UChar** src, UChar* end, ScanEnv* env)
5308 145 : {
5309 : int r;
5310 : OnigToken tok;
5311 :
5312 145 : r = fetch_token(&tok, src, end, env);
5313 145 : if (r < 0) return r;
5314 145 : r = parse_subexp(top, &tok, TK_EOT, src, end, env);
5315 145 : if (r < 0) return r;
5316 145 : return 0;
5317 : }
5318 :
5319 : extern int
5320 : onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end, regex_t* reg,
5321 : ScanEnv* env)
5322 145 : {
5323 : int r;
5324 : UChar* p;
5325 :
5326 : #ifdef USE_NAMED_GROUP
5327 145 : names_clear(reg);
5328 : #endif
5329 :
5330 145 : scan_env_clear(env);
5331 145 : env->option = reg->options;
5332 145 : env->ambig_flag = reg->ambig_flag;
5333 145 : env->enc = reg->enc;
5334 145 : env->syntax = reg->syntax;
5335 145 : env->pattern = (UChar* )pattern;
5336 145 : env->pattern_end = (UChar* )end;
5337 145 : env->reg = reg;
5338 :
5339 145 : *root = NULL;
5340 145 : p = (UChar* )pattern;
5341 145 : r = parse_regexp(root, &p, (UChar* )end, env);
5342 145 : reg->num_mem = env->num_mem;
5343 145 : return r;
5344 : }
5345 :
5346 : extern void
5347 : onig_scan_env_set_error_string(ScanEnv* env, int ecode,
5348 : UChar* arg, UChar* arg_end)
5349 0 : {
5350 0 : env->error = arg;
5351 0 : env->error_end = arg_end;
5352 0 : }
|