Skip to content

Commit

Permalink
add fixes of some different %TypedArray%,prototype.set bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Dec 28, 2021
1 parent b40784e commit 7b9e113
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Changelog
##### Unreleased
- Added a fix of [a V8 ~ Chrome 36- `Object.defineProperty` bug](https://bugs.chromium.org/p/v8/issues/detail?id=3334), [Babel issue](https://github.com/babel/babel/issues/14056)
- Added fixes of some different `%TypedArray%,prototype.set` bugs, affects modern engines (like Chrome < 95 or Safari < 14.1)

##### 3.20.1 - 2021.12.23
- Fixed the order of calling reactions of already fulfilled / rejected promises in `Promise.prototype.then`, [#1026](https://github.com/zloirock/core-js/issues/1026)
Expand Down
8 changes: 4 additions & 4 deletions packages/core-js-compat/src/data.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1390,10 +1390,10 @@ export const data = {
safari: '10.0',
},
'es.typed-array.set': {
chrome: '26',
edge: '13',
firefox: '15',
safari: '7.1',
chrome: '95', // '26',
// edge: '13', // proper in Chakra Edge 13, but buggy in Chromium < 95
firefox: '54', // '15',
safari: '14.1', // '7.1',
},
'es.typed-array.slice': {
chrome: '45',
Expand Down
7 changes: 6 additions & 1 deletion packages/core-js/internals/array-buffer-view-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ var exportTypedArrayMethod = function (KEY, property, forced, options) {
var TypedArrayConstructor = global[ARRAY];
if (TypedArrayConstructor && hasOwn(TypedArrayConstructor.prototype, KEY)) try {
delete TypedArrayConstructor.prototype[KEY];
} catch (error) { /* empty */ }
} catch (error) {
// old WebKit bug - some methods are non-configurable
try {
TypedArrayConstructor.prototype[KEY] = property;
} catch (error2) { /* empty */ }
}
}
if (!TypedArrayPrototype[KEY] || forced) {
redefine(TypedArrayPrototype, KEY, forced ? property
Expand Down
25 changes: 20 additions & 5 deletions packages/core-js/modules/es.typed-array.set.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,44 @@
'use strict';
var global = require('../internals/global');
var call = require('../internals/function-call');
var ArrayBufferViewCore = require('../internals/array-buffer-view-core');
var lengthOfArrayLike = require('../internals/length-of-array-like');
var toOffset = require('../internals/to-offset');
var toObject = require('../internals/to-object');
var toIndexedObject = require('../internals/to-object');
var fails = require('../internals/fails');

var RangeError = global.RangeError;
var Int8Array = global.Int8Array;
var Int8ArrayPrototype = Int8Array && Int8Array.prototype;
var $set = Int8ArrayPrototype && Int8ArrayPrototype.set;
var aTypedArray = ArrayBufferViewCore.aTypedArray;
var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;

var FORCED = fails(function () {
var WORKS_WITH_OBJECTS_AND_GEERIC_ON_TYPED_ARRAYS = !fails(function () {
// eslint-disable-next-line es/no-typed-arrays -- required for testing
new Int8Array(1).set({});
var array = new Uint8ClampedArray(2);
call($set, array, { length: 1, 0: 3 }, 1);
return array[1] !== 3;
});

// https://bugs.chromium.org/p/v8/issues/detail?id=11294 and other
var TO_OBJECT_BUG = WORKS_WITH_OBJECTS_AND_GEERIC_ON_TYPED_ARRAYS && ArrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS && fails(function () {
var array = new Int8Array(2);
array.set(1);
array.set('2', 1);
return array[0] !== 0 || array[1] !== 2;
});

// `%TypedArray%.prototype.set` method
// https://tc39.es/ecma262/#sec-%typedarray%.prototype.set
exportTypedArrayMethod('set', function set(arrayLike /* , offset */) {
aTypedArray(this);
var offset = toOffset(arguments.length > 1 ? arguments[1] : undefined, 1);
var src = toIndexedObject(arrayLike);
if (WORKS_WITH_OBJECTS_AND_GEERIC_ON_TYPED_ARRAYS) return call($set, this, src, offset);
var length = this.length;
var src = toObject(arrayLike);
var len = lengthOfArrayLike(src);
var index = 0;
if (len + offset > length) throw RangeError('Wrong length');
while (index < len) this[offset + index] = src[index++];
}, FORCED);
}, !WORKS_WITH_OBJECTS_AND_GEERIC_ON_TYPED_ARRAYS || TO_OBJECT_BUG);
7 changes: 5 additions & 2 deletions tests/compat/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1169,8 +1169,11 @@ GLOBAL.tests = {
return Int8Array.prototype.reverse;
}],
'es.typed-array.set': [ARRAY_BUFFER_VIEWS_SUPPORT, function () {
new Int8Array(1).set({});
return true;
var array = new Uint8ClampedArray(3);
array.set(1);
array.set('2', 1);
Int8Array.prototype.set.call(array, { length: 1, 0: 3 }, 2);
return array[0] === 0 && array[1] === 2 && array[2] === 3;
}],
'es.typed-array.slice': [ARRAY_BUFFER_VIEWS_SUPPORT, function () {
return new Int8Array(1).slice();
Expand Down
8 changes: 6 additions & 2 deletions tests/tests/es.typed-array.set.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.set', assert => {
assert.throws(() => array2.set(new TypedArray([99, 98, 97, 96]), 2));
assert.throws(() => array2.set([101, 102, 103, 104], 4));
const array3 = new TypedArray(2);
array3.set({ length: 2, 0: 1, 1: 2 });
assert.arrayEqual(array3, [1, 2]);
assert.notThrows(() => array3.set({ length: 2, 0: 1, 1: 2 }), 'set array-like #1');
assert.arrayEqual(array3, [1, 2], 'set array-like #2');
assert.notThrows(() => array3.set('34'), 'set string #1');
assert.arrayEqual(array3, [3, 4], 'set string #2');
assert.notThrows(() => array3.set(1), 'set number #1');
assert.arrayEqual(array3, [3, 4], 'set number #2');
assert.throws(() => set.call([1, 2, 3], [1]), "isn't generic");
}
});

0 comments on commit 7b9e113

Please sign in to comment.