Perl_sv_pos_b2u now calls utf8_mg_len_cache_update for the string end offset.
authorNicholas Clark <nick@ccl4.org>
Mon, 12 Jul 2010 10:56:59 +0000 (11:56 +0100)
committerNicholas Clark <nick@ccl4.org>
Mon, 12 Jul 2010 12:43:19 +0000 (13:43 +0100)
Previously it would not take special action if the offset requested happened to
be the end of the string, meaning that the (fixed size) UTF-8 offset cache
would be used for a value which could (and should) be stored elsewhere.

sv.c
t/op/pos.t

diff --git a/sv.c b/sv.c
index ce16db6..3a25abc 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -6676,8 +6676,12 @@ Perl_sv_pos_b2u(pTHX_ register SV *const sv, I32 *const offsetp)
     }
     *offsetp = len;
 
-    if (PL_utf8cache)
-       utf8_mg_pos_cache_update(sv, &mg, byte, len, blen);
+    if (PL_utf8cache) {
+       if (blen == byte)
+           utf8_mg_len_cache_update(sv, &mg, len);
+       else
+           utf8_mg_pos_cache_update(sv, &mg, byte, len, blen);
+    }
 }
 
 /*
index c3abfbe..04263e1 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan tests => 6;
+plan tests => 7;
 
 $x='banana';
 $x=~/.a/g;
@@ -28,3 +28,11 @@ $x = "123 56"; $x =~ / /g;
 is(pos($x), 4);
 { local $x }
 is(pos($x), 4);
+
+# Explict test that triggers the utf8_mg_len_cache_update() code path in
+# Perl_sv_pos_b2u().
+
+$x = "\x{100}BC";
+$x =~ m/.*/g;
+is(pos $x, 3);
+