summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2017-09-19 14:36:21 +0200
committerNikolai Kosjar <nikolai.kosjar@qt.io>2017-09-20 07:38:04 +0000
commit76006a1353f1282a940bf80a523b93ead7beae93 (patch)
tree1dd61134c864ec691800f4fc338a45ccdeace348
parent0bf27af0a718887248229b9693de16f150a38bf3 (diff)
downloadqt-creator-76006a1353f1282a940bf80a523b93ead7beae93.tar.gz
C++: Fix crash with invalid raw string literal
While parsing a document Bind::asStringLiteral() Token::spell() was called for a raw string literal token with a Token::literal nullptr. This is due scanRawStringLiteral() not properly aborting for invalid/incomplete code and that the code paths handling multi-line-raw-strings were not limited to the highlighting case. Address both cases. Task-number: QTCREATORBUG-18941 Change-Id: I489d288ccbd7b59be396dada846613ff555436cf Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Orgad Shaneh <orgads@gmail.com>
-rw-r--r--src/libs/3rdparty/cplusplus/Lexer.cpp16
-rw-r--r--tests/auto/cplusplus/lexer/tst_lexer.cpp8
-rw-r--r--tests/auto/cplusplus/misc/tst_misc.cpp13
3 files changed, 31 insertions, 6 deletions
diff --git a/src/libs/3rdparty/cplusplus/Lexer.cpp b/src/libs/3rdparty/cplusplus/Lexer.cpp
index e62c9412a4..079ae0ca6e 100644
--- a/src/libs/3rdparty/cplusplus/Lexer.cpp
+++ b/src/libs/3rdparty/cplusplus/Lexer.cpp
@@ -211,7 +211,7 @@ void Lexer::scan_helper(Token *tok)
_state = 0;
scanCppComment(originalKind);
return;
- } else if (isRawStringLiteral(s._tokenKind)) {
+ } else if (!control() && isRawStringLiteral(s._tokenKind)) {
tok->f.kind = s._tokenKind;
if (scanUntilRawStringLiteralEndSimple())
_state = 0;
@@ -755,13 +755,17 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint)
yyinp();
} else if (_yychar == ')') {
yyinp();
- if (delimLength == -1)
- break;
+ if (delimLength == -1) {
+ tok->f.kind = T_ERROR;
+ return;
+ }
closingDelimCandidate = _currentChar;
} else {
if (delimLength == -1) {
- if (_yychar == '\\' || std::isspace(_yychar))
- break;
+ if (_yychar == '\\' || std::isspace(_yychar)) {
+ tok->f.kind = T_ERROR;
+ return;
+ }
yyinp();
} else {
if (!closingDelimCandidate) {
@@ -804,7 +808,7 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint)
else
tok->f.kind = T_RAW_STRING_LITERAL;
- if (!closed)
+ if (!control() && !closed)
s._tokenKind = tok->f.kind;
}
diff --git a/tests/auto/cplusplus/lexer/tst_lexer.cpp b/tests/auto/cplusplus/lexer/tst_lexer.cpp
index a2c415d33c..1721efaedd 100644
--- a/tests/auto/cplusplus/lexer/tst_lexer.cpp
+++ b/tests/auto/cplusplus/lexer/tst_lexer.cpp
@@ -366,6 +366,14 @@ void tst_SimpleLexer::literals_data()
<< T_RAW_STRING_LITERAL
;
QTest::newRow("raw-string-literals") << source << expectedTokenKindList;
+
+ source = "R\"\\" ;
+ expectedTokenKindList = TokenKindList() << T_ERROR;
+ QTest::newRow("invalid-raw-string-literals1") << source << expectedTokenKindList;
+
+ source = "R\")" ;
+ expectedTokenKindList = TokenKindList() << T_ERROR;
+ QTest::newRow("invalid-raw-string-literals2") << source << expectedTokenKindList;
}
void tst_SimpleLexer::preprocessor()
diff --git a/tests/auto/cplusplus/misc/tst_misc.cpp b/tests/auto/cplusplus/misc/tst_misc.cpp
index aff5a12ce0..808408df40 100644
--- a/tests/auto/cplusplus/misc/tst_misc.cpp
+++ b/tests/auto/cplusplus/misc/tst_misc.cpp
@@ -48,6 +48,8 @@ private slots:
void astPathOnGeneratedTokens();
void typeMatcher();
+
+ void doNotCrashForInvalidRawString();
};
void tst_Misc::diagnosticClient_error()
@@ -266,5 +268,16 @@ void tst_Misc::typeMatcher()
}
}
+void tst_Misc::doNotCrashForInvalidRawString()
+{
+ const QByteArray src("\n"
+ "void f() { enum { Size = sizeof(R\"[^\\s]+([^]+)*\") }; }"
+ "}\n"
+ );
+ Document::Ptr doc = Document::create("crash");
+ doc->setUtf8Source(src);
+ doc->check();
+}
+
QTEST_MAIN(tst_Misc)
#include "tst_misc.moc"