From 61784c15c28118638f220aa7387e781f932a67ae Mon Sep 17 00:00:00 2001 From: Matthias Heil Date: Thu, 10 Jul 2003 10:31:24 +0000 Subject: [PATCH] out-of-bounds check for tarval_to_long off by one error in sc_print fixed [r1455] --- ir/tv/strcalc.c | 3 ++- ir/tv/tv.c | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ir/tv/strcalc.c b/ir/tv/strcalc.c index 20d0cbd2f..8a2d9ed90 100644 --- a/ir/tv/strcalc.c +++ b/ir/tv/strcalc.c @@ -1285,6 +1285,7 @@ unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs) /* * convert to a string + * XXX Doesn't check buffer bounds */ const char *sc_print(const void *value, unsigned bits, enum base_t base) { @@ -1305,7 +1306,7 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base) const char *digits = small_digits; pos = output_buffer + BIT_PATTERN_SIZE ; - *pos = '\0'; + *(--pos) = '\0'; /* special case */ if (bits == 0) { diff --git a/ir/tv/tv.c b/ir/tv/tv.c index d1fb32c45..ec539c0ae 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -293,16 +293,28 @@ tarval *new_tarval_from_long(long l, ir_mode *mode) int tarval_is_long(tarval *tv) { ANNOUNCE(); - return ((get_mode_sort(tv->mode) == irms_int_number) || (get_mode_sort(tv->mode) == irms_character)); + if (get_mode_sort(tv->mode) != irms_int_number) return 0; + + if (get_mode_size_bits(tv->mode) > sizeof(long)<<3) + { + /* the value might be too big to fit in a long */ + sc_max_from_bits(sizeof(long)<<3, 0); + if (sc_comp(sc_get_buffer(), tv->value) == -1) + { + /* really doesn't fit */ + return 0; + } + } + return 1; } /* this might overflow the machine's long, so use only with small values */ long tarval_to_long(tarval* tv) { ANNOUNCE(); - assert(tv && get_mode_sort(tv->mode) == irms_int_number); + assert(tarval_is_long(tv) && "tarval too big to fit in long"); - return sc_val_to_long(tv->value); /* might overflow */ + return sc_val_to_long(tv->value); } tarval *new_tarval_from_double(long double d, ir_mode *mode) -- 2.20.1