ScintillaOrg / lexilla

A library of language lexers for use with Scintilla
https://www.scintilla.org/Lexilla.html
Other
187 stars 67 forks source link

[Bash] Correct handle backslash in heredoc delimiter #257

Closed zufuliu closed 3 months ago

zufuliu commented 3 months ago

[Bash] Correct handle backslash in heredoc delimiter Patch and test cases: heredoc-delimiter-0725.zip

This changed "collect the delimiter" block to following:

// * if single quoted, there's no escape
// * if double quoted, there are \\ and \" escapes
if (HereDoc.Quoted && sc.ch == HereDoc.Quote && (HereDoc.BackslashCount & 1) == 0) { // closing quote => end of delimiter
    sc.ForwardSetState(SCE_SH_DEFAULT | insideCommand);
} else if (sc.ch == '\\' && HereDoc.Quote != '\'') {
    HereDoc.Escaped = true;
    HereDoc.BackslashCount += 1;
    if ((HereDoc.BackslashCount & 1) == 0 || (HereDoc.Quoted && !AnyOf(sc.chNext, '\"', '\\'))) {
        // in quoted prefixes only \ and the quote eat the escape
        HereDoc.Append(sc.ch);
    } else {
        // skip escape prefix
    }
} else if (HereDoc.Quoted || setHereDoc2.Contains(sc.ch) || (sc.ch > 32 && sc.ch < 127 && (HereDoc.BackslashCount & 1) != 0)) {
    HereDoc.BackslashCount = 0;
    HereDoc.Append(sc.ch);
} else {
    sc.SetState(SCE_SH_DEFAULT | insideCommand);
}

Also added missing | insideCommand in "closing quote => end of delimiter" block.

|| (sc.ch > 32 && sc.ch < 127 && (HereDoc.BackslashCount & 1) != 0) can be removed if it's not worth to fix escaped quotes and meta characters in unquoted delimiter.