From faa1d5a12643de1e9c4f5a1b887383403fe1b722 Mon Sep 17 00:00:00 2001 From: bridiver Date: Sat, 27 Aug 2016 13:33:58 -0700 Subject: [PATCH] make sure there is only one ipc object per frame fixes https://github.com/brave/browser-laptop/issues/3487 auditors: @bbondy, @diracdeltas --- atom/common/api/resources/ipc_utils.js | 52 ++++++----- atom/common/javascript_bindings.cc | 119 ++++++++++++++++--------- 2 files changed, 105 insertions(+), 66 deletions(-) diff --git a/atom/common/api/resources/ipc_utils.js b/atom/common/api/resources/ipc_utils.js index 1d55e0185e..966a21f65f 100644 --- a/atom/common/api/resources/ipc_utils.js +++ b/atom/common/api/resources/ipc_utils.js @@ -1,32 +1,36 @@ -var atom = requireNative('atom').GetBinding(); -var EventEmitter = require('event_emitter').EventEmitter; -var ipc = atom.ipc; +var atom = requireNative('atom').GetBinding() +var EventEmitter = require('event_emitter').EventEmitter +var ipc = atom.ipc -var slice = [].slice; -var ipcRenderer = new EventEmitter; +var ipcRenderer = atom.v8.getHiddenValue('ipc') +if (!ipcRenderer) { + var slice = [].slice + ipcRenderer = new EventEmitter -ipcRenderer.send = function () { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return ipc.send('ipc-message', slice.call(args)); -}; + ipcRenderer.send = function () { + var args + args = 1 <= arguments.length ? slice.call(arguments, 0) : [] + return ipc.send('ipc-message', slice.call(args)) + } -ipcRenderer.sendSync = function () { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return JSON.parse(ipc.sendSync('ipc-message-sync', slice.call(args))); -}; + ipcRenderer.sendSync = function () { + var args + args = 1 <= arguments.length ? slice.call(arguments, 0) : [] + return JSON.parse(ipc.sendSync('ipc-message-sync', slice.call(args))) + } -ipcRenderer.sendToHost = function () { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return ipc.send('ipc-message-host', slice.call(args)); -}; + ipcRenderer.sendToHost = function () { + var args + args = 1 <= arguments.length ? slice.call(arguments, 0) : [] + return ipc.send('ipc-message-host', slice.call(args)) + } -ipcRenderer.emit = function () { - arguments[1].sender = ipcRenderer; - return EventEmitter.prototype.emit.apply(ipcRenderer, arguments); -}; + ipcRenderer.emit = function () { + arguments[1].sender = ipcRenderer + return EventEmitter.prototype.emit.apply(ipcRenderer, arguments) + } + atom.v8.setHiddenValue('ipc', ipcRenderer) +} exports.on = ipcRenderer.on.bind(ipcRenderer); exports.once = ipcRenderer.once.bind(ipcRenderer); diff --git a/atom/common/javascript_bindings.cc b/atom/common/javascript_bindings.cc index f48e7d9b7d..edf539955c 100644 --- a/atom/common/javascript_bindings.cc +++ b/atom/common/javascript_bindings.cc @@ -17,59 +17,89 @@ #include "third_party/WebKit/public/web/WebDocument.h" namespace { - content::RenderView* GetCurrentRenderView() { - blink::WebLocalFrame* frame = - blink::WebLocalFrame::frameForCurrentContext(); - if (!frame) - return NULL; - blink::WebView* view = frame->view(); - if (!view) - return NULL; // can happen during closing. +content::RenderView* GetCurrentRenderView() { + blink::WebLocalFrame* frame = + blink::WebLocalFrame::frameForCurrentContext(); + if (!frame) + return NULL; - return content::RenderView::FromWebView(view); - } + blink::WebView* view = frame->view(); + if (!view) + return NULL; // can happen during closing. - void IPCSend(mate::Arguments* args, - const base::string16& channel, - const base::ListValue& arguments) { - content::RenderView* render_view = GetCurrentRenderView(); - if (render_view == NULL) - return; + return content::RenderView::FromWebView(view); +} - bool success = render_view->Send(new AtomViewHostMsg_Message( - render_view->GetRoutingID(), channel, arguments)); +v8::Local GetHiddenValue(v8::Isolate* isolate, + v8::Local key) { + content::RenderView* render_view = GetCurrentRenderView(); + v8::Local context = + render_view->GetWebView()->mainFrame()->mainWorldScriptContext(); + v8::Local privateKey = v8::Private::ForApi(isolate, key); + v8::Local value; + v8::Local object = context->Global(); + v8::Maybe result = object->HasPrivate(context, privateKey); + if (!(result.IsJust() && result.FromJust())) + return v8::Local(); + if (object->GetPrivate(context, privateKey).ToLocal(&value)) + return value; + return v8::Local(); +} - if (!success) - args->ThrowError("Unable to send AtomViewHostMsg_Message"); - } +void SetHiddenValue(v8::Isolate* isolate, + v8::Local key, + v8::Local value) { + if (value.IsEmpty()) + return; + content::RenderView* render_view = GetCurrentRenderView(); + v8::Local context = + render_view->GetWebView()->mainFrame()->mainWorldScriptContext(); + v8::Local privateKey = v8::Private::ForApi(isolate, key); + context->Global()->SetPrivate(context, privateKey, value); +} - base::string16 IPCSendSync(mate::Arguments* args, - const base::string16& channel, - const base::ListValue& arguments) { - base::string16 json; +void IPCSend(mate::Arguments* args, + const base::string16& channel, + const base::ListValue& arguments) { + content::RenderView* render_view = GetCurrentRenderView(); + if (render_view == NULL) + return; - content::RenderView* render_view = GetCurrentRenderView(); - if (render_view == NULL) - return json; + bool success = render_view->Send(new AtomViewHostMsg_Message( + render_view->GetRoutingID(), channel, arguments)); - IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync( - render_view->GetRoutingID(), channel, arguments, &json); - bool success = render_view->Send(message); + if (!success) + args->ThrowError("Unable to send AtomViewHostMsg_Message"); +} - if (!success) - args->ThrowError("Unable to send AtomViewHostMsg_Message_Sync"); +base::string16 IPCSendSync(mate::Arguments* args, + const base::string16& channel, + const base::ListValue& arguments) { + base::string16 json; + content::RenderView* render_view = GetCurrentRenderView(); + if (render_view == NULL) return json; - } - - std::vector> ListValueToVector(v8::Isolate* isolate, - const base::ListValue& list) { - v8::Local array = mate::ConvertToV8(isolate, list); - std::vector> result; - mate::ConvertFromV8(isolate, array, &result); - return result; - } + + IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync( + render_view->GetRoutingID(), channel, arguments, &json); + bool success = render_view->Send(message); + + if (!success) + args->ThrowError("Unable to send AtomViewHostMsg_Message_Sync"); + + return json; +} + +std::vector> ListValueToVector(v8::Isolate* isolate, + const base::ListValue& list) { + v8::Local array = mate::ConvertToV8(isolate, list); + std::vector> result; + mate::ConvertFromV8(isolate, array, &result); + return result; +} + } // namespace namespace atom { @@ -103,6 +133,11 @@ void JavascriptBindings::GetBinding( ipc.SetMethod("sendSync", &IPCSendSync); binding.Set("ipc", ipc.GetHandle()); + mate::Dictionary v8(isolate, v8::Object::New(isolate)); + v8.SetMethod("getHiddenValue", &GetHiddenValue); + v8.SetMethod("setHiddenValue", &SetHiddenValue); + binding.Set("v8", v8.GetHandle()); + mate::Dictionary content_settings(isolate, v8::Object::New(isolate)); content_settings.SetMethod("get", base::Bind(&ContentSettingsManager::GetSetting,