On Wed, Dec 10, 2003 a.d., Ilya Zakharevich wrote:
>   perl -MDevel::Peek -MFreezeThaw=freeze,thaw -wle "$a=freeze qq(bc\xa8d); print $a; $a .= chr 567; chop $a; Dump $a; print $a; print thaw $a"

A simple example - it should print a single 'x':

$ perl -CO -e '$y = "x"x 25 . chr 345; substr $y, 2; print substr $y, 8, 1'
xxxxxxxxx

The second substr() was using the cached utf-8/byte length from
the first (see Perl_sv_pos_u2b()).
The following patch (applied to blead as #21875) should fix it for now.

Regards,
Adi

--- /arc/bleadperl/sv.c	Mon Dec  8 06:51:20 2003
+++ ./sv.c	Thu Dec 11 18:00:47 2003
@@ -5735,10 +5735,8 @@ S_utf8_mg_pos_init(pTHX_ SV *sv, MAGIC *
     bool found = FALSE; 
 
     if (SvMAGICAL(sv) && !SvREADONLY(sv)) {
-	if (!*mgp) {
-	    sv_magic(sv, 0, PERL_MAGIC_utf8, 0, 0);
-	    *mgp = mg_find(sv, PERL_MAGIC_utf8);
-	}
+	if (!*mgp)
+	    *mgp = sv_magicext(sv, 0, PERL_MAGIC_utf8, &PL_vtbl_utf8, 0, 0);
 	assert(*mgp);
 
 	if ((*mgp)->mg_ptr)
@@ -5831,6 +5829,12 @@ S_utf8_mg_pos(pTHX_ SV *sv, MAGIC **mgp,
 		      /* Update the cache. */
 		      (*cachep)[i]   = (STRLEN)uoff;
 		      (*cachep)[i+1] = p - start;
+
+		      /* Drop the stale "length" cache */
+		      if (i == 0) {
+			  (*cachep)[2] = 0;
+			  (*cachep)[3] = 0;
+		      }
  
 		      found = TRUE;
 		 }
--- /arc/bleadperl/t/op/substr.t	Mon Aug  4 02:43:17 2003
+++ ./t/op/substr.t	Thu Dec 11 17:40:35 2003
@@ -1,6 +1,6 @@
 #!./perl
 
-print "1..176\n";
+print "1..177\n";
 
 #P = start of string  Q = start of substr  R = end of substr  S = end of string
 
@@ -601,4 +601,11 @@ ok 174, $x eq "\x{100}\x{200}\xFFb";
     }
     my $x = my $y = 'AB'; ss $x; ss $y;
     ok 176, $x eq $y;
+}
+
+# [perl #24605]
+{
+    my $x = "0123456789\x{500}";
+    my $y = substr $x, 4;
+    ok 177, substr($x, 7, 1) eq "7";
 }

