From b42064dc70b799c6777ca3a9420968d53a7a04ef Mon Sep 17 00:00:00 2001 From: FabianLars Date: Mon, 18 Nov 2024 15:53:35 +0100 Subject: [PATCH] fix(fs): Escape paths in Scope methods --- .changes/fix-fs-scope-escape-paths.md | 5 ++++ plugins/fs/Cargo.toml | 2 +- plugins/fs/src/scope.rs | 35 +++++++++++++++++++++------ 3 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 .changes/fix-fs-scope-escape-paths.md diff --git a/.changes/fix-fs-scope-escape-paths.md b/.changes/fix-fs-scope-escape-paths.md new file mode 100644 index 000000000..ade71d4a6 --- /dev/null +++ b/.changes/fix-fs-scope-escape-paths.md @@ -0,0 +1,5 @@ +--- +fs: patch +--- + +Paths given to the `Scope` methods are now correctly escaped, preventing issues with paths containing `[]`. diff --git a/plugins/fs/Cargo.toml b/plugins/fs/Cargo.toml index 5d9a7efb6..9763f193f 100644 --- a/plugins/fs/Cargo.toml +++ b/plugins/fs/Cargo.toml @@ -14,7 +14,7 @@ rustc-args = ["--cfg", "docsrs"] rustdoc-args = ["--cfg", "docsrs"] [package.metadata.platforms.support] -windows = { level = "full", notes = "" } +windows = { level = "full", notes = "No write access to `$RESOURCES` folder with MSI installer and NSIS installers in `perMachine` or `both` mode" } linux = { level = "full", notes = "No write access to `$RESOURCES` folder" } macos = { level = "full", notes = "No write access to `$RESOURCES` folder" } android = { level = "partial", notes = "Access is restricted to Application folder by default" } diff --git a/plugins/fs/src/scope.rs b/plugins/fs/src/scope.rs index e8361d511..83d3b279d 100644 --- a/plugins/fs/src/scope.rs +++ b/plugins/fs/src/scope.rs @@ -4,13 +4,14 @@ use std::{ collections::HashMap, - path::{Path, PathBuf}, + path::{Path, PathBuf, MAIN_SEPARATOR}, sync::{ atomic::{AtomicU32, Ordering}, Mutex, }, }; +use glob::Pattern; use serde::Deserialize; #[derive(Deserialize)] @@ -56,8 +57,9 @@ impl Scope { { let mut allowed = self.allowed.lock().unwrap(); - allowed.push(path.to_path_buf()); - allowed.push(path.join(if recursive { "**" } else { "*" })); + let p = path.to_string_lossy(); + allowed.push(escaped_pattern(&p)); + allowed.push(escaped_pattern_with(&p, if recursive { "**" } else { "*" })); } self.emit(Event::PathAllowed(path.to_path_buf())); @@ -69,7 +71,10 @@ impl Scope { pub fn allow_file>(&self, path: P) { let path = path.as_ref(); - self.allowed.lock().unwrap().push(path.to_path_buf()); + self.allowed + .lock() + .unwrap() + .push(escaped_pattern(&path.to_string_lossy())); self.emit(Event::PathAllowed(path.to_path_buf())); } @@ -82,8 +87,9 @@ impl Scope { { let mut denied = self.denied.lock().unwrap(); - denied.push(path.to_path_buf()); - denied.push(path.join(if recursive { "**" } else { "*" })); + let p = path.to_string_lossy(); + denied.push(escaped_pattern(&p)); + denied.push(escaped_pattern_with(&p, if recursive { "**" } else { "*" })); } self.emit(Event::PathForbidden(path.to_path_buf())); @@ -95,7 +101,10 @@ impl Scope { pub fn forbid_file>(&self, path: P) { let path = path.as_ref(); - self.denied.lock().unwrap().push(path.to_path_buf()); + self.denied + .lock() + .unwrap() + .push(escaped_pattern(&path.to_string_lossy())); self.emit(Event::PathForbidden(path.to_path_buf())); } @@ -129,3 +138,15 @@ impl Scope { id } } + +fn escaped_pattern(p: &str) -> Result { + Pattern::new(&Pattern::escape(p)) +} + +fn escaped_pattern_with(p: &str, append: &str) -> Result { + if p.ends_with(MAIN_SEPARATOR) { + Pattern::new(&format!("{}{append}", Pattern::escape(p))) + } else { + Pattern::new(&format!("{}{}{append}", Pattern::escape(p), MAIN_SEPARATOR)) + } +}