From ff73f422163018669824bc1cece1d663d527e64a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= Date: Wed, 10 Jul 2024 16:51:27 +0200 Subject: [PATCH] test(ls): Add test for #6554 --- tests/by-util/test_ls.rs | 173 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 57802d7f310..736879a7dba 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -2197,6 +2197,179 @@ fn test_ls_recursive_1() { .stdout_is(out); } +#[test] +#[cfg(unix)] +// The test can't run on windows, because a folder in windows can't have a colon +// in it. Therefore, the call to `mkdir dir:name` will fail. +fn test_ls_recursive_escape_dirname() { + #[allow(clippy::type_complexity)] + let cases: &[(&str, &[&str], &[(&str, &str, &str)])] = &[ + ( + // Control case + "dirname", + &[], + &[ + ("literal", "dirname", "./dirname"), + ("shell", "dirname", "./dirname"), + ("shell-always", "'dirname'", "'./dirname'"), + ("shell-escape", "dirname", "./dirname"), + ("shell-escape-always", "'dirname'", "'./dirname'"), + ("c", "\"dirname\"", "\"./dirname\""), + ("escape", "dirname", "./dirname"), + ], + ), + ( + // Space character + "dir name", + &[], + &[ + ("literal", "dir name", "./dir name"), + ("shell", "'dir name'", "'./dir name'"), + ("shell-always", "'dir name'", "'./dir name'"), + ("shell-escape", "'dir name'", "'./dir name'"), + ("shell-escape-always", "'dir name'", "'./dir name'"), + ("c", "\"dir name\"", "\"./dir name\""), + ("escape", "dir\\ name", "./dir name"), + ], + ), + ( + // Dollar character + "dir$name", + &[], + &[ + ("literal", "dir$name", "./dir$name"), + ("shell", "'dir$name'", "'./dir$name'"), + ("shell-always", "'dir$name'", "'./dir$name'"), + ("shell-escape", "'dir$name'", "'./dir$name'"), + ("shell-escape-always", "'dir$name'", "'./dir$name'"), + ("c", "\"dir$name\"", "\"./dir$name\""), + ("escape", "dir$name", "./dir$name"), + ], + ), + ( + // Single quote character + "dir'name", + &[], + &[ + ("literal", "dir'name", "./dir'name"), + ("shell", "\"dir'name\"", "\"./dir'name\""), + ("shell-always", "\"dir'name\"", "\"./dir'name\""), + ("shell-escape", "\"dir'name\"", "\"./dir'name\""), + ("shell-escape-always", "\"dir'name\"", "\"./dir'name\""), + ("c", "\"dir'name\"", "\"./dir'name\""), + ("escape", "dir'name", "./dir'name"), + ], + ), + ( + // Double quote character + "dir\"name", + &[], + &[ + ("literal", "dir\"name", "./dir\"name"), + ("shell", "'dir\"name'", "'./dir\"name'"), + ("shell-always", "'dir\"name'", "'./dir\"name'"), + ("shell-escape", "'dir\"name'", "'./dir\"name'"), + ("shell-escape-always", "'dir\"name'", "'./dir\"name'"), + ("c", "\"dir\\\"name\"", "\"./dir\\\"name\""), + ("escape", "dir\"name", "./dir\"name"), + ], + ), + ( + // Colon character + "dir:name", + &[], + &[ + ("literal", "dir:name", "./dir:name"), + ("shell", "dir:name", "'./dir:name'"), + ("shell-always", "'dir:name'", "'./dir:name'"), + ("shell-escape", "dir:name", "'./dir:name'"), + ("shell-escape-always", "'dir:name'", "'./dir:name'"), + ("c", "\"dir:name\"", "\"./dir\\:name\""), + ("escape", "dir:name", "./dir\\:name"), + ], + ), + ( + // Backslash character + "dir\\name", + &[], + &[ + ("literal", "dir\\name", "./dir\\name"), + ("shell", "'dir\\name'", "'./dir\\name'"), + ("shell-always", "'dir\\name'", "'./dir\\name'"), + ("shell-escape", "'dir\\name'", "'./dir\\name'"), + ("shell-escape-always", "'dir\\name'", "'./dir\\name'"), + ("c", "\"dir\\\\name\"", "\"./dir\\\\name\""), + ("escape", "dir\\\\name", "./dir\\\\name"), + ], + ), + ( + // Linefeed character + "dir\nname", + &[], + &[ + ("literal", "dir\nname", "./dir\nname"), + // FIXME: Current implementation misses the quotes + // ("shell", "'dir\nname'", "'./dir\nname'"), + ("shell-always", "'dir\nname'", "'./dir\nname'"), + ("shell-escape", "'dir'$'\\n''name'", "'./dir'$'\\n''name'"), + ( + "shell-escape-always", + "'dir'$'\\n''name'", + "'./dir'$'\\n''name'", + ), + ("c", "\"dir\\nname\"", "\"./dir\\nname\""), + ("escape", "dir\\nname", "./dir\\nname"), + ], + ), + ( + // Linefeed character WITH hide-control-chars + "dir\nname", + &["--hide-control-chars"], + &[ + ("literal", "dir?name", "./dir?name"), + // FIXME: Current implementation misses the quotes + // ("shell", "'dir?name'", "'./dir?name'"), + ("shell-always", "'dir?name'", "'./dir?name'"), + ("shell-escape", "'dir'$'\\n''name'", "'./dir'$'\\n''name'"), + ( + "shell-escape-always", + "'dir'$'\\n''name'", + "'./dir'$'\\n''name'", + ), + ("c", "\"dir\\nname\"", "\"./dir\\nname\""), + ("escape", "dir\\nname", "./dir\\nname"), + ], + ), + ]; + + for (dirname, extra_args, styles) in cases { + for (qt_style, regular_mode, dir_mode) in *styles { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + at.mkdir(dirname); + + let expected = format!( + "{}:\n{}\n\n{}:\n", + match *qt_style { + "shell-always" | "shell-escape-always" => "'.'", + "c" => "\".\"", + _ => ".", + }, + regular_mode, + dir_mode + ); + + scene + .ucmd() + .arg("-R") + .arg(format!("--quoting-style={qt_style}")) + .args(extra_args) + .succeeds() + .stdout_is(expected); + } + } +} + #[test] fn test_ls_color() { let scene = TestScenario::new(util_name!());