From a09e48e396fafdb7eaa9afff76c1ac3b5166a05a Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Wed, 20 Nov 2024 00:50:10 +0200 Subject: [PATCH] fix(core): manually simplify patterns for fs scope (#11730) closes #11614 Remove UNC manually, instead of `dunce::simplified` because `path` could have `*` in it and that's not allowed on Windows and `dunce::simplified` will check that and return `path` as is without simplification resulting in a missing pattern in scope for the scope pattern `\\?\C:\path\to\dir\**`, we expect the scope to have: - `\\?\C:\path\to\dir\**` - `C:\path\to\dir\**` but if we use `dunce::simplified`, it will see `**` as invalid path component on Windows and will not simplify the path resulting in a scope that only has `\\?\C:\path\to\dir\**` --- crates/tauri/src/manager/mod.rs | 7 ++-- crates/tauri/src/menu/mod.rs | 2 +- crates/tauri/src/scope/fs.rs | 63 ++++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/crates/tauri/src/manager/mod.rs b/crates/tauri/src/manager/mod.rs index 81f0eaae2..08c26b242 100644 --- a/crates/tauri/src/manager/mod.rs +++ b/crates/tauri/src/manager/mod.rs @@ -376,7 +376,7 @@ impl AppManager { pub fn get_asset( &self, mut path: String, - use_https_schema: bool, + _use_https_schema: bool, ) -> Result> { let assets = &self.assets; if path.ends_with('/') { @@ -440,7 +440,10 @@ impl AppManager { let default_src = csp_map .entry("default-src".into()) .or_insert_with(Default::default); - default_src.push(crate::pattern::format_real_schema(schema, use_https_schema)); + default_src.push(crate::pattern::format_real_schema( + schema, + _use_https_schema, + )); } csp_header.replace(Csp::DirectiveMap(csp_map).to_string()); diff --git a/crates/tauri/src/menu/mod.rs b/crates/tauri/src/menu/mod.rs index 2ae33d971..cee643ea2 100644 --- a/crates/tauri/src/menu/mod.rs +++ b/crates/tauri/src/menu/mod.rs @@ -99,7 +99,7 @@ macro_rules! gen_wrappers { // SAFETY: inner was created on main thread and is being dropped on main thread let inner = $crate::UnsafeSend(inner); let _ = self.app_handle.run_on_main_thread(move || { - drop(inner); + drop(inner.take()); }); } } diff --git a/crates/tauri/src/scope/fs.rs b/crates/tauri/src/scope/fs.rs index 0ef56ad80..6fafe6578 100644 --- a/crates/tauri/src/scope/fs.rs +++ b/crates/tauri/src/scope/fs.rs @@ -92,10 +92,27 @@ fn push_pattern, F: Fn(&str) -> Result match p.kind() { + Prefix::VerbatimDisk(..) => true, + _ => false, // Other kinds of UNC paths + }, + _ => false, // relative or empty + }; + + if is_unc { + // we remove UNC manually, instead of `dunce::simplified` because + // `path` could have `*` in it and that's not allowed on Windows and + // `dunce::simplified` will check that and return `path` as is without simplification + let simplified = path + .to_str() + .and_then(|s| s.get(4..)) + .map_or(path.as_path(), Path::new); - if matches!(path.components().next(), Some(Component::Prefix(_))) { - let simplified = dunce::simplified(&path); let simplified_str = simplified.to_string_lossy(); if simplified_str != path_str { list.insert(f(&simplified_str)?); @@ -356,6 +373,7 @@ impl Scope { .unwrap() .iter() .any(|p| p.matches_path_with(&path, self.match_options)); + allowed } } else { @@ -382,7 +400,11 @@ fn escaped_pattern_with(p: &str, append: &str) -> Result Scope { Scope { @@ -600,4 +622,37 @@ mod tests { assert!(!scope.is_allowed("Q:Cargo.toml")); } } + + #[test] + fn push_pattern_generated_paths() { + macro_rules! assert_pattern { + ($patterns:ident, $pattern:literal) => { + assert!($patterns.contains(&Pattern::new($pattern).unwrap())) + }; + } + + let mut patterns = HashSet::new(); + + #[cfg(not(windows))] + { + push_pattern(&mut patterns, "/path/to/dir/", Pattern::new).expect("failed to push pattern"); + push_pattern(&mut patterns, "/path/to/dir/**", Pattern::new).expect("failed to push pattern"); + + assert_pattern!(patterns, "/path/to/dir"); + assert_pattern!(patterns, "/path/to/dir/**"); + } + + #[cfg(windows)] + { + push_pattern(&mut patterns, "C:\\path\\to\\dir", Pattern::new) + .expect("failed to push pattern"); + push_pattern(&mut patterns, "C:\\path\\to\\dir\\**", Pattern::new) + .expect("failed to push pattern"); + + assert_pattern!(patterns, "C:\\path\\to\\dir"); + assert_pattern!(patterns, "C:\\path\\to\\dir\\**"); + assert_pattern!(patterns, "\\\\?\\C:\\path\\to\\dir"); + assert_pattern!(patterns, "\\\\?\\C:\\path\\to\\dir\\**"); + } + } }