Skip to content

Commit

Permalink
fix(core): manually simplify patterns for fs scope (tauri-apps#11730)
Browse files Browse the repository at this point in the history
closes tauri-apps#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\**`
  • Loading branch information
amrbashir authored Nov 19, 2024
1 parent b37c208 commit a09e48e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 7 deletions.
7 changes: 5 additions & 2 deletions crates/tauri/src/manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ impl<R: Runtime> AppManager<R> {
pub fn get_asset(
&self,
mut path: String,
use_https_schema: bool,
_use_https_schema: bool,
) -> Result<Asset, Box<dyn std::error::Error>> {
let assets = &self.assets;
if path.ends_with('/') {
Expand Down Expand Up @@ -440,7 +440,10 @@ impl<R: Runtime> AppManager<R> {
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());
Expand Down
2 changes: 1 addition & 1 deletion crates/tauri/src/menu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
});
}
}
Expand Down
63 changes: 59 additions & 4 deletions crates/tauri/src/scope/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,27 @@ fn push_pattern<P: AsRef<Path>, F: Fn(&str) -> Result<Pattern, glob::PatternErro
// - `C:\\SomeDir`
#[cfg(windows)]
{
use std::path::Component;
use std::path::{Component, Path, Prefix};

let mut components = path.components();

let is_unc = match components.next() {
Some(Component::Prefix(p)) => 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)?);
Expand Down Expand Up @@ -356,6 +373,7 @@ impl Scope {
.unwrap()
.iter()
.any(|p| p.matches_path_with(&path, self.match_options));

allowed
}
} else {
Expand All @@ -382,7 +400,11 @@ fn escaped_pattern_with(p: &str, append: &str) -> Result<Pattern, glob::PatternE

#[cfg(test)]
mod tests {
use super::Scope;
use std::collections::HashSet;

use glob::Pattern;

use super::{push_pattern, Scope};

fn new_scope() -> Scope {
Scope {
Expand Down Expand Up @@ -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\\**");
}
}
}

0 comments on commit a09e48e

Please sign in to comment.