summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2010-04-21 11:56:48 (GMT)
committerRoberto Raggi <roberto.raggi@nokia.com>2010-04-21 12:03:16 (GMT)
commit94cca4856d4a023a6f79ddc290c4495803557e93 (patch)
tree890f45417653f82c7243683521847e05ac6b24d0
parent38b8940413fc83d2e641be580369125709ffa8e1 (diff)
downloadQt-94cca4856d4a023a6f79ddc290c4495803557e93.zip
Qt-94cca4856d4a023a6f79ddc290c4495803557e93.tar.gz
Qt-94cca4856d4a023a6f79ddc290c4495803557e93.tar.bz2
Fix parsing of regular expression literals.
Recognize regular expression classes and escape sequences. Task-number: QTBUG-8108 Reviewed-by: Olivier Goffart
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer.cpp108
-rw-r--r--tests/auto/declarative/parserstress/tst_parserstress.cpp3
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)) {