Stop using comma from command substitution in brace expansion

Fixes #5048
This commit is contained in:
Johannes Altmanninger 2024-04-25 13:32:42 +02:00
parent ec33550cff
commit fb99edae92
3 changed files with 17 additions and 4 deletions

View file

@ -122,6 +122,8 @@ bitflags! {
const SYMBOLIC = 1 << 3; const SYMBOLIC = 1 << 3;
/// Escape : and = /// Escape : and =
const SEPARATORS = 1 << 4; const SEPARATORS = 1 << 4;
/// Escape ,
const COMMA = 1 << 5;
} }
} }
@ -183,6 +185,7 @@ pub fn escape_string(s: &wstr, style: EscapeStringStyle) -> WString {
fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString { fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString {
let escape_printables = !flags.contains(EscapeFlags::NO_PRINTABLES); let escape_printables = !flags.contains(EscapeFlags::NO_PRINTABLES);
let escape_separators = flags.contains(EscapeFlags::SEPARATORS); let escape_separators = flags.contains(EscapeFlags::SEPARATORS);
let escape_comma = flags.contains(EscapeFlags::COMMA);
let no_quoted = flags.contains(EscapeFlags::NO_QUOTED); let no_quoted = flags.contains(EscapeFlags::NO_QUOTED);
let no_tilde = flags.contains(EscapeFlags::NO_TILDE); let no_tilde = flags.contains(EscapeFlags::NO_TILDE);
let no_qmark = feature_test(FeatureFlag::qmark_noglob); let no_qmark = feature_test(FeatureFlag::qmark_noglob);
@ -300,6 +303,13 @@ fn escape_string_script(input: &wstr, flags: EscapeFlags) -> WString {
} }
out.push(c); out.push(c);
} }
',' => {
if escape_comma {
need_escape = true;
out.push('\\');
}
out.push(c);
}
'&' | '$' | ' ' | '#' | '<' | '>' | '(' | ')' | '[' | ']' | '{' | '}' | '?' | '*' '&' | '$' | ' ' | '#' | '<' | '>' | '(' | ')' | '[' | ']' | '{' | '}' | '?' | '*'
| '|' | ';' | '"' | '%' | '~' => { | '|' | ';' | '"' | '%' | '~' => {

View file

@ -8,9 +8,9 @@ use crate::builtins::shared::{
STATUS_INVALID_ARGS, STATUS_NOT_EXECUTABLE, STATUS_READ_TOO_MUCH, STATUS_UNMATCHED_WILDCARD, STATUS_INVALID_ARGS, STATUS_NOT_EXECUTABLE, STATUS_READ_TOO_MUCH, STATUS_UNMATCHED_WILDCARD,
}; };
use crate::common::{ use crate::common::{
char_offset, charptr2wcstring, escape, escape_string_for_double_quotes, unescape_string, char_offset, charptr2wcstring, escape, escape_string, escape_string_for_double_quotes,
valid_var_name_char, wcs2zstring, UnescapeFlags, UnescapeStringStyle, EXPAND_RESERVED_BASE, unescape_string, valid_var_name_char, wcs2zstring, EscapeFlags, EscapeStringStyle,
EXPAND_RESERVED_END, UnescapeFlags, UnescapeStringStyle, EXPAND_RESERVED_BASE, EXPAND_RESERVED_END,
}; };
use crate::complete::{CompleteFlags, Completion, CompletionList, CompletionReceiver}; use crate::complete::{CompleteFlags, Completion, CompletionList, CompletionReceiver};
use crate::env::{EnvVar, Environment}; use crate::env::{EnvVar, Environment};
@ -1096,7 +1096,7 @@ pub fn expand_cmdsubst(
} }
for sub_item in sub_res { for sub_item in sub_res {
let sub_item2 = escape(&sub_item); let sub_item2 = escape_string(&sub_item, EscapeStringStyle::Script(EscapeFlags::COMMA));
for tail_item in &*tail_expand { for tail_item in &*tail_expand {
let mut whole_item = WString::new(); let mut whole_item = WString::new();
whole_item.reserve(paren_begin + 1 + sub_item2.len() + 1 + tail_item.completion.len()); whole_item.reserve(paren_begin + 1 + sub_item2.len() + 1 + tail_item.completion.len());

View file

@ -48,3 +48,6 @@ world}
end end
#CHECK: '{hello #CHECK: '{hello
#CHECK: world}' #CHECK: world}'
echo {a(echo ,)b}
#CHECK: {a,b}