summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-12 06:46:10 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-12 06:46:10 -0700
commit45ae26abca02ae71d46fd4baa2fba1a0b311e816 (patch)
tree855facabe2c2fd16954ef5ce5f20f5ee1c7276fe /ffi.c
parent13265cb31f4f14e1c021929d7d4585c5588dcd9d (diff)
downloadtxr-45ae26abca02ae71d46fd4baa2fba1a0b311e816.tar.gz
txr-45ae26abca02ae71d46fd4baa2fba1a0b311e816.tar.bz2
txr-45ae26abca02ae71d46fd4baa2fba1a0b311e816.zip
ffi: fix carray multiplication overflow checks.
* ffi.c (carray_dup): Do size multiplication using unsigned type, then coerce back to signed. Check for overflow correctly by first testing result for negative, then doing division check. (carray_replace): Add check for negative size, which confirms overflow.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/ffi.c b/ffi.c
index 9dc0bb3a..36b4ce07 100644
--- a/ffi.c
+++ b/ffi.c
@@ -4352,10 +4352,10 @@ val carray_dup(val carray)
self, carray, nao);
} else {
cnum elsize = scry->eltft->size;
- cnum size = scry->nelem * elsize;
+ cnum size = (ucnum) scry->nelem * (ucnum) elsize;
mem_t *dup = chk_copy_obj(scry->data, scry->nelem * scry->eltft->size);
- if (size < scry->nelem || size < elsize)
+ if (size < 0 || (elsize > 0 && size / elsize != scry->nelem))
uw_throwf(error_s, lit("~a: array size overflow"), self, nao);
carray->co.ops = &carray_owned_ops;
@@ -4655,7 +4655,7 @@ val carray_replace(val carray, val values, val from, val to)
if (sn > ln)
sn = ln;
- if ((ln != 0 && size / elsize != ln) || (sn < fn))
+ if (size < 0 || (ln != 0 && size / elsize != ln) || (sn < fn))
uw_throwf(error_s, lit("~a: array size overflow"), self, nao);
ptr = scry->data + fn * elsize;