-
Notifications
You must be signed in to change notification settings - Fork 32
Web incompatibility discovered in theathletic.com #286
Description
Chrome discovered a web incompatibility and is unshipping the iterator helpers proposal for now.
cc the other browser folks @dminor @msaboff
The incompat is reproduced below from the issue for ease of reading. Please see https://bugs.chromium.org/p/chromium/issues/detail?id=1474613 for full details.
- theathletic.com uses a product called airgap.js. This product has a "tamper proof" mode that tries to freeze built-in collections' iterators and iterator prototypes. It has the following snippet:
let e = (s = (r = R) == null ? void 0 : r.Iterator) == null ? void 0 : s.prototype;
e && Dt(e);where R is the global scope, and Dt is a utility function that ultimately called Object.freeze on the argument. The effect of this snippet is that if there's a global called Iterator, Iterator.prototype becomes frozen.
- theathletic.com, like many sites, ships an old version (< 0.13.8) of the regenerator runtime to polyfill generators. The runtime makes its own version of the Generator function, including setting up the prototype chain.
Generator.prototype's [[Prototype]] isIterator.prototype. Prior to regenerator 0.13.8, setting up the generator code looked like the following:
var Gp = GeneratorFunctionPrototype.prototype =
Generator.prototype = Object.create(IteratorPrototype);
GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
GeneratorFunctionPrototype.constructor = GeneratorFunction;The assignment Gp.constructor = GeneratorFunctionPrototype triggers what's commonly called the "override mistake" in JS, where a non-writable property that exists on some object's [[Prototype]] prevents a new data property from being created on that object. In this case, because airgap.js froze Iterator.prototype, Iterator.prototype.constructor is non-writable, causing this assignment to throw.
Regenerator runtime fixed this bug upstream 2 years ago in facebook/regenerator#411