Make numeric-literal parsing even more robust.
authorErik Verbruggen <erik.verbruggen@me.com>
Tue, 15 Jan 2013 12:30:55 +0000 (13:30 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 16 Jan 2013 10:31:53 +0000 (11:31 +0100)
The numeric value could overflow a unsigned 64-bit integer, so instead
just buffer the string and have libc's strtod handle all the conversion.

Change-Id: I220e490ddc22363460b0df65a91b47336e747310
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/qml/parser/qqmljslexer.cpp
tests/auto/qml/qqmllanguage/data/literals.qml
tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp

index b2020d8..d154cec 100644 (file)
@@ -889,12 +889,14 @@ again:
 int Lexer::scanNumber(QChar ch)
 {
     if (ch != QLatin1Char('0')) {
-        quint64 integer = ch.unicode() - '0';
+        QByteArray buf;
+        buf.reserve(64);
+        buf += ch.toLatin1();
 
         QChar n = _char;
         const QChar *code = _codePtr;
         while (n.isDigit()) {
-            integer = integer * 10 + (n.unicode() - '0');
+            buf += n.toLatin1();
             n = *code++;
         }
 
@@ -903,7 +905,8 @@ int Lexer::scanNumber(QChar ch)
                 _codePtr = code - 1;
                 scanChar();
             }
-            _tokenValue = integer;
+            buf.append('\0');
+            _tokenValue = strtod(buf.constData(), 0);
             return T_NUMERIC_LITERAL;
         }
     } else if (_char.isDigit() && !qmlMode()) {
index 462eb4c..564b389 100644 (file)
@@ -9,6 +9,7 @@ QtObject {
     property variant n6:  3e+12
     property variant n7:  0.1e9
     property variant n8:  1152921504606846976
+    property variant n9:  100000000000000000000
 
     property variant c1:  "\b"     // special characters
     property variant c2:  "\f"
index 850e192..d7fa515 100644 (file)
@@ -3053,7 +3053,8 @@ void tst_qqmllanguage::literals_data()
     QTest::newRow("fp3") << "n5" << QVariant(3e-12);
     QTest::newRow("fp4") << "n6" << QVariant(3e+12);
     QTest::newRow("fp5") << "n7" << QVariant(0.1e9);
-    QTest::newRow("large-int") << "n8" << QVariant((double) 1152921504606846976);
+    QTest::newRow("large-int1") << "n8" << QVariant((double) 1152921504606846976);
+    QTest::newRow("large-int2") << "n9" << QVariant(100000000000000000000.);
 
     QTest::newRow("special1") << "c1" << QVariant(QString("\b"));
     QTest::newRow("special2") << "c2" << QVariant(QString("\f"));