From 94cca4856d4a023a6f79ddc290c4495803557e93 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Wed, 21 Apr 2010 13:56:48 +0200
Subject: Fix parsing of regular expression literals.

Recognize regular expression classes and escape sequences.

Task-number: QTBUG-8108
Reviewed-by: Olivier Goffart
---
 src/declarative/qml/parser/qdeclarativejslexer.cpp | 108 +++++++++++++++------
 .../declarative/parserstress/tst_parserstress.cpp  |   3 +-
 2 files changed, 80 insertions(+), 31 deletions(-)

diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp
index a686dca..975ad4c 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer.cpp
+++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp
@@ -1144,47 +1144,97 @@ void Lexer::recordStartPos()
 bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
 {
     pos16 = 0;
-    bool lastWasEscape = false;
+    pattern = 0;
 
     if (prefix == EqualPrefix)
         record16(QLatin1Char('='));
 
-    while (1) {
-        if (isLineTerminator() || current == 0) {
+    while (true) {
+        switch (current) {
+
+        case 0: // eof
+        case '\n': case '\r': // line terminator
             errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression literal");
             return false;
-        }
-        else if (current != '/' || lastWasEscape == true)
-            {
-                record16(current);
-                lastWasEscape = !lastWasEscape && (current == '\\');
-            }
-        else {
-            if (driver)
+
+        case '/':
+            shift(1);
+
+            if (driver) // create the pattern
                 pattern = driver->intern(buffer16, pos16);
-            else
-                pattern = 0;
+
+            // scan the flags
             pos16 = 0;
+            flags = 0;
+            while (isIdentLetter(current)) {
+                int flag = Ecma::RegExp::flagFromChar(current);
+                if (flag == 0) {
+                    errmsg = QCoreApplication::translate("QDeclarativeParser", "Invalid regular expression flag '%0'")
+                             .arg(QChar(current));
+                    return false;
+                }
+                flags |= flag;
+                record16(current);
+                shift(1);
+            }
+            return true;
+
+        case '\\':
+            // regular expression backslash sequence
+            record16(current);
+            shift(1);
+
+            if (! current || isLineTerminator()) {
+                errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
+                return false;
+            }
+
+            record16(current);
             shift(1);
             break;
-        }
-        shift(1);
-    }
 
-    flags = 0;
-    while (isIdentLetter(current)) {
-        int flag = Ecma::RegExp::flagFromChar(current);
-        if (flag == 0) {
-            errmsg = QCoreApplication::translate("QDeclarativeParser", "Invalid regular expression flag '%0'")
-                     .arg(QChar(current));
-            return false;
-        }
-        flags |= flag;
-        record16(current);
-        shift(1);
-    }
+        case '[':
+            // regular expression class
+            record16(current);
+            shift(1);
+
+            while (current && ! isLineTerminator()) {
+                if (current == ']')
+                    break;
+                else if (current == '\\') {
+                    // regular expression backslash sequence
+                    record16(current);
+                    shift(1);
+
+                    if (! current || isLineTerminator()) {
+                        errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
+                        return false;
+                    }
+
+                    record16(current);
+                    shift(1);
+                } else {
+                    record16(current);
+                    shift(1);
+                }
+            }
+
+            if (current != ']') {
+                errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression class");
+                return false;
+            }
+
+            record16(current);
+            shift(1); // skip ]
+            break;
+
+        default:
+            record16(current);
+            shift(1);
+        } // switch
+    } // while
 
-    return true;
+    return false;
 }
 
 void Lexer::syncProhibitAutomaticSemicolon()
diff --git a/tests/auto/declarative/parserstress/tst_parserstress.cpp b/tests/auto/declarative/parserstress/tst_parserstress.cpp
index f61ca9f..f1e9c6e 100644
--- a/tests/auto/declarative/parserstress/tst_parserstress.cpp
+++ b/tests/auto/declarative/parserstress/tst_parserstress.cpp
@@ -131,8 +131,7 @@ void tst_parserstress::ecmascript()
     QDeclarativeComponent component(&engine);
     component.setData(qmlData, QUrl::fromLocalFile(SRCDIR + QString("/dummy.qml")));
     QSet<QString> failingTests;
-    failingTests << "regress-352044-02-n.js"
-                 << "regress-334158.js";
+    failingTests << "regress-352044-02-n.js";
     QFileInfo info(file);
     foreach (const QString &failing, failingTests) {
         if (info.fileName().endsWith(failing)) {
-- 
cgit v0.12


From 44a28b5530d3be2a12c91d084ea02f19aa6a9db3 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Wed, 21 Apr 2010 14:39:20 +0200
Subject: Fixed declarative/parserstress autotest.

The test ecma_3/Unicode/regress-352044-02-n.js is expected to throw
an uncaught syntax error when parsing the expression statement
"i \u002b= 1;".

Task-number: QTBUG-8108
---
 .../declarative/parserstress/tst_parserstress.cpp  | 24 ++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/tests/auto/declarative/parserstress/tst_parserstress.cpp b/tests/auto/declarative/parserstress/tst_parserstress.cpp
index f1e9c6e..294f2f7 100644
--- a/tests/auto/declarative/parserstress/tst_parserstress.cpp
+++ b/tests/auto/declarative/parserstress/tst_parserstress.cpp
@@ -130,16 +130,24 @@ void tst_parserstress::ecmascript()
 
     QDeclarativeComponent component(&engine);
     component.setData(qmlData, QUrl::fromLocalFile(SRCDIR + QString("/dummy.qml")));
-    QSet<QString> failingTests;
-    failingTests << "regress-352044-02-n.js";
+
     QFileInfo info(file);
-    foreach (const QString &failing, failingTests) {
-        if (info.fileName().endsWith(failing)) {
-            QEXPECT_FAIL("", "QTBUG-8108", Continue);
-            break;
-        }
+
+    if (info.fileName() == QLatin1String("regress-352044-02-n.js")) {
+        QVERIFY(component.isError());
+
+        QCOMPARE(component.errors().length(), 2);
+
+        QCOMPARE(component.errors().at(0).description(), QString("Expected token `;'"));
+        QCOMPARE(component.errors().at(0).line(), 66);
+
+        QCOMPARE(component.errors().at(1).description(), QString("Expected token `;'"));
+        QCOMPARE(component.errors().at(1).line(), 142);
+
+    } else {
+
+        QVERIFY(!component.isError());
     }
-    QVERIFY(!component.isError());
 }
 
 
-- 
cgit v0.12