summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pp_pack.c7
-rwxr-xr-xt/op/pack.t5
2 files changed, 9 insertions, 3 deletions
diff --git a/pp_pack.c b/pp_pack.c
index cb3dd89cbe..97e0a06fac 100644
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -1183,7 +1183,10 @@ S_unpack_rec(pTHX_ register tempsym_t* symptr, register char *s, char *strbeg, c
uchar_checksum:
while (len-- > 0) {
auint = *s++ & 255;
- cuv += auint;
+ if (checksum > bits_in_uv)
+ cdouble += (NV)auint;
+ else
+ cuv += auint;
}
}
else {
@@ -1703,7 +1706,7 @@ S_unpack_rec(pTHX_ register tempsym_t* symptr, register char *s, char *strbeg, c
if (checksum) {
if (strchr("fFdD", TYPE_NO_MODIFIERS(datumtype)) ||
(checksum > bits_in_uv &&
- strchr("csSiIlLnNUvVqQjJ", TYPE_NO_MODIFIERS(datumtype))) ) {
+ strchr("cCsSiIlLnNUvVqQjJ", TYPE_NO_MODIFIERS(datumtype))) ) {
NV trouble;
adouble = (NV) (1 << (checksum & 15));
diff --git a/t/op/pack.t b/t/op/pack.t
index d30ae94474..3fc4cfd740 100755
--- 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 => 13856;
+plan tests => 13857;
use strict;
use warnings;
@@ -1498,4 +1498,7 @@ is(unpack('c'), 65, "one-arg unpack (change #18751)"); # defaulting to $_
my (@x) = unpack("b10a", "abcd");
my (@y) = unpack("%b10a", "abcd");
is($x[1], $y[1], "checksum advance ok");
+
+ # verify that the checksum is not overflowed with C0
+ is(unpack("C0%128U", "abcd"), unpack("U0%128U", "abcd"), "checksum not overflowed");
}