Skip to content

Commit 5a39fdc

Browse files
romandevmhdawson
authored andcommitted
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: #216 Reviewed-By: Michael Dawson <[email protected]>
1 parent 1376377 commit 5a39fdc

File tree

1 file changed

+42
-9
lines changed

1 file changed

+42
-9
lines changed

src/node_api.cc

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,30 @@ struct napi_env__ {
144144
(!try_catch.HasCaught() ? napi_ok \
145145
: napi_set_last_error((env), napi_pending_exception))
146146

147+
#define THROW_RANGE_ERROR_IF_FALSE(env, condition, error, message) \
148+
do { \
149+
if (!(condition)) { \
150+
napi_throw_range_error((env), (error), (message)); \
151+
return napi_set_last_error((env), napi_generic_failure); \
152+
} \
153+
} while (0)
154+
155+
#define CREATE_TYPED_ARRAY( \
156+
env, type, size_of_element, buffer, byte_offset, length, out) \
157+
do { \
158+
if ((size_of_element) > 1) { \
159+
THROW_RANGE_ERROR_IF_FALSE( \
160+
(env), (byte_offset) % (size_of_element) == 0, \
161+
"ERR_NAPI_INVALID_TYPEDARRAY_ALIGNMENT", \
162+
"start offset of "#type" should be a multiple of "#size_of_element); \
163+
} \
164+
THROW_RANGE_ERROR_IF_FALSE((env), (length) * (size_of_element) + \
165+
(byte_offset) <= buffer->ByteLength(), \
166+
"ERR_NAPI_INVALID_TYPEDARRAY_LENGTH", \
167+
"Invalid typed array length"); \
168+
(out) = v8::type::New((buffer), (byte_offset), (length)); \
169+
} while (0)
170+
147171
namespace {
148172
namespace v8impl {
149173

@@ -3150,31 +3174,40 @@ napi_status napi_create_typedarray(napi_env env,
31503174

31513175
switch (type) {
31523176
case napi_int8_array:
3153-
typedArray = v8::Int8Array::New(buffer, byte_offset, length);
3177+
CREATE_TYPED_ARRAY(
3178+
env, Int8Array, 1, buffer, byte_offset, length, typedArray);
31543179
break;
31553180
case napi_uint8_array:
3156-
typedArray = v8::Uint8Array::New(buffer, byte_offset, length);
3181+
CREATE_TYPED_ARRAY(
3182+
env, Uint8Array, 1, buffer, byte_offset, length, typedArray);
31573183
break;
31583184
case napi_uint8_clamped_array:
3159-
typedArray = v8::Uint8ClampedArray::New(buffer, byte_offset, length);
3185+
CREATE_TYPED_ARRAY(
3186+
env, Uint8ClampedArray, 1, buffer, byte_offset, length, typedArray);
31603187
break;
31613188
case napi_int16_array:
3162-
typedArray = v8::Int16Array::New(buffer, byte_offset, length);
3189+
CREATE_TYPED_ARRAY(
3190+
env, Int16Array, 2, buffer, byte_offset, length, typedArray);
31633191
break;
31643192
case napi_uint16_array:
3165-
typedArray = v8::Uint16Array::New(buffer, byte_offset, length);
3193+
CREATE_TYPED_ARRAY(
3194+
env, Uint16Array, 2, buffer, byte_offset, length, typedArray);
31663195
break;
31673196
case napi_int32_array:
3168-
typedArray = v8::Int32Array::New(buffer, byte_offset, length);
3197+
CREATE_TYPED_ARRAY(
3198+
env, Int32Array, 4, buffer, byte_offset, length, typedArray);
31693199
break;
31703200
case napi_uint32_array:
3171-
typedArray = v8::Uint32Array::New(buffer, byte_offset, length);
3201+
CREATE_TYPED_ARRAY(
3202+
env, Uint32Array, 4, buffer, byte_offset, length, typedArray);
31723203
break;
31733204
case napi_float32_array:
3174-
typedArray = v8::Float32Array::New(buffer, byte_offset, length);
3205+
CREATE_TYPED_ARRAY(
3206+
env, Float32Array, 4, buffer, byte_offset, length, typedArray);
31753207
break;
31763208
case napi_float64_array:
3177-
typedArray = v8::Float64Array::New(buffer, byte_offset, length);
3209+
CREATE_TYPED_ARRAY(
3210+
env, Float64Array, 8, buffer, byte_offset, length, typedArray);
31783211
break;
31793212
default:
31803213
return napi_set_last_error(env, napi_invalid_arg);

0 commit comments

Comments
 (0)