LibWeb: Make a bunch of CSP classes not realm associated

These are not associated with a javascript realm, so to avoid
confusion about which realm these need to be created in, make
all of these objects a GC::Cell, and deal with the fallout.
This commit is contained in:
Shannon Booth 2025-04-26 11:35:51 +12:00 committed by Andreas Kling
commit 8a3c66d8a6
Notes: github-actions[bot] 2025-04-28 10:42:23 +00:00
20 changed files with 91 additions and 92 deletions

View file

@ -19,9 +19,9 @@ Directive::Directive(String name, Vector<String> value)
{
}
GC::Ref<Directive> Directive::clone(JS::Realm& realm) const
GC::Ref<Directive> Directive::clone(GC::Heap& heap) const
{
return create_directive(realm, m_name, m_value);
return create_directive(heap, m_name, m_value);
}
SerializedDirective Directive::serialize() const

View file

@ -17,8 +17,8 @@ namespace Web::ContentSecurityPolicy::Directives {
// https://w3c.github.io/webappsec-csp/#directives
// Each policy contains an ordered set of directives (its directive set), each of which controls a specific behavior.
// The directives defined in this document are described in detail in § 6 Content Security Policy Directives.
class Directive : public JS::Cell {
GC_CELL(Directive, JS::Cell)
class Directive : public GC::Cell {
GC_CELL(Directive, GC::Cell)
GC_DECLARE_ALLOCATOR(Directive);
public:
@ -94,7 +94,7 @@ public:
[[nodiscard]] String const& name() const { return m_name; }
[[nodiscard]] Vector<String> const& value() const { return m_value; }
[[nodiscard]] GC::Ref<Directive> clone(JS::Realm&) const;
[[nodiscard]] GC::Ref<Directive> clone(GC::Heap&) const;
[[nodiscard]] SerializedDirective serialize() const;
protected:

View file

@ -10,10 +10,10 @@
namespace Web::ContentSecurityPolicy::Directives {
GC::Ref<Directive> create_directive(JS::Realm& realm, String name, Vector<String> value)
GC::Ref<Directive> create_directive(GC::Heap& heap, String name, Vector<String> value)
{
dbgln("Potential FIXME: Creating unknown Content Security Policy directive: {}", name);
return realm.create<Directive>(move(name), move(value));
return heap.allocate<Directive>(move(name), move(value));
}
}

View file

@ -8,11 +8,12 @@
#include <AK/String.h>
#include <AK/Vector.h>
#include <LibGC/Forward.h>
#include <LibGC/Ptr.h>
#include <LibWeb/Forward.h>
namespace Web::ContentSecurityPolicy::Directives {
[[nodiscard]] GC::Ref<Directive> create_directive(JS::Realm&, String name, Vector<String> value);
[[nodiscard]] GC::Ref<Directive> create_directive(GC::Heap&, String name, Vector<String> value);
}

View file

@ -21,7 +21,7 @@ namespace Web::ContentSecurityPolicy {
GC_DEFINE_ALLOCATOR(Policy);
// https://w3c.github.io/webappsec-csp/#abstract-opdef-parse-a-serialized-csp
GC::Ref<Policy> Policy::parse_a_serialized_csp(JS::Realm& realm, Variant<ByteBuffer, String> serialized, Source source, Disposition disposition)
GC::Ref<Policy> Policy::parse_a_serialized_csp(GC::Heap& heap, Variant<ByteBuffer, String> serialized, Source source, Disposition disposition)
{
// To parse a serialized CSP, given a byte sequence or string serialized, a source source, and a disposition disposition,
// execute the following steps.
@ -34,14 +34,14 @@ GC::Ref<Policy> Policy::parse_a_serialized_csp(JS::Realm& realm, Variant<ByteBuf
: Infra::isomorphic_decode(serialized.get<ByteBuffer>());
// 2. Let policy be a new policy with an empty directive set, a source of source, and a disposition of disposition.
auto policy = realm.create<Policy>();
auto policy = heap.allocate<Policy>();
policy->m_pre_parsed_policy_string = serialized_string;
policy->m_source = source;
policy->m_disposition = disposition;
// 3. For each token returned by strictly splitting serialized on the U+003B SEMICOLON character (;):
auto tokens = MUST(serialized_string.split(';', SplitBehavior::KeepEmpty));
for (auto token : tokens) {
for (auto const& token : tokens) {
// 1. Strip leading and trailing ASCII whitespace from token.
auto stripped_token = MUST(token.trim(Infra::ASCII_WHITESPACE));
auto stripped_token_view = stripped_token.bytes_as_string_view();
@ -79,7 +79,7 @@ GC::Ref<Policy> Policy::parse_a_serialized_csp(JS::Realm& realm, Variant<ByteBuf
}
// 7. Let directive be a new directive whose name is directive name, and value is directive value.
auto directive = Directives::create_directive(realm, move(lowercase_directive_name), move(directive_value));
auto directive = Directives::create_directive(heap, move(lowercase_directive_name), move(directive_value));
// 8. Append directive to policys directive set.
policy->m_directives.append(directive);
@ -90,22 +90,22 @@ GC::Ref<Policy> Policy::parse_a_serialized_csp(JS::Realm& realm, Variant<ByteBuf
}
// https://w3c.github.io/webappsec-csp/#abstract-opdef-parse-a-responses-content-security-policies
GC::Ref<PolicyList> Policy::parse_a_responses_content_security_policies(JS::Realm& realm, GC::Ref<Fetch::Infrastructure::Response const> response)
GC::Ref<PolicyList> Policy::parse_a_responses_content_security_policies(GC::Heap& heap, GC::Ref<Fetch::Infrastructure::Response const> response)
{
// To parse a responses Content Security Policies given a response response, execute the following steps.
// This algorithm returns a list of Content Security Policy objects. If the policies cannot be parsed,
// the returned list will be empty.
// 1. Let policies be an empty list.
GC::RootVector<GC::Ref<Policy>> policies(realm.heap());
GC::RootVector<GC::Ref<Policy>> policies(heap);
// 2. For each token returned by extracting header list values given Content-Security-Policy and responses header
// list:
auto enforce_policy_tokens_or_failure = Fetch::Infrastructure::extract_header_list_values("Content-Security-Policy"sv.bytes(), response->header_list());
auto enforce_policy_tokens = enforce_policy_tokens_or_failure.has<Vector<ByteBuffer>>() ? enforce_policy_tokens_or_failure.get<Vector<ByteBuffer>>() : Vector<ByteBuffer> {};
for (auto enforce_policy_token : enforce_policy_tokens) {
for (auto const& enforce_policy_token : enforce_policy_tokens) {
// 1. Let policy be the result of parsing token, with a source of "header", and a disposition of "enforce".
auto policy = parse_a_serialized_csp(realm, enforce_policy_token, Policy::Source::Header, Policy::Disposition::Enforce);
auto policy = parse_a_serialized_csp(heap, enforce_policy_token, Policy::Source::Header, Policy::Disposition::Enforce);
// 2. If policys directive set is not empty, append policy to policies.
if (!policy->m_directives.is_empty()) {
@ -117,9 +117,9 @@ GC::Ref<PolicyList> Policy::parse_a_responses_content_security_policies(JS::Real
// responses header list:
auto report_policy_tokens_or_failure = Fetch::Infrastructure::extract_header_list_values("Content-Security-Policy-Report-Only"sv.bytes(), response->header_list());
auto report_policy_tokens = report_policy_tokens_or_failure.has<Vector<ByteBuffer>>() ? report_policy_tokens_or_failure.get<Vector<ByteBuffer>>() : Vector<ByteBuffer> {};
for (auto report_policy_token : report_policy_tokens) {
for (auto const& report_policy_token : report_policy_tokens) {
// 1. Let policy be the result of parsing token, with a source of "header", and a disposition of "report".
auto policy = parse_a_serialized_csp(realm, report_policy_token, Policy::Source::Header, Policy::Disposition::Report);
auto policy = parse_a_serialized_csp(heap, report_policy_token, Policy::Source::Header, Policy::Disposition::Report);
// 2. If policys directive set is not empty, append policy to policies.
if (!policy->m_directives.is_empty()) {
@ -134,15 +134,15 @@ GC::Ref<PolicyList> Policy::parse_a_responses_content_security_policies(JS::Real
}
// 5. Return policies.
return PolicyList::create(realm, policies);
return PolicyList::create(heap, policies);
}
GC::Ref<Policy> Policy::create_from_serialized_policy(JS::Realm& realm, SerializedPolicy const& serialized_policy)
GC::Ref<Policy> Policy::create_from_serialized_policy(GC::Heap& heap, SerializedPolicy const& serialized_policy)
{
auto policy = realm.create<Policy>();
auto policy = heap.allocate<Policy>();
for (auto const& serialized_directive : serialized_policy.directives) {
auto directive = Directives::create_directive(realm, serialized_directive.name, serialized_directive.value);
auto directive = Directives::create_directive(heap, serialized_directive.name, serialized_directive.value);
policy->m_directives.append(directive);
}
@ -173,12 +173,12 @@ GC::Ptr<Directives::Directive> Policy::get_directive_by_name(StringView name) co
return nullptr;
}
GC::Ref<Policy> Policy::clone(JS::Realm& realm) const
GC::Ref<Policy> Policy::clone(GC::Heap& heap) const
{
auto policy = realm.create<Policy>();
auto policy = heap.allocate<Policy>();
for (auto directive : m_directives) {
auto cloned_directive = directive->clone(realm);
auto cloned_directive = directive->clone(heap);
policy->m_directives.append(cloned_directive);
}

View file

@ -20,8 +20,8 @@ namespace Web::ContentSecurityPolicy {
// https://w3c.github.io/webappsec-csp/#content-security-policy-object
// A policy defines allowed and restricted behaviors, and may be applied to a Document, WorkerGlobalScope,
// or WorkletGlobalScope.
class Policy final : public JS::Cell {
GC_CELL(Policy, JS::Cell);
class Policy final : public GC::Cell {
GC_CELL(Policy, GC::Cell);
GC_DECLARE_ALLOCATOR(Policy);
public:
@ -38,9 +38,9 @@ public:
~Policy() = default;
[[nodiscard]] static GC::Ref<Policy> parse_a_serialized_csp(JS::Realm&, Variant<ByteBuffer, String> serialized, Source source, Disposition disposition);
[[nodiscard]] static GC::Ref<PolicyList> parse_a_responses_content_security_policies(JS::Realm&, GC::Ref<Fetch::Infrastructure::Response const> response);
[[nodiscard]] static GC::Ref<Policy> create_from_serialized_policy(JS::Realm&, SerializedPolicy const&);
[[nodiscard]] static GC::Ref<Policy> parse_a_serialized_csp(GC::Heap&, Variant<ByteBuffer, String> serialized, Source source, Disposition disposition);
[[nodiscard]] static GC::Ref<PolicyList> parse_a_responses_content_security_policies(GC::Heap&, GC::Ref<Fetch::Infrastructure::Response const> response);
[[nodiscard]] static GC::Ref<Policy> create_from_serialized_policy(GC::Heap&, SerializedPolicy const&);
[[nodiscard]] Vector<GC::Ref<Directives::Directive>> const& directives() const { return m_directives; }
[[nodiscard]] Disposition disposition() const { return m_disposition; }
@ -51,7 +51,7 @@ public:
[[nodiscard]] bool contains_directive_with_name(StringView name) const;
[[nodiscard]] GC::Ptr<Directives::Directive> get_directive_by_name(StringView) const;
[[nodiscard]] GC::Ref<Policy> clone(JS::Realm&) const;
[[nodiscard]] GC::Ref<Policy> clone(GC::Heap&) const;
[[nodiscard]] SerializedPolicy serialize() const;
protected:

View file

@ -18,19 +18,19 @@ namespace Web::ContentSecurityPolicy {
GC_DEFINE_ALLOCATOR(PolicyList);
GC::Ref<PolicyList> PolicyList::create(JS::Realm& realm, GC::RootVector<GC::Ref<Policy>> const& policies)
GC::Ref<PolicyList> PolicyList::create(GC::Heap& heap, GC::RootVector<GC::Ref<Policy>> const& policies)
{
auto policy_list = realm.create<PolicyList>();
auto policy_list = heap.allocate<PolicyList>();
for (auto policy : policies)
policy_list->m_policies.append(policy);
return policy_list;
}
GC::Ref<PolicyList> PolicyList::create(JS::Realm& realm, Vector<SerializedPolicy> const& serialized_policies)
GC::Ref<PolicyList> PolicyList::create(GC::Heap& heap, Vector<SerializedPolicy> const& serialized_policies)
{
auto policy_list = realm.create<PolicyList>();
auto policy_list = heap.allocate<PolicyList>();
for (auto const& serialized_policy : serialized_policies) {
auto policy = Policy::create_from_serialized_policy(realm, serialized_policy);
auto policy = Policy::create_from_serialized_policy(heap, serialized_policy);
policy_list->m_policies.append(policy);
}
return policy_list;
@ -79,11 +79,11 @@ HTML::SandboxingFlagSet PolicyList::csp_derived_sandboxing_flags() const
return HTML::SandboxingFlagSet {};
}
GC::Ref<PolicyList> PolicyList::clone(JS::Realm& realm) const
GC::Ref<PolicyList> PolicyList::clone(GC::Heap& heap) const
{
auto policy_list = realm.create<PolicyList>();
auto policy_list = heap.allocate<PolicyList>();
for (auto policy : m_policies) {
auto cloned_policy = policy->clone(realm);
auto cloned_policy = policy->clone(heap);
policy_list->m_policies.append(cloned_policy);
}
return policy_list;

View file

@ -12,13 +12,13 @@
namespace Web::ContentSecurityPolicy {
class PolicyList final : public JS::Cell {
GC_CELL(PolicyList, JS::Cell);
class PolicyList final : public GC::Cell {
GC_CELL(PolicyList, GC::Cell);
GC_DECLARE_ALLOCATOR(PolicyList);
public:
[[nodiscard]] static GC::Ref<PolicyList> create(JS::Realm&, GC::RootVector<GC::Ref<Policy>> const&);
[[nodiscard]] static GC::Ref<PolicyList> create(JS::Realm&, Vector<SerializedPolicy> const&);
[[nodiscard]] static GC::Ref<PolicyList> create(GC::Heap&, GC::RootVector<GC::Ref<Policy>> const&);
[[nodiscard]] static GC::Ref<PolicyList> create(GC::Heap&, Vector<SerializedPolicy> const&);
[[nodiscard]] static GC::Ptr<PolicyList> from_object(JS::Object&);
virtual ~PolicyList() = default;
@ -29,7 +29,7 @@ public:
[[nodiscard]] HTML::SandboxingFlagSet csp_derived_sandboxing_flags() const;
[[nodiscard]] GC::Ref<PolicyList> clone(JS::Realm&) const;
[[nodiscard]] GC::Ref<PolicyList> clone(GC::Heap&) const;
[[nodiscard]] Vector<SerializedPolicy> serialize() const;
protected:

View file

@ -3858,9 +3858,9 @@ void Document::set_active_sandboxing_flag_set(HTML::SandboxingFlagSet sandboxing
GC::Ref<HTML::PolicyContainer> Document::policy_container() const
{
auto& realm = this->realm();
auto& heap = this->heap();
if (!m_policy_container) {
m_policy_container = realm.create<HTML::PolicyContainer>(realm);
m_policy_container = heap.allocate<HTML::PolicyContainer>(heap);
}
return *m_policy_container;
}
@ -3873,10 +3873,8 @@ void Document::set_policy_container(GC::Ref<HTML::PolicyContainer> policy_contai
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#snapshotting-source-snapshot-params
GC::Ref<HTML::SourceSnapshotParams> Document::snapshot_source_snapshot_params() const
{
auto& realm = this->realm();
// To snapshot source snapshot params given a Document sourceDocument, return a new source snapshot params with
return realm.create<HTML::SourceSnapshotParams>(
return heap().allocate<HTML::SourceSnapshotParams>(
// has transient activation
// true if sourceDocument's relevant global object has transient activation; otherwise false
as<HTML::Window>(HTML::relevant_global_object(*this)).has_transient_activation(),
@ -3895,7 +3893,7 @@ GC::Ref<HTML::SourceSnapshotParams> Document::snapshot_source_snapshot_params()
// source policy container
// a clone of sourceDocument's policy container
policy_container()->clone(realm));
policy_container()->clone(heap()));
}
// https://html.spec.whatwg.org/multipage/document-sequences.html#descendant-navigables

View file

@ -22,7 +22,6 @@ GC::Ref<DOM::Document> create_document_for_inline_content(GC::Ptr<HTML::Navigabl
{
auto& vm = navigable->vm();
VERIFY(navigable->active_document());
auto& realm = navigable->active_document()->realm();
// 1. Let origin be a new opaque origin.
URL::Origin origin {};
@ -59,7 +58,7 @@ GC::Ref<DOM::Document> create_document_for_inline_content(GC::Ptr<HTML::Navigabl
auto response = Fetch::Infrastructure::Response::create(vm);
response->url_list().append(URL::about_error()); // AD-HOC: https://github.com/whatwg/html/issues/9122
auto navigation_params = vm.heap().allocate<HTML::NavigationParams>();
navigation_params->id = navigation_id;
navigation_params->id = move(navigation_id);
navigation_params->navigable = navigable;
navigation_params->request = nullptr;
navigation_params->response = response;
@ -68,7 +67,7 @@ GC::Ref<DOM::Document> create_document_for_inline_content(GC::Ptr<HTML::Navigabl
navigation_params->coop_enforcement_result = move(coop_enforcement_result);
navigation_params->reserved_environment = {};
navigation_params->origin = move(origin);
navigation_params->policy_container = vm.heap().allocate<HTML::PolicyContainer>(realm);
navigation_params->policy_container = vm.heap().allocate<HTML::PolicyContainer>(vm.heap());
navigation_params->final_sandboxing_flag_set = HTML::SandboxingFlagSet {};
navigation_params->opener_policy = move(coop);
navigation_params->about_base_url = {};

View file

@ -83,6 +83,7 @@ WebIDL::ExceptionOr<GC::Ref<Infrastructure::FetchController>> fetch(JS::Realm& r
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Running 'fetch' with: request @ {}", &request);
auto& vm = realm.vm();
auto& heap = vm.heap();
// 1. Assert: requests mode is "navigate" or processEarlyHintsResponse is null.
VERIFY(request.mode() == Infrastructure::Request::Mode::Navigate || !algorithms.process_early_hints_response());
@ -185,10 +186,10 @@ WebIDL::ExceptionOr<GC::Ref<Infrastructure::FetchController>> fetch(JS::Realm& r
// 1. If requests client is non-null, then set requests policy container to a clone of requests clients
// policy container.
if (request.client() != nullptr)
request.set_policy_container(request.client()->policy_container()->clone(realm));
request.set_policy_container(request.client()->policy_container()->clone(heap));
// 2. Otherwise, set requests policy container to a new policy container.
else
request.set_policy_container(realm.create<HTML::PolicyContainer>(realm));
request.set_policy_container(heap.allocate<HTML::PolicyContainer>(heap));
}
// 13. If requests header list does not contain `Accept`, then:

View file

@ -251,7 +251,7 @@ WebIDL::ExceptionOr<BrowsingContext::BrowsingContextAndDocument> BrowsingContext
document->set_referrer(creator->url().serialize());
// 2. Set document's policy container to a clone of creator's policy container.
document->set_policy_container(creator->policy_container()->clone(document->realm()));
document->set_policy_container(creator->policy_container()->clone(document->heap()));
// 3. If creator's origin is same origin with creator's relevant settings object's top-level origin,
if (creator->origin().is_same_origin(creator->relevant_settings_object().top_level_origin)) {

View file

@ -621,7 +621,7 @@ Vector<GC::Ref<SessionHistoryEntry>>& Navigable::get_session_history_entries() c
// https://html.spec.whatwg.org/multipage/browsers.html#determining-navigation-params-policy-container
static GC::Ref<PolicyContainer> determine_navigation_params_policy_container(URL::URL const& response_url,
JS::Realm& realm,
GC::Heap& heap,
GC::Ptr<PolicyContainer> history_policy_container,
GC::Ptr<PolicyContainer> initiator_policy_container,
GC::Ptr<PolicyContainer> parent_policy_container,
@ -632,7 +632,7 @@ static GC::Ref<PolicyContainer> determine_navigation_params_policy_container(URL
// FIXME: 1. Assert: responseURL requires storing the policy container in history.
// 2. Return a clone of historyPolicyContainer.
return history_policy_container->clone(realm);
return history_policy_container->clone(heap);
}
// 2. If responseURL is about:srcdoc, then:
@ -641,20 +641,20 @@ static GC::Ref<PolicyContainer> determine_navigation_params_policy_container(URL
VERIFY(parent_policy_container);
// 2. Return a clone of parentPolicyContainer.
return parent_policy_container->clone(realm);
return parent_policy_container->clone(heap);
}
// 3. If responseURL is local and initiatorPolicyContainer is not null, then return a clone of initiatorPolicyContainer.
if (Fetch::Infrastructure::is_local_url(response_url) && initiator_policy_container)
return initiator_policy_container->clone(realm);
return initiator_policy_container->clone(heap);
// 4. If responsePolicyContainer is not null, then return responsePolicyContainer.
// FIXME: File a spec issue to say "a clone of" here for consistency
if (response_policy_container)
return response_policy_container->clone(realm);
return response_policy_container->clone(heap);
// 5. Return a new policy container.
return realm.create<PolicyContainer>(realm);
return heap.allocate<PolicyContainer>(heap);
}
// https://html.spec.whatwg.org/multipage/browsers.html#obtain-coop
@ -743,9 +743,9 @@ static GC::Ref<NavigationParams> create_navigation_params_from_a_srcdoc_resource
// NOTE: Specification assumes that only navigables corresponding to iframes can be navigated to about:srcdoc.
// We also use srcdoc to implement load_html() for top level navigables so we need to null check container
// because it might be null.
policy_container = determine_navigation_params_policy_container(*response->url(), realm, history_policy_container, {}, navigable->container_document()->policy_container(), {});
policy_container = determine_navigation_params_policy_container(*response->url(), realm.heap(), history_policy_container, {}, navigable->container_document()->policy_container(), {});
} else {
policy_container = realm.create<PolicyContainer>(realm);
policy_container = realm.heap().allocate<PolicyContainer>(realm.heap());
}
// 7. Return a new navigation params, with
@ -1036,7 +1036,7 @@ static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation
}
// 9. Set responsePolicyContainer to the result of creating a policy container from a fetch response given response and request's reserved client.
response_policy_container = create_a_policy_container_from_a_fetch_response(realm, *response_holder->response(), request->reserved_client());
response_policy_container = create_a_policy_container_from_a_fetch_response(realm.heap(), *response_holder->response(), request->reserved_client());
// 10. Set finalSandboxFlags to the union of targetSnapshotParams's sandboxing flags and responsePolicyContainer's CSP list's CSP-derived sandboxing flags.
final_sandbox_flags = target_snapshot_params.sandboxing_flags | response_policy_container->csp_list->csp_derived_sandboxing_flags();
@ -1156,7 +1156,7 @@ static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation
GC::Ptr<PolicyContainer> history_policy_container = entry->document_state()->history_policy_container().visit(
[](GC::Ref<PolicyContainer> const& c) -> GC::Ptr<PolicyContainer> { return c; },
[](DocumentState::Client) -> GC::Ptr<PolicyContainer> { return {}; });
auto result_policy_container = determine_navigation_params_policy_container(*response_holder->response()->url(), realm, history_policy_container, source_snapshot_params.source_policy_container, {}, response_policy_container);
auto result_policy_container = determine_navigation_params_policy_container(*response_holder->response()->url(), realm.heap(), history_policy_container, source_snapshot_params.source_policy_container, {}, response_policy_container);
// 24. If navigable's container is an iframe, and response's timing allow passed flag is set, then set container's pending resource-timing start time to null.
if (navigable->container() && is<HTML::HTMLIFrameElement>(*navigable->container()) && response_holder->response()->timing_allow_passed())

View file

@ -28,8 +28,8 @@ enum class UserNavigationInvolvement {
};
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigation-params
struct NavigationParams : JS::Cell {
GC_CELL(NavigationParams, JS::Cell);
struct NavigationParams : GC::Cell {
GC_CELL(NavigationParams, GC::Cell);
GC_DECLARE_ALLOCATOR(NavigationParams);
// null or a navigation ID

View file

@ -18,8 +18,8 @@ namespace Web::HTML {
GC_DEFINE_ALLOCATOR(PolicyContainer);
PolicyContainer::PolicyContainer(JS::Realm& realm)
: csp_list(realm.create<ContentSecurityPolicy::PolicyList>())
PolicyContainer::PolicyContainer(GC::Heap& heap)
: csp_list(heap.allocate<ContentSecurityPolicy::PolicyList>())
{
}
@ -36,16 +36,16 @@ bool url_requires_storing_the_policy_container_in_history(URL::URL const& url)
}
// https://html.spec.whatwg.org/multipage/browsers.html#creating-a-policy-container-from-a-fetch-response
GC::Ref<PolicyContainer> create_a_policy_container_from_a_fetch_response(JS::Realm& realm, GC::Ref<Fetch::Infrastructure::Response const> response, GC::Ptr<Environment>)
GC::Ref<PolicyContainer> create_a_policy_container_from_a_fetch_response(GC::Heap& heap, GC::Ref<Fetch::Infrastructure::Response const> response, GC::Ptr<Environment>)
{
// FIXME: 1. If response's URL's scheme is "blob", then return a clone of response's URL's blob URL entry's
// environment's policy container.
// 2. Let result be a new policy container.
GC::Ref<PolicyContainer> result = realm.create<PolicyContainer>(realm);
GC::Ref<PolicyContainer> result = heap.allocate<PolicyContainer>(heap);
// 3. Set result's CSP list to the result of parsing a response's Content Security Policies given response.
result->csp_list = ContentSecurityPolicy::Policy::parse_a_responses_content_security_policies(realm, response);
result->csp_list = ContentSecurityPolicy::Policy::parse_a_responses_content_security_policies(heap, response);
// FIXME: 4. If environment is non-null, then set result's embedder policy to the result of obtaining an embedder
// policy given response and environment. Otherwise, set it to "unsafe-none".
@ -58,23 +58,23 @@ GC::Ref<PolicyContainer> create_a_policy_container_from_a_fetch_response(JS::Rea
return result;
}
GC::Ref<PolicyContainer> create_a_policy_container_from_serialized_policy_container(JS::Realm& realm, SerializedPolicyContainer const& serialized_policy_container)
GC::Ref<PolicyContainer> create_a_policy_container_from_serialized_policy_container(GC::Heap& heap, SerializedPolicyContainer const& serialized_policy_container)
{
GC::Ref<PolicyContainer> result = realm.create<PolicyContainer>(realm);
result->csp_list = ContentSecurityPolicy::PolicyList::create(realm, serialized_policy_container.csp_list);
GC::Ref<PolicyContainer> result = heap.allocate<PolicyContainer>(heap);
result->csp_list = ContentSecurityPolicy::PolicyList::create(heap, serialized_policy_container.csp_list);
result->embedder_policy = serialized_policy_container.embedder_policy;
result->referrer_policy = serialized_policy_container.referrer_policy;
return result;
}
// https://html.spec.whatwg.org/multipage/browsers.html#clone-a-policy-container
GC::Ref<PolicyContainer> PolicyContainer::clone(JS::Realm& realm) const
GC::Ref<PolicyContainer> PolicyContainer::clone(GC::Heap& heap) const
{
// 1. Let clone be a new policy container.
auto clone = realm.create<PolicyContainer>(realm);
auto clone = heap.allocate<PolicyContainer>(heap);
// 2. For each policy in policyContainer's CSP list, append a copy of policy into clone's CSP list.
clone->csp_list = csp_list->clone(realm);
clone->csp_list = csp_list->clone(heap);
// 3. Set clone's embedder policy to a copy of policyContainer's embedder policy.
// NOTE: This is a C++ copy.

View file

@ -18,8 +18,8 @@ namespace Web::HTML {
// https://html.spec.whatwg.org/multipage/origin.html#policy-container
// A policy container is a struct containing policies that apply to a Document, a WorkerGlobalScope, or a WorkletGlobalScope. It has the following items:
struct PolicyContainer : public JS::Cell {
GC_CELL(PolicyContainer, JS::Cell)
struct PolicyContainer : public GC::Cell {
GC_CELL(PolicyContainer, GC::Cell)
GC_DECLARE_ALLOCATOR(PolicyContainer);
public:
@ -37,22 +37,22 @@ public:
// A referrer policy, which is a referrer policy. It is initially the default referrer policy.
ReferrerPolicy::ReferrerPolicy referrer_policy { ReferrerPolicy::DEFAULT_REFERRER_POLICY };
[[nodiscard]] GC::Ref<PolicyContainer> clone(JS::Realm&) const;
[[nodiscard]] GC::Ref<PolicyContainer> clone(GC::Heap&) const;
[[nodiscard]] SerializedPolicyContainer serialize() const;
protected:
virtual void visit_edges(Cell::Visitor&) override;
private:
PolicyContainer(JS::Realm&);
PolicyContainer(GC::Heap&);
};
// https://html.spec.whatwg.org/multipage/browsers.html#requires-storing-the-policy-container-in-history
[[nodiscard]] bool url_requires_storing_the_policy_container_in_history(URL::URL const& url);
// https://html.spec.whatwg.org/multipage/browsers.html#creating-a-policy-container-from-a-fetch-response
[[nodiscard]] GC::Ref<PolicyContainer> create_a_policy_container_from_a_fetch_response(JS::Realm&, GC::Ref<Fetch::Infrastructure::Response const> response, GC::Ptr<Environment> environment);
[[nodiscard]] GC::Ref<PolicyContainer> create_a_policy_container_from_a_fetch_response(GC::Heap&, GC::Ref<Fetch::Infrastructure::Response const> response, GC::Ptr<Environment> environment);
[[nodiscard]] GC::Ref<PolicyContainer> create_a_policy_container_from_serialized_policy_container(JS::Realm&, SerializedPolicyContainer const&);
[[nodiscard]] GC::Ref<PolicyContainer> create_a_policy_container_from_serialized_policy_container(GC::Heap&, SerializedPolicyContainer const&);
}

View file

@ -15,7 +15,7 @@ EnvironmentSettingsSnapshot::EnvironmentSettingsSnapshot(JS::Realm& realm, Nonnu
, m_api_url_character_encoding(serialized_settings.api_url_character_encoding)
, m_url(serialized_settings.api_base_url)
, m_origin(serialized_settings.origin)
, m_policy_container(create_a_policy_container_from_serialized_policy_container(realm, serialized_settings.policy_container))
, m_policy_container(create_a_policy_container_from_serialized_policy_container(realm.heap(), serialized_settings.policy_container))
, m_time_origin(serialized_settings.time_origin)
{
// Why can't we put these in the init list? grandparent class members are strange it seems

View file

@ -13,8 +13,8 @@
namespace Web::HTML {
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#source-snapshot-params
struct SourceSnapshotParams : public JS::Cell {
GC_CELL(SourceSnapshotParams, JS::Cell)
struct SourceSnapshotParams : public GC::Cell {
GC_CELL(SourceSnapshotParams, GC::Cell)
GC_DECLARE_ALLOCATOR(SourceSnapshotParams);
public:

View file

@ -173,9 +173,9 @@ GC::Ref<CSS::FontFaceSet> WorkerGlobalScope::fonts()
GC::Ref<PolicyContainer> WorkerGlobalScope::policy_container() const
{
auto& realm = this->realm();
auto& heap = this->heap();
if (!m_policy_container) {
m_policy_container = realm.create<PolicyContainer>(realm);
m_policy_container = heap.allocate<PolicyContainer>(heap);
}
return *m_policy_container;
}
@ -195,7 +195,7 @@ void WorkerGlobalScope::initialize_policy_container(GC::Ref<Fetch::Infrastructur
// 2. Otherwise, set workerGlobalScope's policy container to the result of creating a policy container from a fetch
// response given response and environment.
m_policy_container = create_a_policy_container_from_a_fetch_response(realm, response, environment);
m_policy_container = create_a_policy_container_from_a_fetch_response(realm.heap(), response, environment);
}
// https://w3c.github.io/webappsec-csp/#run-global-object-csp-initialization

View file

@ -41,7 +41,7 @@ ErrorOr<GC::Ref<SVGDecodedImageData>> SVGDecodedImageData::create(JS::Realm& rea
navigation_params->navigable = navigable;
navigation_params->response = response;
navigation_params->origin = URL::Origin {};
navigation_params->policy_container = navigable->heap().allocate<HTML::PolicyContainer>(navigable->active_document()->realm());
navigation_params->policy_container = navigable->heap().allocate<HTML::PolicyContainer>(realm.heap());
navigation_params->final_sandboxing_flag_set = HTML::SandboxingFlagSet {};
navigation_params->opener_policy = HTML::OpenerPolicy {};