Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: inject.preload.js

Issue 29586710: Issue 5382 - Wrap DOM mutation APIs to protect frames (Closed) Base URL: https://hg.adblockplus.org/adblockpluschrome/
Patch Set: Bind function to Function.prototype.apply and handle missing descriptors Created Feb. 21, 2018, 4:31 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: inject.preload.js
===================================================================
--- a/inject.preload.js
+++ b/inject.preload.js
@@ -67,53 +67,67 @@
"(" + injectedToString() + ")('" + eventName + "', true);"
);
delete contentWindow[eventName];
}
catch (e) {}
}
}
- for (let element of [HTMLFrameElement, HTMLIFrameElement, HTMLObjectElement])
+ function injectIntoAllFrames()
+ {
+ for (let i = 0; i < window.length; i++)
+ injectIntoContentWindow(window[i]);
+ }
+
+ function wrapAPIForInjection(object, api, callback)
{
- let contentDocumentDesc = Object.getOwnPropertyDescriptor(
- element.prototype, "contentDocument"
- );
- let contentWindowDesc = Object.getOwnPropertyDescriptor(
- element.prototype, "contentWindow"
- );
-
- // Apparently in HTMLObjectElement.prototype.contentWindow does not exist
- // in older versions of Chrome such as 42.
- if (!contentWindowDesc)
- continue;
+ let func = object[api];
+ if (!func || typeof func != "function")
+ return;
+ let applyFunc = Function.prototype.apply.bind(func);
+ Object.defineProperty(object, api, {
+ value(...args)
+ {
+ let returnValue = applyFunc(this, args);
+ callback(returnValue);
+ return returnValue;
+ }
+ });
+ }
- let getContentDocument = Function.prototype.call.bind(
- contentDocumentDesc.get
- );
- let getContentWindow = Function.prototype.call.bind(
- contentWindowDesc.get
- );
+ function wrapPropertyAPIForInjection(object, api, method, callback)
+ {
+ let descriptor = Object.getOwnPropertyDescriptor(object, api);
+ // Apparently HTMLObjectElement.prototype.contentWindow does not exist in
+ // older versions of Chrome such as 42.
+ if (!descriptor)
+ return;
+ wrapAPIForInjection(descriptor, method, callback);
+ Object.defineProperty(object, api, descriptor);
+ }
- contentWindowDesc.get = function()
+ wrapAPIForInjection(Node.prototype, "appendChild", injectIntoAllFrames);
+ wrapAPIForInjection(Node.prototype, "insertBefore", injectIntoAllFrames);
+ wrapAPIForInjection(Node.prototype, "replaceChild", injectIntoAllFrames);
+
+ wrapPropertyAPIForInjection(Element.prototype,
+ "innerHTML", "set", injectIntoAllFrames);
+
+ wrapPropertyAPIForInjection(HTMLObjectElement.prototype,
+ "contentWindow", "get", injectIntoContentWindow);
+ wrapPropertyAPIForInjection(
+ HTMLObjectElement.prototype,
+ "contentDocument", "get",
+ contentDocument =>
{
- let contentWindow = getContentWindow(this);
- injectIntoContentWindow(contentWindow);
- return contentWindow;
- };
- contentDocumentDesc.get = function()
- {
- injectIntoContentWindow(getContentWindow(this));
- return getContentDocument(this);
- };
- Object.defineProperty(element.prototype, "contentWindow",
- contentWindowDesc);
- Object.defineProperty(element.prototype, "contentDocument",
- contentDocumentDesc);
- }
+ if (contentDocument)
+ injectIntoContentWindow(contentDocument.defaultView);
+ }
+ );
/*
* Shadow root getter wrapper
*
* After creating our shadowRoot we must wrap the getter to prevent the
* website from accessing it (#4191, #4298). This is required as a
* workaround for the lack of user style support in Chrome.
* See https://bugs.chromium.org/p/chromium/issues/detail?id=632009&desc=2
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld