Interpret negative hexadecimal literals as NaN.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 23 Jul 2012 10:33:41 +0000 (10:33 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 23 Jul 2012 10:33:41 +0000 (10:33 +0000)
R=rossberg@chromium.org
BUG=v8:2240
TEST=str-to-num.js

Review URL: https://chromiumcodereview.appspot.com/10818003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12169 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/conversions-inl.h
test/mjsunit/str-to-num.js

index 77b260f..a98680f 100644 (file)
@@ -459,16 +459,23 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
   int insignificant_digits = 0;
   bool nonzero_digit_dropped = false;
 
-  bool negative = false;
+  enum Sign {
+    NONE,
+    NEGATIVE,
+    POSITIVE
+  };
+
+  Sign sign = NONE;
 
   if (*current == '+') {
     // Ignore leading sign.
     ++current;
     if (current == end) return JunkStringValue();
+    sign = POSITIVE;
   } else if (*current == '-') {
     ++current;
     if (current == end) return JunkStringValue();
-    negative = true;
+    sign = NEGATIVE;
   }
 
   static const char kInfinitySymbol[] = "Infinity";
@@ -483,34 +490,34 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
     }
 
     ASSERT(buffer_pos == 0);
-    return negative ? -V8_INFINITY : V8_INFINITY;
+    return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY;
   }
 
   bool leading_zero = false;
   if (*current == '0') {
     ++current;
-    if (current == end) return SignedZero(negative);
+    if (current == end) return SignedZero(sign == NEGATIVE);
 
     leading_zero = true;
 
     // It could be hexadecimal value.
     if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
       ++current;
-      if (current == end || !isDigit(*current, 16)) {
+      if (current == end || !isDigit(*current, 16) || sign != NONE) {
         return JunkStringValue();  // "0x".
       }
 
       return InternalStringToIntDouble<4>(unicode_cache,
                                           current,
                                           end,
-                                          negative,
+                                          false,
                                           allow_trailing_junk);
     }
 
     // Ignore leading zeros in the integer part.
     while (*current == '0') {
       ++current;
-      if (current == end) return SignedZero(negative);
+      if (current == end) return SignedZero(sign == NEGATIVE);
     }
   }
 
@@ -555,7 +562,7 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
       // leading zeros (if any).
       while (*current == '0') {
         ++current;
-        if (current == end) return SignedZero(negative);
+        if (current == end) return SignedZero(sign == NEGATIVE);
         exponent--;  // Move this 0 into the exponent.
       }
     }
@@ -647,7 +654,7 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
     return InternalStringToIntDouble<3>(unicode_cache,
                                         buffer,
                                         buffer + buffer_pos,
-                                        negative,
+                                        sign == NEGATIVE,
                                         allow_trailing_junk);
   }
 
@@ -660,7 +667,7 @@ double InternalStringToDouble(UnicodeCache* unicode_cache,
   buffer[buffer_pos] = '\0';
 
   double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
-  return negative ? -converted : converted;
+  return (sign == NEGATIVE) ? -converted : converted;
 }
 
 } }  // namespace v8::internal
index bbfa7d3..cbec87f 100644 (file)
@@ -147,7 +147,6 @@ assertEquals(15, toNumber("0Xf"));
 assertEquals(15, toNumber("0XF"));
 
 assertEquals(0,  toNumber("0x000"));
-assertEquals(-Infinity,  1 / toNumber("-0x000"));
 assertEquals(0,  toNumber("0x000" + repeat('0', 1000)));
 assertEquals(9,  toNumber("0x009"));
 assertEquals(10, toNumber("0x00a"));
@@ -157,7 +156,6 @@ assertEquals(15, toNumber("0x00F"));
 assertEquals(15, toNumber("0x00F "));
 assertEquals(Infinity,  toNumber("0x" + repeat('0', 1000) + '1'
                         + repeat('0', 1000)));
-assertEquals(-Infinity,  toNumber("-0x1" + repeat('0', 1000)));
 
 assertEquals(0x1000000 * 0x10000000, toNumber("0x10000000000000"));
 assertEquals(0x1000000 * 0x10000000 + 1, toNumber("0x10000000000001"));
@@ -207,3 +205,10 @@ assertTrue(isNaN(toNumber("1" + repeat('0', 1000) + 'junk')), "1e1000 junk");
 for (var i = 1; i < 12; i++) {
   assertEquals(toNumber('1' + repeat('0', i)), Math.pow(10.0, i));
 }
+
+assertTrue(isNaN(toNumber("+0x0")));
+assertTrue(isNaN(toNumber("+0xFF")));
+assertTrue(isNaN(toNumber("+0x012")));
+assertTrue(isNaN(toNumber("-0x0")));
+assertTrue(isNaN(toNumber("-0xFF")));
+assertTrue(isNaN(toNumber("-0x012")));
\ No newline at end of file