Fix infinite loop with $tied =~ s/non-utf8/utf8/
authorFather Chrysostomos <sprout@cpan.org>
Sun, 7 Oct 2012 07:31:48 +0000 (00:31 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 7 Oct 2012 07:49:20 +0000 (00:49 -0700)
commit5c1648b021578273785898ffaa60ac0f0c1d04d9
tree32e488eda10fa66a6155acfd760a0a499e3e18d5
parent0efd04728ae1d7e6e4aa59c8370a8108bde6ee36
Fix infinite loop with $tied =~ s/non-utf8/utf8/

Commit 3e462cdc208 fixed bug #41530 (s/non-utf8/utf8/ was not working
properly at all) by upgrading the target and redoing the substitution
if the replacement was utf8 and the target was not.

Commit c95ca9b8cd1 fixed one problem with it calling get-magic too
many times, by checking whether the upgrade caused a string realloca-
tion and only then redoing the substitution.  But it only fixed it
when magic returns a pure ASCII string.

Redoing the substitution meant going back to where the target was
initially stringified and starting again.  That meant calling get-
magic again.

So in those cases where magic returned something other than a UTF8 or
pure ASCII string the substitution restarted and magic would be trig-
gered again, possibly resulting in infinite loops (because it would
have to be upgraded again, resulting a reallocation, and a restart).

This happens with:

• Latin-1 strings
• Copy-on-write non-UTF8 strings
• References that stringify without UTF8

c95ca9b8cd1 also added SvPVX without checking first that it is SvPVX-
able, so a typeglob causes an assertion failure.

It turned out that there were also two other places in pp_subst that
were calling FETCH a second time (the tests I added for the looping/
assertion bugs found this), so I changed them, too.
pp_hot.c
t/re/subst.t