summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-02-08 03:04:22 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-02-08 03:04:22 -0800
commit703f9f9696fa27959d6a7f75e72446ced13fbcb1 (patch)
treeb204ff4100779066259ee336089efe51ae736564 /lib.c
parenta2423f718441993e2a6a010fb13e1b84298424a2 (diff)
downloadtxr-703f9f9696fa27959d6a7f75e72446ced13fbcb1.tar.gz
txr-703f9f9696fa27959d6a7f75e72446ced13fbcb1.tar.bz2
txr-703f9f9696fa27959d6a7f75e72446ced13fbcb1.zip
* lib.c (vector, vec_set_length, cat_vec): When the vector size
overflows the size_t type that is passed to malloc, throw an exception.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/lib.c b/lib.c
index c4415ac2..39928568 100644
--- a/lib.c
+++ b/lib.c
@@ -3839,8 +3839,12 @@ val vector(val length, val initval)
{
int i;
cnum alloc_plus = c_num(length) + 2;
+ size_t size = alloc_plus * sizeof (val);
+ val *v = (size / sizeof *v == alloc_plus)
+ ? (val *) chk_malloc(size)
+ : (val *) uw_throwf(error_s, lit("vector: length ~a is too large"),
+ length, nao);
val vec = make_obj();
- val *v = (val *) chk_malloc(alloc_plus * sizeof *v);
initval = default_bool_arg(initval);
#if HAVE_VALGRIND
vec->v.vec_true_start = v;
@@ -3871,6 +3875,10 @@ val vec_set_length(val vec, val length)
cnum length_delta = new_length - old_length;
cnum alloc_delta = new_length - old_alloc;
+ if (new_length > ((size_t) -1)/(sizeof (val)) - 2)
+ uw_throwf(error_s, lit("vec-set-length: cannot extend to length ~s"),
+ length, nao);
+
if (alloc_delta > 0) {
cnum new_alloc = max(new_length, 2*old_alloc);
val *newvec = (val *) chk_realloc((mem_t *) (vec->v.vec - 2),
@@ -4102,12 +4110,19 @@ val replace_vec(val vec_in, val items, val from, val to)
val cat_vec(val list)
{
- cnum total = 0;
+ size_t total = 0;
val iter;
val vec, *v;
- for (iter = list; iter != nil; iter = cdr(iter))
- total += c_num(length_vec(car(iter)));
+ for (iter = list; iter != nil; iter = cdr(iter)) {
+ size_t newtot = total + c_num(length_vec(car(iter)));
+ if (newtot < total)
+ goto toobig;
+ total = newtot;
+ }
+
+ if (total > ((size_t) -1)/(sizeof (val)) - 2)
+ goto toobig;
vec = make_obj();
v = (val *) chk_malloc((total + 2) * sizeof *v);
@@ -4128,6 +4143,8 @@ val cat_vec(val list)
}
return vec;
+toobig:
+ uw_throwf(error_s, lit("cat-vec: resulting vector too large"), nao);
}
static val simple_lazy_stream_func(val stream, val lcons)