fix: throw instead of crash when using ipcRenderer after context released (#23917)
This commit is contained in:
parent
491caf59c1
commit
a1c55a13e1
2 changed files with 55 additions and 1 deletions
|
@ -16,6 +16,7 @@
|
||||||
#include "shell/common/api/api.mojom.h"
|
#include "shell/common/api/api.mojom.h"
|
||||||
#include "shell/common/gin_converters/blink_converter.h"
|
#include "shell/common/gin_converters/blink_converter.h"
|
||||||
#include "shell/common/gin_converters/value_converter.h"
|
#include "shell/common/gin_converters/value_converter.h"
|
||||||
|
#include "shell/common/gin_helper/error_thrower.h"
|
||||||
#include "shell/common/gin_helper/function_template_extensions.h"
|
#include "shell/common/gin_helper/function_template_extensions.h"
|
||||||
#include "shell/common/gin_helper/promise.h"
|
#include "shell/common/gin_helper/promise.h"
|
||||||
#include "shell/common/node_bindings.h"
|
#include "shell/common/node_bindings.h"
|
||||||
|
@ -29,6 +30,9 @@ using content::RenderFrame;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const char kIPCMethodCalledAfterContextReleasedError[] =
|
||||||
|
"IPC method called after context was released";
|
||||||
|
|
||||||
RenderFrame* GetCurrentRenderFrame() {
|
RenderFrame* GetCurrentRenderFrame() {
|
||||||
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
||||||
if (!frame)
|
if (!frame)
|
||||||
|
@ -83,9 +87,14 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SendMessage(v8::Isolate* isolate,
|
void SendMessage(v8::Isolate* isolate,
|
||||||
|
gin_helper::ErrorThrower thrower,
|
||||||
bool internal,
|
bool internal,
|
||||||
const std::string& channel,
|
const std::string& channel,
|
||||||
v8::Local<v8::Value> arguments) {
|
v8::Local<v8::Value> arguments) {
|
||||||
|
if (!electron_browser_ptr_) {
|
||||||
|
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
blink::CloneableMessage message;
|
blink::CloneableMessage message;
|
||||||
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
||||||
return;
|
return;
|
||||||
|
@ -94,9 +103,14 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Promise> Invoke(v8::Isolate* isolate,
|
v8::Local<v8::Promise> Invoke(v8::Isolate* isolate,
|
||||||
|
gin_helper::ErrorThrower thrower,
|
||||||
bool internal,
|
bool internal,
|
||||||
const std::string& channel,
|
const std::string& channel,
|
||||||
v8::Local<v8::Value> arguments) {
|
v8::Local<v8::Value> arguments) {
|
||||||
|
if (!electron_browser_ptr_) {
|
||||||
|
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
|
||||||
|
return v8::Local<v8::Promise>();
|
||||||
|
}
|
||||||
blink::CloneableMessage message;
|
blink::CloneableMessage message;
|
||||||
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
||||||
return v8::Local<v8::Promise>();
|
return v8::Local<v8::Promise>();
|
||||||
|
@ -119,6 +133,10 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||||
const std::string& channel,
|
const std::string& channel,
|
||||||
v8::Local<v8::Value> message_value,
|
v8::Local<v8::Value> message_value,
|
||||||
base::Optional<v8::Local<v8::Value>> transfer) {
|
base::Optional<v8::Local<v8::Value>> transfer) {
|
||||||
|
if (!electron_browser_ptr_) {
|
||||||
|
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
blink::TransferableMessage transferable_message;
|
blink::TransferableMessage transferable_message;
|
||||||
if (!electron::SerializeV8Value(isolate, message_value,
|
if (!electron::SerializeV8Value(isolate, message_value,
|
||||||
&transferable_message)) {
|
&transferable_message)) {
|
||||||
|
@ -152,11 +170,16 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendTo(v8::Isolate* isolate,
|
void SendTo(v8::Isolate* isolate,
|
||||||
|
gin_helper::ErrorThrower thrower,
|
||||||
bool internal,
|
bool internal,
|
||||||
bool send_to_all,
|
bool send_to_all,
|
||||||
int32_t web_contents_id,
|
int32_t web_contents_id,
|
||||||
const std::string& channel,
|
const std::string& channel,
|
||||||
v8::Local<v8::Value> arguments) {
|
v8::Local<v8::Value> arguments) {
|
||||||
|
if (!electron_browser_ptr_) {
|
||||||
|
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
blink::CloneableMessage message;
|
blink::CloneableMessage message;
|
||||||
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
||||||
return;
|
return;
|
||||||
|
@ -166,8 +189,13 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendToHost(v8::Isolate* isolate,
|
void SendToHost(v8::Isolate* isolate,
|
||||||
|
gin_helper::ErrorThrower thrower,
|
||||||
const std::string& channel,
|
const std::string& channel,
|
||||||
v8::Local<v8::Value> arguments) {
|
v8::Local<v8::Value> arguments) {
|
||||||
|
if (!electron_browser_ptr_) {
|
||||||
|
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
blink::CloneableMessage message;
|
blink::CloneableMessage message;
|
||||||
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
||||||
return;
|
return;
|
||||||
|
@ -176,9 +204,14 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Value> SendSync(v8::Isolate* isolate,
|
v8::Local<v8::Value> SendSync(v8::Isolate* isolate,
|
||||||
|
gin_helper::ErrorThrower thrower,
|
||||||
bool internal,
|
bool internal,
|
||||||
const std::string& channel,
|
const std::string& channel,
|
||||||
v8::Local<v8::Value> arguments) {
|
v8::Local<v8::Value> arguments) {
|
||||||
|
if (!electron_browser_ptr_) {
|
||||||
|
thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError);
|
||||||
|
return v8::Local<v8::Value>();
|
||||||
|
}
|
||||||
blink::CloneableMessage message;
|
blink::CloneableMessage message;
|
||||||
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
if (!electron::SerializeV8Value(isolate, arguments, &message)) {
|
||||||
return v8::Local<v8::Value>();
|
return v8::Local<v8::Value>();
|
||||||
|
|
|
@ -9,7 +9,7 @@ describe('ipcRenderer module', () => {
|
||||||
|
|
||||||
let w: BrowserWindow;
|
let w: BrowserWindow;
|
||||||
before(async () => {
|
before(async () => {
|
||||||
w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } });
|
w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true, nativeWindowOpen: true } });
|
||||||
await w.loadURL('about:blank');
|
await w.loadURL('about:blank');
|
||||||
});
|
});
|
||||||
after(async () => {
|
after(async () => {
|
||||||
|
@ -182,4 +182,25 @@ describe('ipcRenderer module', () => {
|
||||||
expect(result).to.deep.equal([]);
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue