diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-01-28 17:50:45 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2014-01-28 17:50:59 -0800 |
commit | 7e68f15291c4da4e5b8237bfe9690edbd9c5a5d3 (patch) | |
tree | fc099d2a064fcbb7bf2954293e6bcbe3b42f6c04 /t | |
parent | 6e53b6cab73f4cc348a8366106f0569e65c858f1 (diff) | |
download | perl-7e68f15291c4da4e5b8237bfe9690edbd9c5a5d3.tar.gz |
Fix crash with (??{undef *^R}) and (?{})
$ ./perl -Ilib -e '"" =~ /(??{undef *^R;""})(?{42})/'
Segmentation fault: 11
This started crashing in 4b22688e5c.
What happens is that the undef frees the scalar pointed to by oreplsv
in regtry, Then that scalar is reused for the regexp object created
from the return value of the ?? block. sv_setsv(oreplsv,...) ends up
trying to set the IV slot of a regexp, overwriting the engine field
(sv_setsv probably needs an assertion). Then later accesses crash
because r->engine is now a bad pointer.
(Though why it only started crashing in 4b22688e5c and not before I
have not figured out.)
The solution is for S_regtry to hang on to the SV with an extra refer-
ence count in case it gets freed.
Diffstat (limited to 't')
-rw-r--r-- | t/re/pat.t | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/t/re/pat.t b/t/re/pat.t index d875ea67f2..b53853b67b 100644 --- a/t/re/pat.t +++ b/t/re/pat.t @@ -20,7 +20,7 @@ BEGIN { require './test.pl'; } -plan tests => 710; # Update this when adding/deleting tests. +plan tests => 711; # Update this when adding/deleting tests. run_tests() unless caller; @@ -1485,6 +1485,15 @@ EOP *^R = *caretRglobwithnoscalar; "" =~ /(?{42})/; is $^R, 42, 'assigning to *^R does not result in a crash'; + is runperl( + stderr => 1, + prog => 'eval q|' + .' q-..- =~ /(??{undef *^R;q--})(?{42})/; ' + .' print qq-$^R\n-' + .'|' + ), + "42\n", + 'undefining *^R within (??{}) does not result in a crash'; } { |