Enable -Wexit-time-destructors for all in-tree library targets and update process-lifetime library statics so they no longer register exit-time destructors. Long-lived caches, lookup tables, singleton registries, and generated constants now use NeverDestroyed or leaked references where the data is intended to live until process exit. Update LibWeb, LibLine, and the binding generators so regenerated sources follow the same rule instead of reintroducing destructed statics.
98 lines
3.3 KiB
C++
98 lines
3.3 KiB
C++
/*
|
||
* Copyright (c) 2023-2025, Tim Flynn <trflynn89@ladybird.org>
|
||
*
|
||
* SPDX-License-Identifier: BSD-2-Clause
|
||
*/
|
||
|
||
#include <AK/String.h>
|
||
#include <LibURL/Origin.h>
|
||
#include <LibURL/Parser.h>
|
||
#include <LibURL/URL.h>
|
||
#include <LibWeb/DOM/Document.h>
|
||
#include <LibWeb/DOMURL/DOMURL.h>
|
||
#include <LibWeb/PermissionsPolicy/AutoplayAllowlist.h>
|
||
|
||
// FIXME: This is an ad-hoc implementation of the "autoplay" policy-controlled feature:
|
||
// https://w3c.github.io/webappsec-permissions-policy/#policy-controlled-feature
|
||
|
||
namespace Web::PermissionsPolicy {
|
||
|
||
AutoplayAllowlist& AutoplayAllowlist::the()
|
||
{
|
||
static auto& filter = *new AutoplayAllowlist;
|
||
return filter;
|
||
}
|
||
|
||
AutoplayAllowlist::AutoplayAllowlist() = default;
|
||
AutoplayAllowlist::~AutoplayAllowlist() = default;
|
||
|
||
// https://w3c.github.io/webappsec-permissions-policy/#is-feature-enabled
|
||
Decision AutoplayAllowlist::is_allowed_for_origin(DOM::Document const& document, URL::Origin const& origin) const
|
||
{
|
||
// FIXME: 1. Let policy be document’s Permissions Policy
|
||
// FIXME: 2. If policy’s inherited policy for feature is Disabled, return "Disabled".
|
||
|
||
// 3. If feature is present in policy’s declared policy:
|
||
if (m_allowlist.has_value()) {
|
||
// 1. If the allowlist for feature in policy’s declared policy matches origin, then return "Enabled".
|
||
// 2. Otherwise return "Disabled".
|
||
return m_allowlist->visit(
|
||
[](Global) {
|
||
return Decision::Enabled;
|
||
},
|
||
[&](auto const& patterns) {
|
||
for (auto const& pattern : patterns) {
|
||
if (pattern.is_same_origin_domain(origin))
|
||
return Decision::Enabled;
|
||
|
||
// AD-HOC: Allow autoplay for file:// URLs if the document is also from a file:// URL.
|
||
if (origin.is_opaque_file_origin() && document.origin().is_opaque_file_origin())
|
||
return Decision::Enabled;
|
||
}
|
||
|
||
return Decision::Disabled;
|
||
});
|
||
}
|
||
|
||
// 4. If feature’s default allowlist is *, return "Enabled".
|
||
// 5. If feature’s default allowlist is 'self', and origin is same origin with document’s origin, return "Enabled".
|
||
// NOTE: The "autoplay" feature's default allowlist is 'self'.
|
||
// https://html.spec.whatwg.org/multipage/infrastructure.html#autoplay-feature
|
||
if (origin.is_same_origin(document.origin()))
|
||
return Decision::Enabled;
|
||
|
||
// AD-HOC: Allow autoplay for file:// URLs if the document is also from a file:// URL.
|
||
if (origin.is_opaque_file_origin() && document.origin().is_opaque_file_origin())
|
||
return Decision::Enabled;
|
||
|
||
// 6. Return "Disabled".
|
||
return Decision::Disabled;
|
||
}
|
||
|
||
void AutoplayAllowlist::enable_globally()
|
||
{
|
||
m_allowlist = Global {};
|
||
}
|
||
|
||
void AutoplayAllowlist::enable_for_origins(ReadonlySpan<String> origins)
|
||
{
|
||
m_allowlist = Patterns {};
|
||
|
||
auto& allowlist = m_allowlist->get<Patterns>();
|
||
allowlist.ensure_capacity(origins.size());
|
||
|
||
for (auto const& origin : origins) {
|
||
auto url = URL::Parser::basic_parse(origin);
|
||
|
||
if (!url.has_value())
|
||
url = URL::Parser::basic_parse(MUST(String::formatted("https://{}", origin)));
|
||
if (!url.has_value()) {
|
||
dbgln("Invalid origin for autoplay allowlist: {}", origin);
|
||
continue;
|
||
}
|
||
|
||
allowlist.append(url->origin());
|
||
}
|
||
}
|
||
|
||
}
|