From 61a4e88e380f3fe1a68f0c8e1dfe538a0d415c9a Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Sat, 2 Dec 2023 14:33:22 +0100 Subject: [PATCH] fix(cli/installer): percent decode name (#21392) --- cli/tools/installer.rs | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs index eaf61e4333..3259bba48d 100644 --- a/cli/tools/installer.rs +++ b/cli/tools/installer.rs @@ -152,14 +152,21 @@ pub async fn infer_name_from_url(url: &Url) -> Option { return None; } - let path = PathBuf::from(url.path()); - let mut stem = match path.file_stem() { - Some(stem) => stem.to_string_lossy().to_string(), - None => return None, + let percent_decode = percent_encoding::percent_decode(url.path().as_bytes()); + #[cfg(unix)] + let path = { + use std::os::unix::prelude::OsStringExt; + PathBuf::from(std::ffi::OsString::from_vec( + percent_decode.collect::>(), + )) }; - if stem == "main" || stem == "mod" || stem == "index" || stem == "cli" { + #[cfg(windows)] + let path = PathBuf::from(percent_decode.decode_utf8_lossy().as_ref()); + + let mut stem = path.file_stem()?.to_string_lossy(); + if matches!(stem.as_ref(), "main" | "mod" | "index" | "cli") { if let Some(parent_name) = path.parent().and_then(|p| p.file_name()) { - stem = parent_name.to_string_lossy().to_string(); + stem = parent_name.to_string_lossy(); } } @@ -168,12 +175,12 @@ pub async fn infer_name_from_url(url: &Url) -> Option { // a version number. match stem.find('@') { Some(at_index) if at_index > 0 => { - stem = stem.split_at(at_index).0.to_string(); + stem = stem.split_at(at_index).0.to_string().into(); } _ => {} } - Some(stem) + Some(stem.to_string()) } pub fn uninstall(name: String, root: Option) -> Result<(), AnyError> { @@ -521,6 +528,13 @@ mod tests { .await, Some("abc".to_string()) ); + assert_eq!( + infer_name_from_url( + &Url::parse("https://example.com/ab%20c/mod.ts").unwrap() + ) + .await, + Some("ab c".to_string()) + ); assert_eq!( infer_name_from_url( &Url::parse("https://example.com/abc/index.ts").unwrap() @@ -552,6 +566,10 @@ mod tests { infer_name_from_url(&Url::parse("file:///abc/main.ts").unwrap()).await, Some("abc".to_string()) ); + assert_eq!( + infer_name_from_url(&Url::parse("file:///ab%20c/main.ts").unwrap()).await, + Some("ab c".to_string()) + ); assert_eq!( infer_name_from_url(&Url::parse("file:///main.ts").unwrap()).await, Some("main".to_string())