63
63
*/
64
64
#define RE_IS_CAPTURE_GROUP (x ) (((x) < RE_OP_NON_CAPTURE_GROUP_START) ? 1 : 0)
65
65
66
+ /*
67
+ * Check RegExp recursion depth limit
68
+ */
69
+ #ifdef REGEXP_RECURSION_LIMIT
70
+ JERRY_STATIC_ASSERT (REGEXP_RECURSION_LIMIT > 0 , regexp_recursion_limit_must_be_greater_than_zero );
71
+ #endif /* REGEXP_RECURSION_LIMIT */
72
+
66
73
/**
67
74
* Parse RegExp flags (global, ignoreCase, multiline)
68
75
*
@@ -344,6 +351,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
344
351
const lit_utf8_byte_t * str_p , /**< input string pointer */
345
352
const lit_utf8_byte_t * * out_str_p ) /**< [out] matching substring iterator */
346
353
{
354
+ REGEXP_RECURSION_COUNTER_DECREASE_AND_TEST ();
347
355
const lit_utf8_byte_t * str_curr_p = str_p ;
348
356
349
357
while (true)
@@ -356,12 +364,14 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
356
364
{
357
365
JERRY_TRACE_MSG ("Execute RE_OP_MATCH: match\n" );
358
366
* out_str_p = str_curr_p ;
367
+ REGEXP_RECURSION_COUNTER_INCREASE ();
359
368
return ECMA_VALUE_TRUE ; /* match */
360
369
}
361
370
case RE_OP_CHAR :
362
371
{
363
372
if (str_curr_p >= re_ctx_p -> input_end_p )
364
373
{
374
+ REGEXP_RECURSION_COUNTER_INCREASE ();
365
375
return ECMA_VALUE_FALSE ; /* fail */
366
376
}
367
377
@@ -373,6 +383,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
373
383
if (ch1 != ch2 )
374
384
{
375
385
JERRY_TRACE_MSG ("fail\n" );
386
+ REGEXP_RECURSION_COUNTER_INCREASE ();
376
387
return ECMA_VALUE_FALSE ; /* fail */
377
388
}
378
389
@@ -384,6 +395,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
384
395
{
385
396
if (str_curr_p >= re_ctx_p -> input_end_p )
386
397
{
398
+ REGEXP_RECURSION_COUNTER_INCREASE ();
387
399
return ECMA_VALUE_FALSE ; /* fail */
388
400
}
389
401
@@ -393,6 +405,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
393
405
if (lit_char_is_line_terminator (ch ))
394
406
{
395
407
JERRY_TRACE_MSG ("fail\n" );
408
+ REGEXP_RECURSION_COUNTER_INCREASE ();
396
409
return ECMA_VALUE_FALSE ; /* fail */
397
410
}
398
411
@@ -412,6 +425,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
412
425
if (!(re_ctx_p -> flags & RE_FLAG_MULTILINE ))
413
426
{
414
427
JERRY_TRACE_MSG ("fail\n" );
428
+ REGEXP_RECURSION_COUNTER_INCREASE ();
415
429
return ECMA_VALUE_FALSE ; /* fail */
416
430
}
417
431
@@ -422,6 +436,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
422
436
}
423
437
424
438
JERRY_TRACE_MSG ("fail\n" );
439
+ REGEXP_RECURSION_COUNTER_INCREASE ();
425
440
return ECMA_VALUE_FALSE ; /* fail */
426
441
}
427
442
case RE_OP_ASSERT_END :
@@ -437,6 +452,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
437
452
if (!(re_ctx_p -> flags & RE_FLAG_MULTILINE ))
438
453
{
439
454
JERRY_TRACE_MSG ("fail\n" );
455
+ REGEXP_RECURSION_COUNTER_INCREASE ();
440
456
return ECMA_VALUE_FALSE ; /* fail */
441
457
}
442
458
@@ -447,6 +463,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
447
463
}
448
464
449
465
JERRY_TRACE_MSG ("fail\n" );
466
+ REGEXP_RECURSION_COUNTER_INCREASE ();
450
467
return ECMA_VALUE_FALSE ; /* fail */
451
468
}
452
469
case RE_OP_ASSERT_WORD_BOUNDARY :
@@ -478,6 +495,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
478
495
if (is_wordchar_left == is_wordchar_right )
479
496
{
480
497
JERRY_TRACE_MSG ("fail\n" );
498
+ REGEXP_RECURSION_COUNTER_INCREASE ();
481
499
return ECMA_VALUE_FALSE ; /* fail */
482
500
}
483
501
}
@@ -489,6 +507,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
489
507
if (is_wordchar_left != is_wordchar_right )
490
508
{
491
509
JERRY_TRACE_MSG ("fail\n" );
510
+ REGEXP_RECURSION_COUNTER_INCREASE ();
492
511
return ECMA_VALUE_FALSE ; /* fail */
493
512
}
494
513
}
@@ -556,6 +575,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
556
575
}
557
576
558
577
JMEM_FINALIZE_LOCAL_ARRAY (saved_bck_p );
578
+ REGEXP_RECURSION_COUNTER_INCREASE ();
559
579
return match_value ;
560
580
}
561
581
case RE_OP_CHAR_CLASS :
@@ -568,6 +588,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
568
588
if (str_curr_p >= re_ctx_p -> input_end_p )
569
589
{
570
590
JERRY_TRACE_MSG ("fail\n" );
591
+ REGEXP_RECURSION_COUNTER_INCREASE ();
571
592
return ECMA_VALUE_FALSE ; /* fail */
572
593
}
573
594
@@ -598,6 +619,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
598
619
if (!is_match )
599
620
{
600
621
JERRY_TRACE_MSG ("fail\n" );
622
+ REGEXP_RECURSION_COUNTER_INCREASE ();
601
623
return ECMA_VALUE_FALSE ; /* fail */
602
624
}
603
625
}
@@ -607,6 +629,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
607
629
if (is_match )
608
630
{
609
631
JERRY_TRACE_MSG ("fail\n" );
632
+ REGEXP_RECURSION_COUNTER_INCREASE ();
610
633
return ECMA_VALUE_FALSE ; /* fail */
611
634
}
612
635
}
@@ -637,6 +660,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
637
660
if (str_curr_p >= re_ctx_p -> input_end_p )
638
661
{
639
662
JERRY_TRACE_MSG ("fail\n" );
663
+ REGEXP_RECURSION_COUNTER_INCREASE ();
640
664
return ECMA_VALUE_FALSE ; /* fail */
641
665
}
642
666
@@ -646,6 +670,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
646
670
if (ch1 != ch2 )
647
671
{
648
672
JERRY_TRACE_MSG ("fail\n" );
673
+ REGEXP_RECURSION_COUNTER_INCREASE ();
649
674
return ECMA_VALUE_FALSE ; /* fail */
650
675
}
651
676
}
@@ -669,6 +694,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
669
694
if (ecma_is_value_true (match_value ))
670
695
{
671
696
* out_str_p = sub_str_p ;
697
+ REGEXP_RECURSION_COUNTER_INCREASE ();
672
698
return match_value ; /* match */
673
699
}
674
700
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -683,13 +709,15 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
683
709
bc_p = old_bc_p ;
684
710
685
711
re_ctx_p -> saved_p [RE_GLOBAL_START_IDX ] = old_start_p ;
712
+ REGEXP_RECURSION_COUNTER_INCREASE ();
686
713
return ECMA_VALUE_FALSE ; /* fail */
687
714
}
688
715
case RE_OP_SAVE_AND_MATCH :
689
716
{
690
717
JERRY_TRACE_MSG ("End of pattern is reached: match\n" );
691
718
re_ctx_p -> saved_p [RE_GLOBAL_END_IDX ] = str_curr_p ;
692
719
* out_str_p = str_curr_p ;
720
+ REGEXP_RECURSION_COUNTER_INCREASE ();
693
721
return ECMA_VALUE_TRUE ; /* match */
694
722
}
695
723
case RE_OP_ALTERNATIVE :
@@ -754,6 +782,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
754
782
if (ecma_is_value_true (match_value ))
755
783
{
756
784
* out_str_p = sub_str_p ;
785
+ REGEXP_RECURSION_COUNTER_INCREASE ();
757
786
return match_value ; /* match */
758
787
}
759
788
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -812,6 +841,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
812
841
if (ecma_is_value_true (match_value ))
813
842
{
814
843
* out_str_p = sub_str_p ;
844
+ REGEXP_RECURSION_COUNTER_INCREASE ();
815
845
return match_value ; /* match */
816
846
}
817
847
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -836,6 +866,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
836
866
if (ecma_is_value_true (match_value ))
837
867
{
838
868
* out_str_p = sub_str_p ;
869
+ REGEXP_RECURSION_COUNTER_INCREASE ();
839
870
return match_value ; /* match */
840
871
}
841
872
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -845,6 +876,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
845
876
}
846
877
847
878
re_ctx_p -> saved_p [start_idx ] = old_start_p ;
879
+ REGEXP_RECURSION_COUNTER_INCREASE ();
848
880
return ECMA_VALUE_FALSE ; /* fail */
849
881
}
850
882
case RE_OP_CAPTURE_NON_GREEDY_GROUP_END :
@@ -890,6 +922,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
890
922
if (ecma_is_value_true (match_value ))
891
923
{
892
924
* out_str_p = sub_str_p ;
925
+ REGEXP_RECURSION_COUNTER_INCREASE ();
893
926
return match_value ; /* match */
894
927
}
895
928
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -938,6 +971,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
938
971
if (re_ctx_p -> num_of_iterations_p [iter_idx ] >= min
939
972
&& str_curr_p == re_ctx_p -> saved_p [start_idx ])
940
973
{
974
+ REGEXP_RECURSION_COUNTER_INCREASE ();
941
975
return ECMA_VALUE_FALSE ; /* fail */
942
976
}
943
977
@@ -959,6 +993,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
959
993
if (ecma_is_value_true (match_value ))
960
994
{
961
995
* out_str_p = sub_str_p ;
996
+ REGEXP_RECURSION_COUNTER_INCREASE ();
962
997
return match_value ; /* match */
963
998
}
964
999
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -983,6 +1018,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
983
1018
if (ecma_is_value_true (match_value ))
984
1019
{
985
1020
* out_str_p = sub_str_p ;
1021
+ REGEXP_RECURSION_COUNTER_INCREASE ();
986
1022
return match_value ; /* match */
987
1023
}
988
1024
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1004,6 +1040,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1004
1040
if (ecma_is_value_true (match_value ))
1005
1041
{
1006
1042
* out_str_p = sub_str_p ;
1043
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1007
1044
return match_value ; /* match */
1008
1045
}
1009
1046
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1015,6 +1052,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1015
1052
/* restore if fails */
1016
1053
re_ctx_p -> saved_p [end_idx ] = old_end_p ;
1017
1054
re_ctx_p -> num_of_iterations_p [iter_idx ]-- ;
1055
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1018
1056
return ECMA_VALUE_FALSE ; /* fail */
1019
1057
}
1020
1058
case RE_OP_NON_GREEDY_ITERATOR :
@@ -1039,6 +1077,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1039
1077
if (ecma_is_value_true (match_value ))
1040
1078
{
1041
1079
* out_str_p = sub_str_p ;
1080
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1042
1081
return match_value ; /* match */
1043
1082
}
1044
1083
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1062,6 +1101,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1062
1101
str_curr_p = sub_str_p ;
1063
1102
num_of_iter ++ ;
1064
1103
}
1104
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1065
1105
return ECMA_VALUE_FALSE ; /* fail */
1066
1106
}
1067
1107
default :
@@ -1105,6 +1145,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1105
1145
if (ecma_is_value_true (match_value ))
1106
1146
{
1107
1147
* out_str_p = sub_str_p ;
1148
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1108
1149
return match_value ; /* match */
1109
1150
}
1110
1151
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1120,6 +1161,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1120
1161
lit_utf8_read_prev (& str_curr_p );
1121
1162
num_of_iter -- ;
1122
1163
}
1164
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1123
1165
return ECMA_VALUE_FALSE ; /* fail */
1124
1166
}
1125
1167
}
@@ -1208,6 +1250,7 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
1208
1250
re_ctx .input_start_p = input_curr_p ;
1209
1251
const lit_utf8_byte_t * input_end_p = re_ctx .input_start_p + input_buffer_size ;
1210
1252
re_ctx .input_end_p = input_end_p ;
1253
+ REGEXP_RECURSION_COUNTER_INIT ();
1211
1254
1212
1255
/* 1. Read bytecode header and init regexp matcher context. */
1213
1256
re_ctx .flags = bc_p -> header .status_flags ;
0 commit comments