Skip to content

Commit

Permalink
[Fix] ES2017+: IsDetachedBuffer: properly allow SABs
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Feb 4, 2024
1 parent ff8f851 commit 3f96c40
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 47 deletions.
1 change: 0 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@
/2017/IsConcatSpreadable.js spackled linguist-generated=true
/2017/IsConstructor.js spackled linguist-generated=true
/2017/IsDataDescriptor.js spackled linguist-generated=true
/2017/IsDetachedBuffer.js spackled linguist-generated=true
/2017/IsExtensible.js spackled linguist-generated=true
/2017/IsGenericDescriptor.js spackled linguist-generated=true
/2017/IsInteger.js spackled linguist-generated=true
Expand Down
13 changes: 8 additions & 5 deletions 2017/IsDetachedBuffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@ var GetIntrinsic = require('get-intrinsic');
var $TypeError = GetIntrinsic('%TypeError%');

var $byteLength = require('array-buffer-byte-length');

var availableTypedArrays = require('available-typed-arrays')();
var callBound = require('call-bind/callBound');
var isArrayBuffer = require('is-array-buffer');
var isSharedArrayBuffer = require('is-shared-array-buffer');

var availableTypedArrays = require('available-typed-arrays')();
var $sabByteLength = callBound('SharedArrayBuffer.prototype.byteLength', true);

// https://262.ecma-international.org/6.0/#sec-isdetachedbuffer
// https://262.ecma-international.org/8.0/#sec-isdetachedbuffer

module.exports = function IsDetachedBuffer(arrayBuffer) {
if (!isArrayBuffer(arrayBuffer)) {
var isSAB = isSharedArrayBuffer(arrayBuffer);
if (!isArrayBuffer(arrayBuffer) && !isSAB) {
throw new $TypeError('Assertion failed: `arrayBuffer` must be an Object with an [[ArrayBufferData]] internal slot');
}
if ($byteLength(arrayBuffer) === 0) {
if ((isSAB ? $sabByteLength : $byteLength)(arrayBuffer) === 0) {
try {
new global[availableTypedArrays[0]](arrayBuffer); // eslint-disable-line no-new
} catch (error) {
Expand Down
13 changes: 8 additions & 5 deletions 2018/IsDetachedBuffer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions 2019/IsDetachedBuffer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions 2020/IsDetachedBuffer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions 2021/IsDetachedBuffer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions 2022/IsDetachedBuffer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions 2023/IsDetachedBuffer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 49 additions & 11 deletions test/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5920,6 +5920,16 @@ var es2017 = function ES2017(ES, ops, expectedMissing, skips) {
t.end();
});

test('IsDetachedBufer (Shared Array Buffers)', { skip: typeof SharedArrayBuffer !== 'function' }, function (t) {
var sab = new SharedArrayBuffer(1);
t.equal(ES.IsDetachedBuffer(sab), false, 'a new SharedArrayBuffer is not detached');

var zsab = new SharedArrayBuffer(0);
t.equal(ES.IsDetachedBuffer(zsab), false, 'a new zero-length SharedArrayBuffer is not detached');

t.end();
});

test('EnumerableOwnProperties', function (t) {
t['throws'](
function () { ES.EnumerableOwnProperties({}, 'not key, value, or key+value'); },
Expand Down Expand Up @@ -10440,9 +10450,11 @@ var es2020 = function ES2020(ES, ops, expectedMissing, skips) {
});

test('SetValueInBuffer', function (t) {
var order = 'Unordered';

forEach(v.primitives.concat(v.objects), function (nonAB) {
t['throws'](
function () { ES.SetValueInBuffer(nonAB, 0, 'Int8', 0, false, 'Unordered'); },
function () { ES.SetValueInBuffer(nonAB, 0, 'Int8', 0, false, order); },
TypeError,
debug(nonAB) + ' is not an ArrayBuffer'
);
Expand All @@ -10453,29 +10465,29 @@ var es2020 = function ES2020(ES, ops, expectedMissing, skips) {

forEach(v.notNonNegativeIntegers, function (nonNonNegativeInteger) {
st['throws'](
function () { ES.SetValueInBuffer(new ArrayBuffer(8), nonNonNegativeInteger, 'Int8', 0, isTypedArray, 'Unordered'); },
function () { ES.SetValueInBuffer(new ArrayBuffer(8), nonNonNegativeInteger, 'Int8', 0, isTypedArray, order); },
TypeError,
debug(nonNonNegativeInteger) + ' is not a valid byte index'
);
});

forEach(v.nonStrings.concat('not a valid type'), function (nonString) {
st['throws'](
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, nonString, 0, isTypedArray, 'Unordered'); },
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, nonString, 0, isTypedArray, order); },
TypeError,
'type: ' + debug(nonString) + ' is not a valid String (or type) value'
);
});

forEach(v.nonBooleans, function (nonBoolean) {
st['throws'](
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, 'Int8', 0, nonBoolean, 'Unordered'); },
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, 'Int8', 0, nonBoolean, order); },
TypeError,
'isTypedArray: ' + debug(nonBoolean) + ' is not a valid Boolean value'
);

st['throws'](
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, 'Int8', 0, isTypedArray, 'Unordered', nonBoolean); },
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, 'Int8', 0, isTypedArray, order, nonBoolean); },
TypeError,
'isLittleEndian: ' + debug(nonBoolean) + ' is not a valid Boolean value'
);
Expand All @@ -10491,13 +10503,13 @@ var es2020 = function ES2020(ES, ops, expectedMissing, skips) {

if (hasBigInts) {
st['throws'](
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, 'Int8', $BigInt(0), isTypedArray, 'Unordered'); },
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, 'Int8', $BigInt(0), isTypedArray, order); },
TypeError,
debug($BigInt(0)) + ' is not a number, but the given type requires one'
);

