// Copyright 2021 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Flags: --harmony-rab-gsab --allow-natives-syntax "use strict"; d8.file.execute('test/mjsunit/typedarray-helpers.js'); (function ConstructorThrowsIfBufferDetached() { const rab = CreateResizableArrayBuffer(40, 80); %ArrayBufferDetach(rab); assertThrows(() => { new DataView(rab); }, TypeError); })(); (function TypedArrayLengthAndByteLength() { const rab = CreateResizableArrayBuffer(40, 80); let dvs = []; dvs.push(new DataView(rab, 0, 3)); dvs.push(new DataView(rab, 8, 3)); dvs.push(new DataView(rab)); dvs.push(new DataView(rab, 8)); %ArrayBufferDetach(rab); for (let dv of dvs) { assertThrows(() => { dv.byteLength }); } })(); (function AccessDetachedDataView() { const rab = CreateResizableArrayBuffer(64, 128); const fixedLength = new DataView(rab, 0, 32); const fixedLengthWithOffset = new DataView(rab, 2, 32); const lengthTracking = new DataView(rab, 0); const lengthTrackingWithOffset = new DataView(rab, 2); testDataViewMethodsUpToSize(fixedLength, 32); assertAllDataViewMethodsThrow(fixedLength, 33, RangeError); testDataViewMethodsUpToSize(fixedLengthWithOffset, 32); assertAllDataViewMethodsThrow(fixedLengthWithOffset, 33, RangeError); testDataViewMethodsUpToSize(lengthTracking, 64); assertAllDataViewMethodsThrow(lengthTracking, 65, RangeError); testDataViewMethodsUpToSize(lengthTrackingWithOffset, 64 - 2); assertAllDataViewMethodsThrow(lengthTrackingWithOffset, 64 - 2 + 1, RangeError); %ArrayBufferDetach(rab); assertAllDataViewMethodsThrow(fixedLength, 0, TypeError); assertAllDataViewMethodsThrow(fixedLengthWithOffset, 0, TypeError); assertAllDataViewMethodsThrow(lengthTracking, 0, TypeError); assertAllDataViewMethodsThrow(lengthTrackingWithOffset, 0, TypeError); })(); (function GetParameterConversionDetaches() { { const rab = CreateResizableArrayBuffer(640, 1280); const fixedLength = new DataView(rab, 0, 64); const evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { fixedLength.getUint8(evil); }, TypeError); } { const rab = CreateResizableArrayBuffer(640, 1280); const fixedLengthWithOffset = new DataView(rab, 2, 64); const evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { fixedLengthWithOffset.getUint8(evil); }, TypeError); } { const rab = CreateResizableArrayBuffer(640, 1280); const lengthTracking = new DataView(rab); const evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { lengthTracking.getUint8(evil); }, TypeError); } { const rab = CreateResizableArrayBuffer(640, 1280); const lengthTrackingWithOffset = new DataView(rab, 2); let evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { lengthTrackingWithOffset.getUint8(evil); }, TypeError); } })(); (function SetParameterConversionDetaches() { { const rab = CreateResizableArrayBuffer(640, 1280); const fixedLength = new DataView(rab, 0, 64); const evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { fixedLength.setUint8(evil, 0); }, TypeError); } { const rab = CreateResizableArrayBuffer(640, 1280); const fixedLengthWithOffset = new DataView(rab, 2, 64); const evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { fixedLengthWithOffset.setUint8(evil, 0); }, TypeError); } { const rab = CreateResizableArrayBuffer(640, 1280); const lengthTracking = new DataView(rab); const evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { lengthTracking.setUint8(evil, 0); }, TypeError); } { const rab = CreateResizableArrayBuffer(640, 1280); const lengthTrackingWithOffset = new DataView(rab, 2); let evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { lengthTrackingWithOffset.setUint8(evil, 0); }, TypeError); } // The same tests as before, except now the "detaching" parameter is the // second one, not the first one. { const rab = CreateResizableArrayBuffer(640, 1280); const fixedLength = new DataView(rab, 0, 64); const evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { fixedLength.setUint8(0, evil); }, TypeError); } { const rab = CreateResizableArrayBuffer(640, 1280); const fixedLengthWithOffset = new DataView(rab, 2, 64); const evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { fixedLengthWithOffset.setUint8(0, evil); }, TypeError); } { const rab = CreateResizableArrayBuffer(640, 1280); const lengthTracking = new DataView(rab); const evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { lengthTracking.setUint8(0, evil); }, TypeError); } { const rab = CreateResizableArrayBuffer(640, 1280); const lengthTrackingWithOffset = new DataView(rab, 2); let evil = { valueOf: () => { %ArrayBufferDetach(rab); return 0; }}; assertThrows(() => { lengthTrackingWithOffset.setUint8(0, evil); }, TypeError); } })();