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

@ -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