uucore: quote a lone brace in the shell quoting styles

GNU quotes `{` and `}` when they are the whole name in the shell
quoting styles, while braces inside a longer name stay bare. This
affects `printf %q` and `ls --quoting-style=shell*`.
This commit is contained in:
John Costa authored and Dorian Péron committed 2026-10-27 22:10:45 +01:00
1 parent 3caad2f042
commit d7413be9bb
3 files changed
+16 -1

No files matched your search

@@ -1186,6 +1186,14 @@ mod tests {
check_names_both("name#", &[("name#", "shell"), ("name#", "shell-escape")]);
}
#[test]
fn test_lone_brace() {
check_names_both("{", &[("'{'", "shell"), ("'{'", "shell-escape")]);
check_names_both("}", &[("'}'", "shell"), ("'}'", "shell-escape")]);
check_names_both("{}", &[("{}", "shell"), ("{}", "shell-escape")]);
check_names_both("{a,b}", &[("{a,b}", "shell"), ("{a,b}", "shell-escape")]);
}
#[test]
fn test_special_chars_in_double_quotes() {
check_names_both(
@@ -261,7 +261,11 @@ fn finalize_shell_quoter(
must_quote: bool,
quotes: ShellQuotes,
) -> Vec<u8> {
let contains_quote_chars = must_quote || bytes_start_with(reference, SPECIAL_SHELL_CHARS_START);
// A lone brace is quoted, but braces inside a longer name are not.
let contains_quote_chars = must_quote
|| bytes_start_with(reference, SPECIAL_SHELL_CHARS_START)
|| reference == b"{"
|| reference == b"}";
if must_quote | contains_quote_chars {
let mut quoted = Vec::<u8>::with_capacity(buffer.len() + 2);
+3
View File
@@ -20,6 +20,9 @@ use uutests::new_ucmd;
#[case::sub_q_string_non_printable(&["non-printable: %q", "\"$test\""], "non-printable: '\"$test\"'")]
#[case::sub_q_string_special_non_printable(&["non-printable: %q", "test~"], "non-printable: test~")]
#[case::sub_q_string_empty(&["%q", ""], "''")]
#[case::sub_q_string_lone_open_brace(&["%q", "{"], "'{'")]
#[case::sub_q_string_lone_close_brace(&["%q", "}"], "'}'")]
#[case::sub_q_string_brace_group(&["%q", "{a,b}"], "{a,b}")]
#[case::sub_char(&["the letter %c", "A"], "the letter A")]
#[case::sub_char_from_string(&["%c%c%c", "five", "%", "oval"], "f%o")]
#[case::sub_num_int(&["twenty is %i", "20"], "twenty is 20")]