Skip to content

Commit a09e48e

Browse files
authored
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\**`
1 parent b37c208 commit a09e48e

File tree

3 files changed

+65
-7
lines changed

3 files changed

+65
-7
lines changed

crates/tauri/src/manager/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ impl<R: Runtime> AppManager<R> {
376376
pub fn get_asset(
377377
&self,
378378
mut path: String,
379-
use_https_schema: bool,
379+
_use_https_schema: bool,
380380
) -> Result<Asset, Box<dyn std::error::Error>> {
381381
let assets = &self.assets;
382382
if path.ends_with('/') {
@@ -440,7 +440,10 @@ impl<R: Runtime> AppManager<R> {
440440
let default_src = csp_map
441441
.entry("default-src".into())
442442
.or_insert_with(Default::default);
443-
default_src.push(crate::pattern::format_real_schema(schema, use_https_schema));
443+
default_src.push(crate::pattern::format_real_schema(
444+
schema,
445+
_use_https_schema,
446+
));
444447
}
445448

446449
csp_header.replace(Csp::DirectiveMap(csp_map).to_string());

crates/tauri/src/menu/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ macro_rules! gen_wrappers {
9999
// SAFETY: inner was created on main thread and is being dropped on main thread
100100
let inner = $crate::UnsafeSend(inner);
101101
let _ = self.app_handle.run_on_main_thread(move || {
102-
drop(inner);
102+
drop(inner.take());
103103
});
104104
}
105105
}

crates/tauri/src/scope/fs.rs

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,27 @@ fn push_pattern<P: AsRef<Path>, F: Fn(&str) -> Result<Pattern, glob::PatternErro
9292
// - `C:\\SomeDir`
9393
#[cfg(windows)]
9494
{
95-
use std::path::Component;
95+
use std::path::{Component, Path, Prefix};
96+
97+
let mut components = path.components();
98+
99+
let is_unc = match components.next() {
100+
Some(Component::Prefix(p)) => match p.kind() {
101+
Prefix::VerbatimDisk(..) => true,
102+
_ => false, // Other kinds of UNC paths
103+
},
104+
_ => false, // relative or empty
105+
};
106+
107+
if is_unc {
108+
// we remove UNC manually, instead of `dunce::simplified` because
109+
// `path` could have `*` in it and that's not allowed on Windows and
110+
// `dunce::simplified` will check that and return `path` as is without simplification
111+
let simplified = path
112+
.to_str()
113+
.and_then(|s| s.get(4..))
114+
.map_or(path.as_path(), Path::new);
96115

97-
if matches!(path.components().next(), Some(Component::Prefix(_))) {
98-
let simplified = dunce::simplified(&path);
99116
let simplified_str = simplified.to_string_lossy();
100117
if simplified_str != path_str {
101118
list.insert(f(&simplified_str)?);
@@ -356,6 +373,7 @@ impl Scope {
356373
.unwrap()
357374
.iter()
358375
.any(|p| p.matches_path_with(&path, self.match_options));
376+
359377
allowed
360378
}
361379
} else {
@@ -382,7 +400,11 @@ fn escaped_pattern_with(p: &str, append: &str) -> Result<Pattern, glob::PatternE
382400

383401
#[cfg(test)]
384402
mod tests {
385-
use super::Scope;
403+
use std::collections::HashSet;
404+
405+
use glob::Pattern;
406+
407+
use super::{push_pattern, Scope};
386408

387409
fn new_scope() -> Scope {
388410
Scope {
@@ -600,4 +622,37 @@ mod tests {
600622
assert!(!scope.is_allowed("Q:Cargo.toml"));
601623
}
602624
}
625+
626+
#[test]
627+
fn push_pattern_generated_paths() {
628+
macro_rules! assert_pattern {
629+
($patterns:ident, $pattern:literal) => {
630+
assert!($patterns.contains(&Pattern::new($pattern).unwrap()))
631+
};
632+
}
633+
634+
let mut patterns = HashSet::new();
635+
636+
#[cfg(not(windows))]
637+
{
638+
push_pattern(&mut patterns, "/path/to/dir/", Pattern::new).expect("failed to push pattern");
639+
push_pattern(&mut patterns, "/path/to/dir/**", Pattern::new).expect("failed to push pattern");
640+
641+
assert_pattern!(patterns, "/path/to/dir");
642+
assert_pattern!(patterns, "/path/to/dir/**");
643+
}
644+
645+
#[cfg(windows)]
646+
{
647+
push_pattern(&mut patterns, "C:\\path\\to\\dir", Pattern::new)
648+
.expect("failed to push pattern");
649+
push_pattern(&mut patterns, "C:\\path\\to\\dir\\**", Pattern::new)
650+
.expect("failed to push pattern");
651+
652+
assert_pattern!(patterns, "C:\\path\\to\\dir");
653+
assert_pattern!(patterns, "C:\\path\\to\\dir\\**");
654+
assert_pattern!(patterns, "\\\\?\\C:\\path\\to\\dir");
655+
assert_pattern!(patterns, "\\\\?\\C:\\path\\to\\dir\\**");
656+
}
657+
}
603658
}

0 commit comments

Comments
 (0)