fix: MessagePort closing unexpectedly with non-cloneable objects (#42535)
* fix: MessagePort closing unexpectedly with non-cloneable objects * fix: handle serialization failure in parentPort
This commit is contained in:
		
					parent
					
						
							
								6d2c72b14e
							
						
					
				
			
			
				commit
				
					
						8e8ea3ee8b
					
				
			
		
					 4 changed files with 34 additions and 3 deletions
				
			
		|  | @ -76,8 +76,11 @@ void MessagePort::PostMessage(gin::Arguments* args) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   electron::SerializeV8Value(args->isolate(), message_value, |   if (!electron::SerializeV8Value(args->isolate(), message_value, | ||||||
|                              &transferable_message); |                                   &transferable_message)) { | ||||||
|  |     // SerializeV8Value sets an exception.
 | ||||||
|  |     return; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   v8::Local<v8::Value> transferables; |   v8::Local<v8::Value> transferables; | ||||||
|   std::vector<gin::Handle<MessagePort>> wrapped_ports; |   std::vector<gin::Handle<MessagePort>> wrapped_ports; | ||||||
|  |  | ||||||
|  | @ -44,7 +44,13 @@ void ParentPort::PostMessage(v8::Local<v8::Value> message_value) { | ||||||
|   if (!connector_closed_ && connector_ && connector_->is_valid()) { |   if (!connector_closed_ && connector_ && connector_->is_valid()) { | ||||||
|     v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); |     v8::Isolate* isolate = JavascriptEnvironment::GetIsolate(); | ||||||
|     blink::TransferableMessage transferable_message; |     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 = |     mojo::Message mojo_message = | ||||||
|         blink::mojom::TransferableMessage::WrapAsMessage( |         blink::mojom::TransferableMessage::WrapAsMessage( | ||||||
|             std::move(transferable_message)); |             std::move(transferable_message)); | ||||||
|  |  | ||||||
|  | @ -297,6 +297,17 @@ describe('utilityProcess module', () => { | ||||||
|       expect(child.kill()).to.be.true(); |       expect(child.kill()).to.be.true(); | ||||||
|       await exit; |       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', () => { |   describe('behavior', () => { | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								spec/fixtures/api/utility-process/non-cloneable.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								spec/fixtures/api/utility-process/non-cloneable.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -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'); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }); | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Shelley Vohr
				Shelley Vohr