Fix Array::pad limits.

This commit is contained in:
Stephen Chung 2022-01-06 15:30:17 +08:00
parent 0a63e1732b
commit 80edb1200d
2 changed files with 28 additions and 4 deletions

View File

@ -23,6 +23,7 @@ Bug fixes
* Constructing a literal array or object map now checks for size limits for each item instead of at the very end when it is already too late. * Constructing a literal array or object map now checks for size limits for each item instead of at the very end when it is already too late.
* Non-`INT` integer types are now treated exactly as custom types under `only_i64` and `only_i32`. * Non-`INT` integer types are now treated exactly as custom types under `only_i64` and `only_i32`.
* Calling `pad` on an array now checks for total size over limit after each item added.
New features New features
------------ ------------

View File

@ -3,6 +3,7 @@
use crate::engine::OP_EQUALS; use crate::engine::OP_EQUALS;
use crate::plugin::*; use crate::plugin::*;
use crate::types::dynamic::Union;
use crate::{ use crate::{
def_package, Array, Dynamic, ExclusiveRange, FnPtr, InclusiveRange, NativeCallContext, def_package, Array, Dynamic, ExclusiveRange, FnPtr, InclusiveRange, NativeCallContext,
Position, RhaiResultOf, ERR, INT, Position, RhaiResultOf, ERR, INT,
@ -81,20 +82,42 @@ pub mod array_functions {
len: INT, len: INT,
item: Dynamic, item: Dynamic,
) -> RhaiResultOf<()> { ) -> RhaiResultOf<()> {
if len <= 0 { if len <= 0 || (len as usize) <= array.len() {
return Ok(()); return Ok(());
} }
let _ctx = ctx; let _ctx = ctx;
let len = len as usize;
// Check if array will be over max size limit // Check if array will be over max size limit
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if _ctx.engine().max_array_size() > 0 && (len as usize) > _ctx.engine().max_array_size() { if _ctx.engine().max_array_size() > 0 && len > _ctx.engine().max_array_size() {
return Err(ERR::ErrorDataTooLarge("Size of array".to_string(), Position::NONE).into()); return Err(ERR::ErrorDataTooLarge("Size of array".to_string(), Position::NONE).into());
} }
if len as usize > array.len() { #[cfg(not(feature = "unchecked"))]
array.resize(len as usize, item); let check_sizes = match item.0 {
Union::Array(_, _, _) | Union::Str(_, _, _) => true,
Union::Map(_, _, _) => true,
_ => false,
};
#[cfg(feature = "unchecked")]
let check_sizes = false;
if check_sizes {
let arr = mem::take(array);
let mut arr = Dynamic::from_array(arr);
while array.len() < len {
arr.write_lock::<Array>().unwrap().push(item.clone());
#[cfg(not(feature = "unchecked"))]
_ctx.engine().ensure_data_size_within_limits(&arr)?;
}
*array = arr.into_array().unwrap();
} else {
array.resize(len, item);
} }
Ok(()) Ok(())