st['throws'](
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, 'BigUint64', 0, isTypedArray, 'Unordered'); },
function () { ES.SetValueInBuffer(new ArrayBuffer(8), 0, 'BigUint64', 0, isTypedArray, order); },
TypeError,
debug(0) + ' is not a bigint, but the given type requires one'
);
Expand All @@ -10514,14 +10526,24 @@ var es2020 = function ES2020(ES, ops, expectedMissing, skips) {
s2t.equal(ES.DetachArrayBuffer(buffer), null, 'detaching returns null');

s2t['throws'](
function () { ES.SetValueInBuffer(buffer, 0, 'Int8', 0, isTypedArray, 'Unordered'); },
function () { ES.SetValueInBuffer(buffer, 0, 'Int8', 0, isTypedArray, order); },
TypeError,
'detached buffers throw'
);

s2t.end();
});

st.test('SharedArrayBuffers supported', { skip: typeof SharedArrayBuffer !== 'function' }, function (s2t) {
s2t['throws'](
function () { ES.SetValueInBuffer(new SharedArrayBuffer(0), 0, 'Int8', 0, true, order); },
SyntaxError,
'SAB not yet supported'
);

s2t.end();
});

forEach(bufferTestCases, function (testCase, name) {
forEach([].concat(
'Int8',
Expand Down Expand Up @@ -10550,7 +10572,7 @@ var es2020 = function ES2020(ES, ops, expectedMissing, skips) {

/*
st.equal(
ES.SetValueInBuffer(testCase.buffer, 0, type, true, 'Unordered'),
ES.SetValueInBuffer(testCase.buffer, 0, type, true, order),
defaultEndianness === testCase.endian ? testCase[type].little.value] : testCase[type].big.value,
'buffer holding ' + debug(testCase.value) + ' (' + testCase.endian + ' endian) with type ' + type + ', default endian, yields expected value'
);
Expand All @@ -10562,7 +10584,7 @@ var es2020 = function ES2020(ES, ops, expectedMissing, skips) {
clearBuffer(buffer);

st.equal(
ES.SetValueInBuffer(buffer, 0, type, valToSet, isTypedArray, 'Unordered', true),
ES.SetValueInBuffer(buffer, 0, type, valToSet, isTypedArray, order, true),
void undefined,
'returns undefined'
);
Expand All @@ -10576,7 +10598,7 @@ var es2020 = function ES2020(ES, ops, expectedMissing, skips) {
clearBuffer(buffer);

st.equal(
ES.SetValueInBuffer(buffer, 0, type, valToSet, isTypedArray, 'Unordered', false),
ES.SetValueInBuffer(buffer, 0, type, valToSet, isTypedArray, order, false),
void undefined,
'returns undefined'
);
Expand Down Expand Up @@ -12732,6 +12754,22 @@ var es2022 = function ES2022(ES, ops, expectedMissing, skips) {
t.end();
});

test('SetValueInBuffer', function (t) {
var order = 'Unordered';

t.test('SharedArrayBuffers supported', { skip: typeof SharedArrayBuffer !== 'function' }, function (st) {
st['throws'](
function () { ES.SetValueInBuffer(new SharedArrayBuffer(0), 0, 'Int8', 0, true, order); },
SyntaxError,
'SAB not yet supported'
);

st.end();
});

t.end();
});

test('SortIndexedProperties', function (t) {
/* eslint no-unused-vars: 0 */

Expand Down

0 comments on commit 3f96c40

Please sign in to comment.