Throw a parse error on octal numbers and escape sequences
authorLars Knoll <lars.knoll@digia.com>
Mon, 10 Dec 2012 21:06:33 +0000 (22:06 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 11 Dec 2012 13:50:32 +0000 (14:50 +0100)
This is compliant with EcmaScript 5.1, where octal numbers
and escape sequences are an optional and deprecated part
of the syntax.

Allow leading 0's in qml mode, but interpret the result
as decimal. This is also to keep compatibility with
existing code.

Change-Id: Ic3450ec3dd17966846751ee688a90c65939ba78f
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
13 files changed:
src/qml/qml/parser/qqmljslexer.cpp
tests/auto/qml/qqmlecmascript/data/numberParsing.1.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/numberParsing.2.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/numberParsing.3.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/numberParsing.4.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/numberParsing.5.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/numberParsing.6.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/numberParsing.7.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/stringParsing_error.2.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/stringParsing_error.3.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/stringParsing_error.4.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp

index b53f16c..0142e94 100644 (file)
@@ -631,14 +631,24 @@ again:
                 case 'v':  u = QLatin1Char('\v'); scanChar(); break;
 
                 case '0':
-                    if (! _codePtr[1].isDigit()) {
+                    if (! _codePtr->isDigit()) {
                         scanChar();
                         u = QLatin1Char('\0');
-                    } else {
-                        // ### parse deprecated octal escape sequence ?
-                        u = _char;
+                        break;
                     }
-                    break;
+                    // fall through
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                    _errorCode = IllegalEscapeSequence;
+                    _errorMessage = QCoreApplication::translate("QQmlParser", "Octal escape sequences are not allowed");
+                    return T_ERROR;
 
                 case '\r':
                     if (isLineTerminatorSequence() == 2) {
@@ -770,6 +780,10 @@ int Lexer::scanNumber(QChar ch)
             _tokenValue = integer;
             return T_NUMERIC_LITERAL;
         }
+    } else if (_char.isDigit() && !qmlMode()) {
+        _errorCode = IllegalCharacter;
+        _errorMessage = QCoreApplication::translate("QQmlParser", "Decimal numbers can't start with '0'");
+        return T_ERROR;
     }
 
     QVarLengthArray<char,32> chars;
diff --git a/tests/auto/qml/qqmlecmascript/data/numberParsing.1.qml b/tests/auto/qml/qqmlecmascript/data/numberParsing.1.qml
new file mode 100644 (file)
index 0000000..1b83a1b
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = 0;
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/numberParsing.2.qml b/tests/auto/qml/qqmlecmascript/data/numberParsing.2.qml
new file mode 100644 (file)
index 0000000..77f1317
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = 1.01;
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/numberParsing.3.qml b/tests/auto/qml/qqmlecmascript/data/numberParsing.3.qml
new file mode 100644 (file)
index 0000000..f20baf3
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = 1e-10;
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/numberParsing.4.qml b/tests/auto/qml/qqmlecmascript/data/numberParsing.4.qml
new file mode 100644 (file)
index 0000000..e115dbb
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = -1.2;
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/numberParsing.5.qml b/tests/auto/qml/qqmlecmascript/data/numberParsing.5.qml
new file mode 100644 (file)
index 0000000..c3db176
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = .4e-5;
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/numberParsing.6.qml b/tests/auto/qml/qqmlecmascript/data/numberParsing.6.qml
new file mode 100644 (file)
index 0000000..471db87
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = 0x1;
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/numberParsing.7.qml b/tests/auto/qml/qqmlecmascript/data/numberParsing.7.qml
new file mode 100644 (file)
index 0000000..f8f8e1a
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = 0Xa;
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml b/tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml
new file mode 100644 (file)
index 0000000..71b82b9
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = "\01";
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/stringParsing_error.2.qml b/tests/auto/qml/qqmlecmascript/data/stringParsing_error.2.qml
new file mode 100644 (file)
index 0000000..787f1d8
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = "\1a";
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/stringParsing_error.3.qml b/tests/auto/qml/qqmlecmascript/data/stringParsing_error.3.qml
new file mode 100644 (file)
index 0000000..9954617
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = "\012";
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/stringParsing_error.4.qml b/tests/auto/qml/qqmlecmascript/data/stringParsing_error.4.qml
new file mode 100644 (file)
index 0000000..5bf41f0
--- /dev/null
@@ -0,0 +1,9 @@
+
+import QtQuick 2.0
+
+QtObject {
+    function code() {
+        var x = "\00a";
+    }
+}
+
index a99c5fa..852c0ef 100644 (file)
@@ -285,6 +285,8 @@ private slots:
     void propertyOverride();
     void concatenatedStringPropertyAccess();
     void jsOwnedObjectsDeletedOnEngineDestroy();
+    void numberParsing();
+    void stringParsing();
 
 private:
     static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -7335,6 +7337,28 @@ void tst_qqmlecmascript::jsOwnedObjectsDeletedOnEngineDestroy()
     delete object;
 }
 
+void tst_qqmlecmascript::numberParsing()
+{
+    for (int i = 1; i < 8; ++i) {
+        QString file("numberParsing.%1.qml");
+        file = file.arg(i);
+        QQmlComponent component(&engine, testFileUrl(file));
+        QObject *object = component.create();
+        QVERIFY(object != 0);
+    }
+}
+
+void tst_qqmlecmascript::stringParsing()
+{
+    for (int i = 1; i < 5; ++i) {
+        QString file("stringParsing_error.%1.qml");
+        file = file.arg(i);
+        QQmlComponent component(&engine, testFileUrl(file));
+        QObject *object = component.create();
+        QVERIFY(object == 0);
+    }
+}
+
 QTEST_MAIN(tst_qqmlecmascript)
 
 #include "tst_qqmlecmascript.moc"