mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
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\**`
This commit is contained in:
@@ -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('/') {
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)?);
|
||||
@@ -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<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 {
|
||||
@@ -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\\**");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user