summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJinho Bang <zino@chromium.org>2018-01-08 23:37:27 +0900
committerMichael Dawson <michael_dawson@ca.ibm.com>2018-01-16 15:22:36 -0500
commit316b5efd6b02379a490ce62c31a13122729ff1dd (patch)
tree39db3752d7b7f7858dfc8bf38f0e31eda0b6e8bf /src
parent4319780389badf4e173f57408b42949a2841a188 (diff)
downloadandroid-node-v8-316b5efd6b02379a490ce62c31a13122729ff1dd.tar.gz
android-node-v8-316b5efd6b02379a490ce62c31a13122729ff1dd.tar.bz2
android-node-v8-316b5efd6b02379a490ce62c31a13122729ff1dd.zip
n-api: throw RangeError napi_create_typedarray()
According to the ECMA spec, we should throw a RangeError in the following cases: - `(length * elementSize) + offset` > the size of the array passed in - `offset % elementSize` != `0` In the current implementation, this check was omitted. So, the following code will cause a crash. ``` napi_create_typedarray(env, napi_uint16_array, 2 /* length */, buffer, 1 /* byte_offset */, &output_array); ``` This change fixes the problem and write some related tests. Refs: https://tc39.github.io/ecma262/#sec-typedarray-buffer-byteoffset-length PR-URL: https://github.com/nodejs/node/pull/18037 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/node_api.cc51
1 files changed, 42 insertions, 9 deletions
diff --git a/src/node_api.cc b/src/node_api.cc
index 2101fcba02..27ab6707de 100644
--- a/src/node_api.cc
+++ b/src/node_api.cc
@@ -142,6 +142,30 @@ struct napi_env__ {
(!try_catch.HasCaught() ? napi_ok \
: napi_set_last_error((env), napi_pending_exception))
+#define THROW_RANGE_ERROR_IF_FALSE(env, condition, error, message) \
+ do { \
+ if (!(condition)) { \
+ napi_throw_range_error((env), (error), (message)); \
+ return napi_set_last_error((env), napi_generic_failure); \
+ } \
+ } while (0)
+
+#define CREATE_TYPED_ARRAY( \
+ env, type, size_of_element, buffer, byte_offset, length, out) \
+ do { \
+ if ((size_of_element) > 1) { \
+ THROW_RANGE_ERROR_IF_FALSE( \
+ (env), (byte_offset) % (size_of_element) == 0, \
+ "ERR_NAPI_INVALID_TYPEDARRAY_ALIGNMENT", \
+ "start offset of "#type" should be a multiple of "#size_of_element); \
+ } \
+ THROW_RANGE_ERROR_IF_FALSE((env), (length) * (size_of_element) + \
+ (byte_offset) <= buffer->ByteLength(), \
+ "ERR_NAPI_INVALID_TYPEDARRAY_LENGTH", \
+ "Invalid typed array length"); \
+ (out) = v8::type::New((buffer), (byte_offset), (length)); \
+ } while (0)
+
namespace {
namespace v8impl {
@@ -3063,31 +3087,40 @@ napi_status napi_create_typedarray(napi_env env,
switch (type) {
case napi_int8_array:
- typedArray = v8::Int8Array::New(buffer, byte_offset, length);
+ CREATE_TYPED_ARRAY(
+ env, Int8Array, 1, buffer, byte_offset, length, typedArray);
break;
case napi_uint8_array:
- typedArray = v8::Uint8Array::New(buffer, byte_offset, length);
+ CREATE_TYPED_ARRAY(
+ env, Uint8Array, 1, buffer, byte_offset, length, typedArray);
break;
case napi_uint8_clamped_array:
- typedArray = v8::Uint8ClampedArray::New(buffer, byte_offset, length);
+ CREATE_TYPED_ARRAY(
+ env, Uint8ClampedArray, 1, buffer, byte_offset, length, typedArray);
break;
case napi_int16_array:
- typedArray = v8::Int16Array::New(buffer, byte_offset, length);
+ CREATE_TYPED_ARRAY(
+ env, Int16Array, 2, buffer, byte_offset, length, typedArray);
break;
case napi_uint16_array:
- typedArray = v8::Uint16Array::New(buffer, byte_offset, length);
+ CREATE_TYPED_ARRAY(
+ env, Uint16Array, 2, buffer, byte_offset, length, typedArray);
break;
case napi_int32_array:
- typedArray = v8::Int32Array::New(buffer, byte_offset, length);
+ CREATE_TYPED_ARRAY(
+ env, Int32Array, 4, buffer, byte_offset, length, typedArray);
break;
case napi_uint32_array:
- typedArray = v8::Uint32Array::New(buffer, byte_offset, length);
+ CREATE_TYPED_ARRAY(
+ env, Uint32Array, 4, buffer, byte_offset, length, typedArray);
break;
case napi_float32_array:
- typedArray = v8::Float32Array::New(buffer, byte_offset, length);
+ CREATE_TYPED_ARRAY(
+ env, Float32Array, 4, buffer, byte_offset, length, typedArray);
break;
case napi_float64_array:
- typedArray = v8::Float64Array::New(buffer, byte_offset, length);
+ CREATE_TYPED_ARRAY(
+ env, Float64Array, 8, buffer, byte_offset, length, typedArray);
break;
default:
return napi_set_last_error(env, napi_invalid_arg);