Skip to content

Commit

Permalink
Fix an IE bug where the layout engine internally calls the userland `…
Browse files Browse the repository at this point in the history
…Object.getOwnPropertyNames`.

This is nasty, but since this only occurs when:
a) an iframe is created, in which case, it will be a fresh `window`, so the `cachedWindowNames` should be the same list
b) a user manually grabs the `window` object from a different realm (ie, cross-frame iframe), and passes it into `Object.getOwnPropertyNames`. I'm not sure if this is even possible, but since trying to *do* anything with the property names on the foreign `window` object will throw a security error, I'm OK with not throwing one here.

Fixes #333
  • Loading branch information
ljharb committed Jun 1, 2015
1 parent ec75cec commit cee098d
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
12 changes: 11 additions & 1 deletion es6-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -1143,9 +1143,19 @@
if (Object.getOwnPropertyNames) {
var objectGOPNAcceptsPrimitives = !throwsError(function () { Object.getOwnPropertyNames('foo'); });
if (!objectGOPNAcceptsPrimitives) {
var cachedWindowNames = typeof window === 'object' ? Object.getOwnPropertyNames(window) : [];
var originalObjectGetOwnPropertyNames = Object.getOwnPropertyNames;
overrideNative(Object, 'getOwnPropertyNames', function getOwnPropertyNames(value) {
return originalObjectGetOwnPropertyNames(ES.ToObject(value));
var val = ES.ToObject(value);
if (_toString(val) === '[object Window]') {
try {
return originalObjectGetOwnPropertyNames(val);
} catch (e) {
// IE bug where layout engine calls userland gOPN for cross-domain `window` objects
return _concat([], cachedWindowNames);
}
}
return originalObjectGetOwnPropertyNames(val);
});
}
}
Expand Down
12 changes: 12 additions & 0 deletions test/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe('Object', function () {

var hasSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol';
var ifSymbolsIt = hasSymbols ? it : xit;
var ifBrowserIt = typeof window === 'object' && typeof document === 'object' ? it : xit;

if (Object.getOwnPropertyNames) {
describe('.getOwnPropertyNames()', function () {
Expand All @@ -26,6 +27,17 @@ describe('Object', function () {
expect(Object.getOwnPropertyNames(item)).to.eql(Object.getOwnPropertyNames(Object(item)));
});
});

ifBrowserIt('does not break when an iframe is added', function () {
/*global window, document */
var div = document.createElement('div');
div.innerHTML = '<iframe src="http://xkcd.com"></iframe>';
document.body.appendChild(div);
setTimeout(function () {
document.body.removeChild(div);
}, 0);
expect(Array.isArray(Object.getOwnPropertyNames(window))).to.eql(true);
});
});
}

Expand Down

0 comments on commit cee098d

Please sign in to comment.