ScintillaOrg / lexilla

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

[Bash] Don't nest `${}` parameter expansion on `{` #216

Closed zufuliu closed 9 months ago

zufuliu commented 10 months ago

https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion

When braces are used, the matching ending brace is the first ‘}’ not escaped by a backslash or within a quoted string, and not within an embedded arithmetic expansion, command substitution, or parameter expansion.

following code (from __parse_options() inside msys2's usr\share\bash-completion\bash_completion script) is messed by incorrect nesting:

# Expand --[no]foo to --foo and --nofoo etc
if [[ $option =~ (\[((no|dont)-?)\]). ]]; then
    option2=${option/"${BASH_REMATCH[1]}"/}
    option2=${option2%%[<{().[]*}
    printf '%s\n' "${option2/=*/=}"
    option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"}
fi

option=${option%%[<{().[]*}
printf '%s\n' "${option/=*/=}"
zufuliu commented 10 months ago

Patch to fix the bug: 216.patch

@@ -935,7 +935,9 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
                        continue;
                    }
                } else if (sc.ch == QuoteStack.Current.Up) {
-                   QuoteStack.Current.Count++;
+                   if (QuoteStack.Current.Style != QuoteStyle::Parameter) {
+                       QuoteStack.Current.Count++;
+                   }
                } else {
                    if (QuoteStack.Current.Style == QuoteStyle::String ||
                        QuoteStack.Current.Style == QuoteStyle::HereDoc ||
option="no[foo]"
option=${option%%[<{().[]*}
echo $option

replacing second { with } inside option=${option%%[<{().[]*} causes syntax errors, so there is no need to detect regex pattern range.