diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 4a7aa68e8..57bf2c83f 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -10,10 +10,7 @@ cargo-fuzz = true [dependencies] arbitrary = { version = "1.3.2", features = ["derive"] } libfuzzer-sys = "0.4" - -[dependencies.rhai] -path = ".." -features = ["arbitrary"] +rhai = { path = "..", features = ["arbitrary"] } # Prevent this from interfering with workspaces [workspace] diff --git a/fuzz/fuzz_targets/scripting.rs b/fuzz/fuzz_targets/scripting.rs index 4440ac8e2..32b439a9e 100644 --- a/fuzz/fuzz_targets/scripting.rs +++ b/fuzz/fuzz_targets/scripting.rs @@ -3,7 +3,7 @@ use rhai::{Dynamic, Engine, OptimizationLevel}; use arbitrary::Arbitrary; use libfuzzer_sys::fuzz_target; -use std::time::{Duration, Instant}; +use std::time::Instant; #[derive(Debug, Clone, Arbitrary)] struct Ctx<'a> { @@ -13,6 +13,7 @@ struct Ctx<'a> { fuzz_target!(|ctx: Ctx| { let mut engine = Engine::new(); + engine.set_max_string_size(1000); engine.set_max_array_size(500); engine.set_max_map_size(500); @@ -21,16 +22,15 @@ fuzz_target!(|ctx: Ctx| { engine.set_max_call_levels(10); engine.set_max_expr_depths(50, 5); engine.set_optimization_level(ctx.optimization_level); + + // Limit the length of scripts. + let script = &ctx.script[..(ctx.script.len().min(32 * 1020))]; + + // We need fuzzing to be fast, so we'll stop executing after 1s. let start = Instant::now(); - engine.on_progress(move |_| { - // We need fuzzing to be fast, so we'll stop executing after 1s. - if start.elapsed() > Duration::from_secs(1) { - Some(Dynamic::UNIT) - } else { - None - } - }); + engine.on_progress(move |_| (start.elapsed().as_millis() > 1000).then_some(Dynamic::UNIT)); + let engine = engine; - _ = engine.run(ctx.script); + _ = engine.run(script); }); diff --git a/src/api/limits.rs b/src/api/limits.rs index afd4ec009..e03c624b7 100644 --- a/src/api/limits.rs +++ b/src/api/limits.rs @@ -57,18 +57,18 @@ pub struct Limits { #[cfg(not(feature = "no_function"))] pub function_expr_depth: Option, /// Maximum number of operations allowed to run. - pub operations: Option, + pub num_operations: Option, /// Maximum number of variables allowed at any instant. /// /// Set to zero to effectively disable creating variables. - pub variables: usize, + pub num_variables: usize, /// Maximum number of [modules][crate::Module] allowed to load. /// /// Set to zero to effectively disable loading any [module][crate::Module]. /// /// Not available under `no_module`. #[cfg(not(feature = "no_module"))] - pub modules: usize, + pub num_modules: usize, /// Maximum length of a [string][crate::ImmutableString]. pub string_len: Option, /// Maximum length of an [array][crate::Array]. @@ -95,10 +95,10 @@ impl Limits { expr_depth: NonZeroUsize::new(default_limits::MAX_EXPR_DEPTH), #[cfg(not(feature = "no_function"))] function_expr_depth: NonZeroUsize::new(default_limits::MAX_FUNCTION_EXPR_DEPTH), - operations: None, - variables: usize::MAX, + num_operations: None, + num_variables: usize::MAX, #[cfg(not(feature = "no_module"))] - modules: usize::MAX, + num_modules: usize::MAX, string_len: None, #[cfg(not(feature = "no_index"))] array_size: None, @@ -165,7 +165,7 @@ impl Engine { /// Not available under `unchecked`. #[inline(always)] pub fn set_max_operations(&mut self, operations: u64) -> &mut Self { - self.limits.operations = NonZeroU64::new(operations); + self.limits.num_operations = NonZeroU64::new(operations); self } /// The maximum number of operations allowed for a script to run (0 for unlimited). @@ -174,7 +174,7 @@ impl Engine { #[inline] #[must_use] pub const fn max_operations(&self) -> u64 { - match self.limits.operations { + match self.limits.num_operations { Some(n) => n.get(), None => 0, } @@ -184,7 +184,7 @@ impl Engine { /// Not available under `unchecked`. #[inline(always)] pub fn set_max_variables(&mut self, modules: usize) -> &mut Self { - self.limits.variables = modules; + self.limits.num_variables = modules; self } /// The maximum number of imported variables allowed for a script at any instant. @@ -193,7 +193,7 @@ impl Engine { #[inline(always)] #[must_use] pub const fn max_variables(&self) -> usize { - self.limits.variables + self.limits.num_variables } /// Set the maximum number of imported [modules][crate::Module] allowed for a script. /// @@ -201,7 +201,7 @@ impl Engine { #[cfg(not(feature = "no_module"))] #[inline(always)] pub fn set_max_modules(&mut self, modules: usize) -> &mut Self { - self.limits.modules = modules; + self.limits.num_modules = modules; self } /// The maximum number of imported [modules][crate::Module] allowed for a script. @@ -211,7 +211,7 @@ impl Engine { #[must_use] pub const fn max_modules(&self) -> usize { #[cfg(not(feature = "no_module"))] - return self.limits.modules; + return self.limits.num_modules; #[cfg(feature = "no_module")] return 0; } diff --git a/src/lib.rs b/src/lib.rs index 1c58fc4a1..4f270ec68 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,7 +90,7 @@ #![allow(clippy::absurd_extreme_comparisons)] // On `only_i32`, `MAX_USIZE_INT` < `INT::MAX` because `usize` == `u32` and `INT` == `i64` #![allow(clippy::wildcard_imports)] // Wildcard imports are used to import the plugins prelude #![allow(clippy::enum_glob_use)] // Sometimes useful to import all `Tokens` etc. -#![allow(clippy::no_effect_underscore_binding)] // Underscored variables may be used by code within feature guards +#![allow(clippy::no_effect_underscore_binding)] // Underscored variables may be used by code within feature guards #![allow(clippy::semicolon_if_nothing_returned)] // One-liner `match` cases are sometimes formatted as multi-line blocks #[cfg(feature = "no_std")] diff --git a/src/types/fn_ptr.rs b/src/types/fn_ptr.rs index 2e2f2cc12..8c73a7fd4 100644 --- a/src/types/fn_ptr.rs +++ b/src/types/fn_ptr.rs @@ -49,18 +49,17 @@ impl fmt::Debug for FnPtr { #[cold] #[inline(never)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let ff = &mut f.debug_tuple("Fn"); + let func = "Fn"; + #[cfg(not(feature = "no_function"))] + let func = if self.fn_def.is_some() { "Fn*" } else { func }; + + let ff = &mut f.debug_tuple(func); ff.field(&self.name); self.curry.iter().for_each(|curry| { ff.field(curry); }); ff.finish()?; - #[cfg(not(feature = "no_function"))] - if let Some(ref fn_def) = self.fn_def { - write!(f, ": {fn_def}")?; - } - Ok(()) } } diff --git a/tests/serde.rs b/tests/serde.rs index 33f3407b1..66ba67c22 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -1,6 +1,5 @@ #![cfg(feature = "serde")] -use rhai::plugin::*; use rhai::{ serde::{from_dynamic, to_dynamic}, Dynamic, Engine, ImmutableString, Scope, INT,