Skip to content

Commit

Permalink
Fix infinite loop in C# and Nim string interpolating highlighting code.
Browse files Browse the repository at this point in the history
  • Loading branch information
zufuliu committed Feb 2, 2024
1 parent d96452d commit c19dd24
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
13 changes: 9 additions & 4 deletions scintilla/lexers/LexCSharp.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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<InterpolatedStringState> nestedState;

Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -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);
}
}

Expand Down
8 changes: 6 additions & 2 deletions scintilla/lexers/LexNim.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 3 additions & 6 deletions scintilla/lexers/LexPython.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
}

Expand Down

0 comments on commit c19dd24

Please sign in to comment.