From c19dd24d81de9e853e16a1fdfe38a69c7dee8091 Mon Sep 17 00:00:00 2001 From: zufuliu Date: Fri, 2 Feb 2024 18:11:47 +0800 Subject: [PATCH] Fix infinite loop in C# and Nim string interpolating highlighting code. --- scintilla/lexers/LexCSharp.cxx | 13 +++++++++---- scintilla/lexers/LexNim.cxx | 8 ++++++-- scintilla/lexers/LexPython.cxx | 9 +++------ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/scintilla/lexers/LexCSharp.cxx b/scintilla/lexers/LexCSharp.cxx index 9bd465cc19..e287acd17a 100644 --- a/scintilla/lexers/LexCSharp.cxx +++ b/scintilla/lexers/LexCSharp.cxx @@ -206,6 +206,7 @@ void ColouriseCSharpDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init int chPrevNonWhite = 0; DocTagState docTagState = DocTagState::None; EscapeSequence escSeq; + bool closeBrace = false; std::vector nestedState; @@ -477,8 +478,10 @@ void ColouriseCSharpDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init case SCE_CSHARP_RAWSTRING_ML: case SCE_CSHARP_INTERPOLATED_RAWSTRING_ML: if (sc.atLineStart && IsSingleLineString(sc.state)) { - sc.SetState(SCE_CSHARP_DEFAULT); - break; + if (!closeBrace) { + sc.SetState(SCE_CSHARP_DEFAULT); + break; + } } if (sc.ch == '\\') { if (HasEscapeChar(sc.state)) { @@ -551,6 +554,7 @@ void ColouriseCSharpDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init } } } else if (sc.ch == '}') { + closeBrace = false; if (IsInterpolatedString(sc.state)) { const int interpolatorCount = IsPlainString(sc.state) ? 1 : GetMatchedDelimiterCount(styler, sc.currentPos, '}'); const bool interpolating = !nestedState.empty() && (interpolatorCount >= stringInterpolatorCount); @@ -702,6 +706,7 @@ void ColouriseCSharpDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init sc.SetState(SCE_CSHARP_IDENTIFIER); } else if (IsAGraphic(sc.ch) && sc.ch != '\\') { const bool interpolating = !nestedState.empty(); + sc.SetState(interpolating ? SCE_CSHARP_OPERATOR2 : SCE_CSHARP_OPERATOR); if (sc.ch == '(' || sc.ch == '[') { if (interpolating) { nestedState.back().parenCount += 1; @@ -724,7 +729,8 @@ void ColouriseCSharpDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init escSeq.outerState = state.state; stringDelimiterCount = state.delimiterCount; stringInterpolatorCount = state.interpolatorCount; - sc.SetState((sc.ch == '}') ? state.state : SCE_CSHARP_FORMAT_SPECIFIER); + closeBrace = sc.ch == '}'; + sc.ChangeState(closeBrace ? state.state : SCE_CSHARP_FORMAT_SPECIFIER); continue; } } else { @@ -736,7 +742,6 @@ void ColouriseCSharpDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init kwType = KeywordType::None; } } - sc.SetState(interpolating ? SCE_CSHARP_OPERATOR2 : SCE_CSHARP_OPERATOR); } } diff --git a/scintilla/lexers/LexNim.cxx b/scintilla/lexers/LexNim.cxx index 8c8172948b..8df38a5b67 100644 --- a/scintilla/lexers/LexNim.cxx +++ b/scintilla/lexers/LexNim.cxx @@ -237,8 +237,12 @@ void ColouriseNimDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSty case SCE_NIM_TRIPLE_STRING: case SCE_NIM_TRIPLE_FMTSTRING: if (sc.atLineStart && sc.state < SCE_NIM_TRIPLE_STRING) { - sc.SetState(SCE_NIM_DEFAULT); - } else if (sc.ch == '\\') { + if (fmtPart == FormatStringPart::None) { + sc.SetState(SCE_NIM_DEFAULT); + break; + } + } + if (sc.ch == '\\') { if (sc.state <= SCE_NIM_FMTSTRING) { escSeq.resetEscapeState(sc.state, sc.chNext); sc.SetState(SCE_NIM_ESCAPECHAR); diff --git a/scintilla/lexers/LexPython.cxx b/scintilla/lexers/LexPython.cxx index dd57f1c8b9..be70b9b94f 100644 --- a/scintilla/lexers/LexPython.cxx +++ b/scintilla/lexers/LexPython.cxx @@ -785,7 +785,9 @@ void ColourisePyDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyl sc.SetState(SCE_PY_OPERATOR); } } else if (IsAGraphic(sc.ch) && sc.ch != '\\') { + kwType = KeywordType::None; const bool interpolating = !nestedState.empty(); + sc.SetState(interpolating ? SCE_PY_OPERATOR2 : SCE_PY_OPERATOR); int braceCount = 0; if (sc.ch == '{' || sc.ch == '[' || sc.ch == '(') { if (interpolating) { @@ -809,19 +811,14 @@ void ColourisePyDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyl } } } - - int style = SCE_PY_OPERATOR; if (interpolating) { - style = SCE_PY_OPERATOR2; const FormattedStringState &state = nestedState.back(); if (state.parenCount == 0 && IsPyFormattedStringEnd(sc, braceCount)) { fstringPart = (sc.ch == '}') ? FormattedStringPart::End : FormattedStringPart::FormatSpec; - sc.SetState(state.state); + sc.ChangeState(state.state); continue; } } - sc.SetState(style); - kwType = KeywordType::None; } }