From bac602c454f38ddde01167a3f75cb10ce1cfb876 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 10 Dec 2012 22:06:33 +0100 Subject: [PATCH] Throw a parse error on octal numbers and escape sequences 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 --- src/qml/qml/parser/qqmljslexer.cpp | 24 +++++++++++++++---- .../qml/qqmlecmascript/data/numberParsing.1.qml | 9 +++++++ .../qml/qqmlecmascript/data/numberParsing.2.qml | 9 +++++++ .../qml/qqmlecmascript/data/numberParsing.3.qml | 9 +++++++ .../qml/qqmlecmascript/data/numberParsing.4.qml | 9 +++++++ .../qml/qqmlecmascript/data/numberParsing.5.qml | 9 +++++++ .../qml/qqmlecmascript/data/numberParsing.6.qml | 9 +++++++ .../qml/qqmlecmascript/data/numberParsing.7.qml | 9 +++++++ .../qqmlecmascript/data/stringParsing_error.1.qml | 9 +++++++ .../qqmlecmascript/data/stringParsing_error.2.qml | 9 +++++++ .../qqmlecmascript/data/stringParsing_error.3.qml | 9 +++++++ .../qqmlecmascript/data/stringParsing_error.4.qml | 9 +++++++ .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 24 ++++++++++++++++++++ 13 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 tests/auto/qml/qqmlecmascript/data/numberParsing.1.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/numberParsing.2.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/numberParsing.3.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/numberParsing.4.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/numberParsing.5.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/numberParsing.6.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/numberParsing.7.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/stringParsing_error.2.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/stringParsing_error.3.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/stringParsing_error.4.qml diff --git a/src/qml/qml/parser/qqmljslexer.cpp b/src/qml/qml/parser/qqmljslexer.cpp index b53f16c..0142e94 100644 --- a/src/qml/qml/parser/qqmljslexer.cpp +++ b/src/qml/qml/parser/qqmljslexer.cpp @@ -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 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 index 0000000..1b83a1b --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/numberParsing.1.qml @@ -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 index 0000000..77f1317 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/numberParsing.2.qml @@ -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 index 0000000..f20baf3 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/numberParsing.3.qml @@ -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 index 0000000..e115dbb --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/numberParsing.4.qml @@ -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 index 0000000..c3db176 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/numberParsing.5.qml @@ -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 index 0000000..471db87 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/numberParsing.6.qml @@ -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 index 0000000..f8f8e1a --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/numberParsing.7.qml @@ -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 index 0000000..71b82b9 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml @@ -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 index 0000000..787f1d8 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/stringParsing_error.2.qml @@ -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 index 0000000..9954617 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/stringParsing_error.3.qml @@ -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 index 0000000..5bf41f0 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/stringParsing_error.4.qml @@ -0,0 +1,9 @@ + +import QtQuick 2.0 + +QtObject { + function code() { + var x = "\00a"; + } +} + diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index a99c5fa..852c0ef 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -285,6 +285,8 @@ private slots: void propertyOverride(); void concatenatedStringPropertyAccess(); void jsOwnedObjectsDeletedOnEngineDestroy(); + void numberParsing(); + void stringParsing(); private: static void propertyVarWeakRefCallback(v8::Persistent 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" -- 1.7.2.5