Skip to content

Commit 89cb4ac

Browse files
committed
ls: encode path when using --hyperlink
1 parent 181cfc8 commit 89cb4ac

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

src/uu/ls/src/ls.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3019,7 +3019,23 @@ fn display_file_name(
30193019
let absolute_path = fs::canonicalize(&path.p_buf).unwrap_or_default();
30203020
let absolute_path = absolute_path.to_string_lossy();
30213021

3022-
// TODO encode path
3022+
#[cfg(not(target_os = "windows"))]
3023+
let unencoded_chars = "_-.:~/";
3024+
#[cfg(target_os = "windows")]
3025+
let unencoded_chars = "_-.:~/\\";
3026+
3027+
// percentage encoding of path
3028+
let absolute_path: String = absolute_path
3029+
.chars()
3030+
.map(|c| {
3031+
if c.is_alphanumeric() || unencoded_chars.contains(c) {
3032+
c.to_string()
3033+
} else {
3034+
format!("%{:02x}", c as u8)
3035+
}
3036+
})
3037+
.collect();
3038+
30233039
// \x1b = ESC, \x07 = BEL
30243040
name = format!("\x1b]8;;file://{hostname}{absolute_path}\x07{name}\x1b]8;;\x07");
30253041
}

tests/by-util/test_ls.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3904,6 +3904,38 @@ fn test_ls_hyperlink() {
39043904
.stdout_is(format!("{file}\n"));
39053905
}
39063906

3907+
// spell-checker: disable
3908+
#[test]
3909+
fn test_ls_hyperlink_encode_link() {
3910+
let (at, mut ucmd) = at_and_ucmd!();
3911+
3912+
#[cfg(not(target_os = "windows"))]
3913+
{
3914+
at.touch("back\\slash");
3915+
at.touch("ques?tion");
3916+
}
3917+
at.touch("encoded%3Fquestion");
3918+
at.touch("sp ace");
3919+
3920+
let result = ucmd.arg("--hyperlink").succeeds();
3921+
#[cfg(not(target_os = "windows"))]
3922+
{
3923+
assert!(result
3924+
.stdout_str()
3925+
.contains("back%5cslash\x07back\\slash\x1b]8;;\x07"));
3926+
assert!(result
3927+
.stdout_str()
3928+
.contains("ques%3ftion\x07ques?tion\x1b]8;;\x07"));
3929+
}
3930+
assert!(result
3931+
.stdout_str()
3932+
.contains("encoded%253Fquestion\x07encoded%3Fquestion\x1b]8;;\x07"));
3933+
assert!(result
3934+
.stdout_str()
3935+
.contains("sp%20ace\x07sp ace\x1b]8;;\x07"));
3936+
}
3937+
// spell-checker: enable
3938+
39073939
#[test]
39083940
fn test_ls_color_do_not_reset() {
39093941
let scene: TestScenario = TestScenario::new(util_name!());

0 commit comments

Comments
 (0)