summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pp_pack.c2
-rw-r--r--t/op/pack.t22
2 files changed, 22 insertions, 2 deletions
diff --git a/pp_pack.c b/pp_pack.c
index 96dfd20157..044ea7f2ce 100644
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -2488,7 +2488,7 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
if (howlen == e_star) len = fromlen;
field_len = (len+1)/2;
GROWING(utf8, cat, start, cur, field_len);
- if (!utf8 && len > (I32)fromlen) len = fromlen;
+ if (!utf8_source && len > (I32)fromlen) len = fromlen;
bits = 0;
l = 0;
if (datumtype == 'H')
diff --git a/t/op/pack.t b/t/op/pack.t
index e348693bf5..a2da63689b 100644
--- a/t/op/pack.t
+++ b/t/op/pack.t
@@ -12,7 +12,7 @@ my $no_endianness = $] > 5.009 ? '' :
my $no_signedness = $] > 5.009 ? '' :
"Signed/unsigned pack modifiers not available on this perl";
-plan tests => 14708;
+plan tests => 14712;
use strict;
use warnings qw(FATAL all);
@@ -2024,3 +2024,23 @@ is $o::num, 1, 'pack "c" does call num overloading';
#[perl #123874]: argument underflow leads to corrupt length
eval q{ pack "pi/x" };
ok(1, "argument underflow did not crash");
+
+{
+ # [perl #126325] pack [hH] with a unicode string
+ # the hex encoders would read past the end of the string, using
+ # invalid source bytes
+ my $twenty_nuls = "\0" x 20;
+ # This is the case that failed
+ is(pack("WH40", 0x100, ""), "\x{100}$twenty_nuls",
+ "check pack H zero fills (utf8 target)");
+ my $up_nul = "\0";
+
+ utf8::upgrade($up_nul);
+ # check the other combinations too
+ is(pack("WH40", 0x100, $up_nul), "\x{100}$twenty_nuls",
+ "check pack H zero fills (utf8 target/source)");
+ is(pack("H40", ""), $twenty_nuls,
+ "check pack H zero fills (utf8 none)");
+ is(pack("H40", $up_nul), $twenty_nuls,
+ "check pack H zero fills (utf8 source)");
+}