diff --git a/shell/browser/api/message_port.cc b/shell/browser/api/message_port.cc index 6afeaa0c695..a81360b0f1d 100644 --- a/shell/browser/api/message_port.cc +++ b/shell/browser/api/message_port.cc @@ -76,8 +76,11 @@ void MessagePort::PostMessage(gin::Arguments* args) { return; } - electron::SerializeV8Value(args->isolate(), message_value, - &transferable_message); + if (!electron::SerializeV8Value(args->isolate(), message_value, + &transferable_message)) { + // SerializeV8Value sets an exception. + return; + } v8::Local transferables; std::vector> wrapped_ports; diff --git a/shell/services/node/parent_port.cc b/shell/services/node/parent_port.cc index 89cf18dcb59..13d9433f30d 100644 --- a/shell/services/node/parent_port.cc +++ b/shell/services/node/parent_port.cc @@ -44,7 +44,13 @@ void ParentPort::PostMessage(v8::Local message_value) { if (!connector_closed_ && connector_ && connector_->is_valid()) { v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); blink::TransferableMessage transferable_message; - electron::SerializeV8Value(isolate, message_value, &transferable_message); + + if (!electron::SerializeV8Value(isolate, message_value, + &transferable_message)) { + // SerializeV8Value sets an exception. + return; + } + mojo::Message mojo_message = blink::mojom::TransferableMessage::WrapAsMessage( std::move(transferable_message)); diff --git a/spec/api-utility-process-spec.ts b/spec/api-utility-process-spec.ts index c2752ac39a5..3af6f517011 100644 --- a/spec/api-utility-process-spec.ts +++ b/spec/api-utility-process-spec.ts @@ -279,6 +279,17 @@ describe('utilityProcess module', () => { expect(child.kill()).to.be.true(); await exit; }); + + it('handles the parent port trying to send an non-clonable object', async () => { + const child = utilityProcess.fork(path.join(fixturesPath, 'non-cloneable.js')); + await once(child, 'spawn'); + child.postMessage('non-cloneable'); + const [data] = await once(child, 'message'); + expect(data).to.equal('caught-non-cloneable'); + const exit = once(child, 'exit'); + expect(child.kill()).to.be.true(); + await exit; + }); }); describe('behavior', () => { diff --git a/spec/fixtures/api/utility-process/non-cloneable.js b/spec/fixtures/api/utility-process/non-cloneable.js new file mode 100644 index 00000000000..fd416ee2bec --- /dev/null +++ b/spec/fixtures/api/utility-process/non-cloneable.js @@ -0,0 +1,11 @@ +const nonClonableObject = () => {}; + +process.parentPort.on('message', () => { + try { + process.parentPort.postMessage(nonClonableObject); + } catch (error) { + if (/An object could not be cloned/.test(error.message)) { + process.parentPort.postMessage('caught-non-cloneable'); + } + } +});