Files
ladybird/Libraries/LibIPC/TransportHandle.cpp
Jonathan Gamble c61066c0ae LibIPC: Dont VERIFY when encoding placeholder TransportHandles
Empty transport handles can be generated in a few places in Ladybird
sources, notably in WebContentClient::request_worker_agent when
view_for_page_id finds nothing.

If those handles reach encode, a VERIFY is triggered in the broker
process. An page lookup failure should not be fatal to the browser, so
I'll boldly assert it is better to return an error here.

This failure was observed during large runs of origin and IndexedDB
heavy wpt tests in test-web.
2026-04-29 01:07:11 +02:00

90 lines
2.8 KiB
C++

/*
* Copyright (c) 2026, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibCore/Socket.h>
#include <LibIPC/Attachment.h>
#include <LibIPC/Decoder.h>
#include <LibIPC/Encoder.h>
#include <LibIPC/Transport.h>
#include <LibIPC/TransportHandle.h>
namespace IPC {
#if defined(AK_OS_MACOS)
TransportHandle::TransportHandle(Core::MachPort receive_right, Core::MachPort send_right)
: m_receive_right(move(receive_right))
, m_send_right(move(send_right))
{
VERIFY(MACH_PORT_VALID(m_receive_right.port()));
VERIFY(MACH_PORT_VALID(m_send_right.port()));
}
ErrorOr<NonnullOwnPtr<Transport>> TransportHandle::create_transport() const
{
VERIFY(MACH_PORT_VALID(m_receive_right.port()));
VERIFY(MACH_PORT_VALID(m_send_right.port()));
return make<Transport>(move(m_receive_right), move(m_send_right));
}
template<>
ErrorOr<void> encode(Encoder& encoder, TransportHandle const& handle)
{
mach_port_t send_port = handle.m_send_right.port();
mach_port_t receive_port = handle.m_receive_right.port();
if (send_port == MACH_PORT_NULL || send_port == MACH_PORT_DEAD || receive_port == MACH_PORT_NULL || receive_port == MACH_PORT_DEAD)
return Error::from_string_literal("TransportHandle::encode: Invalid Mach port(s)");
TRY(encoder.append_attachment(Attachment::from_mach_port(move(handle.m_receive_right), Core::MachPort::MessageRight::MoveReceive)));
TRY(encoder.append_attachment(Attachment::from_mach_port(move(handle.m_send_right), Core::MachPort::MessageRight::MoveSend)));
return {};
}
template<>
ErrorOr<TransportHandle> decode(Decoder& decoder)
{
auto& attachments = decoder.attachments();
VERIFY(attachments.size() >= 2);
auto recv_attachment = attachments.dequeue();
auto send_attachment = attachments.dequeue();
VERIFY(recv_attachment.message_right() == Core::MachPort::MessageRight::MoveReceive);
VERIFY(send_attachment.message_right() == Core::MachPort::MessageRight::MoveSend);
auto receive_right = recv_attachment.release_mach_port();
auto send_right = send_attachment.release_mach_port();
return TransportHandle { move(receive_right), move(send_right) };
}
#else
TransportHandle::TransportHandle(File file)
: m_file(move(file))
{
}
ErrorOr<NonnullOwnPtr<Transport>> TransportHandle::create_transport() const
{
auto socket = TRY(Core::LocalSocket::adopt_fd(m_file.take_fd()));
TRY(socket->set_blocking(false));
return make<Transport>(move(socket));
}
template<>
ErrorOr<void> encode(Encoder& encoder, TransportHandle const& handle)
{
return encoder.encode(handle.m_file);
}
template<>
ErrorOr<TransportHandle> decode(Decoder& decoder)
{
auto file = TRY(decoder.decode<File>());
return TransportHandle { move(file) };
}
#endif
}