diff --git a/boa/Cargo.toml b/boa/Cargo.toml index 5b1aca6f3f..5a45eab54c 100644 --- a/boa/Cargo.toml +++ b/boa/Cargo.toml @@ -9,7 +9,7 @@ categories = ["parser-implementations", "wasm"] license = "Unlicense/MIT" exclude = ["../.vscode/*", "../Dockerfile", "../Makefile", "../.editorConfig"] edition = "2021" -rust-version = "1.56" +rust-version = "1.57" [features] profiler = ["measureme"] diff --git a/boa/src/builtins/array_buffer/mod.rs b/boa/src/builtins/array_buffer/mod.rs index acb57174c6..36597a5c7f 100644 --- a/boa/src/builtins/array_buffer/mod.rs +++ b/boa/src/builtins/array_buffer/mod.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use crate::{ builtins::{typed_array::TypedArrayName, BuiltIn, JsArgs}, context::StandardObjects, @@ -313,11 +316,7 @@ impl ArrayBuffer { obj.set_prototype(prototype.into()); // 2. Let block be ? CreateByteDataBlock(byteLength). - // TODO: for now just a arbitrary limit to not OOM. - if byte_length > 8589934592 { - return Err(context.construct_range_error("ArrayBuffer allocation failed")); - } - let block = vec![0; byte_length]; + let block = create_byte_data_block(byte_length, context)?; // 3. Set obj.[[ArrayBufferData]] to block. // 4. Set obj.[[ArrayBufferByteLength]] to byteLength. @@ -733,6 +732,27 @@ impl ArrayBuffer { } } +/// `CreateByteDataBlock ( size )` abstract operation. +/// +/// The abstract operation `CreateByteDataBlock` takes argument `size` (a non-negative +/// integer). For more information, check the [spec][spec]. +/// +/// [spec]: https://tc39.es/ecma262/#sec-createbytedatablock +pub fn create_byte_data_block(size: usize, context: &mut Context) -> JsResult> { + // 1. Let db be a new Data Block value consisting of size bytes. If it is impossible to + // create such a Data Block, throw a RangeError exception. + let mut data_block = Vec::new(); + data_block.try_reserve(size).map_err(|e| { + context.construct_range_error(format!("couldn't allocate the data block: {}", e)) + })?; + + // 2. Set all of the bytes of db to 0. + data_block.resize(size, 0); + + // 3. Return db. + Ok(data_block) +} + /// `6.2.8.3 CopyDataBlockBytes ( toBlock, toIndex, fromBlock, fromIndex, count )` /// /// More information: diff --git a/boa/src/builtins/array_buffer/tests.rs b/boa/src/builtins/array_buffer/tests.rs new file mode 100644 index 0000000000..4f50ca9b12 --- /dev/null +++ b/boa/src/builtins/array_buffer/tests.rs @@ -0,0 +1,15 @@ +use super::*; + +#[test] +fn ut_sunnyy_day_create_byte_data_block() { + let mut context = Context::new(); + + assert!(create_byte_data_block(100, &mut context).is_ok()) +} + +#[test] +fn ut_rainy_day_create_byte_data_block() { + let mut context = Context::new(); + + assert!(create_byte_data_block(usize::MAX, &mut context).is_err()) +} diff --git a/boa/src/builtins/typed_array/integer_indexed_object.rs b/boa/src/builtins/typed_array/integer_indexed_object.rs index e4b7ab066f..cf29aacad5 100644 --- a/boa/src/builtins/typed_array/integer_indexed_object.rs +++ b/boa/src/builtins/typed_array/integer_indexed_object.rs @@ -12,7 +12,7 @@ use crate::{ builtins::typed_array::TypedArrayName, gc::{empty_trace, Finalize, Trace}, object::{JsObject, ObjectData}, - Context, JsResult, + Context, }; /// Type of the array content. @@ -147,38 +147,3 @@ impl IntegerIndexed { self.array_length = array_length; } } - -/// A Data Block -/// -/// The Data Block specification type is used to describe a distinct and mutable sequence of -/// byte-sized (8 bit) numeric values. A byte value is an integer value in the range `0` through -/// `255`, inclusive. A Data Block value is created with a fixed number of bytes that each have -/// the initial value `0`. -/// -/// For more information, check the [spec][spec]. -/// -/// [spec]: https://tc39.es/ecma262/#sec-data-blocks -#[derive(Debug, Clone, Default, Trace, Finalize)] -pub struct DataBlock { - inner: Vec, -} - -impl DataBlock { - /// `CreateByteDataBlock ( size )` abstract operation. - /// - /// The abstract operation `CreateByteDataBlock` takes argument `size` (a non-negative - /// integer). For more information, check the [spec][spec]. - /// - /// [spec]: https://tc39.es/ecma262/#sec-createbytedatablock - pub fn create_byte_data_block(size: usize) -> JsResult { - // 1. Let db be a new Data Block value consisting of size bytes. If it is impossible to - // create such a Data Block, throw a RangeError exception. - // 2. Set all of the bytes of db to 0. - // 3. Return db. - // TODO: waiting on for having fallible - // allocation. - Ok(Self { - inner: vec![0u8; size], - }) - } -}