Make limit getters available without unchecked.
This commit is contained in:
parent
e8fd965eba
commit
891214470b
@ -25,6 +25,7 @@ Enhancements
|
|||||||
* `Scope` is now serializable and deserializable via `serde`.
|
* `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.
|
* `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.
|
* `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
|
Version 1.10.1
|
||||||
|
@ -94,12 +94,14 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
/// The maximum levels of function calls allowed for a script.
|
/// The maximum levels of function calls allowed for a script.
|
||||||
///
|
///
|
||||||
/// Not available under `unchecked` or `no_function`.
|
/// Zero under `no_function`.
|
||||||
#[cfg(not(feature = "no_function"))]
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn max_call_levels(&self) -> usize {
|
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
|
/// Set the maximum number of operations allowed for a script to run to avoid
|
||||||
/// consuming too much resources (0 for unlimited).
|
/// 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.
|
/// The maximum number of imported [modules][crate::Module] allowed for a script.
|
||||||
///
|
///
|
||||||
/// Not available under `unchecked` or `no_module`.
|
/// Zero under `no_module`.
|
||||||
#[cfg(not(feature = "no_module"))]
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn max_modules(&self) -> usize {
|
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).
|
/// Set the depth limits for expressions (0 for unlimited).
|
||||||
///
|
///
|
||||||
@ -157,8 +161,6 @@ impl Engine {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// The depth limit for expressions (0 for unlimited).
|
/// The depth limit for expressions (0 for unlimited).
|
||||||
///
|
|
||||||
/// Not available under `unchecked`.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn max_expr_depth(&self) -> usize {
|
pub const fn max_expr_depth(&self) -> usize {
|
||||||
@ -170,16 +172,18 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
/// The depth limit for expressions in functions (0 for unlimited).
|
/// The depth limit for expressions in functions (0 for unlimited).
|
||||||
///
|
///
|
||||||
/// Not available under `unchecked` or `no_function`.
|
/// Zero under `no_function`.
|
||||||
#[cfg(not(feature = "no_function"))]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn max_function_expr_depth(&self) -> usize {
|
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()
|
n.get()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
};
|
||||||
|
#[cfg(feature = "no_function")]
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/// Set the maximum length of [strings][crate::ImmutableString] (0 for unlimited).
|
/// Set the maximum length of [strings][crate::ImmutableString] (0 for unlimited).
|
||||||
///
|
///
|
||||||
@ -190,8 +194,6 @@ impl Engine {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// The maximum length of [strings][crate::ImmutableString] (0 for unlimited).
|
/// The maximum length of [strings][crate::ImmutableString] (0 for unlimited).
|
||||||
///
|
|
||||||
/// Not available under `unchecked`.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn max_string_size(&self) -> usize {
|
pub const fn max_string_size(&self) -> usize {
|
||||||
@ -212,16 +214,18 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
/// The maximum length of [arrays][crate::Array] (0 for unlimited).
|
/// The maximum length of [arrays][crate::Array] (0 for unlimited).
|
||||||
///
|
///
|
||||||
/// Not available under `unchecked` or `no_index`.
|
/// Zero under `no_index`.
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn max_array_size(&self) -> usize {
|
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()
|
n.get()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
};
|
||||||
|
#[cfg(feature = "no_index")]
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/// Set the maximum size of [object maps][crate::Map] (0 for unlimited).
|
/// 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).
|
/// The maximum size of [object maps][crate::Map] (0 for unlimited).
|
||||||
///
|
///
|
||||||
/// Not available under `unchecked` or `no_object`.
|
/// Zero under `no_object`.
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn max_map_size(&self) -> usize {
|
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()
|
n.get()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
};
|
||||||
|
#[cfg(feature = "no_object")]
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,3 +236,55 @@ impl Engine {
|
|||||||
self
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -226,12 +226,12 @@ impl Engine {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn register_type_with_name_raw(
|
pub fn register_type_with_name_raw(
|
||||||
&mut self,
|
&mut self,
|
||||||
fully_qualified_type_path: impl Into<Identifier>,
|
type_path: impl Into<Identifier>,
|
||||||
name: impl Into<Identifier>,
|
name: impl Into<Identifier>,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
// Add the pretty-print type name into the map
|
// Add the pretty-print type name into the map
|
||||||
self.global_namespace_mut()
|
self.global_namespace_mut()
|
||||||
.set_custom_type_raw(fully_qualified_type_path, name);
|
.set_custom_type_raw(type_path, name);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Register a type iterator for an iterable type with the [`Engine`].
|
/// Register a type iterator for an iterable type with the [`Engine`].
|
||||||
|
@ -36,6 +36,7 @@ pub struct GlobalRuntimeState<'a> {
|
|||||||
/// Number of operations performed.
|
/// Number of operations performed.
|
||||||
pub num_operations: u64,
|
pub num_operations: u64,
|
||||||
/// Number of modules loaded.
|
/// Number of modules loaded.
|
||||||
|
#[cfg(not(feature = "no_module"))]
|
||||||
pub num_modules_loaded: usize,
|
pub num_modules_loaded: usize,
|
||||||
/// Level of the current scope.
|
/// Level of the current scope.
|
||||||
///
|
///
|
||||||
|
@ -738,7 +738,7 @@ impl Engine {
|
|||||||
|
|
||||||
#[cfg(feature = "no_object")]
|
#[cfg(feature = "no_object")]
|
||||||
_ => {
|
_ => {
|
||||||
err.take_position();
|
let _ = err.take_position();
|
||||||
err.to_string().into()
|
err.to_string().into()
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
@ -924,7 +924,6 @@ impl Engine {
|
|||||||
let (expr, export) = &**x;
|
let (expr, export) = &**x;
|
||||||
|
|
||||||
// Guard against too many modules
|
// Guard against too many modules
|
||||||
#[cfg(not(feature = "unchecked"))]
|
|
||||||
if global.num_modules_loaded >= self.max_modules() {
|
if global.num_modules_loaded >= self.max_modules() {
|
||||||
return Err(ERR::ErrorTooManyModules(*_pos).into());
|
return Err(ERR::ErrorTooManyModules(*_pos).into());
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,6 @@ impl Engine {
|
|||||||
self.inc_operations(&mut global.num_operations, pos)?;
|
self.inc_operations(&mut global.num_operations, pos)?;
|
||||||
|
|
||||||
// Check for stack overflow
|
// Check for stack overflow
|
||||||
#[cfg(not(feature = "unchecked"))]
|
|
||||||
if level > self.max_call_levels() {
|
if level > self.max_call_levels() {
|
||||||
return Err(ERR::ErrorStackOverflow(pos).into());
|
return Err(ERR::ErrorStackOverflow(pos).into());
|
||||||
}
|
}
|
||||||
|
@ -494,12 +494,12 @@ impl Module {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_custom_type_raw(
|
pub fn set_custom_type_raw(
|
||||||
&mut self,
|
&mut self,
|
||||||
type_name: impl Into<Identifier>,
|
type_path: impl Into<Identifier>,
|
||||||
name: impl Into<Identifier>,
|
name: impl Into<Identifier>,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.custom_types
|
self.custom_types
|
||||||
.get_or_insert_with(CustomTypesCollection::new)
|
.get_or_insert_with(CustomTypesCollection::new)
|
||||||
.add(type_name, name);
|
.add(type_path, name);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Get the display name of a registered custom type.
|
/// Get the display name of a registered custom type.
|
||||||
|
@ -79,7 +79,6 @@ pub mod blob_functions {
|
|||||||
let _ctx = ctx;
|
let _ctx = ctx;
|
||||||
|
|
||||||
// Check if blob will be over max size limit
|
// 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() {
|
if _ctx.engine().max_array_size() > 0 && len > _ctx.engine().max_array_size() {
|
||||||
return Err(
|
return Err(
|
||||||
crate::ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into(),
|
crate::ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into(),
|
||||||
@ -364,7 +363,6 @@ pub mod blob_functions {
|
|||||||
let _ctx = ctx;
|
let _ctx = ctx;
|
||||||
|
|
||||||
// Check if blob will be over max size limit
|
// 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() {
|
if _ctx.engine().max_array_size() > 0 && len > _ctx.engine().max_array_size() {
|
||||||
return Err(
|
return Err(
|
||||||
crate::ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into(),
|
crate::ERR::ErrorDataTooLarge("Size of BLOB".to_string(), Position::NONE).into(),
|
||||||
|
@ -1216,7 +1216,6 @@ mod string_functions {
|
|||||||
let _ctx = ctx;
|
let _ctx = ctx;
|
||||||
|
|
||||||
// Check if string will be over max size limit
|
// 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() {
|
if _ctx.engine().max_string_size() > 0 && len > _ctx.engine().max_string_size() {
|
||||||
return Err(crate::ERR::ErrorDataTooLarge(
|
return Err(crate::ERR::ErrorDataTooLarge(
|
||||||
"Length of string".to_string(),
|
"Length of string".to_string(),
|
||||||
@ -1234,7 +1233,6 @@ mod string_functions {
|
|||||||
p.push(character);
|
p.push(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
|
||||||
if _ctx.engine().max_string_size() > 0 && string.len() > _ctx.engine().max_string_size()
|
if _ctx.engine().max_string_size() > 0 && string.len() > _ctx.engine().max_string_size()
|
||||||
{
|
{
|
||||||
return Err(crate::ERR::ErrorDataTooLarge(
|
return Err(crate::ERR::ErrorDataTooLarge(
|
||||||
@ -1278,7 +1276,6 @@ mod string_functions {
|
|||||||
let _ctx = ctx;
|
let _ctx = ctx;
|
||||||
|
|
||||||
// Check if string will be over max size limit
|
// 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() {
|
if _ctx.engine().max_string_size() > 0 && len > _ctx.engine().max_string_size() {
|
||||||
return Err(crate::ERR::ErrorDataTooLarge(
|
return Err(crate::ERR::ErrorDataTooLarge(
|
||||||
"Length of string".to_string(),
|
"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()
|
if _ctx.engine().max_string_size() > 0 && string.len() > _ctx.engine().max_string_size()
|
||||||
{
|
{
|
||||||
return Err(crate::ERR::ErrorDataTooLarge(
|
return Err(crate::ERR::ErrorDataTooLarge(
|
||||||
|
@ -906,7 +906,6 @@ impl Engine {
|
|||||||
loop {
|
loop {
|
||||||
const MISSING_RBRACKET: &str = "to end this array literal";
|
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() {
|
if self.max_array_size() > 0 && array.len() >= self.max_array_size() {
|
||||||
return Err(PERR::LiteralTooLarge(
|
return Err(PERR::LiteralTooLarge(
|
||||||
"Size of array literal".to_string(),
|
"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() {
|
if self.max_map_size() > 0 && map.len() >= self.max_map_size() {
|
||||||
return Err(PERR::LiteralTooLarge(
|
return Err(PERR::LiteralTooLarge(
|
||||||
"Number of properties in object map literal".to_string(),
|
"Number of properties in object map literal".to_string(),
|
||||||
|
Loading…
Reference in New Issue
Block a user