Skip to content

Commit

Permalink
fix #128109 - do not move RExC_open_parens[0] in reginsert
Browse files Browse the repository at this point in the history
In d5a00e4 I merged GOSUB and GOSTART,
part of which involved making RExC_open_parens[0] refer to the start of
the pattern, and RExC_close_parens[0] referring to the end of the pattern.

This tripped up in reginsert in a subtle way, the start of the pattern
cannot and should not move in reginsert(). Unlike a paren that might
be at the start of the pattern which should move when something is inserted
in front of it, the start is a fixed point and should never move.

This patches fixes this up, and adds an assert to check that reginsert()
is not called once study_chunk() starts, as reginsert() does not adjust
RExC_recurse.

This was noticed by hv while debugging [perl #128085], thanks hugo!
  • Loading branch information
demerphq committed May 10, 2016
1 parent 1bda7a7 commit da7cf1c
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions regcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ struct RExC_state_t {
#endif
bool seen_unfolded_sharp_s;
bool strict;
bool study_started;
};

#define RExC_flags (pRExC_state->flags)
Expand Down Expand Up @@ -288,6 +289,7 @@ struct RExC_state_t {
#define RExC_frame_last (pRExC_state->frame_last)
#define RExC_frame_count (pRExC_state->frame_count)
#define RExC_strict (pRExC_state->strict)
#define RExC_study_started (pRExC_state->study_started)

/* Heuristic check on the complexity of the pattern: if TOO_NAUGHTY, we set
* a flag to disable back-off on the fixed/floating substrings - if it's
Expand Down Expand Up @@ -4102,6 +4104,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
GET_RE_DEBUG_FLAGS_DECL;

PERL_ARGS_ASSERT_STUDY_CHUNK;
RExC_study_started= 1;


if ( depth == 0 ) {
Expand Down Expand Up @@ -6877,6 +6880,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
RExC_contains_locale = 0;
RExC_contains_i = 0;
RExC_strict = cBOOL(pm_flags & RXf_PMf_STRICT);
RExC_study_started = 0;
pRExC_state->runtime_code_qr = NULL;
RExC_frame_head= NULL;
RExC_frame_last= NULL;
Expand Down Expand Up @@ -18235,7 +18239,9 @@ S_reginsert(pTHX_ RExC_state_t *pRExC_state, U8 op, regnode *opnd, U32 depth)
RExC_size += size;
return;
}

assert(!RExC_study_started); /* I believe we should never use reginsert once we have started
studying. If this is wrong then we need to adjust RExC_recurse
below like we do with RExC_open_parens/RExC_close_parens. */
src = RExC_emit;
RExC_emit += size;
dst = RExC_emit;
Expand All @@ -18246,7 +18252,10 @@ S_reginsert(pTHX_ RExC_state_t *pRExC_state, U8 op, regnode *opnd, U32 depth)
* iow it is 1 more than the number of parens seen in
* the pattern so far. */
for ( paren=0 ; paren < RExC_npar ; paren++ ) {
if ( RExC_open_parens[paren] >= opnd ) {
/* note, RExC_open_parens[0] is the start of the
* regex, it can't move. RExC_close_parens[0] is the end
* of the regex, it *can* move. */
if ( paren && RExC_open_parens[paren] >= opnd ) {
/*DEBUG_PARSE_FMT("open"," - %d",size);*/
RExC_open_parens[paren] += size;
} else {
Expand Down

0 comments on commit da7cf1c

Please sign in to comment.