mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-11-28 20:48:52 +03:00
* feat(core): add option for `require_literal_leading_dot`, closes #6158 * change to `Option<bool>` * fix to tokens impl * Apply suggestions from code review Co-authored-by: Simon Hyll <hyllsimon@gmail.com> --------- Co-authored-by: Simon Hyll <hyllsimon@gmail.com>
This commit is contained in:
parent
cd3846c8ce
commit
acc36fe117
5
.changes/config-require-literal_leading_dot.md
Normal file
5
.changes/config-require-literal_leading_dot.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'tauri-utils': 'patch'
|
||||
---
|
||||
|
||||
Add option to configure `require_literal_leading_dot` on `fs` and `asset` protcol scopes.
|
@ -2069,6 +2069,13 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"requireLiteralLeadingDot": {
|
||||
"description": "Whether or not paths that contain components that start with a `.` will require that `.` appears literally in the pattern; `*`, `?`, `**`, or `[...]` will not match. This is useful because such files are conventionally considered hidden on Unix systems and it might be desirable to skip them when listing files.\n\nDefaults to `false` on Unix systems and `true` on Windows",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,10 @@ use crate::TitleBarStyle;
|
||||
|
||||
pub use self::parse::parse;
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// An URL to open on a Tauri webview window.
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
@ -519,7 +523,7 @@ pub enum WebviewInstallMode {
|
||||
/// Results in a smaller installer size, but is not recommended on Windows 7.
|
||||
DownloadBootstrapper {
|
||||
/// Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.
|
||||
#[serde(default = "default_webview_install_silent")]
|
||||
#[serde(default = "default_true")]
|
||||
silent: bool,
|
||||
},
|
||||
/// Embed the bootstrapper and run it.
|
||||
@ -527,7 +531,7 @@ pub enum WebviewInstallMode {
|
||||
/// Increases the installer size by around 1.8MB, but offers better support on Windows 7.
|
||||
EmbedBootstrapper {
|
||||
/// Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.
|
||||
#[serde(default = "default_webview_install_silent")]
|
||||
#[serde(default = "default_true")]
|
||||
silent: bool,
|
||||
},
|
||||
/// Embed the offline installer and run it.
|
||||
@ -535,7 +539,7 @@ pub enum WebviewInstallMode {
|
||||
/// Increases the installer size by around 127MB.
|
||||
OfflineInstaller {
|
||||
/// Instructs the installer to run the installer in silent mode. Defaults to `true`.
|
||||
#[serde(default = "default_webview_install_silent")]
|
||||
#[serde(default = "default_true")]
|
||||
silent: bool,
|
||||
},
|
||||
/// Embed a fixed webview2 version and use it at runtime.
|
||||
@ -549,15 +553,9 @@ pub enum WebviewInstallMode {
|
||||
},
|
||||
}
|
||||
|
||||
fn default_webview_install_silent() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl Default for WebviewInstallMode {
|
||||
fn default() -> Self {
|
||||
Self::DownloadBootstrapper {
|
||||
silent: default_webview_install_silent(),
|
||||
}
|
||||
Self::DownloadBootstrapper { silent: true }
|
||||
}
|
||||
}
|
||||
|
||||
@ -598,7 +596,7 @@ pub struct WindowsConfig {
|
||||
/// For instance, if `1.2.1` is installed, the user won't be able to install app version `1.2.0` or `1.1.5`.
|
||||
///
|
||||
/// The default value of this flag is `true`.
|
||||
#[serde(default = "default_allow_downgrades", alias = "allow-downgrades")]
|
||||
#[serde(default = "default_true", alias = "allow-downgrades")]
|
||||
pub allow_downgrades: bool,
|
||||
/// Configuration for the MSI generated with WiX.
|
||||
pub wix: Option<WixConfig>,
|
||||
@ -615,17 +613,13 @@ impl Default for WindowsConfig {
|
||||
tsp: false,
|
||||
webview_install_mode: Default::default(),
|
||||
webview_fixed_runtime_path: None,
|
||||
allow_downgrades: default_allow_downgrades(),
|
||||
allow_downgrades: true,
|
||||
wix: None,
|
||||
nsis: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_allow_downgrades() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Configuration for tauri-bundler.
|
||||
///
|
||||
/// See more: https://tauri.app/v1/api/config#bundleconfig
|
||||
@ -901,7 +895,7 @@ pub struct WindowConfig {
|
||||
/// Whether the file drop is enabled or not on the webview. By default it is enabled.
|
||||
///
|
||||
/// Disabling it is required to use drag and drop on the frontend on Windows.
|
||||
#[serde(default = "default_file_drop_enabled", alias = "file-drop-enabled")]
|
||||
#[serde(default = "default_true", alias = "file-drop-enabled")]
|
||||
pub file_drop_enabled: bool,
|
||||
/// Whether or not the window starts centered or not.
|
||||
#[serde(default)]
|
||||
@ -929,7 +923,7 @@ pub struct WindowConfig {
|
||||
#[serde(alias = "max-height")]
|
||||
pub max_height: Option<f64>,
|
||||
/// Whether the window is resizable or not.
|
||||
#[serde(default = "default_resizable")]
|
||||
#[serde(default = "default_true")]
|
||||
pub resizable: bool,
|
||||
/// The window title.
|
||||
#[serde(default = "default_title")]
|
||||
@ -938,7 +932,7 @@ pub struct WindowConfig {
|
||||
#[serde(default)]
|
||||
pub fullscreen: bool,
|
||||
/// Whether the window will be initially focused or not.
|
||||
#[serde(default = "default_focus")]
|
||||
#[serde(default = "default_true")]
|
||||
pub focus: bool,
|
||||
/// Whether the window is transparent or not.
|
||||
///
|
||||
@ -950,10 +944,10 @@ pub struct WindowConfig {
|
||||
#[serde(default)]
|
||||
pub maximized: bool,
|
||||
/// Whether the window is visible or not.
|
||||
#[serde(default = "default_visible")]
|
||||
#[serde(default = "default_true")]
|
||||
pub visible: bool,
|
||||
/// Whether the window should have borders and bars.
|
||||
#[serde(default = "default_decorations")]
|
||||
#[serde(default = "default_true")]
|
||||
pub decorations: bool,
|
||||
/// Whether the window should always be on top of other windows.
|
||||
#[serde(default, alias = "always-on-top")]
|
||||
@ -995,7 +989,7 @@ impl Default for WindowConfig {
|
||||
label: default_window_label(),
|
||||
url: WindowUrl::default(),
|
||||
user_agent: None,
|
||||
file_drop_enabled: default_file_drop_enabled(),
|
||||
file_drop_enabled: true,
|
||||
center: false,
|
||||
x: None,
|
||||
y: None,
|
||||
@ -1005,14 +999,14 @@ impl Default for WindowConfig {
|
||||
min_height: None,
|
||||
max_width: None,
|
||||
max_height: None,
|
||||
resizable: default_resizable(),
|
||||
resizable: true,
|
||||
title: default_title(),
|
||||
fullscreen: false,
|
||||
focus: false,
|
||||
transparent: false,
|
||||
maximized: false,
|
||||
visible: default_visible(),
|
||||
decorations: default_decorations(),
|
||||
visible: true,
|
||||
decorations: true,
|
||||
always_on_top: false,
|
||||
content_protected: false,
|
||||
skip_taskbar: false,
|
||||
@ -1038,30 +1032,10 @@ fn default_height() -> f64 {
|
||||
600f64
|
||||
}
|
||||
|
||||
fn default_resizable() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_title() -> String {
|
||||
"Tauri App".to_string()
|
||||
}
|
||||
|
||||
fn default_focus() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_visible() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_decorations() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_file_drop_enabled() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// A Content-Security-Policy directive source list.
|
||||
/// See <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources>.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
@ -1302,12 +1276,13 @@ macro_rules! check_feature {
|
||||
/// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`,
|
||||
/// `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
#[serde(untagged)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
pub enum FsAllowlistScope {
|
||||
/// A list of paths that are allowed by this scope.
|
||||
AllowedPaths(Vec<PathBuf>),
|
||||
/// A complete scope configuration.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Scope {
|
||||
/// A list of paths that are allowed by this scope.
|
||||
#[serde(default)]
|
||||
@ -1316,6 +1291,16 @@ pub enum FsAllowlistScope {
|
||||
/// This gets precedence over the [`Self::Scope::allow`] list.
|
||||
#[serde(default)]
|
||||
deny: Vec<PathBuf>,
|
||||
/// Whether or not paths that contain components that start with a `.`
|
||||
/// will require that `.` appears literally in the pattern; `*`, `?`, `**`,
|
||||
/// or `[...]` will not match. This is useful because such files are
|
||||
/// conventionally considered hidden on Unix systems and it might be
|
||||
/// desirable to skip them when listing files.
|
||||
///
|
||||
/// Defaults to `false` on Unix systems and `true` on Windows
|
||||
// dotfiles are not supposed to be exposed by default on unix
|
||||
#[serde(alias = "require-literal-leading-dot")]
|
||||
require_literal_leading_dot: Option<bool>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -2580,7 +2565,7 @@ pub struct UpdaterConfig {
|
||||
#[serde(default)]
|
||||
pub active: bool,
|
||||
/// Display built-in dialog or use event system if disabled.
|
||||
#[serde(default = "default_dialog")]
|
||||
#[serde(default = "default_true")]
|
||||
pub dialog: bool,
|
||||
/// The updater endpoints. TLS is enforced on production.
|
||||
///
|
||||
@ -2611,7 +2596,7 @@ impl<'de> Deserialize<'de> for UpdaterConfig {
|
||||
struct InnerUpdaterConfig {
|
||||
#[serde(default)]
|
||||
active: bool,
|
||||
#[serde(default = "default_dialog")]
|
||||
#[serde(default = "default_true")]
|
||||
dialog: bool,
|
||||
endpoints: Option<Vec<UpdaterEndpoint>>,
|
||||
pubkey: Option<String>,
|
||||
@ -2641,7 +2626,7 @@ impl Default for UpdaterConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
active: false,
|
||||
dialog: default_dialog(),
|
||||
dialog: true,
|
||||
endpoints: None,
|
||||
pubkey: "".into(),
|
||||
windows: Default::default(),
|
||||
@ -2664,26 +2649,12 @@ pub struct SystemTrayConfig {
|
||||
#[serde(default, alias = "icon-as-template")]
|
||||
pub icon_as_template: bool,
|
||||
/// A Boolean value that determines whether the menu should appear when the tray icon receives a left click on macOS.
|
||||
#[serde(
|
||||
default = "default_tray_menu_on_left_click",
|
||||
alias = "menu-on-left-click"
|
||||
)]
|
||||
#[serde(default = "default_true", alias = "menu-on-left-click")]
|
||||
pub menu_on_left_click: bool,
|
||||
/// Title for MacOS tray
|
||||
pub title: Option<String>,
|
||||
}
|
||||
|
||||
fn default_tray_menu_on_left_click() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// We enable the unnecessary_wraps because we need
|
||||
// to use an Option for dialog otherwise the CLI schema will mark
|
||||
// the dialog as a required field which is not as we default it to true.
|
||||
fn default_dialog() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Defines the URL or assets to embed in the application.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||
@ -3709,10 +3680,11 @@ mod build {
|
||||
let allowed_paths = vec_lit(allow, path_buf_lit);
|
||||
quote! { #prefix::AllowedPaths(#allowed_paths) }
|
||||
}
|
||||
Self::Scope { allow, deny } => {
|
||||
Self::Scope { allow, deny , require_literal_leading_dot} => {
|
||||
let allow = vec_lit(allow, path_buf_lit);
|
||||
let deny = vec_lit(deny, path_buf_lit);
|
||||
quote! { #prefix::Scope { allow: #allow, deny: #deny } }
|
||||
let require_literal_leading_dot = opt_lit(require_literal_leading_dot.as_ref());
|
||||
quote! { #prefix::Scope { allow: #allow, deny: #deny, require_literal_leading_dot: #require_literal_leading_dot } }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ pub struct Scope {
|
||||
allowed_patterns: Arc<Mutex<HashSet<Pattern>>>,
|
||||
forbidden_patterns: Arc<Mutex<HashSet<Pattern>>>,
|
||||
event_listeners: Arc<Mutex<HashMap<Uuid, EventListener>>>,
|
||||
match_options: glob::MatchOptions,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Scope {
|
||||
@ -106,10 +107,29 @@ impl Scope {
|
||||
}
|
||||
}
|
||||
|
||||
let require_literal_leading_dot = match scope {
|
||||
FsAllowlistScope::Scope {
|
||||
require_literal_leading_dot: Some(require),
|
||||
..
|
||||
} => *require,
|
||||
// dotfiles are not supposed to be exposed by default on unix
|
||||
#[cfg(unix)]
|
||||
_ => false,
|
||||
#[cfg(windows)]
|
||||
_ => true,
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
allowed_patterns: Arc::new(Mutex::new(allowed_patterns)),
|
||||
forbidden_patterns: Arc::new(Mutex::new(forbidden_patterns)),
|
||||
event_listeners: Default::default(),
|
||||
match_options: glob::MatchOptions {
|
||||
// this is needed so `/dir/*` doesn't match files within subdirectories such as `/dir/subdir/file.txt`
|
||||
// see: https://github.com/tauri-apps/tauri/security/advisories/GHSA-6mv3-wm7j-h4w5
|
||||
require_literal_separator: true,
|
||||
require_literal_leading_dot,
|
||||
..Default::default()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -216,22 +236,12 @@ impl Scope {
|
||||
|
||||
if let Ok(path) = path {
|
||||
let path: PathBuf = path.components().collect();
|
||||
let options = glob::MatchOptions {
|
||||
// this is needed so `/dir/*` doesn't match files within subdirectories such as `/dir/subdir/file.txt`
|
||||
// see: https://github.com/tauri-apps/tauri/security/advisories/GHSA-6mv3-wm7j-h4w5
|
||||
require_literal_separator: true,
|
||||
// dotfiles are not supposed to be exposed by default
|
||||
#[cfg(unix)]
|
||||
require_literal_leading_dot: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let forbidden = self
|
||||
.forbidden_patterns
|
||||
.lock()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|p| p.matches_path_with(&path, options));
|
||||
.any(|p| p.matches_path_with(&path, self.match_options));
|
||||
|
||||
if forbidden {
|
||||
false
|
||||
@ -241,7 +251,7 @@ impl Scope {
|
||||
.lock()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|p| p.matches_path_with(&path, options));
|
||||
.any(|p| p.matches_path_with(&path, self.match_options));
|
||||
allowed
|
||||
}
|
||||
} else {
|
||||
@ -271,6 +281,17 @@ mod tests {
|
||||
allowed_patterns: Default::default(),
|
||||
forbidden_patterns: Default::default(),
|
||||
event_listeners: Default::default(),
|
||||
match_options: glob::MatchOptions {
|
||||
// this is needed so `/dir/*` doesn't match files within subdirectories such as `/dir/subdir/file.txt`
|
||||
// see: https://github.com/tauri-apps/tauri/security/advisories/GHSA-6mv3-wm7j-h4w5
|
||||
require_literal_separator: true,
|
||||
// dotfiles are not supposed to be exposed by default on unix
|
||||
#[cfg(unix)]
|
||||
require_literal_leading_dot: false,
|
||||
#[cfg(windows)]
|
||||
require_literal_leading_dot: true,
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2069,6 +2069,13 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"requireLiteralLeadingDot": {
|
||||
"description": "Whether or not paths that contain components that start with a `.` will require that `.` appears literally in the pattern; `*`, `?`, `**`, or `[...]` will not match. This is useful because such files are conventionally considered hidden on Unix systems and it might be desirable to skip them when listing files.\n\nDefaults to `false` on Unix systems and `true` on Windows",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user