This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
clear savestack on (?{...}) failure and backtrack
authorDavid Mitchell <davem@iabyn.com>
Tue, 14 Feb 2017 15:59:57 +0000 (15:59 +0000)
committerDavid Mitchell <davem@iabyn.com>
Tue, 14 Feb 2017 17:49:58 +0000 (17:49 +0000)
commit4ee16520199a0e11bf4dbdbac71f0a64e5510271
tree3798512c4f271dc8c418b10a336811ed377c101a
parentf4197b8e1d1f984eb6635ea41ce14394432b96b1
clear savestack on (?{...}) failure and backtrack

RT #126697

In a regex, after executing a (?{...}) code block, if we fail and
backtrack over the codeblock, we're supposed to unwind the savestack, so
that for any example any local()s within the code block are undone.

It turns out that a backtracking state isn't pushed for (?{...}), only
for postponed evals ( i.e.  (??{...})). This means that it relies on one
of the earlier backtracking states to clear the savestack on its behalf.
This can't always be relied upon, and the ticket above contains code where
this falls down; in particular:

    'ABC' =~ m{
        \A
        (?:
            (?: AB | A | BC )
            (?{
                local $count = $count + 1;
                print "! count=$count; ; pos=${\pos}\n";
            })
        )*
        \z
    }x

Here we end up relying on TRIE_next to do the cleaning up, but TRIE_next
doesn't, since there's nothing it would be responsible for that needs
cleaning up.

The solution to this is to push a backtrack state for every (?{...}) as
well as every (??{...}). The sole job of that state is to do a
LEAVE_SCOPE(ST.lastcp).

The existing backtrack state EVAL_AB has been renamed EVAL_postponed_AB
to make it clear it's only used on postponed /(??{A})B/ regexes, and a new
state has been added, EVAL_B, which is only called when backtracking after
failing something in the B in /(?{...})B/.
regcomp.sym
regexec.c
regnodes.h
t/re/pat_re_eval.t