diff --git a/Libraries/LibIPC/Decoder.cpp b/Libraries/LibIPC/Decoder.cpp index 1d17fcd87a..a75537be75 100644 --- a/Libraries/LibIPC/Decoder.cpp +++ b/Libraries/LibIPC/Decoder.cpp @@ -100,6 +100,10 @@ ErrorOr decode(Decoder& decoder) template<> ErrorOr decode(Decoder& decoder) { + auto is_opaque = TRY(decoder.decode()); + if (is_opaque) + return URL::Origin {}; + auto scheme = TRY(decoder.decode()); auto host = TRY(decoder.decode()); auto port = TRY(decoder.decode>()); diff --git a/Libraries/LibIPC/Encoder.cpp b/Libraries/LibIPC/Encoder.cpp index a01a58cf9b..b23c73a477 100644 --- a/Libraries/LibIPC/Encoder.cpp +++ b/Libraries/LibIPC/Encoder.cpp @@ -119,9 +119,14 @@ ErrorOr encode(Encoder& encoder, URL::URL const& value) template<> ErrorOr encode(Encoder& encoder, URL::Origin const& origin) { - TRY(encoder.encode(origin.scheme())); - TRY(encoder.encode(origin.host())); - TRY(encoder.encode(origin.port())); + if (origin.is_opaque()) { + TRY(encoder.encode(true)); + } else { + TRY(encoder.encode(false)); + TRY(encoder.encode(origin.scheme())); + TRY(encoder.encode(origin.host())); + TRY(encoder.encode(origin.port())); + } return {}; } diff --git a/Libraries/LibURL/Origin.cpp b/Libraries/LibURL/Origin.cpp index 2ce5a56fad..82943ece5b 100644 --- a/Libraries/LibURL/Origin.cpp +++ b/Libraries/LibURL/Origin.cpp @@ -42,13 +42,15 @@ namespace AK { unsigned Traits::hash(URL::Origin const& origin) { + if (origin.is_opaque()) + return 0; + unsigned hash = origin.scheme().hash(); if (origin.port().has_value()) hash = pair_int_hash(hash, *origin.port()); - if (!origin.host().has()) - hash = pair_int_hash(hash, URL::Parser::serialize_host(origin.host()).release_value_but_fixme_should_propagate_errors().hash()); + hash = pair_int_hash(hash, URL::Parser::serialize_host(origin.host()).release_value_but_fixme_should_propagate_errors().hash()); return hash; } diff --git a/Libraries/LibURL/Origin.h b/Libraries/LibURL/Origin.h index 07901a1332..6cba035293 100644 --- a/Libraries/LibURL/Origin.h +++ b/Libraries/LibURL/Origin.h @@ -16,21 +16,23 @@ class Origin { public: Origin() = default; Origin(Optional const& scheme, Host const& host, Optional port) - : m_scheme(scheme) - , m_host(host) - , m_port(port) + : m_state(State { + .scheme = scheme, + .host = host, + .port = move(port), + }) { } // https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque - bool is_opaque() const { return !m_scheme.has_value() && m_host.has() && !m_port.has_value(); } + bool is_opaque() const { return !m_state.has_value(); } StringView scheme() const { - return m_scheme.map([](auto& str) { return str.view(); }).value_or(StringView {}); + return m_state->scheme.map([](auto& str) { return str.view(); }).value_or(StringView {}); } - Host const& host() const { return m_host; } - Optional port() const { return m_port; } + Host const& host() const { return m_state->host; } + Optional port() const { return m_state->port; } // https://html.spec.whatwg.org/multipage/origin.html#same-origin bool is_same_origin(Origin const& other) const @@ -40,10 +42,15 @@ public: return true; // 2. If A and B are both tuple origins and their schemes, hosts, and port are identical, then return true. - // 3. Return false. - return scheme() == other.scheme() + if (!is_opaque() && !other.is_opaque() + && scheme() == other.scheme() && host() == other.host() - && port() == other.port(); + && port() == other.port()) { + return true; + } + + // 3. Return false. + return false; } // https://html.spec.whatwg.org/multipage/origin.html#same-origin-domain @@ -83,15 +90,18 @@ public: // FIXME: 2. If origin's domain is non-null, then return origin's domain. // 3. Return origin's host. - return m_host; + return m_state->host; } bool operator==(Origin const& other) const { return is_same_origin(other); } private: - Optional m_scheme; - Host m_host; - Optional m_port; + struct State { + Optional scheme; + Host host; + Optional port; + }; + Optional m_state; }; }