mathiasbynens / Array.from

A robust & optimized ES3-compatible polyfill for the `Array.from` method in ECMAScript 6.

Home Page:https://mths.be/array-from

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Compliance issues

anba opened this issue · comments

Array.from({__proto__: {0: "abc", length: 1}})[0] === "abc";
  • This line actually needs to use Object.defineProperty() to avoid executing setters. Test case:
Object.defineProperty(Array.prototype, "0", {
    set: function(x) { throw "set:" + x }
});
Array.from({length: 1, 0: "abc"}); // should not throw
Array.from.call(function(){ return Object.freeze({}); }, {}); // should throw

Awesome bug reports, as usual! Thanks so much. I’ll fix these, except for the isConstructor thing, as these polyfills are meant to be usable in ES3/ES5 environments (like you said).

except for the isConstructor thing, as these polyfills are meant to be usable in ES3/ES5 environments

Yeah, that's why I've added the sad smiley face. It's a shame that there is no built-in way to test for constructors in pre-ES6 environments.

Could you give an example of how to use Object.defineProperty(obj, x, { … }) to avoid executing the getter for x?

// in Node / V8
Object.defineProperty(Array.prototype, '0', { 'set': function(x) { throw 'set:' + x; } });
var x = [];
Object.defineProperty(x, '0', { 'value': 42 }); // throws :(

Huh? The code you've given should never throw (*), well unless there is a bug in the JavaScript implementation. 😕

The spec text CreateDataPropertyOrThrow(A, Pk, mappedValue) directly translates to:

Object.defineProperty(A, Pk, {
  value: mappedValue, writable: true, enumerable: true, configurable: true
});

(*) There is actually one possibility for this to throw a TypeError exception. When there is either a "get" or "set" property on Object.prototype, the property descriptor object {'value': 42} will be considered both a value and a accessor property descriptor. Both that's somewhat unlikely here.

Thanks for taking a look. I’ve filed this as a V8 bug: https://code.google.com/p/v8/issues/detail?id=3068.

Closing as all ‘fixable’ bugs should now be fixed. Let me know if you spot anything sloppy in the patches. Thanks again!

@ljharb reverted 1b022c8 in 51f4749 because the tests were invalid as per the latest spec. @anba Can you confirm/deny?

Re-opening pending @anba’s feedback.

The original bug report had no accompanying spec references, so I'm not actually sure if we even need the Object.freeze check.

22.1.2.1 Array.from, step 17.f uses 7.3.4 CreateDataPropertyOrThrow which in turn calls 7.3.3 CreateDataProperty. And CreateDataProperty invokes [[DefineOwnProperty]] to create the property. That means no setters get called.

Interesting - %TypedArray%.from uses [[Put]] but all other mentions of that internal method have been removed. I'll restore the defineProperty checks here, and add them to the MDN polyfill and es6 shim later today, thanks.