Make limit getters available without unchecked.

This commit is contained in:
Stephen Chung 2022-10-04 15:33:51 +08:00
parent e8fd965eba
commit 891214470b
11 changed files with 87 additions and 37 deletions

View File

@ -25,6 +25,7 @@ Enhancements
* `Scope` is now serializable and deserializable via `serde`.
* `Scope` now contains a const generic parameter that allows specifying how many entries to be kept inline.
* `parse_json` function is added to parse a JSON string into an object map.
* Methods return maximum limits (e.g. `max_string_len`) are now available even under `unchecked` in order to avoid unnecessary feature flags in third-party library code.
Version 1.10.1

View File

@ -94,12 +94,14 @@ impl Engine {
}
/// The maximum levels of function calls allowed for a script.
///
/// Not available under `unchecked` or `no_function`.
#[cfg(not(feature = "no_function"))]
/// Zero under `no_function`.
#[inline(always)]
#[must_use]
pub const fn max_call_levels(&self) -> usize {
self.limits.max_call_stack_depth
#[cfg(not(feature = "no_function"))]
return self.limits.max_call_stack_depth;
#[cfg(feature = "no_function")]
return 0;
}
/// Set the maximum number of operations allowed for a script to run to avoid
/// consuming too much resources (0 for unlimited).
@ -133,12 +135,14 @@ impl Engine {
}
/// The maximum number of imported [modules][crate::Module] allowed for a script.
///
/// Not available under `unchecked` or `no_module`.
#[cfg(not(feature = "no_module"))]
/// Zero under `no_module`.
#[inline(always)]
#[must_use]
pub const fn max_modules(&self) -> usize {
self.limits.max_modules
#[cfg(not(feature = "no_module"))]
return self.limits.max_modules;
#[cfg(feature = "no_module")]
return 0;
}
/// Set the depth limits for expressions (0 for unlimited).
///
@ -157,8 +161,6 @@ impl Engine {
self
}
/// The depth limit for expressions (0 for unlimited).
///
/// Not available under `unchecked`.
#[inline]
#[must_use]
pub const fn max_expr_depth(&self) -> usize {
@ -170,16 +172,18 @@ impl Engine {
}
/// The depth limit for expressions in functions (0 for unlimited).
///
/// Not available under `unchecked` or `no_function`.
#[cfg(not(feature = "no_function"))]
/// Zero under `no_function`.
#[inline]
#[must_use]
pub const fn max_function_expr_depth(&self) -> usize {
if let Some(n) = self.limits.max_function_expr_depth {
#[cfg(not(feature = "no_function"))]
return if let Some(n) = self.limits.max_function_expr_depth {
n.get()
} else {
0
}
};
#[cfg(feature = "no_function")]
return 0;
}
/// Set the maximum length of [strings][crate::ImmutableString] (0 for unlimited).
///
@ -190,8 +194,6 @@ impl Engine {
self
}
/// The maximum length of [strings][crate::ImmutableString] (0 for unlimited).
///
/// Not available under `unchecked`.
#[inline]
#[must_use]
pub const fn max_string_size(&self) -> usize {
@ -212,16 +214,18 @@ impl Engine {
}
/// The maximum length of [arrays][crate::Array] (0 for unlimited).
///
/// Not available under `unchecked` or `no_index`.
#[cfg(not(feature = "no_index"))]
/// Zero under `no_index`.
#[inline]
#[must_use]
pub const fn max_array_size(&self) -> usize {
if let Some(n) = self.limits.max_array_size {
#[cfg(not(feature = "no_index"))]
return if let Some(n) = self.limits.max_array_size {
n.get()
} else {
0
}
};
#[cfg(feature = "no_index")]
return 0;
}
/// Set the maximum size of [object maps][crate::Map] (0 for unlimited).
///
@ -234,15 +238,17 @@ impl Engine {
}
/// The maximum size of [object maps][crate::Map] (0 for unlimited).
///
/// Not available under `unchecked` or `no_object`.
#[cfg(not(feature = "no_object"))]
/// Zero under `no_object`.
#[inline]
#[must_use]
pub const fn max_map_size(&self) -> usize {
if let Some(n) = self.limits.max_map_size {
#[cfg(not(feature = "no_object"))]
return if let Some(n) = self.limits.max_map_size {
n.get()
} else {
0
}
};
#[cfg(feature = "no_object")]
return 0;
}
}

View File

@ -236,3 +236,55 @@ impl Engine {
self
}
}
#[cfg(feature = "unchecked")]
impl Engine {
/// The maximum levels of function calls allowed for a script.
#[inline(always)]
#[must_use]
pub const fn max_call_levels(&self) -> usize {
usize::MAX
}
/// The maximum number of operations allowed for a script to run (0 for unlimited).
#[inline]
#[must_use]
pub const fn max_operations(&self) -> u64 {
0
}
/// The maximum number of imported [modules][crate::Module] allowed for a script.
#[inline(always)]
#[must_use]
pub const fn max_modules(&self) -> usize {
usize::MAX
}
/// The depth limit for expressions (0 for unlimited).
#[inline(always)]
#[must_use]
pub const fn max_expr_depth(&self) -> usize {
0
}
/// The depth limit for expressions in functions (0 for unlimited).
#[inline(always)]
#[must_use]
pub const fn max_function_expr_depth(&self) -> usize {
0
}
/// The maximum length of [strings][crate::ImmutableString] (0 for unlimited).
#[inline(always)]
#[must_use]
pub const fn max_string_size(&self) -> usize {
0
}
/// The maximum length of [arrays][crate::Array] (0 for unlimited).
#[inline(always)]
#[must_use]
pub const fn max_array_size(&self) -> usize {
0
}
/// The maximum size of [object maps][crate::Map] (0 for unlimited).
#[inline(always)]
#[must_use]
pub const fn max_map_size(&self) -> usize {
0
}
}

