Everywhere: Make ByteBuffer::bytes() lvalue-only

This helps prevent us from accidentally using pointers to the underlying
memory of temporary `ByteBuffer` values.
This commit is contained in:
Aliaksandr Kalenik
2025-12-10 10:32:02 +01:00
committed by Tim Flynn
parent 420187ba7c
commit 55e6e6f117
6 changed files with 19 additions and 12 deletions

View File

@@ -147,11 +147,14 @@ public:
# pragma GCC diagnostic pop
#endif
[[nodiscard]] Bytes bytes() LIFETIME_BOUND
[[nodiscard]] Bytes bytes() && LIFETIME_BOUND = delete;
[[nodiscard]] Bytes bytes() & LIFETIME_BOUND
{
return { data(), size() };
}
[[nodiscard]] ReadonlyBytes bytes() const LIFETIME_BOUND { return { data(), size() }; }
[[nodiscard]] ReadonlyBytes bytes() const&& = delete;
[[nodiscard]] ReadonlyBytes bytes() const& LIFETIME_BOUND { return { data(), size() }; }
[[nodiscard]] AK::Bytes span() LIFETIME_BOUND { return { data(), size() }; }
[[nodiscard]] AK::ReadonlyBytes span() const LIFETIME_BOUND { return { data(), size() }; }
@@ -306,8 +309,10 @@ public:
__builtin_memset(data(), 0, m_size);
}
operator Bytes() LIFETIME_BOUND { return bytes(); }
operator ReadonlyBytes() const LIFETIME_BOUND { return bytes(); }
operator Bytes() && = delete;
operator Bytes() & LIFETIME_BOUND { return bytes(); }
operator ReadonlyBytes() const&& = delete;
operator ReadonlyBytes() const& LIFETIME_BOUND { return bytes(); }
ALWAYS_INLINE size_t capacity() const { return m_inline ? inline_capacity : m_outline_capacity; }
ALWAYS_INLINE bool is_inline() const { return m_inline; }

View File

@@ -39,8 +39,8 @@ void RequestClient::ensure_connection(URL::URL const& url, ::RequestServer::Cach
RefPtr<Request> RequestClient::start_request(ByteString const& method, URL::URL const& url, Optional<HTTP::HeaderList const&> request_headers, ReadonlyBytes request_body, Core::ProxyData const& proxy_data)
{
auto body_result = ByteBuffer::copy(request_body);
if (body_result.is_error())
auto body_result_or_error = ByteBuffer::copy(request_body);
if (body_result_or_error.is_error())
return nullptr;
static i32 s_next_request_id = 0;
@@ -48,7 +48,8 @@ RefPtr<Request> RequestClient::start_request(ByteString const& method, URL::URL
auto headers = request_headers.map([](auto const& headers) { return headers.headers().span(); }).value_or({});
IPCProxy::async_start_request(request_id, method, url, headers, body_result.release_value(), proxy_data);
auto body_result = body_result_or_error.release_value();
IPCProxy::async_start_request(request_id, method, url, headers, body_result, proxy_data);
auto request = Request::create_from_id({}, *this, request_id);
m_requests.set(request_id, request);
return request;

View File

@@ -37,7 +37,7 @@ void WebSocket::set_subprotocol_in_use(ByteString subprotocol)
void WebSocket::send(ByteBuffer binary_or_text_message, bool is_text)
{
m_client->async_websocket_send(m_websocket_id, is_text, move(binary_or_text_message));
m_client->async_websocket_send(m_websocket_id, is_text, binary_or_text_message);
}
void WebSocket::send(StringView text_message)

View File

@@ -116,7 +116,7 @@ WebIDL::ExceptionOr<void> CompressionStream::compress_and_enqueue_chunk(JS::Valu
// 2. Let buffer be the result of compressing chunk with cs's format and context.
auto maybe_buffer = [&]() -> ErrorOr<ByteBuffer> {
auto chunk_buffer = TRY(WebIDL::get_buffer_source_copy(chunk.as_object()));
return compress(move(chunk_buffer), Finish::No);
return compress(chunk_buffer, Finish::No);
}();
if (maybe_buffer.is_error())
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, MUST(String::formatted("Unable to compress chunk: {}", maybe_buffer.error())) };

View File

@@ -4420,7 +4420,7 @@ WebIDL::ExceptionOr<GC::Ref<CryptoKey>> ECDSA::import_key(AlgorithmParams const&
// The uncompressed point format MUST be supported.
// 2. If the implementation does not support the compressed point format and a compressed point is provided, throw a DataError.
// 3. If a decode error occurs or an identity point is found, throw a DataError.
auto maybe_public_key = ::Crypto::PK::EC::parse_ec_key(move(key_bytes), false, {});
auto maybe_public_key = ::Crypto::PK::EC::parse_ec_key(key_bytes, false, {});
if (maybe_public_key.is_error())
return WebIDL::DataError::create(m_realm, "Failed to parse key"_utf16);
@@ -5372,7 +5372,7 @@ WebIDL::ExceptionOr<GC::Ref<CryptoKey>> ECDH::import_key(AlgorithmParams const&
// The uncompressed point format MUST be supported.
// 2. If the implementation does not support the compressed point format and a compressed point is provided, throw a DataError.
// 3. If a decode error occurs or an identity point is found, throw a DataError.
auto maybe_public_key = ::Crypto::PK::EC::parse_ec_key(move(key_bytes), false, {});
auto maybe_public_key = ::Crypto::PK::EC::parse_ec_key(key_bytes, false, {});
if (maybe_public_key.is_error())
return WebIDL::DataError::create(m_realm, "Failed to parse key"_utf16);

View File

@@ -49,7 +49,8 @@ TEST_CASE(test_TLS_hello_handshake)
return;
auto line = TRY_OR_FAIL(tls->read_until_any_of(read_buffer, Array { "\r\n"sv }));
EXPECT(line.starts_with("HTTP/1.1 204 No Content"_b));
auto no_content_prefix = "HTTP/1.1 204 No Content"_b;
EXPECT(line.starts_with(no_content_prefix));
loop.quit(0);
};
tls->set_notifications_enabled(true);