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
*
@@ -364,6 +371,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
364
371
const lit_utf8_byte_t * str_p , /**< input string pointer */
365
372
const lit_utf8_byte_t * * out_str_p ) /**< [out] matching substring iterator */
366
373
{
374
+ REGEXP_RECURSION_COUNTER_DECREASE_AND_TEST ();
367
375
const lit_utf8_byte_t * str_curr_p = str_p ;
368
376
369
377
while (true)
@@ -376,12 +384,14 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
376
384
{
377
385
JERRY_TRACE_MSG ("Execute RE_OP_MATCH: match\n" );
378
386
* out_str_p = str_curr_p ;
387
+ REGEXP_RECURSION_COUNTER_INCREASE ();
379
388
return ECMA_VALUE_TRUE ; /* match */
380
389
}
381
390
case RE_OP_CHAR :
382
391
{
383
392
if (str_curr_p >= re_ctx_p -> input_end_p )
384
393
{
394
+ REGEXP_RECURSION_COUNTER_INCREASE ();
385
395
return ECMA_VALUE_FALSE ; /* fail */
386
396
}
387
397
@@ -393,6 +403,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
393
403
if (ch1 != ch2 )
394
404
{
395
405
JERRY_TRACE_MSG ("fail\n" );
406
+ REGEXP_RECURSION_COUNTER_INCREASE ();
396
407
return ECMA_VALUE_FALSE ; /* fail */
397
408
}
398
409
@@ -404,6 +415,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
404
415
{
405
416
if (str_curr_p >= re_ctx_p -> input_end_p )
406
417
{
418
+ REGEXP_RECURSION_COUNTER_INCREASE ();
407
419
return ECMA_VALUE_FALSE ; /* fail */
408
420
}
409
421
@@ -413,6 +425,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
413
425
if (lit_char_is_line_terminator (ch ))
414
426
{
415
427
JERRY_TRACE_MSG ("fail\n" );
428
+ REGEXP_RECURSION_COUNTER_INCREASE ();
416
429
return ECMA_VALUE_FALSE ; /* fail */
417
430
}
418
431
@@ -432,6 +445,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
432
445
if (!(re_ctx_p -> flags & RE_FLAG_MULTILINE ))
433
446
{
434
447
JERRY_TRACE_MSG ("fail\n" );
448
+ REGEXP_RECURSION_COUNTER_INCREASE ();
435
449
return ECMA_VALUE_FALSE ; /* fail */
436
450
}
437
451
@@ -442,6 +456,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
442
456
}
443
457
444
458
JERRY_TRACE_MSG ("fail\n" );
459
+ REGEXP_RECURSION_COUNTER_INCREASE ();
445
460
return ECMA_VALUE_FALSE ; /* fail */
446
461
}
447
462
case RE_OP_ASSERT_END :
@@ -457,6 +472,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
457
472
if (!(re_ctx_p -> flags & RE_FLAG_MULTILINE ))
458
473
{
459
474
JERRY_TRACE_MSG ("fail\n" );
475
+ REGEXP_RECURSION_COUNTER_INCREASE ();
460
476
return ECMA_VALUE_FALSE ; /* fail */
461
477
}
462
478
@@ -467,6 +483,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
467
483
}
468
484
469
485
JERRY_TRACE_MSG ("fail\n" );
486
+ REGEXP_RECURSION_COUNTER_INCREASE ();
470
487
return ECMA_VALUE_FALSE ; /* fail */
471
488
}
472
489
case RE_OP_ASSERT_WORD_BOUNDARY :
@@ -498,6 +515,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
498
515
if (is_wordchar_left == is_wordchar_right )
499
516
{
500
517
JERRY_TRACE_MSG ("fail\n" );
518
+ REGEXP_RECURSION_COUNTER_INCREASE ();
501
519
return ECMA_VALUE_FALSE ; /* fail */
502
520
}
503
521
}
@@ -509,6 +527,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
509
527
if (is_wordchar_left != is_wordchar_right )
510
528
{
511
529
JERRY_TRACE_MSG ("fail\n" );
530
+ REGEXP_RECURSION_COUNTER_INCREASE ();
512
531
return ECMA_VALUE_FALSE ; /* fail */
513
532
}
514
533
}
@@ -563,6 +582,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
563
582
564
583
if (!ECMA_IS_VALUE_ERROR (match_value ))
565
584
{
585
+ REGEXP_RECURSION_COUNTER_INCREASE ();
566
586
if (ecma_is_value_true (match_value ))
567
587
{
568
588
* out_str_p = sub_str_p ;
@@ -588,6 +608,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
588
608
if (str_curr_p >= re_ctx_p -> input_end_p )
589
609
{
590
610
JERRY_TRACE_MSG ("fail\n" );
611
+ REGEXP_RECURSION_COUNTER_INCREASE ();
591
612
return ECMA_VALUE_FALSE ; /* fail */
592
613
}
593
614
@@ -618,6 +639,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
618
639
if (!is_match )
619
640
{
620
641
JERRY_TRACE_MSG ("fail\n" );
642
+ REGEXP_RECURSION_COUNTER_INCREASE ();
621
643
return ECMA_VALUE_FALSE ; /* fail */
622
644
}
623
645
}
@@ -627,6 +649,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
627
649
if (is_match )
628
650
{
629
651
JERRY_TRACE_MSG ("fail\n" );
652
+ REGEXP_RECURSION_COUNTER_INCREASE ();
630
653
return ECMA_VALUE_FALSE ; /* fail */
631
654
}
632
655
}
@@ -657,6 +680,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
657
680
if (str_curr_p >= re_ctx_p -> input_end_p )
658
681
{
659
682
JERRY_TRACE_MSG ("fail\n" );
683
+ REGEXP_RECURSION_COUNTER_INCREASE ();
660
684
return ECMA_VALUE_FALSE ; /* fail */
661
685
}
662
686
@@ -666,6 +690,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
666
690
if (ch1 != ch2 )
667
691
{
668
692
JERRY_TRACE_MSG ("fail\n" );
693
+ REGEXP_RECURSION_COUNTER_INCREASE ();
669
694
return ECMA_VALUE_FALSE ; /* fail */
670
695
}
671
696
}
@@ -689,6 +714,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
689
714
if (ecma_is_value_true (match_value ))
690
715
{
691
716
* out_str_p = sub_str_p ;
717
+ REGEXP_RECURSION_COUNTER_INCREASE ();
692
718
return match_value ; /* match */
693
719
}
694
720
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -703,13 +729,15 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
703
729
bc_p = old_bc_p ;
704
730
705
731
re_ctx_p -> saved_p [RE_GLOBAL_START_IDX ] = old_start_p ;
732
+ REGEXP_RECURSION_COUNTER_INCREASE ();
706
733
return ECMA_VALUE_FALSE ; /* fail */
707
734
}
708
735
case RE_OP_SAVE_AND_MATCH :
709
736
{
710
737
JERRY_TRACE_MSG ("End of pattern is reached: match\n" );
711
738
re_ctx_p -> saved_p [RE_GLOBAL_END_IDX ] = str_curr_p ;
712
739
* out_str_p = str_curr_p ;
740
+ REGEXP_RECURSION_COUNTER_INCREASE ();
713
741
return ECMA_VALUE_TRUE ; /* match */
714
742
}
715
743
case RE_OP_ALTERNATIVE :
@@ -774,6 +802,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
774
802
if (ecma_is_value_true (match_value ))
775
803
{
776
804
* out_str_p = sub_str_p ;
805
+ REGEXP_RECURSION_COUNTER_INCREASE ();
777
806
return match_value ; /* match */
778
807
}
779
808
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -832,6 +861,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
832
861
if (ecma_is_value_true (match_value ))
833
862
{
834
863
* out_str_p = sub_str_p ;
864
+ REGEXP_RECURSION_COUNTER_INCREASE ();
835
865
return match_value ; /* match */
836
866
}
837
867
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -856,6 +886,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
856
886
if (ecma_is_value_true (match_value ))
857
887
{
858
888
* out_str_p = sub_str_p ;
889
+ REGEXP_RECURSION_COUNTER_INCREASE ();
859
890
return match_value ; /* match */
860
891
}
861
892
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -865,6 +896,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
865
896
}
866
897
867
898
re_ctx_p -> saved_p [start_idx ] = old_start_p ;
899
+ REGEXP_RECURSION_COUNTER_INCREASE ();
868
900
return ECMA_VALUE_FALSE ; /* fail */
869
901
}
870
902
case RE_OP_CAPTURE_NON_GREEDY_GROUP_END :
@@ -910,6 +942,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
910
942
if (ecma_is_value_true (match_value ))
911
943
{
912
944
* out_str_p = sub_str_p ;
945
+ REGEXP_RECURSION_COUNTER_INCREASE ();
913
946
return match_value ; /* match */
914
947
}
915
948
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -958,6 +991,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
958
991
if (re_ctx_p -> num_of_iterations_p [iter_idx ] >= min
959
992
&& str_curr_p == re_ctx_p -> saved_p [start_idx ])
960
993
{
994
+ REGEXP_RECURSION_COUNTER_INCREASE ();
961
995
return ECMA_VALUE_FALSE ; /* fail */
962
996
}
963
997
@@ -979,6 +1013,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
979
1013
if (ecma_is_value_true (match_value ))
980
1014
{
981
1015
* out_str_p = sub_str_p ;
1016
+ REGEXP_RECURSION_COUNTER_INCREASE ();
982
1017
return match_value ; /* match */
983
1018
}
984
1019
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1003,6 +1038,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1003
1038
if (ecma_is_value_true (match_value ))
1004
1039
{
1005
1040
* out_str_p = sub_str_p ;
1041
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1006
1042
return match_value ; /* match */
1007
1043
}
1008
1044
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1024,6 +1060,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1024
1060
if (ecma_is_value_true (match_value ))
1025
1061
{
1026
1062
* out_str_p = sub_str_p ;
1063
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1027
1064
return match_value ; /* match */
1028
1065
}
1029
1066
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1035,6 +1072,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1035
1072
/* restore if fails */
1036
1073
re_ctx_p -> saved_p [end_idx ] = old_end_p ;
1037
1074
re_ctx_p -> num_of_iterations_p [iter_idx ]-- ;
1075
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1038
1076
return ECMA_VALUE_FALSE ; /* fail */
1039
1077
}
1040
1078
case RE_OP_NON_GREEDY_ITERATOR :
@@ -1059,6 +1097,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1059
1097
if (ecma_is_value_true (match_value ))
1060
1098
{
1061
1099
* out_str_p = sub_str_p ;
1100
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1062
1101
return match_value ; /* match */
1063
1102
}
1064
1103
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1082,6 +1121,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1082
1121
str_curr_p = sub_str_p ;
1083
1122
num_of_iter ++ ;
1084
1123
}
1124
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1085
1125
return ECMA_VALUE_FALSE ; /* fail */
1086
1126
}
1087
1127
default :
@@ -1125,6 +1165,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1125
1165
if (ecma_is_value_true (match_value ))
1126
1166
{
1127
1167
* out_str_p = sub_str_p ;
1168
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1128
1169
return match_value ; /* match */
1129
1170
}
1130
1171
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1140,6 +1181,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1140
1181
lit_utf8_read_prev (& str_curr_p );
1141
1182
num_of_iter -- ;
1142
1183
}
1184
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1143
1185
return ECMA_VALUE_FALSE ; /* fail */
1144
1186
}
1145
1187
}
@@ -1232,6 +1274,7 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
1232
1274
re_ctx .input_start_p = input_curr_p ;
1233
1275
const lit_utf8_byte_t * input_end_p = re_ctx .input_start_p + input_buffer_size ;
1234
1276
re_ctx .input_end_p = input_end_p ;
1277
+ REGEXP_RECURSION_COUNTER_INIT ();
1235
1278
1236
1279
/* 1. Read bytecode header and init regexp matcher context. */
1237
1280
re_ctx .flags = bc_p -> header .status_flags ;
0 commit comments