mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
Validate typed array set and constructors on resizable buffers
This commit is contained in:
parent
6c6023cac9
commit
d8e52b4fce
5 changed files with 77 additions and 11 deletions
|
|
@ -1047,12 +1047,18 @@ function TypedArraySet(overloaded, offset = 0) {
|
||||||
// Steps 9-10.
|
// Steps 9-10.
|
||||||
var targetBuffer = GetAttachedArrayBuffer(target);
|
var targetBuffer = GetAttachedArrayBuffer(target);
|
||||||
|
|
||||||
|
ThrowIfTypedArrayOutOfBounds(target);
|
||||||
|
|
||||||
// Step 11.
|
// Step 11.
|
||||||
var targetLength = TypedArrayLength(target);
|
var targetLength = TypedArrayLength(target);
|
||||||
|
|
||||||
// Steps 12 et seq.
|
// Steps 12 et seq.
|
||||||
if (IsPossiblyWrappedTypedArray(overloaded))
|
if (IsPossiblyWrappedTypedArray(overloaded)) {
|
||||||
|
if (PossiblyWrappedTypedArrayHasDetachedBuffer(overloaded))
|
||||||
|
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
|
ThrowIfPossiblyWrappedTypedArrayOutOfBounds(overloaded);
|
||||||
return SetFromTypedArray(target, overloaded, targetOffset, targetLength);
|
return SetFromTypedArray(target, overloaded, targetOffset, targetLength);
|
||||||
|
}
|
||||||
|
|
||||||
return SetFromNonTypedArray(target, overloaded, targetOffset, targetLength, targetBuffer);
|
return SetFromNonTypedArray(target, overloaded, targetOffset, targetLength, targetBuffer);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,15 @@ methodRab.resize(2);
|
||||||
methodRab.resize(4);
|
methodRab.resize(4);
|
||||||
assertEq(methodFixed.length, 2);
|
assertEq(methodFixed.length, 2);
|
||||||
|
|
||||||
|
var sourceRab = new ArrayBuffer(4, { maxByteLength: 8 });
|
||||||
|
var oobSource = new Uint8Array(sourceRab, 2, 2);
|
||||||
|
sourceRab.resize(2);
|
||||||
|
assertThrowsInstanceOf(() => new Uint8Array(oobSource), TypeError);
|
||||||
|
assertThrowsInstanceOf(() => new Uint16Array(oobSource), TypeError);
|
||||||
|
assertThrowsInstanceOf(() => new Uint8Array(4).set(oobSource), TypeError);
|
||||||
|
sourceRab.resize(4);
|
||||||
|
assertEq(new Uint8Array(oobSource).length, 2);
|
||||||
|
|
||||||
var ctorRab = new ArrayBuffer(8, { maxByteLength: 8 });
|
var ctorRab = new ArrayBuffer(8, { maxByteLength: 8 });
|
||||||
var ShrinkingNewTarget = new Proxy(function() {}, {
|
var ShrinkingNewTarget = new Proxy(function() {}, {
|
||||||
get(target, prop, receiver) {
|
get(target, prop, receiver) {
|
||||||
|
|
|
||||||
|
|
@ -1462,6 +1462,10 @@ intrinsic_SetFromTypedArrayApproach(JSContext* cx, unsigned argc, Value* vp)
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (unsafeTypedArrayCrossCompartment->isOutOfBounds()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_OUT_OF_BOUNDS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Steps 21, 23.
|
// Steps 21, 23.
|
||||||
uint32_t unsafeSrcLengthCrossCompartment = unsafeTypedArrayCrossCompartment->length();
|
uint32_t unsafeSrcLengthCrossCompartment = unsafeTypedArrayCrossCompartment->length();
|
||||||
|
|
|
||||||
|
|
@ -1065,16 +1065,40 @@ class TypedArrayMethods
|
||||||
if (!ToInt32(cx, args[1], &offset))
|
if (!ToInt32(cx, args[1], &offset))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (offset < 0 || uint32_t(offset) > target->length()) {
|
if (offset < 0) {
|
||||||
// the given offset is bogus
|
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target->hasDetachedBuffer()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (target->isOutOfBounds()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_OUT_OF_BOUNDS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t targetLength = target->length();
|
||||||
|
if (uint32_t(offset) > targetLength) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
RootedObject arg0(cx, &args[0].toObject());
|
RootedObject arg0(cx, &args[0].toObject());
|
||||||
if (arg0->is<TypedArrayObject>()) {
|
if (arg0->is<TypedArrayObject>()) {
|
||||||
if (arg0->as<TypedArrayObject>().length() > target->length() - offset) {
|
Rooted<TypedArrayObject*> source(cx, &arg0->as<TypedArrayObject>());
|
||||||
|
if (source->hasDetachedBuffer()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (source->isOutOfBounds()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_OUT_OF_BOUNDS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source->length() > targetLength - offset) {
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH);
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1086,7 +1110,7 @@ class TypedArrayMethods
|
||||||
if (!GetLengthProperty(cx, arg0, &len))
|
if (!GetLengthProperty(cx, arg0, &len))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (uint32_t(offset) > target->length() || len > target->length() - offset) {
|
if (len > targetLength - offset) {
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH);
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1105,7 +1129,26 @@ class TypedArrayMethods
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(source->is<TypedArrayObject>(), "use setFromNonTypedArray");
|
MOZ_ASSERT(source->is<TypedArrayObject>(), "use setFromNonTypedArray");
|
||||||
|
|
||||||
bool isShared = target->isSharedMemory() || source->as<TypedArrayObject>().isSharedMemory();
|
if (target->hasDetachedBuffer()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (target->isOutOfBounds()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_OUT_OF_BOUNDS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rooted<TypedArrayObject*> sourceArray(cx, &source->as<TypedArrayObject>());
|
||||||
|
if (sourceArray->hasDetachedBuffer()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (sourceArray->isOutOfBounds()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_OUT_OF_BOUNDS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isShared = target->isSharedMemory() || sourceArray->isSharedMemory();
|
||||||
|
|
||||||
switch (target->type()) {
|
switch (target->type()) {
|
||||||
case Scalar::Int8:
|
case Scalar::Int8:
|
||||||
|
|
|
||||||
|
|
@ -1337,6 +1337,10 @@ TypedArrayObjectTemplate<T>::fromTypedArray(JSContext* cx, HandleObject other, b
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
if (srcArray->isOutOfBounds()) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_OUT_OF_BOUNDS);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Step 9.
|
// Step 9.
|
||||||
uint32_t elementLength = srcArray->length();
|
uint32_t elementLength = srcArray->length();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue