fix(persisted-scope): Unescape paths before saving to disk.

pull/328/head
FabianLars 2 years ago
parent 70e2ad0f3b
commit ae3122cf47
No known key found for this signature in database
GPG Key ID: 3B12BC1DEBF61125

1
Cargo.lock generated

@ -4362,6 +4362,7 @@ dependencies = [
name = "tauri-plugin-persisted-scope" name = "tauri-plugin-persisted-scope"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"aho-corasick",
"bincode", "bincode",
"log", "log",
"serde", "serde",

@ -15,6 +15,7 @@ serde_json.workspace = true
tauri.workspace = true tauri.workspace = true
log.workspace = true log.workspace = true
thiserror.workspace = true thiserror.workspace = true
aho-corasick = "0.7"
bincode = "1" bincode = "1"
[features] [features]

@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use aho_corasick::AhoCorasick;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tauri::{ use tauri::{
plugin::{Builder, TauriPlugin}, plugin::{Builder, TauriPlugin},
@ -14,6 +15,8 @@ use std::{
}; };
const SCOPE_STATE_FILENAME: &str = ".persisted-scope"; const SCOPE_STATE_FILENAME: &str = ".persisted-scope";
const PATTERNS: &[&str] = &["[?]", "[[]", "[]]", "[*]"];
const REPLACE_WITH: &[&str] = &["?", "[", "]", "*"];
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
enum Error { enum Error {
@ -45,6 +48,29 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
if let Some(app_dir) = app_dir { if let Some(app_dir) = app_dir {
let scope_state_path = app_dir.join(SCOPE_STATE_FILENAME); let scope_state_path = app_dir.join(SCOPE_STATE_FILENAME);
// We need to filter out glob pattern paths from the scope configs to not pollute the scope with incorrect paths.
// We can't plainly filter for `*` because `*` is valid in paths on unix.
let initial_fs_allowed: Vec<String> = fs_scope
.allowed_patterns()
.into_iter()
.map(|p| p.to_string())
.collect();
let initial_asset_allowed: Vec<String> = asset_protocol_scope
.allowed_patterns()
.into_iter()
.map(|p| p.to_string())
.collect();
let initial_fs_forbidden: Vec<String> = fs_scope
.forbidden_patterns()
.into_iter()
.map(|p| p.to_string())
.collect();
let initial_asset_forbidden: Vec<String> = asset_protocol_scope
.forbidden_patterns()
.into_iter()
.map(|p| p.to_string())
.collect();
let _ = fs_scope.forbid_file(&scope_state_path); let _ = fs_scope.forbid_file(&scope_state_path);
#[cfg(feature = "protocol-asset")] #[cfg(feature = "protocol-asset")]
let _ = asset_protocol_scope.forbid_file(&scope_state_path); let _ = asset_protocol_scope.forbid_file(&scope_state_path);
@ -55,19 +81,29 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
.and_then(|scope| bincode::deserialize(&scope).map_err(Into::into)) .and_then(|scope| bincode::deserialize(&scope).map_err(Into::into))
.unwrap_or_default(); .unwrap_or_default();
for allowed in &scope.allowed_paths { for allowed in &scope.allowed_paths {
// allows the path as is if !initial_fs_allowed.contains(&allowed) {
let _ = fs_scope.allow_file(allowed); let _ = fs_scope.allow_file(&allowed);
}
#[cfg(feature = "protocol-asset")] #[cfg(feature = "protocol-asset")]
let _ = asset_protocol_scope.allow_file(allowed); if !initial_asset_allowed.contains(&allowed) {
let _ = asset_protocol_scope.allow_file(&allowed);
}
} }
for forbidden in &scope.forbidden_patterns { for forbidden in &scope.forbidden_patterns {
// forbid the path as is // forbid the path as is
let _ = fs_scope.forbid_file(forbidden); if !initial_fs_forbidden.contains(&forbidden) {
let _ = fs_scope.forbid_file(&forbidden);
}
#[cfg(feature = "protocol-asset")] #[cfg(feature = "protocol-asset")]
let _ = asset_protocol_scope.forbid_file(forbidden); if !initial_asset_forbidden.contains(&forbidden) {
let _ = asset_protocol_scope.forbid_file(&forbidden);
}
} }
} }
// We could also "fix" the paths on app start if we notice any runtime performance problems.
let ac = AhoCorasick::new_auto_configured(PATTERNS);
fs_scope.listen(move |event| { fs_scope.listen(move |event| {
let fs_scope = app.fs_scope(); let fs_scope = app.fs_scope();
if let FsScopeEvent::PathAllowed(_) = event { if let FsScopeEvent::PathAllowed(_) = event {
@ -75,18 +111,17 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
allowed_paths: fs_scope allowed_paths: fs_scope
.allowed_patterns() .allowed_patterns()
.into_iter() .into_iter()
.map(|p| p.to_string()) .map(|p| ac.replace_all(p.as_str(), REPLACE_WITH))
.collect(), .collect(),
forbidden_patterns: fs_scope forbidden_patterns: fs_scope
.forbidden_patterns() .forbidden_patterns()
.into_iter() .into_iter()
.map(|p| p.to_string()) .map(|p| ac.replace_all(p.as_str(), REPLACE_WITH))
.collect(), .collect(),
}; };
let scope_state_path = scope_state_path.clone();
let _ = create_dir_all(&app_dir) let _ = create_dir_all(&app_dir)
.and_then(|_| File::create(scope_state_path)) .and_then(|_| File::create(&scope_state_path))
.map_err(Error::Io) .map_err(Error::Io)
.and_then(|mut f| { .and_then(|mut f| {
f.write_all(&bincode::serialize(&scope).map_err(Error::from)?) f.write_all(&bincode::serialize(&scope).map_err(Error::from)?)

Loading…
Cancel
Save