summaryrefslogtreecommitdiff
path: root/t/op
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2014-05-02 13:51:00 +0100
committerDavid Mitchell <davem@iabyn.com>2014-05-02 13:56:20 +0100
commitfc9668ae737de7993bbd27aa5c3eaddf41c5c885 (patch)
tree03fd7fdca31125b7c66d5f7cb5b945c3d0868f23 /t/op
parent70c5bd909f9ac3bc4de89d30e73693f3d07ea794 (diff)
downloadperl-fc9668ae737de7993bbd27aa5c3eaddf41c5c885.tar.gz
vec(): downgrade before accessing string buffer
This code: #!perl -l $x = substr "\x{100}\xff\xfe", 1; print vec($x, 0, 8); print vec($x, 0, 8); In 5.18 and earlier prints 255 255 With blead it prints: 195 255 This is due to the fact that it does SvPV() first to get the string buffer, then calls sv_utf8_downgrade(). With COW, the PVX of the SV may no longer equal the value earlier returned by SvPV(), but vec() continues to use the old pointer. This bug has always been present, but COW made it more noticeable. The fix is to just redo the SvPV() after a downgrade.
Diffstat (limited to 't/op')
-rw-r--r--t/op/vec.t18
1 files changed, 17 insertions, 1 deletions
diff --git a/t/op/vec.t b/t/op/vec.t
index b4afcf9cb8..30badb0138 100644
--- a/t/op/vec.t
+++ b/t/op/vec.t
@@ -6,7 +6,7 @@ BEGIN {
}
require "test.pl";
-plan( tests => 33 );
+plan( tests => 35 );
my $Is_EBCDIC = (ord('A') == 193) ? 1 : 0;
@@ -112,3 +112,19 @@ use constant roref => \1;
eval { for (roref) { vec($_,0,1) = 1 } };
like($@, qr/^Modification of a read-only value attempted at /,
'err msg when modifying read-only refs');
+
+
+{
+ # downgradeable utf8 strings should be downgraded before accessing
+ # the byte string.
+ # See the p5p thread with Message-ID:
+ # <CAMx+QJ6SAv05nmpnc7bmp0Wo+sjcx=ssxCcE-P_PZ8HDuCQd9A@mail.gmail.com>
+
+
+ my $x = substr "\x{100}\xff\xfe", 1; # a utf8 string with all ords < 256
+ my $v;
+ $v = vec($x, 0, 8);
+ is($v, 255, "downgraded utf8 try 1");
+ $v = vec($x, 0, 8);
+ is($v, 255, "downgraded utf8 try 2");
+}