mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix: throw instead of crash when using ipcRenderer after context released (#23979)
* fix: throw instead of crash when using ipcRenderer after context released (#23917) * meh * Update api-ipc-renderer-spec.ts
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "shell/common/api/api.mojom.h"
|
||||
#include "shell/common/gin_converters/blink_converter_gin_adapter.h"
|
||||
#include "shell/common/gin_converters/value_converter_gin_adapter.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/node_bindings.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/promise_util.h"
|
||||
@@ -26,6 +27,9 @@ using content::RenderFrame;
|
||||
|
||||
namespace {
|
||||
|
||||
const char kIPCMethodCalledAfterContextReleasedError[] =
|
||||
"IPC method called after context was released";
|
||||
|
||||
RenderFrame* GetCurrentRenderFrame() {
|
||||
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
||||
if (!frame)
|
||||
@@ -82,6 +86,11 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||
bool internal,
|
||||
const std::string& channel,
|
||||
v8::Local<v8::Value> arguments) {
|
||||
if (!electron_browser_ptr_) {
|
||||
gin_helper::ErrorThrower(isolate).ThrowError(
|
||||
kIPCMethodCalledAfterContextReleasedError);
|
||||
return;
|
||||
}
|
||||
blink::CloneableMessage message;
|
||||
if (!mate::ConvertFromV8(isolate, arguments, &message)) {
|
||||
return;
|
||||
@@ -93,6 +102,11 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||
bool internal,
|
||||
const std::string& channel,
|
||||
v8::Local<v8::Value> arguments) {
|
||||
if (!electron_browser_ptr_) {
|
||||
gin_helper::ErrorThrower(isolate).ThrowError(
|
||||
kIPCMethodCalledAfterContextReleasedError);
|
||||
return v8::Local<v8::Promise>();
|
||||
}
|
||||
blink::CloneableMessage message;
|
||||
if (!mate::ConvertFromV8(isolate, arguments, &message)) {
|
||||
return v8::Local<v8::Promise>();
|
||||
@@ -116,6 +130,11 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||
int32_t web_contents_id,
|
||||
const std::string& channel,
|
||||
v8::Local<v8::Value> arguments) {
|
||||
if (!electron_browser_ptr_) {
|
||||
gin_helper::ErrorThrower(isolate).ThrowError(
|
||||
kIPCMethodCalledAfterContextReleasedError);
|
||||
return;
|
||||
}
|
||||
blink::CloneableMessage message;
|
||||
if (!mate::ConvertFromV8(isolate, arguments, &message)) {
|
||||
return;
|
||||
@@ -127,6 +146,11 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||
void SendToHost(v8::Isolate* isolate,
|
||||
const std::string& channel,
|
||||
v8::Local<v8::Value> arguments) {
|
||||
if (!electron_browser_ptr_) {
|
||||
gin_helper::ErrorThrower(isolate).ThrowError(
|
||||
kIPCMethodCalledAfterContextReleasedError);
|
||||
return;
|
||||
}
|
||||
blink::CloneableMessage message;
|
||||
if (!mate::ConvertFromV8(isolate, arguments, &message)) {
|
||||
return;
|
||||
@@ -138,6 +162,11 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||
bool internal,
|
||||
const std::string& channel,
|
||||
v8::Local<v8::Value> arguments) {
|
||||
if (!electron_browser_ptr_) {
|
||||
gin_helper::ErrorThrower(isolate).ThrowError(
|
||||
kIPCMethodCalledAfterContextReleasedError);
|
||||
return blink::CloneableMessage();
|
||||
}
|
||||
blink::CloneableMessage message;
|
||||
if (!mate::ConvertFromV8(isolate, arguments, &message)) {
|
||||
return blink::CloneableMessage();
|
||||
|
||||
@@ -9,7 +9,7 @@ describe('ipcRenderer module', () => {
|
||||
|
||||
let w: BrowserWindow
|
||||
before(async () => {
|
||||
w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } })
|
||||
w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, nativeWindowOpen: true, nodeIntegrationInSubFrames: true } })
|
||||
await w.loadURL('about:blank')
|
||||
})
|
||||
after(async () => {
|
||||
@@ -192,4 +192,25 @@ describe('ipcRenderer module', () => {
|
||||
expect(result).to.deep.equal([])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('after context is released', () => {
|
||||
it('throws an exception', async () => {
|
||||
const error = await w.webContents.executeJavaScript(`(${() => {
|
||||
const child = window.open('', 'child', 'show=no,nodeIntegration=yes')! as any;
|
||||
const childIpc = child.require('electron').ipcRenderer;
|
||||
child.close();
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
childIpc.send('hello');
|
||||
} catch (e) {
|
||||
resolve(e);
|
||||
}
|
||||
resolve(false);
|
||||
}, 100);
|
||||
});
|
||||
}})()`);
|
||||
expect(error).to.have.property('message', 'IPC method called after context was released');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user