LibWeb: Implement create_policy function for TrustedTypePolicyFactory

It simply consists of a wrapper around the main algorithm
This commit is contained in:
Tete17 2025-07-31 09:30:53 +02:00 committed by Luke Wilde
commit 6398e771a3
Notes: github-actions[bot] 2025-08-11 11:23:34 +00:00
5 changed files with 85 additions and 5 deletions

View file

@ -9,13 +9,16 @@
#include <LibGC/Ptr.h>
#include <LibJS/Runtime/Realm.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web::TrustedTypes {
GC_DEFINE_ALLOCATOR(TrustedTypePolicy);
TrustedTypePolicy::TrustedTypePolicy(JS::Realm& realm)
TrustedTypePolicy::TrustedTypePolicy(JS::Realm& realm, String const& name, TrustedTypePolicyOptions const& options)
: PlatformObject(realm)
, m_name(name)
, m_options(options)
{
}

View file

@ -26,8 +26,11 @@ public:
virtual ~TrustedTypePolicy() override = default;
private:
explicit TrustedTypePolicy(JS::Realm&);
explicit TrustedTypePolicy(JS::Realm&, String const&, TrustedTypePolicyOptions const&);
virtual void initialize(JS::Realm&) override;
String const m_name;
TrustedTypePolicyOptions const m_options;
};
}

View file

@ -9,13 +9,19 @@
#include <LibGC/Ptr.h>
#include <LibJS/Runtime/Realm.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/ContentSecurityPolicy/Directives/Directive.h>
#include <LibWeb/ContentSecurityPolicy/Directives/Names.h>
#include <LibWeb/ContentSecurityPolicy/PolicyList.h>
#include <LibWeb/HTML/AttributeNames.h>
#include <LibWeb/HTML/GlobalEventHandlers.h>
#include <LibWeb/HTML/Scripting/Environments.h>
#include <LibWeb/HTML/TagNames.h>
#include <LibWeb/HTML/WindowEventHandlers.h>
#include <LibWeb/Namespace.h>
#include <LibWeb/SVG/TagNames.h>
#include <LibWeb/TrustedTypes/TrustedHTML.h>
#include <LibWeb/TrustedTypes/TrustedTypePolicy.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web::TrustedTypes {
@ -133,6 +139,23 @@ void TrustedTypePolicyFactory::initialize(JS::Realm& realm)
Base::initialize(realm);
}
void TrustedTypePolicyFactory::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_default_policy);
}
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-createpolicy
WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> TrustedTypePolicyFactory::create_policy(String const& policy_name, TrustedTypePolicyOptions const& policy_options)
{
// 1. Returns the result of executing a Create a Trusted Type Policy algorithm, with the following arguments:
// factory: this value
// policyName: policyName
// options: policyOptions
// global: this values relevant global object
return create_a_trusted_type_policy(policy_name, policy_options, HTML::relevant_global_object(*this));
}
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-ishtml
bool TrustedTypePolicyFactory::is_html(JS::Value value)
{
@ -140,6 +163,39 @@ bool TrustedTypePolicyFactory::is_html(JS::Value value)
return value.is_object() && is<TrustedHTML>(value.as_object());
}
// https://w3c.github.io/trusted-types/dist/spec/#create-trusted-type-policy-algorithm
WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> TrustedTypePolicyFactory::create_a_trusted_type_policy(String const& policy_name, TrustedTypePolicyOptions const& options, JS::Object&)
{
auto& realm = this->realm();
// TODO
// 1. Let allowedByCSP be the result of executing Should Trusted Type policy creation be blocked by Content Security Policy? algorithm with global, policyName and factorys created policy names value.
auto const allowed_by_csp = ContentSecurityPolicy::Directives::Directive::Result::Blocked;
// 2. If allowedByCSP is "Blocked", throw a TypeError and abort further steps.
if (allowed_by_csp == ContentSecurityPolicy::Directives::Directive::Result::Blocked)
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, MUST(String::formatted("Content Security Policy blocked the creation of the policy {}", policy_name)) };
// 3. If policyName is default and the factorys default policy value is not null, throw a TypeError and abort further steps.
if (policy_name == "default"sv && m_default_policy)
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Policy Factory already has a default value defined"_string };
// 4. Let policy be a new TrustedTypePolicy object.
// 5. Set policys name property value to policyName.
// 6. Set policys options value to «[ "createHTML" -> options["createHTML", "createScript" -> options["createScript", "createScriptURL" -> options["createScriptURL" ]».
auto const policy = realm.create<TrustedTypePolicy>(realm, policy_name, options);
// 7. If the policyName is default, set the factorys default policy value to policy.
if (policy_name == "default"sv)
m_default_policy = policy;
// 8. Append policyName to factorys created policy names.
m_created_policy_names.append(policy_name);
// 9. Return policy.
return policy;
}
// https://w3c.github.io/trusted-types/dist/spec/#abstract-opdef-get-trusted-type-data-for-attribute
Optional<TrustedTypeData> get_trusted_type_data_for_attribute(String const& element, String const& attribute, Optional<String> const& attribute_ns)
{

View file

@ -9,6 +9,7 @@
#include <LibJS/Forward.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/Bindings/TrustedTypePolicyFactoryPrototype.h>
#include <LibWeb/TrustedTypes/TrustedTypePolicy.h>
namespace Web::TrustedTypes {
@ -21,16 +22,31 @@ public:
virtual ~TrustedTypePolicyFactory() override { }
WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> create_policy(String const&, TrustedTypePolicyOptions const&);
bool is_html(JS::Value);
Optional<String> get_attribute_type(String const& tag_name, String& attribute, Optional<String> element_ns, Optional<String> attr_ns);
Optional<String> get_property_type(String const& tag_name, String const& property, Optional<String> element_ns);
GC::Ptr<TrustedTypePolicy> default_policy() const
{
return m_default_policy;
}
private:
explicit TrustedTypePolicyFactory(JS::Realm&);
virtual void initialize(JS::Realm&) override;
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Visitor&) override;
WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> create_a_trusted_type_policy(String const&, TrustedTypePolicyOptions const&, JS::Object&);
// https://w3c.github.io/trusted-types/dist/spec/#trustedtypepolicyfactory-created-policy-names
Vector<String> m_created_policy_names;
// https://w3c.github.io/trusted-types/dist/spec/#trustedtypepolicyfactory-default-policy
GC::Ptr<TrustedTypePolicy> m_default_policy;
};
struct TrustedTypeData {

View file

@ -1,7 +1,9 @@
#import <TrustedTypes/TrustedTypePolicy.idl>
// https://w3c.github.io/trusted-types/dist/spec/#trustedtypepolicyfactory
[Exposed=(Window,Worker)]
interface TrustedTypePolicyFactory {
[FIXME] TrustedTypePolicy createPolicy(
TrustedTypePolicy createPolicy(
DOMString policyName, optional TrustedTypePolicyOptions policyOptions = {});
boolean isHTML(any value);
[FIXME] boolean isScript(any value);
@ -17,5 +19,5 @@ interface TrustedTypePolicyFactory {
DOMString tagName,
DOMString property,
optional DOMString? elementNs = "");
[FIXME] readonly attribute TrustedTypePolicy? defaultPolicy;
readonly attribute TrustedTypePolicy? defaultPolicy;
};