Fix lexer handling of escape sequences in string

The lexer handled escape sequences inside string literals
wrongly which could led to follow-up problems like wrong
offsets or even lines of tokens.

Change-Id: Ief14dda77f9079931a7d19ea549017a1d59c2d0b
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Christian Stenger 2020-04-20 15:23:12 +02:00
parent 0e393fa01f
commit dc56e57cc5
2 changed files with 31 additions and 1 deletions

View File

@ -925,6 +925,7 @@ int Lexer::scanString(ScanStringMode mode)
// rewind by one char, so things gets scanned correctly // rewind by one char, so things gets scanned correctly
--_codePtr; --_codePtr;
--_currentColumnNumber;
_validTokenText = true; _validTokenText = true;
_tokenText = QString(startCode, _codePtr - startCode); _tokenText = QString(startCode, _codePtr - startCode);

View File

@ -288,7 +288,7 @@ void tst_qqmlparser::stringLiteral()
Engine engine; Engine engine;
Lexer lexer(&engine); Lexer lexer(&engine);
QLatin1String code("'hello string'"); QString code("'hello string'");
lexer.setCode(code , 1); lexer.setCode(code , 1);
Parser parser(&engine); Parser parser(&engine);
QVERIFY(parser.parseExpression()); QVERIFY(parser.parseExpression());
@ -299,6 +299,35 @@ void tst_qqmlparser::stringLiteral()
QCOMPARE(literal->value, "hello string"); QCOMPARE(literal->value, "hello string");
QCOMPARE(literal->firstSourceLocation().begin(), 0u); QCOMPARE(literal->firstSourceLocation().begin(), 0u);
QCOMPARE(literal->lastSourceLocation().end(), quint32(code.size())); QCOMPARE(literal->lastSourceLocation().end(), quint32(code.size()));
// test for correct handling escape sequences inside strings
QLatin1String leftCode("'hello\\n\\tstring'");
QLatin1String plusCode(" + ");
QLatin1String rightCode("'\\nbye'");
code = leftCode + plusCode + rightCode;
lexer.setCode(code , 1);
QVERIFY(parser.parseExpression());
expression = parser.expression();
QVERIFY(expression);
auto *binaryExpression = QQmlJS::AST::cast<QQmlJS::AST::BinaryExpression *>(expression);
QVERIFY(binaryExpression);
literal = QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(binaryExpression->left);
QVERIFY(literal);
QCOMPARE(literal->value, "hello\n\tstring");
QCOMPARE(literal->firstSourceLocation().begin(), 0u);
QCOMPARE(literal->firstSourceLocation().startLine, 1u);
QCOMPARE(literal->lastSourceLocation().end(), quint32(leftCode.size()));
QVERIFY(binaryExpression->right);
literal = QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(binaryExpression->right);
QVERIFY(literal);
QCOMPARE(literal->value, "\nbye");
quint32 offset = quint32(leftCode.size() + plusCode.size());
QCOMPARE(literal->firstSourceLocation().begin(), offset);
QCOMPARE(literal->firstSourceLocation().startLine, 1u);
QCOMPARE(literal->lastSourceLocation().end(), quint32(code.size()));
} }
void tst_qqmlparser::noSubstitutionTemplateLiteral() void tst_qqmlparser::noSubstitutionTemplateLiteral()