Browse Source

fix: emit IPC event in correct context if isolation and sandbox enabled (#16352) (#18668)

* fix: emit IPC event in correct context if isolation and sandbox enabled

IPC events were not being delivered to renderer processes when both
`contextIsolation` and `sandbox` were enabled. This is because the
`AtomSandboxedRenderFrameObserver` class was incorrectly using the
`MainWorldScriptContext`, rather than conditionally selecting the
context based on if isolation was enabled.

Fixes #11922
Milan Burda 5 years ago
parent
commit
516233c0da

+ 3 - 1
atom/renderer/atom_sandboxed_renderer_client.cc

@@ -125,8 +125,10 @@ class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver {
 
     auto* isolate = blink::MainThreadIsolate();
     v8::HandleScope handle_scope(isolate);
-    auto context = frame->MainWorldScriptContext();
+
+    auto context = renderer_client_->GetContext(frame, isolate);
     v8::Context::Scope context_scope(context);
+
     v8::Local<v8::Value> argv[] = {mate::ConvertToV8(isolate, channel),
                                    mate::ConvertToV8(isolate, args)};
     renderer_client_->InvokeIpcCallback(

+ 25 - 10
spec/api-ipc-renderer-spec.js

@@ -140,20 +140,35 @@ describe('ipc renderer module', () => {
       contents = null
     })
 
-    it('sends message to WebContents', done => {
-      const webContentsId = remote.getCurrentWebContents().id
+    const generateSpecs = (description, webPreferences) => {
+      describe(description, () => {
+        it('sends message to WebContents', done => {
+          contents = webContents.create({
+            preload: path.join(fixtures, 'module', 'preload-ipc-ping-pong.js'),
+            ...webPreferences
+          })
 
-      ipcRenderer.once('pong', (event, id) => {
-        expect(webContentsId).to.equal(id)
-        done()
-      })
+          const payload = 'Hello World!'
+          const webContentsId = remote.getCurrentWebContents().id
+
+          ipcRenderer.once('pong', (event, data) => {
+            expect(payload).to.equal(data)
+            done()
+          })
 
-      contents.once('did-finish-load', () => {
-        ipcRenderer.sendTo(contents.id, 'ping', webContentsId)
+          contents.once('did-finish-load', () => {
+            ipcRenderer.sendTo(contents.id, 'ping', webContentsId, payload)
+          })
+
+          contents.loadFile(path.join(fixtures, 'pages', 'base-page.html'))
+        })
       })
+    }
 
-      contents.loadURL(`file://${path.join(fixtures, 'pages', 'ping-pong.html')}`)
-    })
+    generateSpecs('without sandbox', {})
+    generateSpecs('with sandbox', { sandbox: true })
+    generateSpecs('with contextIsolation', { contextIsolation: true })
+    generateSpecs('with contextIsolation + sandbox', { contextIsolation: true, sandbox: true })
   })
 
   describe('remote listeners', () => {

+ 0 - 2
spec/fixtures/module/preload-inject-ipc.js

@@ -1,2 +0,0 @@
-const {ipcRenderer} = require('electron')
-window.ipcRenderer = ipcRenderer

+ 5 - 0
spec/fixtures/module/preload-ipc-ping-pong.js

@@ -0,0 +1,5 @@
+const { ipcRenderer } = require('electron')
+
+ipcRenderer.on('ping', function (event, senderId, payload) {
+  ipcRenderer.sendTo(senderId, 'pong', payload)
+})

+ 0 - 11
spec/fixtures/pages/ping-pong.html

@@ -1,11 +0,0 @@
-<html>
-<body>
-<script type="text/javascript" charset="utf-8">
-  const {ipcRenderer} = require('electron')
-  ipcRenderer.on('ping', function (event, id) {
-    ipcRenderer.sendTo(id, 'pong', id)
-  })
-</script>
-</body>
-</html>
-