core-js breaks existing Uint8Array default constructor behaviour

Created on 4 Apr 2017  ยท  3Comments  ยท  Source: zloirock/core-js

I posted a bug report with tests to the babel-polyfil tracker:

https://github.com/babel/babel/issues/5565

It was closed as being an upstream issue. Not sure how its going to be fixed if upstream doesn't know about it, so I'm mirroring it here :)

Thankyou

--

In vanilla IE11, Edge, Chrome, Safari, FireFox, PhantomJS and Node the following code succeeds.

var array = new Uint8Array();

When executing the above line after importing the babel-polyfill, it throws 'TypeError: Wrong length!' in all browsers except Chrome.

The expected behavuour is that new Uint8Array() should not throw, as this is the existing behaviour in ALL user-agents tested.

This affects the usage of legacy libraries which initialise a default Uint8Array and then replace the array with larger arrays if the length of the array is smaller than required. Similar to how a vector might work in some other languages.

A code-change in the user code can be made to instead declare the array as :

var array = new Uint8Array(0);

But this is not applicable in to modules and other code bases which are imported.

The following mocha/karma test suite tests the behaviour, and reproduces the failures. If you comment the babel-polyfill line, the tests all pass.

Using [email protected] and [email protected]

import { assert } from 'chai';
import type from 'type-detect';
import 'babel-polyfill';

describe('Uint8Array', function () {
    it('constructor with no arguments does not throw', function () {
        let array;

        assert.doesNotThrow(function () {
            array = new Uint8Array();
        });
    });

    it('type of default Uint8Array is Uint8Array', function () {
        let array;

        assert.doesNotThrow(function () {
            array = new Uint8Array();
        });

        assert.strictEqual(type(array), 'Uint8Array');
    });

    it('length of default Uint8Array is 0', function () {
        let array;
        let length;

        assert.doesNotThrow(function () {
            array = new Uint8Array();
            length = array.length;
        });

        assert.strictEqual(length, 0);
    });
});

Karma test run in IE, Edge, Chrome, Safari, Firefox, PhantomJS with babel-polyfill disabled: :

   START:
   Uint8Array
       โˆš constructor with no arguments does not throw
       โˆš type of default Uint8Array is Uint8Array
       โˆš length of default Uint8Array is 0

   Finished in 0.134 secs / 0.035 secs @ 17:35:57 GMT+1100 (AUS Eastern Daylight Time)

   SUMMARY:
   โˆš 18 tests completed

node mocha test with babel-polyfill disabled:

   Uint8Array
       โˆš constructor with no arguments does not throw
       โˆš type of default Uint8Array is Uint8Array
       โˆš length of default Uint8Array is 0

   3 passing (652ms)

Karma in IE, Edge, Chrome, Safari, Firefox, PhantomJS with babel-polyfill enabled:

   START:
   Uint8Array
       ร— constructor with no arguments does not throw
       ร— type of default Uint8Array is Uint8Array
       ร— length of default Uint8Array is 0

   Finished in 0.178 secs / 0.104 secs @ 17:37:55 GMT+1100 (AUS Eastern Daylight Time)

   SUMMARY:
   โˆš 3 tests completed
   ร— 15 tests failed

   FAILED TESTS:
   Uint8Array
       ร— constructor with no arguments does not throw
       PhantomJS 2.1.1 (Windows 8 0.0.0)
       IE 11.0.0 (Windows 10 0.0.0)
       Safari 10.0.3 (Mac OS X 10.11.6)
       Edge 14.14393.0 (Windows 10 0.0.0)
       Firefox 52.0.0 (Windows 10 0.0.0)
       expected [Function] to not throw an error but 'TypeError: Wrong length!' was thrown
AssertionError@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:592:13
require<[26]</module.exports/Assertion.prototype.assert@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29
   d9dc.browserify:3633:13
assertThrows@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:5092:5
require<[33]</module.exports/ctx[name]@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:7
   619:18
require<[29]</module.exports/assert.doesNotThrow@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.br
   owserify:6727:5
require<["C:\\Users\\dev\\Documents\\GitHub\\<redacted>\tests\\node\\unit\\testUint8Array.js"]</</<@C:/Users/dev/Ap
pData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:178231:3


       ร— type of default Uint8Array is Uint8Array
       PhantomJS 2.1.1 (Windows 8 0.0.0)
       IE 11.0.0 (Windows 10 0.0.0)
       Safari 10.0.3 (Mac OS X 10.11.6)
       Edge 14.14393.0 (Windows 10 0.0.0)
       Firefox 52.0.0 (Windows 10 0.0.0)
       expected [Function] to not throw an error but 'TypeError: Wrong length!' was thrown
AssertionError@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:592:13
require<[26]</module.exports/Assertion.prototype.assert@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29
   d9dc.browserify:3633:13
assertThrows@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:5092:5
require<[33]</module.exports/ctx[name]@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:7
   619:18
require<[29]</module.exports/assert.doesNotThrow@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.br
   owserify:6727:5
require<["C:\\Users\\dev\\Documents\\GitHub\\<redacted>\\tests\\node\\unit\\testUint8Array.js"]</</<@C:/Users/dev/Ap
pData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:178241:3


       ร— length of default Uint8Array is 0
       PhantomJS 2.1.1 (Windows 8 0.0.0)
       IE 11.0.0 (Windows 10 0.0.0)
       Safari 10.0.3 (Mac OS X 10.11.6)
       Edge 14.14393.0 (Windows 10 0.0.0)
       Firefox 52.0.0 (Windows 10 0.0.0)
       expected [Function] to not throw an error but 'TypeError: Wrong length!' was thrown
AssertionError@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:592:13
require<[26]</module.exports/Assertion.prototype.assert@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29
   d9dc.browserify:3633:13
assertThrows@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:5092:5
require<[33]</module.exports/ctx[name]@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:7
   619:18
require<[29]</module.exports/assert.doesNotThrow@C:/Users/dev/AppData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.br
   owserify:6727:5
require<["C:\\Users\\dev\\Documents\\GitHub\\<redacted>\\tests\\node\\unit\\testUint8Array.js"]</</<@C:/Users/dev/Ap
pData/Local/Temp/b66d671ed5a59eaa0a0fd7eafc29d9dc.browserify:178253:3

Note: the tests above passed in Chrome only.

node mocha test with babel-polyfill enabled:

   Uint8Array
       โˆš constructor with no arguments does not throw
       โˆš type of default Uint8Array is Uint8Array
       โˆš length of default Uint8Array is 0


   3 passing (650ms)

The tests also pass in Node.

Thankyou

bug

Most helpful comment

Seems you are right.

All 3 comments

http://www.ecma-international.org/ecma-262/6.0/#table-49

22.2.1.1 %TypedArray% ( )

This description applies only if the %TypedArray% function is called with no arguments.

If NewTarget is undefined, throw a TypeError exception.
Return AllocateTypedArray(NewTarget, 0).

Seems you are right.

this is currently critical when using node 8, because importing the 'v8' modules trigger this issue

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ajbowler picture ajbowler  ยท  3Comments

yusidi picture yusidi  ยท  3Comments

fender picture fender  ยท  5Comments

Sequoia picture Sequoia  ยท  5Comments

brunops picture brunops  ยท  3Comments