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
*
@@ -347,6 +354,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
347
354
const lit_utf8_byte_t * str_p , /**< input string pointer */
348
355
const lit_utf8_byte_t * * out_str_p ) /**< [out] matching substring iterator */
349
356
{
357
+ REGEXP_RECURSION_COUNTER_DECREASE_AND_TEST ();
350
358
const lit_utf8_byte_t * str_curr_p = str_p ;
351
359
352
360
while (true)
@@ -359,12 +367,14 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
359
367
{
360
368
JERRY_TRACE_MSG ("Execute RE_OP_MATCH: match\n" );
361
369
* out_str_p = str_curr_p ;
370
+ REGEXP_RECURSION_COUNTER_INCREASE ();
362
371
return ECMA_VALUE_TRUE ; /* match */
363
372
}
364
373
case RE_OP_CHAR :
365
374
{
366
375
if (str_curr_p >= re_ctx_p -> input_end_p )
367
376
{
377
+ REGEXP_RECURSION_COUNTER_INCREASE ();
368
378
return ECMA_VALUE_FALSE ; /* fail */
369
379
}
370
380
@@ -376,6 +386,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
376
386
if (ch1 != ch2 )
377
387
{
378
388
JERRY_TRACE_MSG ("fail\n" );
389
+ REGEXP_RECURSION_COUNTER_INCREASE ();
379
390
return ECMA_VALUE_FALSE ; /* fail */
380
391
}
381
392
@@ -387,6 +398,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
387
398
{
388
399
if (str_curr_p >= re_ctx_p -> input_end_p )
389
400
{
401
+ REGEXP_RECURSION_COUNTER_INCREASE ();
390
402
return ECMA_VALUE_FALSE ; /* fail */
391
403
}
392
404
@@ -396,6 +408,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
396
408
if (lit_char_is_line_terminator (ch ))
397
409
{
398
410
JERRY_TRACE_MSG ("fail\n" );
411
+ REGEXP_RECURSION_COUNTER_INCREASE ();
399
412
return ECMA_VALUE_FALSE ; /* fail */
400
413
}
401
414
@@ -415,6 +428,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
415
428
if (!(re_ctx_p -> flags & RE_FLAG_MULTILINE ))
416
429
{
417
430
JERRY_TRACE_MSG ("fail\n" );
431
+ REGEXP_RECURSION_COUNTER_INCREASE ();
418
432
return ECMA_VALUE_FALSE ; /* fail */
419
433
}
420
434
@@ -425,6 +439,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
425
439
}
426
440
427
441
JERRY_TRACE_MSG ("fail\n" );
442
+ REGEXP_RECURSION_COUNTER_INCREASE ();
428
443
return ECMA_VALUE_FALSE ; /* fail */
429
444
}
430
445
case RE_OP_ASSERT_END :
@@ -440,6 +455,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
440
455
if (!(re_ctx_p -> flags & RE_FLAG_MULTILINE ))
441
456
{
442
457
JERRY_TRACE_MSG ("fail\n" );
458
+ REGEXP_RECURSION_COUNTER_INCREASE ();
443
459
return ECMA_VALUE_FALSE ; /* fail */
444
460
}
445
461
@@ -450,6 +466,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
450
466
}
451
467
452
468
JERRY_TRACE_MSG ("fail\n" );
469
+ REGEXP_RECURSION_COUNTER_INCREASE ();
453
470
return ECMA_VALUE_FALSE ; /* fail */
454
471
}
455
472
case RE_OP_ASSERT_WORD_BOUNDARY :
@@ -481,6 +498,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
481
498
if (is_wordchar_left == is_wordchar_right )
482
499
{
483
500
JERRY_TRACE_MSG ("fail\n" );
501
+ REGEXP_RECURSION_COUNTER_INCREASE ();
484
502
return ECMA_VALUE_FALSE ; /* fail */
485
503
}
486
504
}
@@ -492,6 +510,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
492
510
if (is_wordchar_left != is_wordchar_right )
493
511
{
494
512
JERRY_TRACE_MSG ("fail\n" );
513
+ REGEXP_RECURSION_COUNTER_INCREASE ();
495
514
return ECMA_VALUE_FALSE ; /* fail */
496
515
}
497
516
}
@@ -546,6 +565,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
546
565
547
566
if (!ECMA_IS_VALUE_ERROR (match_value ))
548
567
{
568
+ REGEXP_RECURSION_COUNTER_INCREASE ();
549
569
if (ecma_is_value_true (match_value ))
550
570
{
551
571
* out_str_p = sub_str_p ;
@@ -571,6 +591,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
571
591
if (str_curr_p >= re_ctx_p -> input_end_p )
572
592
{
573
593
JERRY_TRACE_MSG ("fail\n" );
594
+ REGEXP_RECURSION_COUNTER_INCREASE ();
574
595
return ECMA_VALUE_FALSE ; /* fail */
575
596
}
576
597
@@ -601,6 +622,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
601
622
if (!is_match )
602
623
{
603
624
JERRY_TRACE_MSG ("fail\n" );
625
+ REGEXP_RECURSION_COUNTER_INCREASE ();
604
626
return ECMA_VALUE_FALSE ; /* fail */
605
627
}
606
628
}
@@ -610,6 +632,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
610
632
if (is_match )
611
633
{
612
634
JERRY_TRACE_MSG ("fail\n" );
635
+ REGEXP_RECURSION_COUNTER_INCREASE ();
613
636
return ECMA_VALUE_FALSE ; /* fail */
614
637
}
615
638
}
@@ -640,6 +663,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
640
663
if (str_curr_p >= re_ctx_p -> input_end_p )
641
664
{
642
665
JERRY_TRACE_MSG ("fail\n" );
666
+ REGEXP_RECURSION_COUNTER_INCREASE ();
643
667
return ECMA_VALUE_FALSE ; /* fail */
644
668
}
645
669
@@ -649,6 +673,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
649
673
if (ch1 != ch2 )
650
674
{
651
675
JERRY_TRACE_MSG ("fail\n" );
676
+ REGEXP_RECURSION_COUNTER_INCREASE ();
652
677
return ECMA_VALUE_FALSE ; /* fail */
653
678
}
654
679
}
@@ -672,6 +697,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
672
697
if (ecma_is_value_true (match_value ))
673
698
{
674
699
* out_str_p = sub_str_p ;
700
+ REGEXP_RECURSION_COUNTER_INCREASE ();
675
701
return match_value ; /* match */
676
702
}
677
703
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -686,13 +712,15 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
686
712
bc_p = old_bc_p ;
687
713
688
714
re_ctx_p -> saved_p [RE_GLOBAL_START_IDX ] = old_start_p ;
715
+ REGEXP_RECURSION_COUNTER_INCREASE ();
689
716
return ECMA_VALUE_FALSE ; /* fail */
690
717
}
691
718
case RE_OP_SAVE_AND_MATCH :
692
719
{
693
720
JERRY_TRACE_MSG ("End of pattern is reached: match\n" );
694
721
re_ctx_p -> saved_p [RE_GLOBAL_END_IDX ] = str_curr_p ;
695
722
* out_str_p = str_curr_p ;
723
+ REGEXP_RECURSION_COUNTER_INCREASE ();
696
724
return ECMA_VALUE_TRUE ; /* match */
697
725
}
698
726
case RE_OP_ALTERNATIVE :
@@ -757,6 +785,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
757
785
if (ecma_is_value_true (match_value ))
758
786
{
759
787
* out_str_p = sub_str_p ;
788
+ REGEXP_RECURSION_COUNTER_INCREASE ();
760
789
return match_value ; /* match */
761
790
}
762
791
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -815,6 +844,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
815
844
if (ecma_is_value_true (match_value ))
816
845
{
817
846
* out_str_p = sub_str_p ;
847
+ REGEXP_RECURSION_COUNTER_INCREASE ();
818
848
return match_value ; /* match */
819
849
}
820
850
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -839,6 +869,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
839
869
if (ecma_is_value_true (match_value ))
840
870
{
841
871
* out_str_p = sub_str_p ;
872
+ REGEXP_RECURSION_COUNTER_INCREASE ();
842
873
return match_value ; /* match */
843
874
}
844
875
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -848,6 +879,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
848
879
}
849
880
850
881
re_ctx_p -> saved_p [start_idx ] = old_start_p ;
882
+ REGEXP_RECURSION_COUNTER_INCREASE ();
851
883
return ECMA_VALUE_FALSE ; /* fail */
852
884
}
853
885
case RE_OP_CAPTURE_NON_GREEDY_GROUP_END :
@@ -893,6 +925,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
893
925
if (ecma_is_value_true (match_value ))
894
926
{
895
927
* out_str_p = sub_str_p ;
928
+ REGEXP_RECURSION_COUNTER_INCREASE ();
896
929
return match_value ; /* match */
897
930
}
898
931
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -941,6 +974,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
941
974
if (re_ctx_p -> num_of_iterations_p [iter_idx ] >= min
942
975
&& str_curr_p == re_ctx_p -> saved_p [start_idx ])
943
976
{
977
+ REGEXP_RECURSION_COUNTER_INCREASE ();
944
978
return ECMA_VALUE_FALSE ; /* fail */
945
979
}
946
980
@@ -962,6 +996,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
962
996
if (ecma_is_value_true (match_value ))
963
997
{
964
998
* out_str_p = sub_str_p ;
999
+ REGEXP_RECURSION_COUNTER_INCREASE ();
965
1000
return match_value ; /* match */
966
1001
}
967
1002
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -986,6 +1021,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
986
1021
if (ecma_is_value_true (match_value ))
987
1022
{
988
1023
* out_str_p = sub_str_p ;
1024
+ REGEXP_RECURSION_COUNTER_INCREASE ();
989
1025
return match_value ; /* match */
990
1026
}
991
1027
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1007,6 +1043,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1007
1043
if (ecma_is_value_true (match_value ))
1008
1044
{
1009
1045
* out_str_p = sub_str_p ;
1046
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1010
1047
return match_value ; /* match */
1011
1048
}
1012
1049
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1018,6 +1055,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1018
1055
/* restore if fails */
1019
1056
re_ctx_p -> saved_p [end_idx ] = old_end_p ;
1020
1057
re_ctx_p -> num_of_iterations_p [iter_idx ]-- ;
1058
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1021
1059
return ECMA_VALUE_FALSE ; /* fail */
1022
1060
}
1023
1061
case RE_OP_NON_GREEDY_ITERATOR :
@@ -1042,6 +1080,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1042
1080
if (ecma_is_value_true (match_value ))
1043
1081
{
1044
1082
* out_str_p = sub_str_p ;
1083
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1045
1084
return match_value ; /* match */
1046
1085
}
1047
1086
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1065,6 +1104,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1065
1104
str_curr_p = sub_str_p ;
1066
1105
num_of_iter ++ ;
1067
1106
}
1107
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1068
1108
return ECMA_VALUE_FALSE ; /* fail */
1069
1109
}
1070
1110
default :
@@ -1108,6 +1148,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1108
1148
if (ecma_is_value_true (match_value ))
1109
1149
{
1110
1150
* out_str_p = sub_str_p ;
1151
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1111
1152
return match_value ; /* match */
1112
1153
}
1113
1154
else if (ECMA_IS_VALUE_ERROR (match_value ))
@@ -1123,6 +1164,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
1123
1164
lit_utf8_read_prev (& str_curr_p );
1124
1165
num_of_iter -- ;
1125
1166
}
1167
+ REGEXP_RECURSION_COUNTER_INCREASE ();
1126
1168
return ECMA_VALUE_FALSE ; /* fail */
1127
1169
}
1128
1170
}
@@ -1211,6 +1253,7 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
1211
1253
re_ctx .input_start_p = input_curr_p ;
1212
1254
const lit_utf8_byte_t * input_end_p = re_ctx .input_start_p + input_buffer_size ;
1213
1255
re_ctx .input_end_p = input_end_p ;
1256
+ REGEXP_RECURSION_COUNTER_INIT ();
1214
1257
1215
1258
/* 1. Read bytecode header and init regexp matcher context. */
1216
1259
re_ctx .flags = bc_p -> header .status_flags ;
0 commit comments