vec(): downgrade before accessing string buffer
authorDavid Mitchell <davem@iabyn.com>
Fri, 2 May 2014 12:51:00 +0000 (13:51 +0100)
committerDavid Mitchell <davem@iabyn.com>
Fri, 2 May 2014 12:56:20 +0000 (13:56 +0100)
commitfc9668ae737de7993bbd27aa5c3eaddf41c5c885
tree03fd7fdca31125b7c66d5f7cb5b945c3d0868f23
parent70c5bd909f9ac3bc4de89d30e73693f3d07ea794
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.
doop.c
t/op/vec.t