From 9dd8df8fb683038deaaba9959872c9ba6ae66fb2 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 20 Jan 2007 19:37:02 +0000 Subject: [PATCH] intnum.c: Better internal error checking on intnum creation input strings. svn path=/trunk/yasm/; revision=1739 --- libyasm/intnum.c | 76 +++++++++++++++++--------- tools/python-yasm/intnum.pxi | 23 +++++--- tools/python-yasm/tests/test_intnum.py | 12 ++++ 3 files changed, 78 insertions(+), 33 deletions(-) diff --git a/libyasm/intnum.c b/libyasm/intnum.c index b444d585..95d23a1a 100644 --- a/libyasm/intnum.c +++ b/libyasm/intnum.c @@ -89,10 +89,18 @@ yasm_intnum_create_dec(char *str) intn->origsize = 0; /* no reliable way to figure this out */ - if (BitVector_from_Dec_static(from_dec_data, conv_bv, - (unsigned char *)str) == ErrCode_Ovfl) - yasm_warn_set(YASM_WARN_GENERAL, - N_("Numeric constant too large for internal format")); + switch (BitVector_from_Dec_static(from_dec_data, conv_bv, + (unsigned char *)str)) { + case ErrCode_Pars: + yasm_error_set(YASM_ERROR_VALUE, N_("invalid decimal literal")); + break; + case ErrCode_Ovfl: + yasm_error_set(YASM_ERROR_OVERFLOW, + N_("Numeric constant too large for internal format")); + break; + default: + break; + } if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0); @@ -111,11 +119,17 @@ yasm_intnum_create_bin(char *str) intn->origsize = (unsigned char)strlen(str); - if(intn->origsize > BITVECT_NATIVE_SIZE) - yasm_warn_set(YASM_WARN_GENERAL, - N_("Numeric constant too large for internal format")); - - BitVector_from_Bin(conv_bv, (unsigned char *)str); + switch (BitVector_from_Bin(conv_bv, (unsigned char *)str)) { + case ErrCode_Pars: + yasm_error_set(YASM_ERROR_VALUE, N_("invalid binary literal")); + break; + case ErrCode_Ovfl: + yasm_error_set(YASM_ERROR_OVERFLOW, + N_("Numeric constant too large for internal format")); + break; + default: + break; + } if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0); @@ -134,11 +148,17 @@ yasm_intnum_create_oct(char *str) intn->origsize = strlen(str)*3; - if(intn->origsize > BITVECT_NATIVE_SIZE) - yasm_warn_set(YASM_WARN_GENERAL, - N_("Numeric constant too large for internal format")); - - BitVector_from_Oct(conv_bv, (unsigned char *)str); + switch (BitVector_from_Oct(conv_bv, (unsigned char *)str)) { + case ErrCode_Pars: + yasm_error_set(YASM_ERROR_VALUE, N_("invalid octal literal")); + break; + case ErrCode_Ovfl: + yasm_error_set(YASM_ERROR_OVERFLOW, + N_("Numeric constant too large for internal format")); + break; + default: + break; + } if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0); @@ -157,11 +177,17 @@ yasm_intnum_create_hex(char *str) intn->origsize = strlen(str)*4; - if(intn->origsize > BITVECT_NATIVE_SIZE) - yasm_warn_set(YASM_WARN_GENERAL, - N_("Numeric constant too large for internal format")); - - BitVector_from_Hex(conv_bv, (unsigned char *)str); + switch (BitVector_from_Hex(conv_bv, (unsigned char *)str)) { + case ErrCode_Pars: + yasm_error_set(YASM_ERROR_VALUE, N_("invalid hex literal")); + break; + case ErrCode_Ovfl: + yasm_error_set(YASM_ERROR_OVERFLOW, + N_("Numeric constant too large for internal format")); + break; + default: + break; + } if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0); @@ -183,8 +209,8 @@ yasm_intnum_create_charconst_nasm(const char *str) intn->origsize = len*8; if(intn->origsize > BITVECT_NATIVE_SIZE) - yasm_warn_set(YASM_WARN_GENERAL, - N_("Character constant too large for internal format")); + yasm_error_set(YASM_ERROR_OVERFLOW, + N_("Character constant too large for internal format")); if (len > 4) { BitVector_Empty(conv_bv); @@ -280,8 +306,8 @@ yasm_intnum_create_leb128(const unsigned char *ptr, int sign, *size = (ptr-ptr_orig)+1; if(i > BITVECT_NATIVE_SIZE) - yasm_warn_set(YASM_WARN_GENERAL, - N_("Numeric constant too large for internal format")); + yasm_error_set(YASM_ERROR_OVERFLOW, + N_("Numeric constant too large for internal format")); else if (sign && (*ptr & 0x40) == 0x40) BitVector_Interval_Fill(conv_bv, i, BITVECT_NATIVE_SIZE-1); @@ -306,8 +332,8 @@ yasm_intnum_create_sized(unsigned char *ptr, int sign, size_t srcsize, intn->origsize = 0; if (srcsize*8 > BITVECT_NATIVE_SIZE) - yasm_warn_set(YASM_WARN_GENERAL, - N_("Numeric constant too large for internal format")); + yasm_error_set(YASM_ERROR_OVERFLOW, + N_("Numeric constant too large for internal format")); /* Read the buffer into a bitvect */ BitVector_Empty(conv_bv); diff --git a/tools/python-yasm/intnum.pxi b/tools/python-yasm/intnum.pxi index 42db35eb..7f77af95 100644 --- a/tools/python-yasm/intnum.pxi +++ b/tools/python-yasm/intnum.pxi @@ -109,18 +109,25 @@ cdef class IntNum: self.intn = __get_voidp(value, IntNum) return - val = None if isinstance(value, str): - val = long(value, base) + if base == 2: + self.intn = yasm_intnum_create_bin(value) + elif base == 8: + self.intn = yasm_intnum_create_oct(value) + elif base == 10 or base is None: + self.intn = yasm_intnum_create_dec(value) + elif base == 16: + self.intn = yasm_intnum_create_hex(value) + elif base == "nasm": + self.intn = yasm_intnum_create_charconst_nasm(value) + else: + raise ValueError("base must be 2, 8, 10, 16, or \"nasm\"") elif isinstance(value, (int, long)): - val = long(value) - - if val is None: + _PyLong_AsByteArray(long(value), buf, 16, 1, 1) + self.intn = yasm_intnum_create_sized(buf, 1, 16, 0) + else: raise ValueError - _PyLong_AsByteArray(val, buf, 16, 1, 1) - self.intn = yasm_intnum_create_sized(buf, 1, 16, 0) - def __dealloc__(self): if self.intn != NULL: yasm_intnum_destroy(self.intn) diff --git a/tools/python-yasm/tests/test_intnum.py b/tools/python-yasm/tests/test_intnum.py index 1c157f6a..65e09efc 100644 --- a/tools/python-yasm/tests/test_intnum.py +++ b/tools/python-yasm/tests/test_intnum.py @@ -16,11 +16,23 @@ class TIntNum(TestCase): def test_to_from(self): for i in self.legal_values: self.assertEquals(i, int(IntNum(i))) + self.assertEquals(i, long(IntNum(i))) def test_overflow(self): for i in self.overflow_values: self.assertRaises(OverflowError, IntNum, i) + str_values = [ + "0", "00000", "1234", "87654321", "010101010", "FADCBEEF" + ] + base_values = [2, 8, 10, 12, 16, None, "nasm", "foo"] + + def test_from_str(self): + pass + + def test_from_str_base(self): + pass + def test_exceptions(self): self.assertRaises(ZeroDivisionError, IntNum(1).__div__, 0) -- 2.40.0