diff options
author | David Mitchell <davem@iabyn.com> | 2013-07-20 16:16:10 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2013-07-28 10:33:40 +0100 |
commit | 5411a0e56ca69f51e1eeaf89ee0a73dcbcf05fb9 (patch) | |
tree | 2db7c978f7f6723602d17d520328a013a8e7de89 /t/re | |
parent | 63a3746a9fd4390177c052a5873163bc11fa8f69 (diff) | |
download | perl-5411a0e56ca69f51e1eeaf89ee0a73dcbcf05fb9.tar.gz |
fix COW match capture optimisation
When an SV matches, a new SV is created which is a COW copy of the original
SV, and stored in prog->saved_copy, then prog->subbeg is set to point to
the (shared) PVX buffer.
Earlier in this branch I introduced an optimisation that skipped freeing
the old saved_copy and creating a new COW SV each time, if the old
saved_copy SV was already a shared copy of the SV being matched.
So far so good, except that I implemented it wrongly: if non-COW
matches (which malloc() subbeg) are interspersed with COW matches,
then the subbeg of the COW and the malloced subbeg get mixed up and
AddressSanitizer throws a wobbly.
The fix is simple: in the optimised branch, we still need to free subbeg
if RXp_MATCH_COPIED is true, then reassign it.
Diffstat (limited to 't/re')
-rw-r--r-- | t/re/pat.t | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/t/re/pat.t b/t/re/pat.t index a89249087e..020068cc25 100644 --- a/t/re/pat.t +++ b/t/re/pat.t @@ -20,7 +20,7 @@ BEGIN { require './test.pl'; } -plan tests => 689; # Update this when adding/deleting tests. +plan tests => 694; # Update this when adding/deleting tests. run_tests() unless caller; @@ -1435,6 +1435,20 @@ EOP } } + # this mixture of readonly (not COWable) and COWable strings + # messed up the capture buffers under COW. The actual test results + # are incidental; the issue is was an AddressSanitizer failure + { + my $c ='AB'; + my $res = ''; + for ($c, 'C', $c, 'DE') { + ok(/(.)/, "COWable match"); + $res .= $1; + } + is($res, "ACAD"); + } + + } # End of sub run_tests 1; |