From a26007f1950bbe54226d350fa472f5eba9fd8587 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 28 Aug 2025 12:57:55 +0200 Subject: [PATCH] LibWeb: Don't die when transferring the same MessagePort more than once One MessagePort can be entangled with another MessagePort, either in the same agent, or in another agent. In the same-agent case, the MessagePort objects point to each other via the MessagePort::m_remote_port field. In the separate-agent case, they live in separate processes entirely and thus can't point at each other. In both cases, the MessagePorts have an underlying transport channel, which means they are "entangled". However, we can't assume that being entangled means having a non-null m_remote_port. This patch simply adds a missing null check for m_remote_port and thus makes https://vscode.dev/ stop crashing with a null dereference. --- Libraries/LibWeb/HTML/MessagePort.cpp | 6 ++++- .../HTML/MessagePort-transfer-twice.txt | 2 ++ .../HTML/MessagePort-transfer-twice.html | 27 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 Tests/LibWeb/Text/expected/HTML/MessagePort-transfer-twice.txt create mode 100644 Tests/LibWeb/Text/input/HTML/MessagePort-transfer-twice.html diff --git a/Libraries/LibWeb/HTML/MessagePort.cpp b/Libraries/LibWeb/HTML/MessagePort.cpp index b347fe554be..2c955155490 100644 --- a/Libraries/LibWeb/HTML/MessagePort.cpp +++ b/Libraries/LibWeb/HTML/MessagePort.cpp @@ -99,7 +99,11 @@ WebIDL::ExceptionOr MessagePort::transfer_steps(HTML::TransferDataEncoder& // 3. If value is entangled with another port remotePort, then: if (is_entangled()) { // 1. Set remotePort's has been shipped flag to true. - m_remote_port->m_has_been_shipped = true; + + // NOTE: We have to null check here because we can be entangled with a port living in another agent. + // In that case, we'll have a transport, but no remote port object. + if (m_remote_port) + m_remote_port->m_has_been_shipped = true; auto fd = MUST(m_transport->release_underlying_transport_for_transfer()); m_transport.clear(); diff --git a/Tests/LibWeb/Text/expected/HTML/MessagePort-transfer-twice.txt b/Tests/LibWeb/Text/expected/HTML/MessagePort-transfer-twice.txt new file mode 100644 index 00000000000..33c112e2685 --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/MessagePort-transfer-twice.txt @@ -0,0 +1,2 @@ +first receipt: re-transferring same port +we good diff --git a/Tests/LibWeb/Text/input/HTML/MessagePort-transfer-twice.html b/Tests/LibWeb/Text/input/HTML/MessagePort-transfer-twice.html new file mode 100644 index 00000000000..d0245d81383 --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/MessagePort-transfer-twice.html @@ -0,0 +1,27 @@ + + +