From 7475b073fb8084cf1304cea8a1781e74204a0a11 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 21 Nov 2023 16:07:53 +0100 Subject: CPlusPlus: Fix finding end of raw string literal The employed algorithm lacked proper backtracking, potentially causing us to miss the delimiter altogether. Change-Id: I7993c3c27d034925bd884e192779c85c54be9ec4 Reviewed-by: hjk --- src/libs/3rdparty/cplusplus/Lexer.cpp | 18 +++++++++--------- src/plugins/cppeditor/cpphighlighter.cpp | 6 ++++++ .../cppeditor/testcases/highlightingtestcase.cpp | 3 +++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/libs/3rdparty/cplusplus/Lexer.cpp b/src/libs/3rdparty/cplusplus/Lexer.cpp index deafe432b6..62a95f455a 100644 --- a/src/libs/3rdparty/cplusplus/Lexer.cpp +++ b/src/libs/3rdparty/cplusplus/Lexer.cpp @@ -838,16 +838,16 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint) bool Lexer::scanUntilRawStringLiteralEndPrecise() { - int matchLen = 0; + QByteArray slidingWindow; + slidingWindow.reserve(_expectedRawStringSuffix.size()); while (_yychar) { - if (_yychar == _expectedRawStringSuffix.at(matchLen)) { - if (++matchLen == _expectedRawStringSuffix.length()) { - _expectedRawStringSuffix.clear(); - yyinp(); - return true; - } - } else { - matchLen = 0; + slidingWindow.append(_yychar); + if (slidingWindow.size() > _expectedRawStringSuffix.size()) + slidingWindow.removeFirst(); + if (slidingWindow == _expectedRawStringSuffix) { + _expectedRawStringSuffix.clear(); + yyinp(); + return true; } yyinp(); } diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp index f562d9afec..142b2b296c 100644 --- a/src/plugins/cppeditor/cpphighlighter.cpp +++ b/src/plugins/cppeditor/cpphighlighter.cpp @@ -590,6 +590,12 @@ void CppHighlighterTest::test_data() << 38 << 18 << 39 << 3 << C_STRING; QTest::newRow("multi-line user-defined UTF-16 string literal (suffix)") << 39 << 4 << 39 << 5 << C_OPERATOR; + QTest::newRow("multi-line raw string literal with consecutive closing parens (prefix)") + << 48 << 18 << 48 << 20 << C_KEYWORD; + QTest::newRow("multi-line raw string literal with consecutive closing parens (content)") + << 49 << 1 << 49 << 1 << C_STRING; + QTest::newRow("multi-line raw string literal with consecutive closing parens (suffix)") + << 49 << 2 << 49 << 3 << C_KEYWORD; } void CppHighlighterTest::test() diff --git a/src/plugins/cppeditor/testcases/highlightingtestcase.cpp b/src/plugins/cppeditor/testcases/highlightingtestcase.cpp index d1ec061aa2..a9102ce457 100644 --- a/src/plugins/cppeditor/testcases/highlightingtestcase.cpp +++ b/src/plugins/cppeditor/testcases/highlightingtestcase.cpp @@ -44,3 +44,6 @@ static void parenTest() /* comment */ \ } while (false); } + +const char* s7 = R"( +))"; -- cgit v1.2.3