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