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:
Amr Bashir
2024-11-20 00:50:10 +02:00
committed by GitHub
parent b37c208d61
commit a09e48e396
3 changed files with 65 additions and 7 deletions

View File

@@ -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());

View File

@@ -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());
});
}
}

View File

@@ -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\\**");
}
}
}