aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2012-02-23 14:36:49 +0100
committerSverker Eriksson <[email protected]>2012-02-23 14:37:23 +0100
commit3398aa592af611b84edad4fa56e88379df6d1735 (patch)
tree85def0f7ec0332102aa5bc85cd4705c81e1dc982 /erts/emulator
parent045810f873df73a09b105d051eed244be2edf7ee (diff)
parentde742bb6eb202c5a524bab3617a2ede918598705 (diff)
downloadotp-3398aa592af611b84edad4fa56e88379df6d1735.tar.gz
otp-3398aa592af611b84edad4fa56e88379df6d1735.tar.bz2
otp-3398aa592af611b84edad4fa56e88379df6d1735.zip
Merge branch 'sverk/ets-compress-bug' into maint
* sverk/ets-compress-bug: erts: Fail binary_to_term if bignum arity is too large erts: Fix bignum-bug in ETS with compressed option OTP-9932
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/big.c16
-rw-r--r--erts/emulator/beam/external.c3
2 files changed, 16 insertions, 3 deletions
diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c
index 976f05c990..25ac790d81 100644
--- a/erts/emulator/beam/big.c
+++ b/erts/emulator/beam/big.c
@@ -1844,6 +1844,7 @@ dsize_t big_bytes(Eterm x)
/*
** Load a bignum from bytes
** xsz is the number of bytes in xp
+** *r is untouched if number fits in small
*/
Eterm bytes_to_big(byte *xp, dsize_t xsz, int xsgn, Eterm *r)
{
@@ -1852,7 +1853,7 @@ Eterm bytes_to_big(byte *xp, dsize_t xsz, int xsgn, Eterm *r)
ErtsDigit d;
int i;
- while(xsz >= sizeof(ErtsDigit)) {
+ while(xsz > sizeof(ErtsDigit)) {
d = 0;
for(i = sizeof(ErtsDigit); --i >= 0;)
d = (d << 8) | xp[i];
@@ -1867,11 +1868,20 @@ Eterm bytes_to_big(byte *xp, dsize_t xsz, int xsgn, Eterm *r)
d = 0;
for(i = xsz; --i >= 0;)
d = (d << 8) | xp[i];
+ if (++rsz == 1 && IS_USMALL(xsgn,d)) {
+ if (xsgn) d = -d;
+ return make_small(d);
+ }
*rwp = d;
rwp++;
- rsz++;
}
- return big_norm(r, rsz, (short) xsgn);
+ if (xsgn) {
+ *r = make_neg_bignum_header(rsz);
+ }
+ else {
+ *r = make_pos_bignum_header(rsz);
+ }
+ return make_big(r);
}
/*
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 152dbcf085..9d52ed4e98 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -3118,6 +3118,9 @@ decoded_size(byte *ep, byte* endp, int internal_tags)
case LARGE_BIG_EXT:
CHKSIZE(4);
n = get_int32(ep);
+ if (n > BIG_ARITY_MAX*sizeof(ErtsDigit)) {
+ return -1;
+ }
SKIP2(n,4+1); /* skip, size,sign,digits */
heap_size += 1+1+(n+sizeof(Eterm)-1)/sizeof(Eterm); /* XXX: 1 too much? */
break;