A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/Perl/perl5/commit/ba6840fbf2fdde3e7f1bda1a26f46c901f36d5ec below:

fix Perl #126182, out of memory due to infinite pattern recursion · Perl/perl5@ba6840f · GitHub

@@ -3126,6 +3126,9 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,

3126 3126

));

3127 3127

}

3128 3128 3129 +

if (prog->recurse_locinput)

3130 +

Zero(prog->recurse_locinput,prog->nparens + 1, char *);

3131 + 3129 3132

/* Simplest case: anchored match need be tried only once, or with

3130 3133

* MBOL, only at the beginning of each line.

3131 3134

*

@@ -5184,7 +5187,6 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)

5184 5187

bool is_utf8_pat = reginfo->is_utf8_pat;

5185 5188

bool match = FALSE;

5186 5189 5187 - 5188 5190

#ifdef DEBUGGING

5189 5191

GET_RE_DEBUG_FLAGS_DECL;

5190 5192

#endif

@@ -6494,11 +6496,11 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)

6494 6496

regexp *re;

6495 6497

regexp_internal *rei;

6496 6498

regnode *startpoint;

6499 +

U32 arg;

6497 6500 6498 6501

case GOSUB: /* /(...(?1))/ /(...(?&foo))/ */

6499 -

if (cur_eval && cur_eval->locinput==locinput) {

6500 -

if ( EVAL_CLOSE_PAREN_IS( cur_eval, (U32)ARG(scan) ) )

6501 -

Perl_croak(aTHX_ "Infinite recursion in regex");

6502 +

arg= (U32)ARG(scan);

6503 +

if (cur_eval && cur_eval->locinput == locinput) {

6502 6504

if ( ++nochange_depth > max_nochange_depth )

6503 6505

Perl_croak(aTHX_

6504 6506

"Pattern subroutine nesting without pos change"

@@ -6510,7 +6512,32 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)

6510 6512

re = rex;

6511 6513

rei = rexi;

6512 6514

startpoint = scan + ARG2L(scan);

6513 -

EVAL_CLOSE_PAREN_SET( st, ARG(scan) ); /* ST.close_paren = 1 + ARG(scan) */

6515 +

EVAL_CLOSE_PAREN_SET( st, arg ); /* ST.close_paren = 1 + ARG(scan) */

6516 +

/* Detect infinite recursion

6517 +

*

6518 +

* A pattern like /(?R)foo/ or /(?<x>(?&y)foo)(?<y>(?&x)bar)/

6519 +

* or "a"=~/(.(?2))((?<=(?=(?1)).))/ could recurse forever.

6520 +

* So we track the position in the string we are at each time

6521 +

* we recurse and if we try to enter the same routine twice from

6522 +

* the same position we fail. This means that a pattern like

6523 +

* "aaabbb"=~/a(?R)?b/ works as expected and does not throw an

6524 +

* error.

6525 +

*/

6526 +

if ( rex->recurse_locinput[arg] == locinput ) {

6527 +

DEBUG_r({

6528 +

GET_RE_DEBUG_FLAGS_DECL;

6529 +

DEBUG_EXECUTE_r({

6530 +

PerlIO_printf(Perl_debug_log,

6531 +

"%*s pattern left-recursion without consuming input always fails...\n",

6532 +

REPORT_CODE_OFF + depth*2, "");

6533 +

});

6534 +

});

6535 +

/* this would be infinite recursion, so we fail */

6536 +

sayNO;

6537 +

} else {

6538 +

ST.prev_recurse_locinput= rex->recurse_locinput[arg];

6539 +

rex->recurse_locinput[arg]= locinput;

6540 +

}

6514 6541 6515 6542

/* Save all the positions seen so far. */

6516 6543

ST.cp = regcppush(rex, 0, maxopenparen);

@@ -6547,10 +6574,9 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)

6547 6574

n = ARG(scan);

6548 6575 6549 6576

if (rexi->data->what[n] == 'r') { /* code from an external qr */

6550 -

newcv = (ReANY(

6551 -

(REGEXP*)(rexi->data->data[n])

6552 -

))->qr_anoncv

6553 -

;

6577 +

newcv = (ReANY(

6578 +

(REGEXP*)(rexi->data->data[n])

6579 +

))->qr_anoncv;

6554 6580

nop = (OP*)rexi->data->data[n+1];

6555 6581

}

6556 6582

else if (rexi->data->what[n] == 'l') { /* literal code */

@@ -6771,6 +6797,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)

6771 6797

startpoint = rei->program + 1;

6772 6798

EVAL_CLOSE_PAREN_CLEAR(st); /* ST.close_paren = 0;

6773 6799

* close_paren only for GOSUB */

6800 +

ST.prev_recurse_locinput= NULL; /* only used for GOSUB */

6774 6801

/* Save all the seen positions so far. */

6775 6802

ST.cp = regcppush(rex, 0, maxopenparen);

6776 6803

REGCP_SET(ST.lastcp);

@@ -6812,6 +6839,9 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)

6812 6839 6813 6840

case EVAL_AB: /* cleanup after a successful (??{A})B */

6814 6841

/* note: this is called twice; first after popping B, then A */

6842 +

if ( cur_eval && cur_eval->u.eval.close_paren )

6843 +

rex->recurse_locinput[cur_eval->u.eval.close_paren - 1] = cur_eval->u.eval.prev_recurse_locinput;

6844 + 6815 6845

rex_sv = ST.prev_rex;

6816 6846

is_utf8_pat = reginfo->is_utf8_pat = cBOOL(RX_UTF8(rex_sv));

6817 6847

SET_reg_curpm(rex_sv);

@@ -6837,6 +6867,9 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)

6837 6867 6838 6868

case EVAL_AB_fail: /* unsuccessfully ran A or B in (??{A})B */

6839 6869

/* note: this is called twice; first after popping B, then A */

6870 +

if ( cur_eval && cur_eval->u.eval.close_paren )

6871 +

rex->recurse_locinput[cur_eval->u.eval.close_paren - 1] = cur_eval->u.eval.prev_recurse_locinput;

6872 + 6840 6873

rex_sv = ST.prev_rex;

6841 6874

is_utf8_pat = reginfo->is_utf8_pat = cBOOL(RX_UTF8(rex_sv));

6842 6875

SET_reg_curpm(rex_sv);

@@ -7905,6 +7938,8 @@ NULL

7905 7938

fake_end:

7906 7939

if (cur_eval) {

7907 7940

/* we've just finished A in /(??{A})B/; now continue with B */

7941 +

if ( cur_eval->u.eval.close_paren )

7942 +

rex->recurse_locinput[cur_eval->u.eval.close_paren - 1] = cur_eval->u.eval.prev_recurse_locinput;

7908 7943 7909 7944

st->u.eval.prev_rex = rex_sv; /* inner */

7910 7945

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4