Legacy numeric literals should not permit separators or BigInt
authorross.kirsling@sony.com <ross.kirsling@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2019 23:55:45 +0000 (23:55 +0000)
committerross.kirsling@sony.com <ross.kirsling@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2019 23:55:45 +0000 (23:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=199984

Reviewed by Keith Miller.

JSTests:

* stress/big-int-literals.js:
* stress/numeric-literal-separators.js:

Source/JavaScriptCore:

* parser/Lexer.cpp:
(JSC::Lexer<T>::parseOctal):
(JSC::Lexer<T>::parseDecimal):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247845 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/stress/big-int-literals.js
JSTests/stress/numeric-literal-separators.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/parser/Lexer.cpp

index d88721e..04d011a 100644 (file)
@@ -1,5 +1,15 @@
 2019-07-25  Ross Kirsling  <ross.kirsling@sony.com>
 
+        Legacy numeric literals should not permit separators or BigInt
+        https://bugs.webkit.org/show_bug.cgi?id=199984
+
+        Reviewed by Keith Miller.
+
+        * stress/big-int-literals.js:
+        * stress/numeric-literal-separators.js:
+
+2019-07-25  Ross Kirsling  <ross.kirsling@sony.com>
+
         [ESNext] Implement nullish coalescing
         https://bugs.webkit.org/show_bug.cgi?id=200072
 
index 54957e8..2c2327c 100644 (file)
@@ -18,9 +18,6 @@ function assertThrowSyntaxError(input) {
 let n = 0n;
 assert(n === 0n);
 
-n = 00n;
-assert(n === 0n);
-
 // Binary representation
 
 n = 0b1111n;
@@ -105,3 +102,6 @@ assertThrowSyntaxError("100nn");
 assertThrowSyntaxError("1a0nn");
 assertThrowSyntaxError("10E20n");
 assertThrowSyntaxError("--10n");
+assertThrowSyntaxError("00n");
+assertThrowSyntaxError("01n");
+assertThrowSyntaxError("09n");
index 51b4063..d89d11d 100644 (file)
@@ -94,3 +94,13 @@ shouldThrow('1e+2__2', SyntaxError);
 shouldThrow('1e-_2', SyntaxError);
 shouldThrow('1e-2_', SyntaxError);
 shouldThrow('1e-2__2', SyntaxError);
+
+shouldThrow('01_1', SyntaxError);
+shouldThrow('01_9', SyntaxError);
+shouldThrow('09_1', SyntaxError);
+shouldThrow('0100_001', SyntaxError);
+shouldThrow('0100_009', SyntaxError);
+shouldThrow('0900_001', SyntaxError);
+shouldThrow('010000000000_1', SyntaxError);
+shouldThrow('010000000000_9', SyntaxError);
+shouldThrow('090000000000_1', SyntaxError);
index 4cd9b62..8c01809 100644 (file)
@@ -1,3 +1,14 @@
+2019-07-25  Ross Kirsling  <ross.kirsling@sony.com>
+
+        Legacy numeric literals should not permit separators or BigInt
+        https://bugs.webkit.org/show_bug.cgi?id=199984
+
+        Reviewed by Keith Miller.
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::parseOctal):
+        (JSC::Lexer<T>::parseDecimal):
+
 2019-07-25  Yusuke Suzuki  <ysuzuki@apple.com>
 
         Unreviewed, build fix due to C++17's std::invoke_result_t
index 16bfa8a..e98cdb5 100644 (file)
@@ -1625,6 +1625,8 @@ template <typename T>
 ALWAYS_INLINE auto Lexer<T>::parseOctal() -> Optional<NumberParseResult>
 {
     ASSERT(isASCIIOctalDigit(m_current));
+    ASSERT(!m_buffer8.size() || (m_buffer8.size() == 1 && m_buffer8[0] == '0'));
+    bool isLegacyLiteral = m_buffer8.size();
 
     // Optimization: most octal values fit into 4 bytes.
     uint32_t octalValue = 0;
@@ -1636,7 +1638,7 @@ ALWAYS_INLINE auto Lexer<T>::parseOctal() -> Optional<NumberParseResult>
 
     do {
         if (m_current == '_') {
-            if (UNLIKELY(!isASCIIOctalDigit(peek(1))))
+            if (UNLIKELY(!isASCIIOctalDigit(peek(1)) || isLegacyLiteral))
                 return WTF::nullopt;
 
             shift();
@@ -1656,7 +1658,7 @@ ALWAYS_INLINE auto Lexer<T>::parseOctal() -> Optional<NumberParseResult>
 
     while (isASCIIOctalDigitOrSeparator(m_current)) {
         if (m_current == '_') {
-            if (UNLIKELY(!isASCIIOctalDigit(peek(1))))
+            if (UNLIKELY(!isASCIIOctalDigit(peek(1)) || isLegacyLiteral))
                 return WTF::nullopt;
 
             shift();
@@ -1666,7 +1668,7 @@ ALWAYS_INLINE auto Lexer<T>::parseOctal() -> Optional<NumberParseResult>
         shift();
     }
 
-    if (UNLIKELY(Options::useBigInt() && m_current == 'n'))
+    if (UNLIKELY(Options::useBigInt() && m_current == 'n') && !isLegacyLiteral)
         return NumberParseResult { makeIdentifier(m_buffer8.data(), m_buffer8.size()) };
 
     if (isASCIIDigit(m_current))
@@ -1679,6 +1681,7 @@ template <typename T>
 ALWAYS_INLINE auto Lexer<T>::parseDecimal() -> Optional<NumberParseResult>
 {
     ASSERT(isASCIIDigit(m_current) || m_buffer8.size());
+    bool isLegacyLiteral = m_buffer8.size() && isASCIIDigitOrSeparator(m_current);
 
     // Optimization: most decimal values fit into 4 bytes.
     uint32_t decimalValue = 0;
@@ -1694,7 +1697,7 @@ ALWAYS_INLINE auto Lexer<T>::parseDecimal() -> Optional<NumberParseResult>
 
         do {
             if (m_current == '_') {
-                if (UNLIKELY(!isASCIIDigit(peek(1))))
+                if (UNLIKELY(!isASCIIDigit(peek(1)) || isLegacyLiteral))
                     return WTF::nullopt;
 
                 shift();
@@ -1715,7 +1718,7 @@ ALWAYS_INLINE auto Lexer<T>::parseDecimal() -> Optional<NumberParseResult>
 
     while (isASCIIDigitOrSeparator(m_current)) {
         if (m_current == '_') {
-            if (UNLIKELY(!isASCIIDigit(peek(1))))
+            if (UNLIKELY(!isASCIIDigit(peek(1)) || isLegacyLiteral))
                 return WTF::nullopt;
 
             shift();
@@ -1725,7 +1728,7 @@ ALWAYS_INLINE auto Lexer<T>::parseDecimal() -> Optional<NumberParseResult>
         shift();
     }
     
-    if (UNLIKELY(Options::useBigInt() && m_current == 'n'))
+    if (UNLIKELY(Options::useBigInt() && m_current == 'n' && !isLegacyLiteral))
         return NumberParseResult { makeIdentifier(m_buffer8.data(), m_buffer8.size()) };
 
     return WTF::nullopt;