diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-12-02 17:27:41 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-12-03 08:53:43 -0800 |
commit | 77381e15105d6b7991dbe57c5ee42bb4b06dba0f (patch) | |
tree | 447e1627a5748abb9d0e69e9c599acfeccf9da3f /t | |
parent | a5e7bc5140f5e3ea032317511826fa1cc38ec7fc (diff) | |
download | perl-77381e15105d6b7991dbe57c5ee42bb4b06dba0f.tar.gz |
Stop /(?{})?/ from leaking under fatal warnings
Fatal errors in regexp compilation do SAVEFREESV before croaking, to
make sure the regexp is freed.
Warnings that happen after the sizing pass need to be protected the
same way, in case they are fatal.
This commit arranges for the regexp to be freed in case the ‘Quanti-
fier unexpected on zero-length expression’ warning proves fatal.
/(?{})?/ also triggers some others leaks. Before re_op_compile calls
S_study_chunk, it allocates three scalars for study_chunk’s use. Some
of those are freed after the call to study_chunk, while others become
part of the regexp.
I surrounded the allocation and freeing with an ENTER/LEAVE pair,
using SAVEFREESV to free them when there is a croak. So those cases
SvREFCNT_dec was used, it is simply omitted. Those cases where it was
omitted now have SvREFCNT_inc.
One more complication was that sometimes there is a goto between the
ENTER and the LEAVE which restarts the surrounding code. It already=
took those scalars into account, freeing them. But to balance ENTER/
LEAVE pairs properly I had to do a LEAVE just before the goto, and
remove the freeing of the SVs after the goto.
The new name of the macro that uses goto was inspired by
Acme::ButFirst.
Diffstat (limited to 't')
-rw-r--r-- | t/op/svleak.t | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/t/op/svleak.t b/t/op/svleak.t index 59ff7f81cc..bbccfa98d9 100644 --- a/t/op/svleak.t +++ b/t/op/svleak.t @@ -98,8 +98,8 @@ eleak(2, 0, "$f 'misc'; our\$a,our\$a", 'double our with fatal warnings'); eleak(2, 0, "$f 'closure'; sub foo { my \$x; format=\n\@\n\$x\n.\n} write; ", 'format closing over unavailable var with fatal warnings'); -$::TODO = 'still leaks'; eleak(2, 0, "$all /(?{})?/ ", '(?{})? with fatal warnings'); +$::TODO = 'still leaks'; eleak(2, 0, "$all /(?{})+/ ", '(?{})+ with fatal warnings'); eleak(2, 0, "$all /[\\i]/ ", 'invalid charclass escape with fatal warns'); eleak(2, 0, "$all /[:foo:]/ ", '/[:foo:]/ with fatal warnings'); |