1 /*
2 * base.c contributed by Mark Griffin
3 * Copyright (c) 2019-2021 K.Kosako
4 */
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <time.h>
13 #include "oniguruma.h"
14
15 #define PARSE_DEPTH_LIMIT 8
16 #define MAX_SUBEXP_CALL_NEST_LEVEL 8
17 #define SUBEXP_CALL_LIMIT 1000
18 #define BASE_RETRY_LIMIT 20000
19 #define BASE_LENGTH 2048
20 #define MATCH_STACK_LIMIT 10000000
21 #define MAX_REM_SIZE 1048576
22 #define MAX_SLOW_REM_SIZE 1024
23 #define MAX_SLOW_REM_SIZE2 100
24 #define SLOW_RETRY_LIMIT 2000
25 #define SLOW_SUBEXP_CALL_LIMIT 100
26 #define MAX_SLOW_BACKWARD_REM_SIZE 200
27
28 //#define EXEC_PRINT_INTERVAL 500000
29 //#define DUMP_DATA_INTERVAL 100000
30 //#define STAT_PATH "fuzzer.stat_log"
31 //#define PREV_CONTROL
32
33 #ifdef PREV_CONTROL
34 #define OPTIONS_AT_COMPILE (ONIG_OPTION_IGNORECASE | ONIG_OPTION_EXTEND | ONIG_OPTION_MULTILINE | ONIG_OPTION_SINGLELINE | ONIG_OPTION_FIND_LONGEST | ONIG_OPTION_FIND_NOT_EMPTY | ONIG_OPTION_NEGATE_SINGLELINE | ONIG_OPTION_DONT_CAPTURE_GROUP | ONIG_OPTION_CAPTURE_GROUP | ONIG_OPTION_WORD_IS_ASCII | ONIG_OPTION_DIGIT_IS_ASCII | ONIG_OPTION_SPACE_IS_ASCII | ONIG_OPTION_POSIX_IS_ASCII | ONIG_OPTION_TEXT_SEGMENT_EXTENDED_GRAPHEME_CLUSTER | ONIG_OPTION_TEXT_SEGMENT_WORD)
35 #else
36 #define OPTIONS_AT_COMPILE (ONIG_OPTION_IGNORECASE | ONIG_OPTION_EXTEND | ONIG_OPTION_MULTILINE | ONIG_OPTION_SINGLELINE | ONIG_OPTION_FIND_LONGEST | ONIG_OPTION_FIND_NOT_EMPTY | ONIG_OPTION_NEGATE_SINGLELINE | ONIG_OPTION_DONT_CAPTURE_GROUP | ONIG_OPTION_CAPTURE_GROUP | ONIG_OPTION_WORD_IS_ASCII | ONIG_OPTION_DIGIT_IS_ASCII | ONIG_OPTION_SPACE_IS_ASCII | ONIG_OPTION_POSIX_IS_ASCII | ONIG_OPTION_TEXT_SEGMENT_EXTENDED_GRAPHEME_CLUSTER | ONIG_OPTION_TEXT_SEGMENT_WORD | ONIG_OPTION_IGNORECASE_IS_ASCII)
37 #endif
38
39 #define OPTIONS_AT_RUNTIME (ONIG_OPTION_NOTBOL | ONIG_OPTION_NOTEOL | ONIG_OPTION_CHECK_VALIDITY_OF_STRING | ONIG_OPTION_NOT_BEGIN_STRING | ONIG_OPTION_NOT_END_STRING | ONIG_OPTION_NOT_BEGIN_POSITION | ONIG_OPTION_CALLBACK_EACH_MATCH)
40
41
42 #define ADJUST_LEN(enc, len) do {\
43 int mlen = ONIGENC_MBC_MINLEN(enc);\
44 if (mlen != 1) { len -= len % mlen; }\
45 } while (0)
46
47 typedef unsigned char uint8_t;
48
49
50 //#define TEST_PATTERN
51
52 #ifdef TEST_PATTERN
53
54 #if 1
55 unsigned char TestPattern[] = {
56 };
57 #endif
58
59 #endif /* TEST_PATTERN */
60
61 #ifdef STANDALONE
62
63 static void
print_options(FILE * fp,OnigOptionType o)64 print_options(FILE* fp, OnigOptionType o)
65 {
66 if ((o & ONIG_OPTION_IGNORECASE) != 0) fprintf(fp, " IGNORECASE");
67 if ((o & ONIG_OPTION_EXTEND) != 0) fprintf(fp, " EXTEND");
68 if ((o & ONIG_OPTION_MULTILINE) != 0) fprintf(fp, " MULTILINE");
69 if ((o & ONIG_OPTION_SINGLELINE) != 0) fprintf(fp, " SINGLELINE");
70 if ((o & ONIG_OPTION_FIND_LONGEST) != 0) fprintf(fp, " FIND_LONGEST");
71 if ((o & ONIG_OPTION_FIND_NOT_EMPTY) != 0) fprintf(fp, " FIND_NOT_EMPTY");
72 if ((o & ONIG_OPTION_NEGATE_SINGLELINE) != 0) fprintf(fp, " NEGATE_SINGLELINE");
73 if ((o & ONIG_OPTION_DONT_CAPTURE_GROUP) != 0) fprintf(fp, " DONT_CAPTURE_GROUP");
74 if ((o & ONIG_OPTION_CAPTURE_GROUP) != 0) fprintf(fp, " CAPTURE_GROUP");
75 if ((o & ONIG_OPTION_NOTBOL) != 0) fprintf(fp, " NOTBOL");
76 if ((o & ONIG_OPTION_NOTEOL) != 0) fprintf(fp, " NOTEOL");
77 if ((o & ONIG_OPTION_POSIX_REGION) != 0) fprintf(fp, " POSIX_REGION");
78 if ((o & ONIG_OPTION_CHECK_VALIDITY_OF_STRING) != 0) fprintf(fp, " CHECK_VALIDITY_OF_STRING");
79 if ((o & ONIG_OPTION_IGNORECASE_IS_ASCII) != 0) fprintf(fp, " IGNORECASE_IS_ASCII");
80 if ((o & ONIG_OPTION_WORD_IS_ASCII) != 0) fprintf(fp, " WORD_IS_ASCII");
81 if ((o & ONIG_OPTION_DIGIT_IS_ASCII) != 0) fprintf(fp, " DIGIT_IS_ASCII");
82 if ((o & ONIG_OPTION_SPACE_IS_ASCII) != 0) fprintf(fp, " SPACE_IS_ASCII");
83 if ((o & ONIG_OPTION_POSIX_IS_ASCII) != 0) fprintf(fp, " POSIX_IS_ASCII");
84 if ((o & ONIG_OPTION_TEXT_SEGMENT_EXTENDED_GRAPHEME_CLUSTER) != 0) fprintf(fp, " TEXT_SEGMENT_EXTENDED_GRAPHEME_CLUSTER");
85 if ((o & ONIG_OPTION_TEXT_SEGMENT_WORD) != 0) fprintf(fp, " TEXT_SEGMENT_WORD");
86 if ((o & ONIG_OPTION_NOT_BEGIN_STRING) != 0) fprintf(fp, " NOT_BIGIN_STRING");
87 if ((o & ONIG_OPTION_NOT_END_STRING) != 0) fprintf(fp, " NOT_END_STRING");
88 if ((o & ONIG_OPTION_NOT_BEGIN_POSITION) != 0) fprintf(fp, " NOT_BEGIN_POSITION");
89 if ((o & ONIG_OPTION_CALLBACK_EACH_MATCH) != 0) fprintf(fp, " CALLBACK_EACH_MATCH");
90 }
91
92 static void
to_binary(unsigned int v,char s[])93 to_binary(unsigned int v, char s[/* 33 */])
94 {
95 unsigned int mask;
96 int i;
97
98 mask = 1 << (sizeof(v) * 8 - 1);
99 i = 0;
100 do {
101 s[i++] = (mask & v ? '1' : '0');
102 } while (mask >>= 1);
103 s[i] = 0;
104 }
105 #endif
106
107 #ifdef DUMP_INPUT
108 static void
dump_input(unsigned char * data,size_t len)109 dump_input(unsigned char* data, size_t len)
110 {
111 static FILE* DumpFp;
112 static char end[] = { 'E', 'N', 'D' };
113
114 if (DumpFp == 0)
115 DumpFp = fopen("dump-input", "w");
116
117 fseek(DumpFp, 0, SEEK_SET);
118 fwrite(data, sizeof(unsigned char), len, DumpFp);
119 fwrite(end, sizeof(char), sizeof(end), DumpFp);
120 fflush(DumpFp);
121 }
122 #endif
123
124 #ifdef DUMP_DATA_INTERVAL
125 static void
dump_file(char * path,unsigned char * data,size_t len)126 dump_file(char* path, unsigned char* data, size_t len)
127 {
128 FILE* fp;
129
130 fp = fopen(path, "w");
131 fwrite(data, sizeof(unsigned char), len, fp);
132 fclose(fp);
133 }
134 #endif
135
136 #ifdef STANDALONE
137 #include <ctype.h>
138
139 static void
dump_data(FILE * fp,unsigned char * data,int len)140 dump_data(FILE* fp, unsigned char* data, int len)
141 {
142 int i;
143
144 fprintf(fp, "{\n");
145 for (i = 0; i < len; i++) {
146 unsigned char c = data[i];
147
148 if (isprint((int )c)) {
149 if (c == '\\')
150 fprintf(fp, " '\\\\'");
151 else
152 fprintf(fp, " '%c'", c);
153 }
154 else {
155 fprintf(fp, "0x%02x", (int )c);
156 }
157
158 if (i == len - 1) {
159 fprintf(fp, "\n");
160 }
161 else {
162 if (i % 8 == 7)
163 fprintf(fp, ",\n");
164 else
165 fprintf(fp, ", ");
166 }
167 }
168 fprintf(fp, "};\n");
169 }
170
171 #else
172
173 #ifdef EXEC_PRINT_INTERVAL
174 static void
output_current_time(FILE * fp)175 output_current_time(FILE* fp)
176 {
177 char d[64];
178 time_t t;
179
180 t = time(NULL);
181 strftime(d, sizeof(d), "%m/%d %H:%M:%S", localtime(&t));
182
183 fprintf(fp, "%s", d);
184 }
185 #endif
186
187 #endif
188
189 static int
progress_callout_func(OnigCalloutArgs * args,void * user_data)190 progress_callout_func(OnigCalloutArgs* args, void* user_data)
191 {
192 return ONIG_CALLOUT_SUCCESS;
193 }
194
195 static int
each_match_callback_func(const UChar * str,const UChar * end,const UChar * match_start,OnigRegion * region,void * user_data)196 each_match_callback_func(const UChar* str, const UChar* end,
197 const UChar* match_start, OnigRegion* region, void* user_data)
198 {
199 return ONIG_NORMAL;
200 }
201
202 static int
search(regex_t * reg,unsigned char * str,unsigned char * end,OnigOptionType options,int backward,int sl)203 search(regex_t* reg, unsigned char* str, unsigned char* end, OnigOptionType options, int backward, int sl)
204 {
205 int r;
206 unsigned char *start, *range;
207 OnigRegion *region;
208 unsigned int retry_limit;
209 size_t len;
210
211 region = onig_region_new();
212
213 len = (size_t )(end - str);
214 if (len < BASE_LENGTH) {
215 if (sl >= 2)
216 retry_limit = (unsigned int )SLOW_RETRY_LIMIT;
217 else
218 retry_limit = (unsigned int )BASE_RETRY_LIMIT;
219 }
220 else
221 retry_limit = (unsigned int )(BASE_RETRY_LIMIT * BASE_LENGTH / len);
222
223 #ifdef STANDALONE
224 fprintf(stdout, "retry limit: %u\n", retry_limit);
225 #endif
226
227 onig_set_retry_limit_in_search(retry_limit);
228 onig_set_match_stack_limit_size(MATCH_STACK_LIMIT);
229 if (sl >= 2)
230 onig_set_subexp_call_limit_in_search(SLOW_SUBEXP_CALL_LIMIT);
231 else
232 onig_set_subexp_call_limit_in_search(SUBEXP_CALL_LIMIT);
233
234 if (backward != 0) {
235 start = end;
236 range = str;
237 }
238 else {
239 start = str;
240 range = end;
241 }
242
243 r = onig_search(reg, str, end, start, range, region, (options & OPTIONS_AT_RUNTIME));
244 if (r >= 0) {
245 #ifdef STANDALONE
246 int i;
247
248 fprintf(stdout, "match at %d (%s)\n", r,
249 ONIGENC_NAME(onig_get_encoding(reg)));
250 for (i = 0; i < region->num_regs; i++) {
251 fprintf(stdout, "%d: (%d-%d)\n", i, region->beg[i], region->end[i]);
252 }
253 #endif
254 }
255 else if (r == ONIG_MISMATCH) {
256 #ifdef STANDALONE
257 fprintf(stdout, "search fail (%s)\n",
258 ONIGENC_NAME(onig_get_encoding(reg)));
259 #endif
260 }
261 else { /* error */
262 #ifdef STANDALONE
263 char s[ONIG_MAX_ERROR_MESSAGE_LEN];
264
265 onig_error_code_to_str((UChar* )s, r);
266 fprintf(stdout, "ERROR: %s\n", s);
267 fprintf(stdout, " (%s)\n", ONIGENC_NAME(onig_get_encoding(reg)));
268 #endif
269 onig_region_free(region, 1 /* 1:free self, 0:free contents only */);
270
271 if (r == ONIGERR_STACK_BUG ||
272 r == ONIGERR_UNDEFINED_BYTECODE ||
273 r == ONIGERR_UNEXPECTED_BYTECODE)
274 return -2;
275
276 return -1;
277 }
278
279 onig_region_free(region, 1 /* 1:free self, 0:free contents only */);
280 return 0;
281 }
282
283 static long INPUT_COUNT;
284 static long EXEC_COUNT;
285 static long EXEC_COUNT_INTERVAL;
286 static long REGEX_SUCCESS_COUNT;
287 static long VALID_STRING_COUNT;
288
289 static int
exec(OnigEncoding enc,OnigOptionType options,OnigSyntaxType * syntax,char * apattern,char * apattern_end,char * astr,UChar * end,int backward,int sl)290 exec(OnigEncoding enc, OnigOptionType options, OnigSyntaxType* syntax,
291 char* apattern, char* apattern_end, char* astr, UChar* end, int backward,
292 int sl)
293 {
294 int r;
295 regex_t* reg;
296 OnigErrorInfo einfo;
297 UChar* pattern = (UChar* )apattern;
298 UChar* str = (UChar* )astr;
299 UChar* pattern_end = (UChar* )apattern_end;
300
301 EXEC_COUNT++;
302 EXEC_COUNT_INTERVAL++;
303
304 onig_initialize(&enc, 1);
305 (void)onig_set_progress_callout(progress_callout_func);
306 #ifdef PARSE_DEPTH_LIMIT
307 onig_set_parse_depth_limit(PARSE_DEPTH_LIMIT);
308 #endif
309 onig_set_subexp_call_max_nest_level(MAX_SUBEXP_CALL_NEST_LEVEL);
310 onig_set_callback_each_match(each_match_callback_func);
311
312 r = onig_new(®, pattern, pattern_end,
313 (options & OPTIONS_AT_COMPILE), enc, syntax, &einfo);
314 if (r != ONIG_NORMAL) {
315 char s[ONIG_MAX_ERROR_MESSAGE_LEN];
316 onig_error_code_to_str((UChar* )s, r, &einfo);
317 #ifdef STANDALONE
318 fprintf(stdout, "ERROR: %s\n", s);
319 #endif
320 onig_end();
321
322 if (r == ONIGERR_PARSER_BUG ||
323 r == ONIGERR_STACK_BUG ||
324 r == ONIGERR_UNDEFINED_BYTECODE ||
325 r == ONIGERR_UNEXPECTED_BYTECODE) {
326 return -2;
327 }
328 else
329 return -1;
330 }
331 REGEX_SUCCESS_COUNT++;
332
333 r = search(reg, pattern, pattern_end, options, backward, sl);
334 if (r == -2) return -2;
335
336 if (onigenc_is_valid_mbc_string(enc, str, end) != 0) {
337 VALID_STRING_COUNT++;
338 r = search(reg, str, end, options, backward, sl);
339 if (r == -2) return -2;
340 }
341
342 onig_free(reg);
343 onig_end();
344 return 0;
345 }
346
347 static int
alloc_exec(OnigEncoding enc,OnigOptionType options,OnigSyntaxType * syntax,int backward,int pattern_size,size_t rem_size,unsigned char * data)348 alloc_exec(OnigEncoding enc, OnigOptionType options, OnigSyntaxType* syntax,
349 int backward, int pattern_size, size_t rem_size, unsigned char *data)
350 {
351 extern int onig_detect_can_be_slow_pattern(const UChar* pattern, const UChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax);
352
353 int r;
354 int sl;
355 unsigned char *pattern;
356 unsigned char *pattern_end;
357 unsigned char *str_null_end;
358
359 #ifdef TEST_PATTERN
360 pattern = (unsigned char *)malloc(sizeof(TestPattern));
361 memcpy(pattern, TestPattern, sizeof(TestPattern));
362 pattern_end = pattern + sizeof(TestPattern);
363 #else
364 pattern = (unsigned char *)malloc(pattern_size != 0 ? pattern_size : 1);
365 memcpy(pattern, data, pattern_size);
366 pattern_end = pattern + pattern_size;
367 #endif
368
369 data += pattern_size;
370 rem_size -= pattern_size;
371
372 if (rem_size > MAX_REM_SIZE) rem_size = MAX_REM_SIZE;
373
374 sl = onig_detect_can_be_slow_pattern(pattern, pattern_end, options, enc, syntax);
375 #ifdef STANDALONE
376 fprintf(stdout, "sl: %d\n", sl);
377 #endif
378 if (sl > 0) {
379 if (sl >= 100) {
380 if (rem_size > MAX_SLOW_REM_SIZE2)
381 rem_size = MAX_SLOW_REM_SIZE2;
382 }
383 else {
384 if (rem_size > MAX_SLOW_REM_SIZE)
385 rem_size = MAX_SLOW_REM_SIZE;
386 }
387 }
388 if (backward != 0 && enc == ONIG_ENCODING_GB18030) {
389 if (rem_size > MAX_SLOW_BACKWARD_REM_SIZE)
390 rem_size = MAX_SLOW_BACKWARD_REM_SIZE;
391 }
392
393 ADJUST_LEN(enc, rem_size);
394 #ifdef STANDALONE
395 fprintf(stdout, "rem_size: %ld\n", rem_size);
396 #endif
397
398 unsigned char *str = (unsigned char*)malloc(rem_size != 0 ? rem_size : 1);
399 memcpy(str, data, rem_size);
400 str_null_end = str + rem_size;
401
402 r = exec(enc, options, syntax,
403 (char *)pattern, (char *)pattern_end,
404 (char *)str, str_null_end, backward, sl);
405
406 free(pattern);
407 free(str);
408 return r;
409 }
410
411 #ifdef PREV_CONTROL
412 #ifdef SYNTAX_TEST
413 #define NUM_CONTROL_BYTES 7
414 #else
415 #define NUM_CONTROL_BYTES 6
416 #endif
417 #else
418 #ifdef SYNTAX_TEST
419 #define NUM_CONTROL_BYTES 8
420 #else
421 #define NUM_CONTROL_BYTES 7
422 #endif
423 #endif
424
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)425 int LLVMFuzzerTestOneInput(const uint8_t * Data, size_t Size)
426 {
427 #if !defined(UTF16_BE) && !defined(UTF16_LE)
428 static OnigEncoding encodings[] = {
429 ONIG_ENCODING_UTF8,
430 ONIG_ENCODING_UTF8,
431 ONIG_ENCODING_UTF8,
432 ONIG_ENCODING_UTF8,
433 ONIG_ENCODING_UTF8,
434 ONIG_ENCODING_UTF8,
435 ONIG_ENCODING_UTF8,
436 ONIG_ENCODING_UTF8,
437 ONIG_ENCODING_ASCII,
438 ONIG_ENCODING_EUC_JP,
439 ONIG_ENCODING_EUC_TW,
440 ONIG_ENCODING_EUC_KR,
441 ONIG_ENCODING_EUC_CN,
442 ONIG_ENCODING_SJIS,
443 ONIG_ENCODING_KOI8_R,
444 ONIG_ENCODING_CP1251,
445 ONIG_ENCODING_BIG5,
446 ONIG_ENCODING_GB18030,
447 ONIG_ENCODING_UTF16_BE,
448 ONIG_ENCODING_UTF16_LE,
449 ONIG_ENCODING_UTF16_BE,
450 ONIG_ENCODING_UTF16_LE,
451 ONIG_ENCODING_UTF32_BE,
452 ONIG_ENCODING_UTF32_LE,
453 ONIG_ENCODING_UTF32_BE,
454 ONIG_ENCODING_UTF32_LE,
455 ONIG_ENCODING_ISO_8859_1,
456 ONIG_ENCODING_ISO_8859_2,
457 ONIG_ENCODING_ISO_8859_3,
458 ONIG_ENCODING_ISO_8859_4,
459 ONIG_ENCODING_ISO_8859_5,
460 ONIG_ENCODING_ISO_8859_6,
461 ONIG_ENCODING_ISO_8859_7,
462 ONIG_ENCODING_ISO_8859_8,
463 ONIG_ENCODING_ISO_8859_9,
464 ONIG_ENCODING_ISO_8859_10,
465 ONIG_ENCODING_ISO_8859_11,
466 ONIG_ENCODING_ISO_8859_13,
467 ONIG_ENCODING_ISO_8859_14,
468 ONIG_ENCODING_ISO_8859_15,
469 ONIG_ENCODING_ISO_8859_16
470 };
471 unsigned char encoding_choice;
472 #endif
473
474 #ifdef SYNTAX_TEST
475 static OnigSyntaxType* syntaxes[] = {
476 ONIG_SYNTAX_POSIX_EXTENDED,
477 ONIG_SYNTAX_EMACS,
478 ONIG_SYNTAX_GREP,
479 ONIG_SYNTAX_GNU_REGEX,
480 ONIG_SYNTAX_JAVA,
481 ONIG_SYNTAX_PERL_NG,
482 ONIG_SYNTAX_PYTHON,
483 ONIG_SYNTAX_ONIGURUMA
484 };
485
486 #ifdef STANDALONE
487 static char* syntax_names[] = {
488 "Posix Extended",
489 "Emacs",
490 "Grep",
491 "GNU Regex",
492 "Java",
493 "Perl+NG",
494 "Python",
495 "Oniguruma"
496 };
497 #endif
498
499 unsigned char syntax_choice;
500 #endif
501
502 int r;
503 int backward;
504 int pattern_size;
505 size_t rem_size;
506 unsigned char *data;
507 unsigned char pattern_size_choice;
508 OnigOptionType options;
509 OnigEncoding enc;
510 OnigSyntaxType* syntax;
511
512 #ifndef STANDALONE
513 #ifdef EXEC_PRINT_INTERVAL
514 static FILE* STAT_FP;
515 #endif
516 #endif
517
518 INPUT_COUNT++;
519
520 #ifdef DUMP_DATA_INTERVAL
521 if (INPUT_COUNT % DUMP_DATA_INTERVAL == 0) {
522 char path[20];
523 sprintf(path, "dump-%ld", INPUT_COUNT);
524 dump_file(path, (unsigned char* )Data, Size);
525 }
526 #endif
527
528 if (Size < NUM_CONTROL_BYTES) return 0;
529
530 rem_size = Size;
531 data = (unsigned char* )(Data);
532
533 #ifdef UTF16_BE
534 enc = ONIG_ENCODING_UTF16_BE;
535 #else
536 #ifdef UTF16_LE
537 enc = ONIG_ENCODING_UTF16_LE;
538 #else
539 encoding_choice = data[0];
540 data++;
541 rem_size--;
542
543 int num_encodings = sizeof(encodings)/sizeof(encodings[0]);
544 enc = encodings[encoding_choice % num_encodings];
545 #endif
546 #endif
547
548 #ifdef SYNTAX_TEST
549 syntax_choice = data[0];
550 data++;
551 rem_size--;
552
553 int num_syntaxes = sizeof(syntaxes)/sizeof(syntaxes[0]);
554 syntax = syntaxes[syntax_choice % num_syntaxes];
555 #else
556 syntax = ONIG_SYNTAX_DEFAULT;
557 #endif
558
559 #ifdef PREV_CONTROL
560 if ((data[2] & 0xc0) == 0)
561 options = data[0] | (data[1] << 8) | (data[2] << 16);
562 #else
563 if ((data[3] & 0xc0) == 0)
564 options = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
565 #endif
566 else
567 options = data[0] & ONIG_OPTION_IGNORECASE;
568
569 data++; rem_size--;
570 data++; rem_size--;
571 data++; rem_size--;
572 #ifndef PREV_CONTROL
573 data++; rem_size--;
574 #endif
575
576 pattern_size_choice = data[0];
577 data++; rem_size--;
578
579 backward = (data[0] == 0xbb);
580 data++; rem_size--;
581
582 if (backward != 0) {
583 options = options & ~ONIG_OPTION_FIND_LONGEST;
584 }
585
586 if (rem_size == 0)
587 pattern_size = 0;
588 else {
589 pattern_size = (int )pattern_size_choice % rem_size;
590 ADJUST_LEN(enc, pattern_size);
591 }
592
593 #ifdef STANDALONE
594 {
595 char soptions[33];
596
597 dump_data(stdout, data, pattern_size);
598 to_binary(options, soptions);
599 #ifdef SYNTAX_TEST
600 fprintf(stdout,
601 "enc: %s, syntax: %s, pattern_size: %d, back:%d\noptions: %s\n",
602 ONIGENC_NAME(enc),
603 syntax_names[syntax_choice % num_syntaxes],
604 pattern_size, backward, soptions);
605 #else
606 fprintf(stdout, "enc: %s, pattern_size: %d, back:%d\noptions: %s\n",
607 ONIGENC_NAME(enc), pattern_size, backward, soptions);
608 #endif
609
610 print_options(stdout, options);
611 fprintf(stdout, "\n");
612 }
613 #endif
614
615 #ifdef DUMP_INPUT
616 dump_input((unsigned char* )Data, Size);
617 #endif
618
619 r = alloc_exec(enc, options, syntax, backward, pattern_size,
620 rem_size, data);
621 if (r == -2) exit(-2);
622
623 #ifndef STANDALONE
624 #ifdef EXEC_PRINT_INTERVAL
625 if (EXEC_COUNT_INTERVAL == EXEC_PRINT_INTERVAL) {
626 float fexec, freg, fvalid;
627
628 if (STAT_FP == 0) {
629 #ifdef STAT_PATH
630 STAT_FP = fopen(STAT_PATH, "a");
631 #else
632 STAT_FP = stdout;
633 #endif
634 }
635
636 output_current_time(STAT_FP);
637
638 if (INPUT_COUNT != 0) { // overflow check
639 fexec = (float )EXEC_COUNT / INPUT_COUNT;
640 freg = (float )REGEX_SUCCESS_COUNT / INPUT_COUNT;
641 fvalid = (float )VALID_STRING_COUNT / INPUT_COUNT;
642
643 fprintf(STAT_FP, ": %ld: EXEC:%.2f, REG:%.2f, VALID:%.2f\n",
644 EXEC_COUNT, fexec, freg, fvalid);
645 fflush(STAT_FP);
646 }
647 else {
648 fprintf(STAT_FP, ": ignore (input count overflow)\n");
649 }
650
651 EXEC_COUNT_INTERVAL = 0;
652 }
653 else if (EXEC_COUNT == 1) {
654 output_current_time(stdout);
655 fprintf(stdout, ": ------------ START ------------\n");
656 }
657 #endif
658 #endif
659
660 return r;
661 }
662
663 #ifdef STANDALONE
664
665 #define MAX_INPUT_DATA_SIZE 4194304
666
main(int argc,char * argv[])667 extern int main(int argc, char* argv[])
668 {
669 size_t max_size;
670 size_t n;
671 uint8_t Data[MAX_INPUT_DATA_SIZE];
672
673 if (argc > 1) {
674 max_size = (size_t )atoi(argv[1]);
675 }
676 else {
677 max_size = sizeof(Data);
678 }
679
680 n = read(0, Data, max_size);
681 fprintf(stdout, "read size: %ld, max_size: %ld\n", n, max_size);
682
683 LLVMFuzzerTestOneInput(Data, n);
684 return 0;
685 }
686 #endif /* STANDALONE */
687