readnum(): handle prefix-suffix collision like "0h"
authorH. Peter Anvin <hpa@zytor.com>
Sat, 27 Oct 2007 04:38:02 +0000 (21:38 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Sat, 27 Oct 2007 04:38:02 +0000 (21:38 -0700)
Suffixed versions of zero will look like both a prefix and a suffix.
Reject the prefixed version as being too short to decode.

nasmlib.c
test/radix.asm

index ee947c2..a1a1af0 100644 (file)
--- a/nasmlib.c
+++ b/nasmlib.c
@@ -220,7 +220,7 @@ int64_t readnum(char *str, bool *error)
 {
     char *r = str, *q;
     int32_t pradix, sradix, radix;
-    int plen, slen;
+    int plen, slen, len;
     uint64_t result, checklimit;
     int digit, last;
     bool warn = false;
@@ -245,6 +245,13 @@ int64_t readnum(char *str, bool *error)
     while (lib_isnumchar(*q))
         q++;                    /* find end of number */
 
+    len = q-r;
+    if (!len) {
+       /* Not numeric */
+       *error = true;
+       return 0;
+    }
+
     /*
      * Handle radix formats:
      *
@@ -255,12 +262,12 @@ int64_t readnum(char *str, bool *error)
     pradix = sradix = 0;
     plen = slen = 0;
 
-    if (*r == '0' && (pradix = radix_letter(r[1])) != 0)
+    if (len > 2 && *r == '0' && (pradix = radix_letter(r[1])) != 0)
        plen = 2;
-    else if (*r == '$')
+    else if (len > 1 && *r == '$')
        pradix = 16, plen = 1;
 
-    if ((sradix = radix_letter(q[-1])) != 0)
+    if (len > 1 && (sradix = radix_letter(q[-1])) != 0)
        slen = 1;
 
     if (pradix > sradix) {
@@ -276,17 +283,6 @@ int64_t readnum(char *str, bool *error)
     }
 
     /*
-     * If this number has been found for us by something other than
-     * the ordinary scanners, then it might be malformed by having
-     * nothing between the prefix and the suffix. Check this case
-     * now.
-     */
-    if (r >= q) {
-        *error = true;
-        return 0;
-    }
-
-    /*
      * `checklimit' must be 2**(32|64) / radix. We can't do that in
      * 32/64-bit arithmetic, which we're (probably) using, so we
      * cheat: since we know that all radices we use are even, we
index 2c0afab..d5b6e0e 100644 (file)
@@ -23,6 +23,9 @@
        dd 1010_0101x           ; Hex
        dd $1010_0101           ; Hex
 
+       db 0h                   ; Zero!
+       db 0x                   ; Zero!
+       db 0b                   ; Zero!
        db 0dh                  ; Hex
        db 0bh                  ; Hex
        db 0dx                  ; Hex
@@ -35,7 +38,7 @@
        ;; Floating-point constants
        ;; All of these should output B4A21147
        dd 3.7282705e+4         ; Decimal
-       dd 00003.7282705e+4     ; Decimal
+       dd 00003.7282705e+4     ; Decimal
        dd 0d3.7282705e+4       ; Decimal
        dd 0t3.7282705e+4       ; Decimal