summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-12 06:58:17 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-12 06:58:17 -0700
commit21386d3b62ea2fd08a9afd376e39d02185f67baf (patch)
tree4be40b47f9e0f81ec582af71c0b91141a6bbd8f9 /lib.c
parent91b4c9db63bc5c96e100dc2e3e864bba53ba1f39 (diff)
downloadtxr-21386d3b62ea2fd08a9afd376e39d02185f67baf.tar.gz
txr-21386d3b62ea2fd08a9afd376e39d02185f67baf.tar.bz2
txr-21386d3b62ea2fd08a9afd376e39d02185f67baf.zip
lib: revamp overflow checks in vec operations.
* lib.c (vector): Bugfix: we are checking whether length + 2 is negative, not length. Check the original value, and simplify everything using check_mulloc. (list_vec, sub_vec): Use chk_xalloc just in case. There shouldn't be any overflow if the vector was constructed and manipulated properly. (replace_vec): Replace division-based oveflow check with a simple test that total + 2 doesn't overflow; then rely on chk_xalloc to do the multiplication overflow check.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c27
1 files changed, 11 insertions, 16 deletions
diff --git a/lib.c b/lib.c
index f096045c..f53c467b 100644
--- a/lib.c
+++ b/lib.c
@@ -6695,15 +6695,10 @@ val dupl(val fun)
val vector(val length, val initval)
{
int i;
- cnum alloc_plus = c_num(length) + 2;
- size_t size = if3(alloc_plus > 0,
- alloc_plus * sizeof (val),
- (uw_throwf(error_s, lit("vector: negative length ~a specified"),
- length, nao), 0));
- val *v = (convert(cnum, size / sizeof *v) == alloc_plus)
- ? coerce(val *, chk_malloc(size))
- : coerce(val *, uw_throwf(error_s, lit("vector: length ~a is too large"),
- length, nao));
+ ucnum len = c_unum(length);
+ ucnum alloc_plus = len + 2;
+ ucnum size = if3(alloc_plus > len, alloc_plus, -1);
+ val *v = coerce(val *, chk_xalloc(size, sizeof *v, lit("vector")));
val vec = make_obj();
vec->v.type = VEC;
initval = default_null_arg(initval);
@@ -6869,8 +6864,8 @@ val list_vec(val vec)
val copy_vec(val vec_in)
{
val length = length_vec(vec_in);
- cnum alloc_plus = c_num(length) + 2;
- val *v = coerce(val *, chk_malloc(alloc_plus * sizeof *v));
+ ucnum alloc_plus = c_unum(length) + 2;
+ val *v = coerce(val *, chk_xalloc(alloc_plus, sizeof *v, lit("copy-vec")));
val vec = make_obj();
vec->v.type = VEC;
#if HAVE_VALGRIND
@@ -6911,7 +6906,7 @@ val sub_vec(val vec_in, val from, val to)
} else {
cnum cfrom = c_num(from);
size_t nelem = c_num(to) - cfrom;
- val *v = coerce(val *, chk_malloc((nelem + 2) * sizeof *v));
+ val *v = coerce(val *, chk_xalloc((nelem + 2), sizeof *v, lit("sub-vec")));
val vec = make_obj();
vec->v.type = VEC;
#if HAVE_VALGRIND
@@ -7042,23 +7037,23 @@ val replace_vec(val vec_in, val items, val from, val to)
val cat_vec(val list)
{
- size_t total = 0;
+ ucnum total = 0;
val iter;
val vec, *v;
list = nullify(list);
for (iter = list; iter != nil; iter = cdr(iter)) {
- size_t newtot = total + c_num(length_vec(car(iter)));
+ ucnum newtot = total + c_unum(length_vec(car(iter)));
if (newtot < total)
goto toobig;
total = newtot;
}
- if (total > (convert(size_t, -1)/(sizeof (val)) - 2))
+ if (total + 2 < total)
goto toobig;
- v = coerce(val *, chk_malloc((total + 2) * sizeof *v));
+ v = coerce(val *, chk_xalloc(total + 2, sizeof *v, lit("cat-vec")));
vec = make_obj();
vec->v.type = VEC;