diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b2d71ec..f801b08d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. * 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 ------------ diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 6c07f94d..72c40e87 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -3,6 +3,7 @@ use crate::engine::OP_EQUALS; use crate::plugin::*; +use crate::types::dynamic::Union; use crate::{ def_package, Array, Dynamic, ExclusiveRange, FnPtr, InclusiveRange, NativeCallContext, Position, RhaiResultOf, ERR, INT, @@ -81,20 +82,42 @@ pub mod array_functions { len: INT, item: Dynamic, ) -> RhaiResultOf<()> { - if len <= 0 { + if len <= 0 || (len as usize) <= array.len() { return Ok(()); } let _ctx = ctx; + let len = len as usize; // Check if array will be over max size limit #[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()); } - if len as usize > array.len() { - array.resize(len as usize, item); + #[cfg(not(feature = "unchecked"))] + 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::().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(())