mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2026-04-18 09:50:27 +00:00
The same-origin domain check always returned true if only the scheme matched. This was because of missing steps to check for the origin's domain, which didn't exist. Add this concept to URL::Origin, even though we do not use it at this stage in document.domain setter. Co-Authored-By: Luke Wilde <luke@ladybird.org>
207 lines
4.8 KiB
C++
207 lines
4.8 KiB
C++
/*
|
|
* Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
|
|
* Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>
|
|
* Copyright (c) 2023-2025, Tim Flynn <trflynn89@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <AK/BitCast.h>
|
|
#include <AK/ByteBuffer.h>
|
|
#include <AK/ByteString.h>
|
|
#include <AK/JsonObject.h>
|
|
#include <AK/JsonValue.h>
|
|
#include <AK/NumericLimits.h>
|
|
#include <AK/String.h>
|
|
#include <AK/Time.h>
|
|
#include <AK/Utf16String.h>
|
|
#include <AK/Utf16View.h>
|
|
#include <LibCore/AnonymousBuffer.h>
|
|
#include <LibCore/Proxy.h>
|
|
#include <LibCore/System.h>
|
|
#include <LibIPC/Encoder.h>
|
|
#include <LibIPC/File.h>
|
|
#include <LibURL/Origin.h>
|
|
#include <LibURL/URL.h>
|
|
|
|
namespace IPC {
|
|
|
|
ErrorOr<void> Encoder::encode_size(size_t size)
|
|
{
|
|
if (static_cast<u64>(size) > static_cast<u64>(NumericLimits<u32>::max()))
|
|
return Error::from_string_literal("Container exceeds the maximum allowed size");
|
|
return encode(static_cast<u32>(size));
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, float const& value)
|
|
{
|
|
return encoder.encode(bit_cast<u32>(value));
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, double const& value)
|
|
{
|
|
return encoder.encode(bit_cast<u64>(value));
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, String const& value)
|
|
{
|
|
return encoder.encode(value.bytes_as_string_view());
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, StringView const& value)
|
|
{
|
|
TRY(encoder.encode_size(value.length()));
|
|
TRY(encoder.append(reinterpret_cast<u8 const*>(value.characters_without_null_termination()), value.length()));
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, Utf16String const& value)
|
|
{
|
|
return encoder.encode(value.utf16_view());
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, Utf16View const& value)
|
|
{
|
|
TRY(encoder.encode(value.has_ascii_storage()));
|
|
TRY(encoder.encode_size(value.length_in_code_units()));
|
|
|
|
if (value.has_ascii_storage())
|
|
TRY(encoder.append(value.bytes().data(), value.length_in_code_units()));
|
|
else
|
|
TRY(encoder.append(reinterpret_cast<u8 const*>(value.utf16_span().data()), value.length_in_code_units() * sizeof(char16_t)));
|
|
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, ByteString const& value)
|
|
{
|
|
return encoder.encode(value.view());
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, ByteBuffer const& value)
|
|
{
|
|
TRY(encoder.encode_size(value.size()));
|
|
TRY(encoder.append(value.data(), value.size()));
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, JsonValue const& value)
|
|
{
|
|
return encoder.encode(value.serialized());
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, AK::Duration const& value)
|
|
{
|
|
return encoder.encode(value.to_nanoseconds());
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, UnixDateTime const& value)
|
|
{
|
|
return encoder.encode(value.nanoseconds_since_epoch());
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, URL::URL const& value)
|
|
{
|
|
TRY(encoder.encode(value.serialize()));
|
|
|
|
if (!value.blob_url_entry().has_value())
|
|
return encoder.encode(false);
|
|
|
|
TRY(encoder.encode(true));
|
|
|
|
auto const& entry = value.blob_url_entry().value();
|
|
|
|
TRY(encoder.encode(entry.object));
|
|
TRY(encoder.encode(entry.environment.origin));
|
|
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, URL::Origin const& origin)
|
|
{
|
|
if (origin.is_opaque()) {
|
|
TRY(encoder.encode(true));
|
|
TRY(encoder.encode(origin.nonce()));
|
|
} else {
|
|
TRY(encoder.encode(false));
|
|
TRY(encoder.encode(origin.scheme()));
|
|
TRY(encoder.encode(origin.host()));
|
|
TRY(encoder.encode(origin.port()));
|
|
TRY(encoder.encode(origin.domain()));
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, URL::Host const& host)
|
|
{
|
|
TRY(encoder.encode(host.value()));
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, File const& file)
|
|
{
|
|
int fd = file.take_fd();
|
|
|
|
TRY(encoder.append_file_descriptor(fd));
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder&, Empty const&)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, Core::AnonymousBuffer const& buffer)
|
|
{
|
|
TRY(encoder.encode(buffer.is_valid()));
|
|
|
|
if (buffer.is_valid()) {
|
|
TRY(encoder.encode_size(buffer.size()));
|
|
TRY(encoder.encode(TRY(IPC::File::clone_fd(buffer.fd()))));
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, Core::ProxyData const& proxy)
|
|
{
|
|
TRY(encoder.encode(proxy.type));
|
|
TRY(encoder.encode(proxy.host_ipv4));
|
|
TRY(encoder.encode(proxy.port));
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder& encoder, URL::BlobURLEntry::Blob const& blob)
|
|
{
|
|
TRY(encoder.encode(blob.type));
|
|
TRY(encoder.encode(blob.data));
|
|
return {};
|
|
}
|
|
|
|
template<>
|
|
ErrorOr<void> encode(Encoder&, URL::BlobURLEntry::MediaSource const&)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
}
|