mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-25 11:43:06 +03:00
refactor(core): simplify shell scope, input only string arrays (#3372)
This commit is contained in:
parent
55726f236c
commit
7aca0a6233
@ -376,25 +376,22 @@ fn get_allowed_clis(root: &TokenStream, scope: &ShellAllowlistScope) -> TokenStr
|
||||
ShellAllowedArg::Fixed(fixed) => {
|
||||
quote!(#root::scope::ShellScopeAllowedArg::Fixed(#fixed.into()))
|
||||
}
|
||||
ShellAllowedArg::Var { name, validate } => {
|
||||
let validate = match validate {
|
||||
None => quote!(::std::option::Option::None),
|
||||
Some(regex) => match regex::Regex::new(regex) {
|
||||
Ok(regex) => {
|
||||
let regex = regex.as_str();
|
||||
quote!(::std::option::Option::Some(#root::regex::Regex::new(#regex).unwrap()))
|
||||
}
|
||||
Err(error) => {
|
||||
let error = error.to_string();
|
||||
quote!({
|
||||
compile_error!(#error);
|
||||
::std::option::Option::Some(#root::regex::Regex::new(#regex).unwrap())
|
||||
})
|
||||
}
|
||||
},
|
||||
ShellAllowedArg::Var { validator } => {
|
||||
let validator = match regex::Regex::new(validator) {
|
||||
Ok(regex) => {
|
||||
let regex = regex.as_str();
|
||||
quote!(#root::regex::Regex::new(#regex).unwrap())
|
||||
}
|
||||
Err(error) => {
|
||||
let error = error.to_string();
|
||||
quote!({
|
||||
compile_error!(#error);
|
||||
#root::regex::Regex::new(#validator).unwrap()
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
quote!(#root::scope::ShellScopeAllowedArg::Var { name: #name.into(), validate: #validate })
|
||||
quote!(#root::scope::ShellScopeAllowedArg::Var { validator: #validator })
|
||||
}
|
||||
_ => panic!("unknown shell scope arg, unable to prepare"),
|
||||
});
|
||||
|
@ -930,19 +930,14 @@ pub enum ShellAllowedArg {
|
||||
/// A variable that is set while calling the command from the webview API.
|
||||
///
|
||||
Var {
|
||||
/// The name of the variable to be passed in.
|
||||
/// [regex] validator to require passed values to conform to an expected input.
|
||||
///
|
||||
/// This will try to match the key of the passed arguments object from the webview API.
|
||||
name: String,
|
||||
|
||||
/// Optional [regex] validator to require passed values to conform to an expected input.
|
||||
///
|
||||
/// This will require the argument value passed to this variable to match the `validate` regex
|
||||
/// This will require the argument value passed to this variable to match the `validator` regex
|
||||
/// before it will be executed.
|
||||
///
|
||||
/// [regex]: https://docs.rs/regex/latest/regex/#syntax
|
||||
#[serde(default)]
|
||||
validate: Option<String>,
|
||||
validator: String,
|
||||
},
|
||||
}
|
||||
|
||||
@ -2427,10 +2422,9 @@ mod build {
|
||||
let fixed = str_lit(fixed);
|
||||
quote!(#prefix::Fixed(#fixed))
|
||||
}
|
||||
Self::Var { name, validate } => {
|
||||
let name = str_lit(name);
|
||||
let validate = opt_str_lit(validate.as_ref());
|
||||
quote!(#prefix::Var { name: #name, validate: #validate })
|
||||
Self::Var { validator } => {
|
||||
let validator = str_lit(validator);
|
||||
quote!(#prefix::Var { validator: #validator })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -135,7 +135,11 @@ impl Cmd {
|
||||
.prepare(&program, args, false)
|
||||
{
|
||||
Ok(cmd) => cmd,
|
||||
Err(_) => return Err(crate::Error::ProgramNotAllowed(PathBuf::from(program))),
|
||||
Err(e) => {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!("{}", e);
|
||||
return Err(crate::Error::ProgramNotAllowed(PathBuf::from(program)));
|
||||
}
|
||||
}
|
||||
};
|
||||
#[cfg(any(shell_execute, shell_sidecar))]
|
||||
|
@ -24,9 +24,6 @@ pub enum ExecuteArgs {
|
||||
|
||||
/// Multiple string arguments
|
||||
List(Vec<String>),
|
||||
|
||||
/// Multiple string arguments in a key-value fashion
|
||||
Map(HashMap<String, String>),
|
||||
}
|
||||
|
||||
impl ExecuteArgs {
|
||||
@ -36,7 +33,6 @@ impl ExecuteArgs {
|
||||
Self::None => true,
|
||||
Self::Single(s) if s.is_empty() => true,
|
||||
Self::List(l) => l.is_empty(),
|
||||
Self::Map(m) => m.is_empty(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -60,12 +56,6 @@ impl From<Vec<String>> for ExecuteArgs {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<HashMap<String, String>> for ExecuteArgs {
|
||||
fn from(map: HashMap<String, String>) -> Self {
|
||||
Self::Map(map)
|
||||
}
|
||||
}
|
||||
|
||||
/// Shell scope configuration.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ScopeConfig {
|
||||
@ -95,13 +85,10 @@ pub enum ScopeAllowedArg {
|
||||
/// A non-configurable argument.
|
||||
Fixed(String),
|
||||
|
||||
/// An argument with a value to be evaluated at runtime, optionally must pass a regex validation.
|
||||
/// An argument with a value to be evaluated at runtime, must pass a regex validation.
|
||||
Var {
|
||||
/// The key name of the argument variable
|
||||
name: String,
|
||||
|
||||
/// The validation, if set, that the variable value must pass in order to be called.
|
||||
validate: Option<Regex>,
|
||||
/// The validation that the variable value must pass in order to be called.
|
||||
validator: Regex,
|
||||
},
|
||||
}
|
||||
|
||||
@ -157,13 +144,15 @@ pub enum ScopeError {
|
||||
NotFound(String),
|
||||
|
||||
/// A command variable has no value set in the arguments.
|
||||
#[error("Scoped command argument {0} was not found")]
|
||||
#[error(
|
||||
"Scoped command argument at position {0} must match regex validation {1} but it was not found"
|
||||
)]
|
||||
#[cfg(any(shell_execute, shell_sidecar))]
|
||||
#[cfg_attr(
|
||||
doc_cfg,
|
||||
doc(cfg(any(feature = "shell-execute", feature = "shell-sidecar")))
|
||||
)]
|
||||
MissingVar(String),
|
||||
MissingVar(usize, String),
|
||||
|
||||
/// At least one argument did not pass input validation.
|
||||
#[cfg(shell_scope)]
|
||||
@ -171,10 +160,10 @@ pub enum ScopeError {
|
||||
doc_cfg,
|
||||
doc(cfg(any(feature = "shell-execute", feature = "shell-open")))
|
||||
)]
|
||||
#[error("Scoped command argument {var} was found, but failed regex validation {validation}")]
|
||||
#[error("Scoped command argument at position {index} was found, but failed regex validation {validation}")]
|
||||
Validation {
|
||||
/// Name of the variable.
|
||||
var: String,
|
||||
/// Index of the variable.
|
||||
index: usize,
|
||||
|
||||
/// Regex that the variable value failed to match.
|
||||
validation: String,
|
||||
@ -229,28 +218,23 @@ impl Scope {
|
||||
(None, ExecuteArgs::None) => Ok(vec![]),
|
||||
(None, ExecuteArgs::List(list)) => Ok(list),
|
||||
(None, ExecuteArgs::Single(string)) => Ok(vec![string]),
|
||||
(None, _) => Err(ScopeError::InvalidInput(command_name.into())),
|
||||
(Some(list), ExecuteArgs::Map(args)) => list
|
||||
(Some(list), ExecuteArgs::List(args)) => list
|
||||
.iter()
|
||||
.map(|arg| match arg {
|
||||
.enumerate()
|
||||
.map(|(i, arg)| match arg {
|
||||
ScopeAllowedArg::Fixed(fixed) => Ok(fixed.to_string()),
|
||||
ScopeAllowedArg::Var { name, validate } => {
|
||||
ScopeAllowedArg::Var { validator } => {
|
||||
let value = args
|
||||
.get(name)
|
||||
.ok_or_else(|| ScopeError::MissingVar(name.into()))?
|
||||
.get(i)
|
||||
.ok_or_else(|| ScopeError::MissingVar(i, validator.to_string()))?
|
||||
.to_string();
|
||||
match validate {
|
||||
None => Ok(value),
|
||||
Some(regex) => {
|
||||
if regex.is_match(&value) {
|
||||
Ok(value)
|
||||
} else {
|
||||
Err(ScopeError::Validation {
|
||||
var: name.into(),
|
||||
validation: regex.as_str().into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
if validator.is_match(&value) {
|
||||
Ok(value)
|
||||
} else {
|
||||
Err(ScopeError::Validation {
|
||||
index: i,
|
||||
validation: validator.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -286,7 +270,7 @@ impl Scope {
|
||||
if let Some(regex) = &self.0.open {
|
||||
if !regex.is_match(path) {
|
||||
return Err(ScopeError::Validation {
|
||||
var: "open".into(),
|
||||
index: 0,
|
||||
validation: regex.as_str().into(),
|
||||
});
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ interface ChildProcess {
|
||||
async function execute(
|
||||
onEvent: (event: CommandEvent) => void,
|
||||
program: string,
|
||||
args?: string | string[] | { [key: string]: string },
|
||||
args: string | string[] = [],
|
||||
options?: InternalSpawnOptions
|
||||
): Promise<number> {
|
||||
if (typeof args === 'object') {
|
||||
|
Loading…
Reference in New Issue
Block a user