refactor: clean up webFrame implementation to use gin wrappers (#28497)
* refactor: clean up webFrame implementation to use gin wrappers The previous implementation of webFrame in the renderer process leaked sub-frame contexts and global objects across the context boundaries thus making it possible for apps to either maliciously or accidentally violate the contextIsolation boundary. This re-implementation binds all methods in native code directly to content::RenderFrame instances instead of relying on JS to provide a "window" with every method request. This is much more consistent with the rest of the Electron codebase and is substantially safer. * chore: un-re-order for ease of review * chore: pass isolate around instead of ErrorThrower * chore: fix rebase typo * chore: remove unused variables
This commit is contained in:
parent
e775467e9c
commit
6df2680cb6
8 changed files with 604 additions and 632 deletions
|
@ -1,69 +1,3 @@
|
|||
import { EventEmitter } from 'events';
|
||||
const { mainFrame } = process._linkedBinding('electron_renderer_web_frame');
|
||||
|
||||
const binding = process._linkedBinding('electron_renderer_web_frame');
|
||||
|
||||
class WebFrame extends EventEmitter {
|
||||
constructor (public context: Window) {
|
||||
super();
|
||||
|
||||
// Lots of webview would subscribe to webFrame's events.
|
||||
this.setMaxListeners(0);
|
||||
}
|
||||
|
||||
findFrameByRoutingId (routingId: number) {
|
||||
return getWebFrame(binding._findFrameByRoutingId(this.context, routingId));
|
||||
}
|
||||
|
||||
getFrameForSelector (selector: string) {
|
||||
return getWebFrame(binding._getFrameForSelector(this.context, selector));
|
||||
}
|
||||
|
||||
findFrameByName (name: string) {
|
||||
return getWebFrame(binding._findFrameByName(this.context, name));
|
||||
}
|
||||
|
||||
get opener () {
|
||||
return getWebFrame(binding._getOpener(this.context));
|
||||
}
|
||||
|
||||
get parent () {
|
||||
return getWebFrame(binding._getParent(this.context));
|
||||
}
|
||||
|
||||
get top () {
|
||||
return getWebFrame(binding._getTop(this.context));
|
||||
}
|
||||
|
||||
get firstChild () {
|
||||
return getWebFrame(binding._getFirstChild(this.context));
|
||||
}
|
||||
|
||||
get nextSibling () {
|
||||
return getWebFrame(binding._getNextSibling(this.context));
|
||||
}
|
||||
|
||||
get routingId () {
|
||||
return binding._getRoutingId(this.context);
|
||||
}
|
||||
}
|
||||
|
||||
// Populate the methods.
|
||||
for (const name in binding) {
|
||||
if (!name.startsWith('_')) { // some methods are manually populated above
|
||||
// TODO(felixrieseberg): Once we can type web_frame natives, we could
|
||||
// use a neat `keyof` here
|
||||
(WebFrame as any).prototype[name] = function (...args: Array<any>) {
|
||||
return (binding as any)[name](this.context, ...args);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to return WebFrame or null depending on context.
|
||||
// TODO(zcbenz): Consider returning same WebFrame for the same frame.
|
||||
function getWebFrame (context: Window) {
|
||||
return context ? new WebFrame(context) : null;
|
||||
}
|
||||
|
||||
const _webFrame = new WebFrame(window);
|
||||
|
||||
export default _webFrame;
|
||||
export default mainFrame;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue