From 12b25c01ba0fbe7706bada2519c28193d73f7061 Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Sun, 3 Aug 2014 20:45:26 +0900 Subject: [PATCH] Giving a proper OOM error on arithmetic-shift with a huge shift. --- bignum.c | 12 ++++++++---- lib/srfi/33/bit.c | 30 +++++++++++++++++------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/bignum.c b/bignum.c index c80e3603..023bdfe1 100644 --- a/bignum.c +++ b/bignum.c @@ -19,15 +19,19 @@ static int hex_digit (int n) { sexp sexp_make_bignum (sexp ctx, sexp_uint_t len) { sexp_uint_t size = sexp_sizeof(bignum) + len*sizeof(sexp_uint_t); sexp res = sexp_alloc_tagged(ctx, size, SEXP_BIGNUM); - sexp_bignum_length(res) = len; - sexp_bignum_sign(res) = 1; + if (!sexp_exceptionp(res)) { + sexp_bignum_length(res) = len; + sexp_bignum_sign(res) = 1; + } return res; } sexp sexp_fixnum_to_bignum (sexp ctx, sexp a) { sexp res = sexp_make_bignum(ctx, 1); - sexp_bignum_data(res)[0] = sexp_unbox_fixnum(sexp_fx_abs(a)); - sexp_bignum_sign(res) = sexp_fx_sign(a); + if (!sexp_exceptionp(res)) { + sexp_bignum_data(res)[0] = sexp_unbox_fixnum(sexp_fx_abs(a)); + sexp_bignum_sign(res) = sexp_fx_sign(a); + } return res; } diff --git a/lib/srfi/33/bit.c b/lib/srfi/33/bit.c index 6e026238..b81f5d77 100644 --- a/lib/srfi/33/bit.c +++ b/lib/srfi/33/bit.c @@ -215,12 +215,14 @@ static sexp sexp_arithmetic_shift (sexp ctx, sexp self, sexp_sint_t n, sexp i, s res = sexp_make_fixnum(sexp_bignum_sign(i) > 0 ? 0 : -1); } else { res = sexp_make_bignum(ctx, len - offset + 1); - sexp_bignum_sign(res) = sexp_bignum_sign(i); - for (j=len-offset-1, tmp=0; j>=0; j--) { - sexp_bignum_data(res)[j] - = (sexp_bignum_data(i)[j+offset] >> bit_shift)+ tmp; - tmp = sexp_bignum_data(i)[j+offset] - << (sizeof(sexp_uint_t)*CHAR_BIT-bit_shift); + if (!sexp_exceptionp(res)) { + sexp_bignum_sign(res) = sexp_bignum_sign(i); + for (j=len-offset-1, tmp=0; j>=0; j--) { + sexp_bignum_data(res)[j] + = (sexp_bignum_data(i)[j+offset] >> bit_shift)+ tmp; + tmp = sexp_bignum_data(i)[j+offset] + << (sizeof(sexp_uint_t)*CHAR_BIT-bit_shift); + } } } } else { @@ -228,14 +230,16 @@ static sexp sexp_arithmetic_shift (sexp ctx, sexp self, sexp_sint_t n, sexp i, s bit_shift = c - offset*(sizeof(sexp_uint_t)*CHAR_BIT); tail_shift = (sizeof(sexp_uint_t)*CHAR_BIT-bit_shift); res = sexp_make_bignum(ctx, len + offset + 1); - sexp_bignum_sign(res) = sexp_bignum_sign(i); - for (j=tmp=0; j> tail_shift; + if (!sexp_exceptionp(res)) { + sexp_bignum_sign(res) = sexp_bignum_sign(i); + for (j=tmp=0; j> tail_shift; + } + if (bit_shift != 0) sexp_bignum_data(res)[len+offset] = tmp; } - if (bit_shift != 0) sexp_bignum_data(res)[len+offset] = tmp; } #endif } else {