Make sure the size arg of alloc will not overflow (#1618)
Also make sure the bytelength = arraylength << shift will not overflow Fix issue #1616 JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang zidong.jiang@intel.com
This commit is contained in:
@@ -321,6 +321,12 @@ ecma_builtin_typedarray_prototype_map (ecma_value_t this_arg, /**< this argument
|
||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ecma_value_t new_typedarray = ecma_op_create_typedarray_with_type_and_length (obj_p, len);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (new_typedarray))
|
||||
{
|
||||
return new_typedarray;
|
||||
}
|
||||
|
||||
ecma_object_t *new_obj_p = ecma_get_object_from_value (new_typedarray);
|
||||
|
||||
for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++)
|
||||
@@ -331,7 +337,7 @@ ecma_builtin_typedarray_prototype_map (ecma_value_t this_arg, /**< this argument
|
||||
|
||||
ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, cb_this_arg, call_args, 3), ret_value);
|
||||
|
||||
ecma_value_t set_status = ecma_op_typedarray_set_index_prop (new_obj_p, index, mapped_value);
|
||||
bool set_status = ecma_op_typedarray_set_index_prop (new_obj_p, index, mapped_value);
|
||||
|
||||
if (!set_status)
|
||||
{
|
||||
@@ -574,25 +580,33 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum
|
||||
if (ecma_is_value_empty (ret_value))
|
||||
{
|
||||
ecma_value_t new_typedarray = ecma_op_create_typedarray_with_type_and_length (obj_p, pass_num);
|
||||
ecma_object_t *new_obj_p = ecma_get_object_from_value (new_typedarray);
|
||||
|
||||
for (uint32_t index = 0; index < pass_num && ecma_is_value_empty (ret_value); index++)
|
||||
{
|
||||
ecma_value_t set_status = ecma_op_typedarray_set_index_prop (new_obj_p, index, *(pass_value_list + index));
|
||||
|
||||
if (!set_status)
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("error in typedarray set"));
|
||||
}
|
||||
}
|
||||
|
||||
if (ecma_is_value_empty (ret_value))
|
||||
if (ECMA_IS_VALUE_ERROR (new_typedarray))
|
||||
{
|
||||
ret_value = new_typedarray;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_free_value (new_typedarray);
|
||||
ecma_object_t *new_obj_p = ecma_get_object_from_value (new_typedarray);
|
||||
|
||||
for (uint32_t index = 0; index < pass_num && ecma_is_value_empty (ret_value); index++)
|
||||
{
|
||||
bool set_status = ecma_op_typedarray_set_index_prop (new_obj_p, index, *(pass_value_list + index));
|
||||
|
||||
if (!set_status)
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("error in typedarray set"));
|
||||
}
|
||||
}
|
||||
|
||||
if (ecma_is_value_empty (ret_value))
|
||||
{
|
||||
ret_value = new_typedarray;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_free_value (new_typedarray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "jmem.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_ARRAYBUFFER_BUILTIN
|
||||
|
||||
@@ -68,6 +69,11 @@ ecma_op_create_arraybuffer_object (const ecma_value_t *arguments_list_p, /**< li
|
||||
}
|
||||
}
|
||||
|
||||
if (length > UINT32_MAX - sizeof (ecma_extended_object_t) - JMEM_ALIGNMENT + 1)
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid ArrayBuffer length."));
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_arraybuffer_new_object (length);
|
||||
|
||||
return ecma_make_object_value (object_p);
|
||||
|
||||
@@ -205,18 +205,28 @@ set_typedarray_element (lit_utf8_byte_t *dst, /**< the location in the internal
|
||||
*
|
||||
* See also: ES2015 22.2.1.2.1
|
||||
*
|
||||
* @return pointer to the new typedarray object
|
||||
* @return ecma value of the new typedarray object
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
static ecma_object_t *
|
||||
static ecma_value_t
|
||||
ecma_typedarray_create_object_with_length (ecma_length_t array_length, /**< length of the typedarray */
|
||||
ecma_object_t *proto_p, /**< prototype object */
|
||||
uint8_t element_size_shift, /**< the size shift of the element length */
|
||||
lit_magic_string_id_t class_id) /**< class name of the typedarray */
|
||||
{
|
||||
if (array_length > (UINT32_MAX >> element_size_shift))
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum typedarray size is reached."));
|
||||
}
|
||||
|
||||
ecma_length_t byte_length = array_length << element_size_shift;
|
||||
|
||||
ecma_value_t new_arraybuffer_p = ecma_make_object_value (ecma_arraybuffer_new_object (byte_length));
|
||||
if (byte_length > UINT32_MAX - sizeof (ecma_extended_object_t) - JMEM_ALIGNMENT + 1)
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum typedarray size is reached."));
|
||||
}
|
||||
|
||||
ecma_value_t new_arraybuffer_p = ecma_make_object_value (ecma_arraybuffer_new_object (byte_length));
|
||||
ecma_object_t *object_p = ecma_create_object (proto_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_PSEUDO_ARRAY);
|
||||
@@ -229,7 +239,7 @@ ecma_typedarray_create_object_with_length (ecma_length_t array_length, /**< leng
|
||||
|
||||
ecma_free_value (new_arraybuffer_p);
|
||||
|
||||
return object_p;
|
||||
return ecma_make_object_value (object_p);
|
||||
} /* !ecma_typedarray_create_object_with_length */
|
||||
|
||||
/**
|
||||
@@ -237,9 +247,10 @@ ecma_typedarray_create_object_with_length (ecma_length_t array_length, /**< leng
|
||||
*
|
||||
* See also: ES2015 22.2.1.5
|
||||
*
|
||||
* @return pointer to the new typedarray object
|
||||
* @return ecma value of the new typedarray object
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
static ecma_object_t *
|
||||
static ecma_value_t
|
||||
ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< the arraybuffer inside */
|
||||
ecma_length_t byte_offset, /**< the byte offset of the arraybuffer */
|
||||
ecma_length_t array_length, /**< length of the typedarray */
|
||||
@@ -248,6 +259,7 @@ ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< th
|
||||
lit_magic_string_id_t class_id) /**< class name of the typedarray */
|
||||
{
|
||||
ecma_object_t *object_p;
|
||||
|
||||
if (byte_offset == 0 && array_length == ecma_arraybuffer_get_length (arraybuffer_p) >> element_size_shift)
|
||||
{
|
||||
object_p = ecma_create_object (proto_p,
|
||||
@@ -260,7 +272,7 @@ ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< th
|
||||
ext_object_p->u.pseudo_array.extra_info = element_size_shift;
|
||||
ext_object_p->u.pseudo_array.u2.arraybuffer = ecma_make_object_value (arraybuffer_p);
|
||||
|
||||
return object_p;
|
||||
return ecma_make_object_value (object_p);
|
||||
}
|
||||
|
||||
object_p = ecma_create_object (proto_p,
|
||||
@@ -277,7 +289,7 @@ ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< th
|
||||
typedarray_info_p->array_length = array_length;
|
||||
typedarray_info_p->byte_offset = byte_offset;
|
||||
|
||||
return object_p;
|
||||
return ecma_make_object_value (object_p);
|
||||
} /* ecma_typedarray_create_object_with_buffer */
|
||||
|
||||
/**
|
||||
@@ -285,9 +297,10 @@ ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< th
|
||||
*
|
||||
* See also: ES2015 22.2.1.3
|
||||
*
|
||||
* @return pointer to the new typedarray object
|
||||
* @return ecma value of the new typedarray object
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
static ecma_object_t *
|
||||
static ecma_value_t
|
||||
ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**< a typedarray object */
|
||||
ecma_object_t *proto_p, /**< prototype object */
|
||||
uint8_t element_size_shift, /**< the size shift of the element length */
|
||||
@@ -306,7 +319,18 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**<
|
||||
}
|
||||
else
|
||||
{
|
||||
if (array_length > (UINT32_MAX >> element_size_shift))
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum typedarray size is reached."));
|
||||
}
|
||||
|
||||
ecma_length_t byte_length = array_length << element_size_shift;
|
||||
|
||||
if (byte_length > UINT32_MAX - sizeof (ecma_extended_object_t) - JMEM_ALIGNMENT + 1)
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum typedarray size is reached."));
|
||||
}
|
||||
|
||||
arraybuffer_p = ecma_arraybuffer_new_object (byte_length);
|
||||
lit_utf8_byte_t *src_buf = ecma_arraybuffer_get_buffer (src_arraybuffer_p);
|
||||
lit_utf8_byte_t *dst_buf = ecma_arraybuffer_get_buffer (arraybuffer_p);
|
||||
@@ -324,16 +348,16 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**<
|
||||
}
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_typedarray_create_object_with_buffer (arraybuffer_p,
|
||||
0,
|
||||
array_length,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
ecma_value_t obj = ecma_typedarray_create_object_with_buffer (arraybuffer_p,
|
||||
0,
|
||||
array_length,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
|
||||
ecma_deref_object (arraybuffer_p);
|
||||
|
||||
return object_p;
|
||||
return obj;
|
||||
} /* ecma_typedarray_create_object_with_typedarray */
|
||||
|
||||
/**
|
||||
@@ -341,7 +365,7 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**<
|
||||
*
|
||||
* See also: ES2015 22.2.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* @return ecma value of the new typedarray object
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
@@ -364,11 +388,11 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
|
||||
}
|
||||
|
||||
/* 10 */
|
||||
ECMA_TRY_CATCH (arraylike_val,
|
||||
ECMA_TRY_CATCH (arraylike,
|
||||
ecma_op_to_object (items_val),
|
||||
ret_value);
|
||||
|
||||
ecma_object_t *arraylike_p = ecma_get_object_from_value (arraylike_val);
|
||||
ecma_object_t *arraylike_p = ecma_get_object_from_value (arraylike);
|
||||
|
||||
/* 12 */
|
||||
ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string ();
|
||||
@@ -382,10 +406,17 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
|
||||
uint32_t len = ecma_number_to_uint32 (len_number);
|
||||
|
||||
/* 14 */
|
||||
ecma_object_t *new_typedarray_p = ecma_typedarray_create_object_with_length (len,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (len,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (new_typedarray))
|
||||
{
|
||||
ret_value = ecma_copy_value (new_typedarray);
|
||||
}
|
||||
|
||||
ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray);
|
||||
|
||||
/* 17 */
|
||||
ecma_value_t current_index;
|
||||
@@ -446,7 +477,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (len_number);
|
||||
ECMA_FINALIZE (len_value);
|
||||
ecma_deref_ecma_string (magic_string_length_p);
|
||||
ECMA_FINALIZE (arraylike_val);
|
||||
ECMA_FINALIZE (arraylike);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_typedarray_from */
|
||||
@@ -539,7 +570,7 @@ ecma_typedarray_get_offset (ecma_object_t *typedarray_p) /**< the pointer to the
|
||||
* extend_part
|
||||
* typedarray_info
|
||||
*
|
||||
* @return ecma value
|
||||
* @return ecma value of the new typedarray object
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
@@ -556,7 +587,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
|
||||
if (arguments_list_len == 0)
|
||||
{
|
||||
/* 22.2.1.1 */
|
||||
ret = ecma_make_object_value (ecma_typedarray_create_object_with_length (0, proto_p, element_size_shift, class_id));
|
||||
ret = ecma_typedarray_create_object_with_length (0, proto_p, element_size_shift, class_id);
|
||||
}
|
||||
else if (!ecma_is_value_object (arguments_list_p[0]))
|
||||
{
|
||||
@@ -576,10 +607,10 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ecma_make_object_value (ecma_typedarray_create_object_with_length (length,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id));
|
||||
ret = ecma_typedarray_create_object_with_length (length,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
}
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num);
|
||||
@@ -590,10 +621,10 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
|
||||
{
|
||||
/* 22.2.1.3 */
|
||||
ecma_object_t *typedarray_p = ecma_get_object_from_value (arguments_list_p[0]);
|
||||
ret = ecma_make_object_value (ecma_typedarray_create_object_with_typedarray (typedarray_p,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id));
|
||||
ret = ecma_typedarray_create_object_with_typedarray (typedarray_p,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
}
|
||||
else if (ecma_is_arraybuffer (arguments_list_p[0]))
|
||||
{
|
||||
@@ -638,6 +669,12 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num3, arg3, ret);
|
||||
int32_t new_length = ecma_number_to_int32 (num3);
|
||||
new_length = (new_length > 0) ? new_length : 0;
|
||||
|
||||
if ((uint32_t) new_length > (UINT32_MAX >> element_size_shift))
|
||||
{
|
||||
ret = ecma_raise_range_error (ECMA_ERR_MSG ("Maximum typedarray size is reached."));
|
||||
}
|
||||
|
||||
new_byte_length = (ecma_length_t) new_length << element_size_shift;
|
||||
|
||||
if (new_byte_length + offset > buf_byte_length)
|
||||
@@ -651,12 +688,12 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
|
||||
if (ecma_is_value_empty (ret))
|
||||
{
|
||||
ecma_length_t array_length = new_byte_length >> element_size_shift;
|
||||
ret = ecma_make_object_value (ecma_typedarray_create_object_with_buffer (arraybuffer_p,
|
||||
offset,
|
||||
array_length,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id));
|
||||
ret = ecma_typedarray_create_object_with_buffer (arraybuffer_p,
|
||||
offset,
|
||||
array_length,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -665,10 +702,10 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
|
||||
else
|
||||
{
|
||||
/* 22.2.1.4 */
|
||||
ecma_value_t undef_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
ecma_value_t undef = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
ret = ecma_op_typedarray_from (arguments_list_p[0],
|
||||
undef_val,
|
||||
undef_val,
|
||||
undef,
|
||||
undef,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
@@ -825,9 +862,9 @@ ecma_op_typedarray_set_index_prop (ecma_object_t *obj_p, /**< a TypedArray objec
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_value_t error_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
ecma_value_t error = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (value_num, value, error_val);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (value_num, value, error);
|
||||
|
||||
ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (obj_p);
|
||||
ecma_length_t offset = ecma_typedarray_get_offset (obj_p);
|
||||
@@ -839,7 +876,7 @@ ecma_op_typedarray_set_index_prop (ecma_object_t *obj_p, /**< a TypedArray objec
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (value_num);
|
||||
|
||||
if (ecma_is_value_empty (error_val))
|
||||
if (ecma_is_value_empty (error))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -929,14 +966,14 @@ ecma_op_create_typedarray_with_type_and_length (ecma_object_t *obj_p, /**< Typed
|
||||
}
|
||||
}
|
||||
|
||||
ecma_object_t *new_obj_p = ecma_typedarray_create_object_with_length (array_length,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
ecma_value_t new_obj = ecma_typedarray_create_object_with_length (array_length,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
|
||||
ecma_deref_object (proto_p);
|
||||
|
||||
return ecma_make_object_value (new_obj_p);
|
||||
return new_obj;
|
||||
} /* ecma_op_create_typedarray_with_type_and_length */
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright JS Foundation and other contributors, http://js.foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
var name = "";
|
||||
|
||||
try
|
||||
{
|
||||
var a = new ArrayBuffer (0xfffffffe)
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
name = e.name;
|
||||
}
|
||||
|
||||
assert(name === "RangeError");
|
||||
|
||||
Reference in New Issue
Block a user