add route min/max arg restrictions
This commit is contained in:
parent
7585687710
commit
0df0c60013
3 changed files with 84 additions and 10 deletions
|
@ -67,7 +67,7 @@ impl<'de> Deserialize<'de> for Route {
|
|||
D: Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
#[serde(field_identifier, rename_all = "lowercase")]
|
||||
#[serde(field_identifier, rename_all = "snake_case")]
|
||||
enum Field {
|
||||
Path,
|
||||
Hidden,
|
||||
|
|
|
@ -66,6 +66,7 @@ async fn run() -> Result<(), BunBunError> {
|
|||
groups: conf.groups,
|
||||
}));
|
||||
|
||||
// Cannot be named _ or Rust will immediately drop it.
|
||||
let _watch = start_watch(Arc::clone(&state), conf_data, opts.large_config)?;
|
||||
|
||||
HttpServer::new(move || {
|
||||
|
|
|
@ -158,29 +158,51 @@ fn resolve_hop<'a>(
|
|||
}
|
||||
};
|
||||
|
||||
if maybe_route.is_some() {
|
||||
split_args.next();
|
||||
}
|
||||
|
||||
let args = split_args.collect::<Vec<_>>().join(" ");
|
||||
let args = split_args.collect::<Vec<_>>();
|
||||
let arg_count = args.len();
|
||||
|
||||
// Try resolving with a matched command
|
||||
if let Some(route) = maybe_route {
|
||||
let args = if args.is_empty() { &[] } else { &args[1..] }.join(" ");
|
||||
let arg_count = arg_count - 1;
|
||||
if check_route(route, arg_count) {
|
||||
debug!("Resolved {} with args {}", route, args);
|
||||
return RouteResolution::Resolved { route, args };
|
||||
}
|
||||
}
|
||||
|
||||
// Try resolving with the default route, if it exists
|
||||
if let Some(route) = default_route {
|
||||
if let Some(route) = routes.get(route) {
|
||||
if check_route(route, arg_count) {
|
||||
let args = args.join(" ");
|
||||
debug!("Using default route {} with args {}", route, args);
|
||||
return RouteResolution::Resolved { route, args };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RouteResolution::Unresolved
|
||||
}
|
||||
|
||||
/// Checks if the user provided string has the correct properties required by
|
||||
/// the route to be successfully matched.
|
||||
fn check_route(route: &Route, arg_count: usize) -> bool {
|
||||
if let Some(min_args) = route.min_args {
|
||||
if arg_count < min_args {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(max_args) = route.max_args {
|
||||
if arg_count > max_args {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Runs the executable with the user's input as a single argument. Returns Ok
|
||||
/// so long as the executable was successfully executed. Returns an Error if the
|
||||
/// file doesn't exist or bunbun did not have permission to read and execute the
|
||||
|
@ -284,6 +306,57 @@ mod resolve_hop {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod check_route {
|
||||
use super::*;
|
||||
|
||||
fn create_route(
|
||||
min_args: impl Into<Option<usize>>,
|
||||
max_args: impl Into<Option<usize>>,
|
||||
) -> Route {
|
||||
Route {
|
||||
description: None,
|
||||
hidden: false,
|
||||
max_args: max_args.into(),
|
||||
min_args: min_args.into(),
|
||||
path: String::new(),
|
||||
route_type: RouteType::External,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_min_arg_no_max_arg_counts() {
|
||||
assert!(check_route(&create_route(None, None), 0));
|
||||
assert!(check_route(&create_route(None, None), usize::MAX));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn min_arg_no_max_arg_counts() {
|
||||
assert!(!check_route(&create_route(3, None), 0));
|
||||
assert!(!check_route(&create_route(3, None), 2));
|
||||
assert!(check_route(&create_route(3, None), 3));
|
||||
assert!(check_route(&create_route(3, None), 4));
|
||||
assert!(check_route(&create_route(3, None), usize::MAX));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_min_arg_max_arg_counts() {
|
||||
assert!(check_route(&create_route(None, 3), 0));
|
||||
assert!(check_route(&create_route(None, 3), 2));
|
||||
assert!(check_route(&create_route(None, 3), 3));
|
||||
assert!(!check_route(&create_route(None, 3), 4));
|
||||
assert!(!check_route(&create_route(None, 3), usize::MAX));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn min_arg_max_arg_counts() {
|
||||
assert!(!check_route(&create_route(2, 3), 1));
|
||||
assert!(check_route(&create_route(2, 3), 2));
|
||||
assert!(check_route(&create_route(2, 3), 3));
|
||||
assert!(!check_route(&create_route(2, 3), 4));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod resolve_path {
|
||||
use super::resolve_path;
|
||||
|
|
Loading…
Reference in a new issue