View File

@ -226,12 +226,12 @@ impl Engine {
#[inline(always)]
pub fn register_type_with_name_raw(
&mut self,
fully_qualified_type_path: impl Into<Identifier>,
type_path: impl Into<Identifier>,
name: impl Into<Identifier>,
) -> &mut Self {
// Add the pretty-print type name into the map
self.global_namespace_mut()
.set_custom_type_raw(fully_qualified_type_path, name);
.set_custom_type_raw(type_path, name);
self
}
/// Register a type iterator for an iterable type with the [`Engine`].

View File

@ -36,6 +36,7 @@ pub struct GlobalRuntimeState<'a> {
/// Number of operations performed.
pub num_operations: u64,
/// Number of modules loaded.
#[cfg(not(feature = "no_module"))]
pub num_modules_loaded: usize,
/// Level of the current scope.
///

View File

@ -738,7 +738,7 @@ impl Engine {
#[cfg(feature = "no_object")]
_ => {
err.take_position();
let _ = err.take_position();
err.to_string().into()
}
#[cfg(not(feature = "no_object"))]
@ -924,7 +924,6 @@ impl Engine {
let (expr, export) = &**x;
// Guard against too many modules
#[cfg(not(feature = "unchecked"))]
if global.num_modules_loaded >= self.max_modules() {
return Err(ERR::ErrorTooManyModules(*_pos).into());
}

View File

@ -67,7 +67,6 @@ impl Engine {
self.inc_operations(&mut global.num_operations, pos)?;
// Check for stack overflow
#[cfg(not(feature = "unchecked"))]
if level > self.max_call_levels() {
return Err(ERR::ErrorStackOverflow(pos).into());
}

View File

@ -494,12 +494,12 @@ impl Module {
#[inline(always)]
pub fn set_custom_type_raw(
&mut self,
type_name: impl Into<Identifier>,
type_path: impl Into<Identifier>,
name: impl Into<Identifier>,
) -> &mut Self {
self.custom_types
.get_or_insert_with(CustomTypesCollection::new)
.add(type_name, name);
.add(type_path, name);
self
}
/// Get the display name of a registered custom type.

View File

@ -79,7 +79,6 @@ pub mod blob_functions {
let _ctx = ctx;
// Check if blob will be over max size limit
#[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_array_size() > 0 && len > _ctx.engine().max_array_size() {
return Err(
crate::ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into(),
@ -364,7 +363,6 @@ pub mod blob_functions {
let _ctx = ctx;
// Check if blob will be over max size limit
#[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_array_size() > 0 && len > _ctx.engine().max_array_size() {
return Err(
crate::ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into(),

View File

@ -1216,7 +1216,6 @@ mod string_functions {
let _ctx = ctx;
// Check if string will be over max size limit
#[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_string_size() > 0 && len > _ctx.engine().max_string_size() {
return Err(crate::ERR::ErrorDataTooLarge(
"Length of string".to_string(),
@ -1234,7 +1233,6 @@ mod string_functions {
p.push(character);
}
#[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_string_size() > 0 && string.len() > _ctx.engine().max_string_size()
{
return Err(crate::ERR::ErrorDataTooLarge(
@ -1278,7 +1276,6 @@ mod string_functions {
let _ctx = ctx;
// Check if string will be over max size limit
#[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_string_size() > 0 && len > _ctx.engine().max_string_size() {
return Err(crate::ERR::ErrorDataTooLarge(
"Length of string".to_string(),
@ -1303,7 +1300,6 @@ mod string_functions {
}
}
#[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_string_size() > 0 && string.len() > _ctx.engine().max_string_size()
{
return Err(crate::ERR::ErrorDataTooLarge(

View File

@ -906,7 +906,6 @@ impl Engine {
loop {
const MISSING_RBRACKET: &str = "to end this array literal";
#[cfg(not(feature = "unchecked"))]
if self.max_array_size() > 0 && array.len() >= self.max_array_size() {
return Err(PERR::LiteralTooLarge(
"Size of array literal".to_string(),
@ -1043,7 +1042,6 @@ impl Engine {
}
};
#[cfg(not(feature = "unchecked"))]
if self.max_map_size() > 0 && map.len() >= self.max_map_size() {
return Err(PERR::LiteralTooLarge(
"Number of properties in object map literal".to_string(),