diff --git a/lib/iframeProtection.js b/lib/iframeProtection.js index ae90465..6457747 100644 --- a/lib/iframeProtection.js +++ b/lib/iframeProtection.js @@ -11,43 +11,52 @@ else { scope = require.register("./iframeProtection", {}); } - const {getWrapped} = require("./modifiedAPIFunctions"); scope.protect = function protect(window, wrappedWindow, singleCallback, allCallback){ - [window.HTMLIFrameElement, window.HTMLFrameElement].forEach(function(constructor){ - var oldContentWindowGetter = constructor.prototype.__lookupGetter__("contentWindow"); - Object.defineProperty( - getWrapped(constructor.prototype), - "contentWindow", - { - enumerable: true, - configurable: true, - get: exportFunction(function(){ - var window = oldContentWindowGetter.call(this); - if (window){ - singleCallback(window); - } - return window; - }, window) - } + ["HTMLIFrameElement", "HTMLFrameElement"].forEach(function(constructorName){ + const constructor = window[constructorName]; + const wrappedConstructor = wrappedWindow[constructorName]; + + const contentWindowDescriptor = Object.getOwnPropertyDescriptor( + constructor.prototype, + "contentWindow" ); - var oldContentDocumentGetter = constructor.prototype.__lookupGetter__("contentDocument"); - Object.defineProperty( - getWrapped(constructor.prototype), - "contentDocument", - { - enumerable: true, - configurable: true, - get: exportFunction(function(){ - var document = oldContentDocumentGetter.call(this); - if (document){ - singleCallback(document.defaultView); - } - return document; - }, window) + const originalContentWindowGetter = contentWindowDescriptor.get; + const contentWindowTemp = { + get contentWindow(){ + var window = originalContentWindowGetter.call(this); + if (window){ + singleCallback(window); + } + return window; } + }; + contentWindowDescriptor.get = exportFunction( + Object.getOwnPropertyDescriptor(contentWindowTemp, "contentWindow").get, + window ); + Object.defineProperty(wrappedConstructor.prototype, "contentWindow", contentWindowDescriptor); + + const contentDocumentDescriptor = Object.getOwnPropertyDescriptor( + constructor.prototype, + "contentDocument" + ); + const originalContentDocumentGetter = contentDocumentDescriptor.get; + const contentDocumentTemp = { + get contentDocument(){ + var document = originalContentDocumentGetter.call(this); + if (document){ + singleCallback(document.defaultView); + } + return document; + } + }; + contentDocumentDescriptor.get = exportFunction( + Object.getOwnPropertyDescriptor(contentDocumentTemp, "contentDocument").get, + window + ); + Object.defineProperty(wrappedConstructor.prototype, "contentDocument", contentDocumentDescriptor); }); [ // useless as length could be obtained before the iframe is created and window.frames === window diff --git a/releaseNotes.txt b/releaseNotes.txt index 32e7a98..d561bd7 100644 --- a/releaseNotes.txt +++ b/releaseNotes.txt @@ -6,7 +6,7 @@ Version 0.5.11: - fixes: - - + - improved protection of (i)frame properties known issues: - if a data URL is blocked the page action button does not appear diff --git a/test/detectionTest.js b/test/detectionTest.js index 9a133ce..48a1df1 100644 --- a/test/detectionTest.js +++ b/test/detectionTest.js @@ -200,6 +200,10 @@ addTest("function name", function(log){ func: window.__lookupSetter__("name"), expectedName: "set name" }, + { + func: HTMLIFrameElement.prototype.__lookupGetter__("contentDocument"), + expectedName: "get contentDocument" + }, ].map(checkName).some(function(b){return b;}); }); addTest("property descriptor", function(log){