]> granicus.if.org Git - yasm/commitdiff
intnum.c: Better internal error checking on intnum creation input strings.
authorPeter Johnson <peter@tortall.net>
Sat, 20 Jan 2007 19:37:02 +0000 (19:37 -0000)
committerPeter Johnson <peter@tortall.net>
Sat, 20 Jan 2007 19:37:02 +0000 (19:37 -0000)
svn path=/trunk/yasm/; revision=1739

libyasm/intnum.c
tools/python-yasm/intnum.pxi
tools/python-yasm/tests/test_intnum.py

index b444d5858eea45041e39cd4e1e62c0961cda8312..95d23a1a241c6ff7a3c0e0e23fd65cc881b96079 100644 (file)
@@ -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);
index 42db35eb1afe621ce72d78a4e40d0399935d8ba7..7f77af9543a50efaddeb4d9c935a8468661e328d 100644 (file)
@@ -109,18 +109,25 @@ cdef class IntNum:
             self.intn = <yasm_intnum *>__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)
 
index 1c157f6afc1f8f8c487e2c179c48899e7c377764..65e09efc95f637b0a31d5fc5ca9f1290fbe30283 100644 (file)
@@ -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)