This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #77692] substr causes panic: sv_len_utf8 cache...
authorFather Chrysostomos <sprout@cpan.org>
Thu, 10 Feb 2011 17:20:14 +0000 (09:20 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 10 Feb 2011 17:20:49 +0000 (09:20 -0800)
pp_substr contains this comment, which was added in perl 5.0 alpha 2
(commit 79072805bf63):

    PUSHs(TARG); /* avoid SvSETMAGIC here */

Calling set-magic when substr returns an lvalue will cause its argu-
ment to be stringified even if the lvalue is not assigned to. That’s
why set-magic has to be avoided.

But the result is that utf8 caches (stored in magic) on TARG are not
reset properly.

Since substr lvalues now follow a different code path (and do not use
TARG at all), it’s perfectly safe to call set-magic at this point.
It’s also the right thing to do in case of other types of magic that
might get attached to TARG.

pp.c
t/re/substr.t

diff --git a/pp.c b/pp.c
index d2bb466..d857c7e 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -3540,7 +3540,8 @@ PP(pp_substr)
        }
     }
     SPAGAIN;
-    PUSHs(TARG);               /* avoid SvSETMAGIC here */
+    SvSETMAGIC(TARG);
+    PUSHs(TARG);
     RETURN;
 
 bound_fail:
index 4f34b26..a0cac6a 100644 (file)
@@ -22,9 +22,9 @@ $SIG{__WARN__} = sub {
      }
 };
 
-require './test.pl';
+BEGIN { require './test.pl'; }
 
-plan(361);
+plan(362);
 
 run_tests() unless caller;
 
@@ -735,3 +735,13 @@ $destroyed = 0;
     $x = bless({}, 'Class');
 }
 is($destroyed, 1, 'Timely scalar destruction with lvalue substr');
+
+# [perl #77692] UTF8 cache not being reset when TARG is reused
+ok eval {
+ local ${^UTF8CACHE} = -1;
+ for my $i (0..1)
+ {
+   my $dummy = length(substr("\x{100}",0,$i));
+ }
+ 1
+}, 'UTF8 cache is reset when TARG is reused [perl #77692]';