Skip to content

Commit 4b196cd

Browse files
demerphqrgs
authored andcommitted
Re: Regexp recursion limit too low?
Message-ID: <9b18b3110702150822o13a4f240g86463c60e625fb8f@mail.gmail.com> p4raw-id: //depot/perl@30412
1 parent 7aa88b2 commit 4b196cd

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

regexec.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2640,7 +2640,11 @@ S_regmatch(pTHX_ regmatch_info *reginfo, regnode *prog)
26402640

26412641
bool result = 0; /* return value of S_regmatch */
26422642
int depth = 0; /* depth of backtrack stack */
2643-
int nochange_depth = 0; /* depth of GOSUB recursion with nochange*/
2643+
U32 nochange_depth = 0; /* depth of GOSUB recursion with nochange */
2644+
const U32 max_nochange_depth =
2645+
(3 * rex->nparens > MAX_RECURSE_EVAL_NOCHANGE_DEPTH) ?
2646+
3 * rex->nparens : MAX_RECURSE_EVAL_NOCHANGE_DEPTH;
2647+
26442648
regmatch_state *yes_state = NULL; /* state to pop to on success of
26452649
subpattern */
26462650
/* mark_state piggy backs on the yes_state logic so that when we unwind
@@ -3568,7 +3572,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, regnode *prog)
35683572
if (cur_eval && cur_eval->locinput==locinput) {
35693573
if (cur_eval->u.eval.close_paren == (U32)ARG(scan))
35703574
Perl_croak(aTHX_ "Infinite recursion in regex");
3571-
if ( ++nochange_depth > MAX_RECURSE_EVAL_NOCHANGE_DEPTH )
3575+
if ( ++nochange_depth > max_nochange_depth )
35723576
Perl_croak(aTHX_
35733577
"Pattern subroutine nesting without pos change"
35743578
" exceeded limit in regex");
@@ -3589,7 +3593,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, regnode *prog)
35893593
/* NOTREACHED */
35903594
case EVAL: /* /(?{A})B/ /(??{A})B/ and /(?(?{A})X|Y)B/ */
35913595
if (cur_eval && cur_eval->locinput==locinput) {
3592-
if ( ++nochange_depth > MAX_RECURSE_EVAL_NOCHANGE_DEPTH )
3596+
if ( ++nochange_depth > max_nochange_depth )
35933597
Perl_croak(aTHX_ "EVAL without pos change exceeded limit in regex");
35943598
} else {
35953599
nochange_depth = 0;
@@ -3738,6 +3742,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, regnode *prog)
37383742
cur_curlyx = ST.prev_curlyx;
37393743
/* XXXX This is too dramatic a measure... */
37403744
PL_reg_maxiter = 0;
3745+
if ( nochange_depth > 0 );
3746+
nochange_depth--;
37413747
sayYES;
37423748

37433749

@@ -3754,6 +3760,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, regnode *prog)
37543760
cur_curlyx = ST.prev_curlyx;
37553761
/* XXXX This is too dramatic a measure... */
37563762
PL_reg_maxiter = 0;
3763+
if ( nochange_depth > 0 );
3764+
nochange_depth--;
37573765
sayNO_SILENT;
37583766
#undef ST
37593767

@@ -4774,6 +4782,8 @@ NULL
47744782
DEBUG_EXECUTE_r(
47754783
PerlIO_printf(Perl_debug_log, "%*s EVAL trying tail ... %"UVxf"\n",
47764784
REPORT_CODE_OFF+depth*2, "",PTR2UV(cur_eval)););
4785+
if ( nochange_depth > 0 );
4786+
nochange_depth++;
47774787
PUSH_YES_STATE_GOTO(EVAL_AB,
47784788
st->u.eval.prev_eval->u.eval.B); /* match B */
47794789
}

regexp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ typedef struct {
300300
/* structures for holding and saving the state maintained by regmatch() */
301301

302302
#ifndef MAX_RECURSE_EVAL_NOCHANGE_DEPTH
303-
#define MAX_RECURSE_EVAL_NOCHANGE_DEPTH 50
303+
#define MAX_RECURSE_EVAL_NOCHANGE_DEPTH 1000
304304
#endif
305305

306306
typedef I32 CHECKPOINT;

0 commit comments

Comments
 (0)