LibURL: Use a nonce to distinguish opaque origins

Opaque origins are meant to be unique in terms of equality from
one another. Since this uniqueness needs to be across processes,
use a nonce to implement the uniqueness check.
This commit is contained in:
Shannon Booth 2025-06-17 14:49:37 +12:00 committed by Tim Ledbetter
commit 38765fd617
Notes: github-actions[bot] 2025-06-25 15:48:27 +00:00
7 changed files with 77 additions and 24 deletions

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2025, Shannon Booth <shannon@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -15,8 +16,17 @@ namespace URL {
class Origin {
public:
using Nonce = Array<u8, 16>;
explicit Origin(Nonce nonce)
: m_state(move(nonce))
{
}
static Origin create_opaque();
Origin(Optional<String> const& scheme, Host const& host, Optional<u16> port)
: m_state(State {
: m_state(Tuple {
.scheme = scheme,
.host = host,
.port = move(port),
@ -24,22 +34,21 @@ public:
{
}
static Origin create_opaque();
// https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque
bool is_opaque() const { return !m_state.has_value(); }
bool is_opaque() const { return m_state.has<Nonce>(); }
Optional<String> const& scheme() const { return m_state->scheme; }
Host const& host() const { return m_state->host; }
Optional<u16> port() const { return m_state->port; }
Optional<String> const& scheme() const { return m_state.get<Tuple>().scheme; }
Host const& host() const { return m_state.get<Tuple>().host; }
Optional<u16> port() const { return m_state.get<Tuple>().port; }
Nonce const& nonce() const { return m_state.get<Nonce>(); }
// https://html.spec.whatwg.org/multipage/origin.html#same-origin
bool is_same_origin(Origin const& other) const
{
// 1. If A and B are the same opaque origin, then return true.
// FIXME: What about opaque origins that are not equal to one another?
if (is_opaque() && other.is_opaque())
return true;
return nonce() == other.nonce();
// 2. If A and B are both tuple origins and their schemes, hosts, and port are identical, then return true.
if (!is_opaque() && !other.is_opaque()
@ -57,9 +66,8 @@ public:
bool is_same_origin_domain(Origin const& other) const
{
// 1. If A and B are the same opaque origin, then return true.
// FIXME: What about opaque origins that are not equal to one another?
if (is_opaque() && other.is_opaque())
return true;
return nonce() == other.nonce();
// 2. If A and B are both tuple origins, run these substeps:
if (!is_opaque() && !other.is_opaque()) {
@ -94,20 +102,19 @@ public:
// FIXME: 2. If origin's domain is non-null, then return origin's domain.
// 3. Return origin's host.
return m_state->host;
return m_state.get<Tuple>().host;
}
bool operator==(Origin const& other) const { return is_same_origin(other); }
private:
Origin() = default;
struct State {
struct Tuple {
Optional<String> scheme;
Host host;
Optional<u16> port;
};
Optional<State> m_state;
Variant<Tuple, Nonce> m_state;
};
}