mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 07:45:30 +00:00
Bug 1520434-Improve the error messages when creating unaligned typed arrays r=mgaudet
Improved error messages emitted by JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS.Error messages improved to specify the type and cause of error. Added the test to check the error messages modified matches the expected cases. Differential Revision: https://phabricator.services.mozilla.com/D113874
This commit is contained in:
parent
0882de8cee
commit
b332049130
@ -159,6 +159,32 @@ static inline const char* name(Type atype) {
|
||||
MOZ_CRASH("invalid scalar type");
|
||||
}
|
||||
|
||||
static inline const char* byteSizeString(Type atype) {
|
||||
switch (atype) {
|
||||
case Int8:
|
||||
case Uint8:
|
||||
case Uint8Clamped:
|
||||
return "1";
|
||||
case Int16:
|
||||
case Uint16:
|
||||
return "2";
|
||||
case Int32:
|
||||
case Uint32:
|
||||
case Float32:
|
||||
return "4";
|
||||
case Int64:
|
||||
case Float64:
|
||||
case BigInt64:
|
||||
case BigUint64:
|
||||
return "8";
|
||||
case Simd128:
|
||||
return "16";
|
||||
case MaxTypedArrayViewType:
|
||||
break;
|
||||
}
|
||||
MOZ_CRASH("invalid scalar type");
|
||||
}
|
||||
|
||||
} // namespace Scalar
|
||||
|
||||
} // namespace js
|
||||
|
@ -640,7 +640,12 @@ MSG_DEF(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, 2, JSEXN_TYPEERR, "expected ArrayBuff
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS, 0, JSEXN_TYPEERR, "invalid arguments")
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG,1, JSEXN_RANGEERR, "argument {0} must be >= 0")
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_DETACHED, 0, JSEXN_TYPEERR, "attempting to access detached ArrayBuffer")
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS, 0, JSEXN_RANGEERR, "attempting to construct out-of-bounds TypedArray on ArrayBuffer")
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_OFFSET_BOUNDS, 2, JSEXN_RANGEERR, "start offset of {0}Array should be a multiple of {1}")
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_OFFSET_MISALIGNED, 2, JSEXN_RANGEERR, "buffer length for {0}Array should be a multiple of {1}")
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_OFFSET_LENGTH_BOUNDS, 1, JSEXN_RANGEERR, "size of buffer is too small for {0}Array with byteOffset")
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_ARRAY_LENGTH_BOUNDS, 1, JSEXN_RANGEERR, "attempting to construct out-of-bounds {0}Array on ArrayBuffer")
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_CONSTRUCT_TOO_LARGE, 1, JSEXN_RANGEERR, "{0}Array too large")
|
||||
|
||||
MSG_DEF(JSMSG_TYPED_ARRAY_CALL_OR_CONSTRUCT, 1, JSEXN_TYPEERR, "cannot directly {0} builtin %TypedArray%")
|
||||
MSG_DEF(JSMSG_NON_TYPED_ARRAY_RETURNED, 0, JSEXN_TYPEERR, "constructor didn't return TypedArray object")
|
||||
MSG_DEF(JSMSG_SHORT_TYPED_ARRAY_RETURNED, 2, JSEXN_TYPEERR, "expected TypedArray of at least length {0}, but constructor returned TypedArray of length {1}")
|
||||
|
38
js/src/jit-test/tests/typedarray/error-messages.js
Normal file
38
js/src/jit-test/tests/typedarray/error-messages.js
Normal file
@ -0,0 +1,38 @@
|
||||
function assertThrowsMessage(f, regexp) {
|
||||
var threw = true;
|
||||
var error = null;
|
||||
try {
|
||||
f();
|
||||
threw = false;
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
// Make sure f threw
|
||||
assertEq(threw, true);
|
||||
// Make sure the message is as we expected
|
||||
assertEq(regexp.test(error.message), true);
|
||||
}
|
||||
|
||||
var shared = new SharedArrayBuffer(4096);
|
||||
assertThrowsMessage(() => new Int32Array(shared, 7), /start offset of Int32Array should be a multiple of 4/);
|
||||
|
||||
var shared = new SharedArrayBuffer(4096);
|
||||
assertThrowsMessage(() => new Float64Array(shared, 3), /start offset of Float64Array should be a multiple of 8/);
|
||||
|
||||
var shared = new SharedArrayBuffer(1025);
|
||||
assertThrowsMessage(() => new Float32Array(shared, 8), /buffer length for Float32Array should be a multiple of 4/);
|
||||
|
||||
var shared = new SharedArrayBuffer(513);
|
||||
assertThrowsMessage(() => new Int16Array(shared, 8), /buffer length for Int16Array should be a multiple of 2/);
|
||||
|
||||
var shared = new SharedArrayBuffer(32);
|
||||
assertThrowsMessage(() => new Int16Array(shared, 36), /size of buffer is too small for Int16Array with byteOffset/);
|
||||
|
||||
var shared = new SharedArrayBuffer(2048);
|
||||
assertThrowsMessage(() => new BigInt64Array(shared, 4096), /size of buffer is too small for BigInt64Array with byteOffset/);
|
||||
|
||||
var shared = new SharedArrayBuffer(4096);
|
||||
assertThrowsMessage(() => new Int32Array(shared, 4096, 4), /attempting to construct out-of-bounds Int32Array on ArrayBuffer/);
|
||||
|
||||
var shared = new SharedArrayBuffer(1024);
|
||||
assertThrowsMessage(() => new Float32Array(shared, 800, 300), /attempting to construct out-of-bounds Float32Array on ArrayBuffer/);
|
@ -641,7 +641,9 @@ class TypedArrayObjectTemplate : public TypedArrayObject {
|
||||
// Step 7.
|
||||
if (*byteOffset % BYTES_PER_ELEMENT != 0) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS);
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_OFFSET_BOUNDS,
|
||||
Scalar::name(ArrayTypeID()),
|
||||
Scalar::byteSizeString(ArrayTypeID()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -681,12 +683,22 @@ class TypedArrayObjectTemplate : public TypedArrayObject {
|
||||
size_t len;
|
||||
if (lengthIndex == UINT64_MAX) {
|
||||
// Steps 11.a, 11.c.
|
||||
if (bufferByteLength % BYTES_PER_ELEMENT != 0 ||
|
||||
byteOffset > bufferByteLength) {
|
||||
if (bufferByteLength % BYTES_PER_ELEMENT != 0) {
|
||||
// The given byte array doesn't map exactly to
|
||||
// |BYTES_PER_ELEMENT * N| or |byteOffset| is invalid.
|
||||
// |BYTES_PER_ELEMENT * N|
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS);
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_OFFSET_MISALIGNED,
|
||||
Scalar::name(ArrayTypeID()),
|
||||
Scalar::byteSizeString(ArrayTypeID()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (byteOffset > bufferByteLength) {
|
||||
// |byteOffset| is invalid.
|
||||
JS_ReportErrorNumberASCII(
|
||||
cx, GetErrorMessage, nullptr,
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_OFFSET_LENGTH_BOUNDS,
|
||||
Scalar::name(ArrayTypeID()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -700,8 +712,10 @@ class TypedArrayObjectTemplate : public TypedArrayObject {
|
||||
// Step 12.b.
|
||||
if (byteOffset + newByteLength > bufferByteLength) {
|
||||
// |byteOffset + newByteLength| is too big for the arraybuffer
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS);
|
||||
JS_ReportErrorNumberASCII(
|
||||
cx, GetErrorMessage, nullptr,
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_ARRAY_LENGTH_BOUNDS,
|
||||
Scalar::name(ArrayTypeID()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -710,7 +724,8 @@ class TypedArrayObjectTemplate : public TypedArrayObject {
|
||||
|
||||
if (len > maxByteLength() / BYTES_PER_ELEMENT) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS);
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_TOO_LARGE,
|
||||
Scalar::name(ArrayTypeID()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -811,7 +826,9 @@ class TypedArrayObjectTemplate : public TypedArrayObject {
|
||||
size_t byteOffset, int64_t lengthInt) {
|
||||
if (byteOffset % BYTES_PER_ELEMENT != 0) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_BOUNDS);
|
||||
JSMSG_TYPED_ARRAY_CONSTRUCT_OFFSET_BOUNDS,
|
||||
Scalar::name(ArrayTypeID()),
|
||||
Scalar::byteSizeString(ArrayTypeID()));
|
||||
return nullptr; // invalid byteOffset
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user