This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix pad/scope issue in re_evals
authorDavid Mitchell <davem@iabyn.com>
Sat, 11 Feb 2017 11:53:41 +0000 (11:53 +0000)
committerDavid Mitchell <davem@iabyn.com>
Tue, 14 Feb 2017 17:49:58 +0000 (17:49 +0000)
commit4b9c7caeaecf4e9df0be3a2e296644f763f775d6
treea51595dedf7f0db78a07b189005470203bfd7e8a
parent57c819f845c985ed9979bfa76b1b8ca1708370f0
fix pad/scope issue in re_evals

RT #129881 heap-buffer-overflow Perl_pad_sv

In some circumstances involving a pattern which has embedded code blocks
from more than one source, e.g.

    my $r = qr{(?{1;}){2}X};
    "" =~ /$r|(?{1;})/;

the wrong PL_comppad could be active while doing a LEAVE_SCOPE() or on
exit from the pattern.

This was mainly due to the big context stack changes in 5.24.0 - in
particular, since POP_MULTICALL() now does CX_LEAVE_SCOPE(cx) *before*
restoring PL_comppad, the (correct) unwinding of any SAVECOMPPAD's was
being followed by C<PL_comppad = cx->blk_sub.prevcomppad>, which wasn't
necessarily a sensible value.

To fix this, record the value of PL_savestack_ix at entry to S_regmatch(),
and set the cx->blk_oldsaveix of the MULTICALL to this value when pushed.
On exit from S_regmatch, we either POP_MULTICALL which will do a
LEAVE_SCOPE(cx->blk_oldsaveix), or in the absense of any EVAL, do the
explicit but equivalent LEAVE_SCOPE(orig_savestack_ix).

Note that this is a change in behaviour to S_regmatch() - formerly it
wouldn't necessarily clear the savestack completely back the point of
entry - that would get left to do by its caller, S_regtry(), or indirectly
by Perl_regexec_flags(). This shouldn't make any practical difference, but
is tidier and less likely to introduce bugs later.
regexec.c
t/re/pat_re_eval.t