LibWeb: Migrate TrustedTypes to Utf16String

This commit is contained in:
Tete17 2025-08-05 23:26:38 +02:00 committed by Luke Wilde
commit cf211cf99a
Notes: github-actions[bot] 2025-08-11 11:22:35 +00:00
6 changed files with 81 additions and 82 deletions

View file

@ -20,7 +20,7 @@ namespace Web::TrustedTypes {
GC_DEFINE_ALLOCATOR(TrustedTypePolicy);
TrustedTypePolicy::TrustedTypePolicy(JS::Realm& realm, String const& name, TrustedTypePolicyOptions const& options)
TrustedTypePolicy::TrustedTypePolicy(JS::Realm& realm, Utf16String const& name, TrustedTypePolicyOptions const& options)
: PlatformObject(realm)
, m_name(name)
, m_options(options)
@ -34,7 +34,7 @@ void TrustedTypePolicy::initialize(JS::Realm& realm)
}
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicy-createhtml
WebIDL::ExceptionOr<GC::Root<TrustedHTML>> TrustedTypePolicy::create_html(String const& input, GC::RootVector<JS::Value> const& arguments)
WebIDL::ExceptionOr<GC::Root<TrustedHTML>> TrustedTypePolicy::create_html(Utf16String const& input, GC::RootVector<JS::Value> const& arguments)
{
// 1. Returns the result of executing the Create a Trusted Type algorithm, with the following arguments:
// policy
@ -50,7 +50,7 @@ WebIDL::ExceptionOr<GC::Root<TrustedHTML>> TrustedTypePolicy::create_html(String
}
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicy-createscript
WebIDL::ExceptionOr<GC::Root<TrustedScript>> TrustedTypePolicy::create_script(String const& input, GC::RootVector<JS::Value> const& arguments)
WebIDL::ExceptionOr<GC::Root<TrustedScript>> TrustedTypePolicy::create_script(Utf16String const& input, GC::RootVector<JS::Value> const& arguments)
{
// 1. Returns the result of executing the Create a Trusted Type algorithm, with the following arguments:
// policy
@ -66,7 +66,7 @@ WebIDL::ExceptionOr<GC::Root<TrustedScript>> TrustedTypePolicy::create_script(St
}
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicy-createscripturl
WebIDL::ExceptionOr<GC::Root<TrustedScriptURL>> TrustedTypePolicy::create_script_url(String const& input, GC::RootVector<JS::Value> const& arguments)
WebIDL::ExceptionOr<GC::Root<TrustedScriptURL>> TrustedTypePolicy::create_script_url(Utf16String const& input, GC::RootVector<JS::Value> const& arguments)
{
// 1. Returns the result of executing the Create a Trusted Type algorithm, with the following arguments:
// policy
@ -82,7 +82,7 @@ WebIDL::ExceptionOr<GC::Root<TrustedScriptURL>> TrustedTypePolicy::create_script
}
// https://w3c.github.io/trusted-types/dist/spec/#create-a-trusted-type-algorithm
TrustedTypesVariants TrustedTypePolicy::create_a_trusted_type(TrustedTypeName trusted_type_name, String const& value, GC::RootVector<JS::Value> const& arguments)
TrustedTypesVariants TrustedTypePolicy::create_a_trusted_type(TrustedTypeName trusted_type_name, Utf16String const& value, GC::RootVector<JS::Value> const& arguments)
{
auto& vm = this->vm();
auto& realm = this->realm();
@ -124,7 +124,7 @@ TrustedTypesVariants TrustedTypePolicy::create_a_trusted_type(TrustedTypeName tr
}
// https://w3c.github.io/trusted-types/dist/spec/#abstract-opdef-get-trusted-type-policy-value
WebIDL::ExceptionOr<JS::Value> TrustedTypePolicy::get_trusted_type_policy_value(TrustedTypeName trusted_type_name, String const& value, GC::RootVector<JS::Value> const& values, ThrowIfCallbackMissing throw_if_missing)
WebIDL::ExceptionOr<JS::Value> TrustedTypePolicy::get_trusted_type_policy_value(TrustedTypeName trusted_type_name, Utf16String const& value, GC::RootVector<JS::Value> const& values, ThrowIfCallbackMissing throw_if_missing)
{
auto& vm = this->vm();

View file

@ -41,21 +41,21 @@ class TrustedTypePolicy final : public Bindings::PlatformObject {
public:
virtual ~TrustedTypePolicy() override = default;
String const& name() const { return m_name; }
Utf16String const& name() const { return m_name; }
WebIDL::ExceptionOr<GC::Root<TrustedHTML>> create_html(String const&, GC::RootVector<JS::Value> const&);
WebIDL::ExceptionOr<GC::Root<TrustedScript>> create_script(String const&, GC::RootVector<JS::Value> const&);
WebIDL::ExceptionOr<GC::Root<TrustedScriptURL>> create_script_url(String const&, GC::RootVector<JS::Value> const&);
WebIDL::ExceptionOr<GC::Root<TrustedHTML>> create_html(Utf16String const&, GC::RootVector<JS::Value> const&);
WebIDL::ExceptionOr<GC::Root<TrustedScript>> create_script(Utf16String const&, GC::RootVector<JS::Value> const&);
WebIDL::ExceptionOr<GC::Root<TrustedScriptURL>> create_script_url(Utf16String const&, GC::RootVector<JS::Value> const&);
private:
explicit TrustedTypePolicy(JS::Realm&, String const&, TrustedTypePolicyOptions const&);
explicit TrustedTypePolicy(JS::Realm&, Utf16String const&, TrustedTypePolicyOptions const&);
virtual void initialize(JS::Realm&) override;
TrustedTypesVariants create_a_trusted_type(TrustedTypeName, String const&, GC::RootVector<JS::Value> const& values);
TrustedTypesVariants create_a_trusted_type(TrustedTypeName, Utf16String const&, GC::RootVector<JS::Value> const& values);
WebIDL::ExceptionOr<JS::Value> get_trusted_type_policy_value(TrustedTypeName, String const& value, GC::RootVector<JS::Value> const& values, ThrowIfCallbackMissing throw_if_missing);
WebIDL::ExceptionOr<JS::Value> get_trusted_type_policy_value(TrustedTypeName, Utf16String const& value, GC::RootVector<JS::Value> const& values, ThrowIfCallbackMissing throw_if_missing);
String const m_name;
Utf16String const m_name;
TrustedTypePolicyOptions const m_options;
};

View file

@ -5,10 +5,10 @@
// https://w3c.github.io/trusted-types/dist/spec/#trusted-type-policy
[Exposed=(Window,Worker)]
interface TrustedTypePolicy {
readonly attribute DOMString name;
TrustedHTML createHTML(DOMString input, any... arguments);
TrustedScript createScript(DOMString input, any... arguments);
TrustedScriptURL createScriptURL(DOMString input, any... arguments);
readonly attribute Utf16DOMString name;
TrustedHTML createHTML(Utf16DOMString input, any... arguments);
TrustedScript createScript(Utf16DOMString input, any... arguments);
TrustedScriptURL createScriptURL(Utf16DOMString input, any... arguments);
};
// https://w3c.github.io/trusted-types/dist/spec/#trusted-type-policy-options
@ -17,6 +17,6 @@ dictionary TrustedTypePolicyOptions {
CreateScriptCallback createScript;
CreateScriptURLCallback createScriptURL;
};
callback CreateHTMLCallback = DOMString? (DOMString input, any... arguments);
callback CreateScriptCallback = DOMString? (DOMString input, any... arguments);
callback CreateScriptURLCallback = USVString? (DOMString input, any... arguments);
callback CreateHTMLCallback = Utf16DOMString? (Utf16DOMString input, any... arguments);
callback CreateScriptCallback = Utf16DOMString? (Utf16DOMString input, any... arguments);
callback CreateScriptURLCallback = Utf16USVString? (Utf16DOMString input, any... arguments);

View file

@ -37,7 +37,7 @@ GC::Ref<TrustedTypePolicyFactory> TrustedTypePolicyFactory::create(JS::Realm& re
}
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-getattributetype
Optional<String> TrustedTypePolicyFactory::get_attribute_type(String const& tag_name, String& attribute, Optional<String> element_ns, Optional<String> attr_ns)
Optional<Utf16String> TrustedTypePolicyFactory::get_attribute_type(Utf16String const& tag_name, Utf16String& attribute, Optional<Utf16String> element_ns, Optional<Utf16String> attr_ns)
{
// 1. Set localName to tagName in ASCII lowercase.
auto const local_name = tag_name.to_ascii_lowercase();
@ -47,7 +47,7 @@ Optional<String> TrustedTypePolicyFactory::get_attribute_type(String const& tag_
// 3. If elementNs is null or an empty string, set elementNs to HTML namespace.
if (!element_ns.has_value() || element_ns.value().is_empty())
element_ns = String { Namespace::HTML };
element_ns = Utf16String::from_utf8(Namespace::HTML);
// 4. If attrNs is an empty string, set attrNs to null.
if (attr_ns.has_value() && attr_ns.value().is_empty())
@ -56,19 +56,19 @@ Optional<String> TrustedTypePolicyFactory::get_attribute_type(String const& tag_
// FIXME: We don't have a method in ElementFactory that can give us the interface name but these are all the cases
// we care about in the table in get_trusted_type_data_for_attribute function
// 5. Let interface be the element interface for localName and elementNs.
String interface;
Utf16String interface;
if (local_name == HTML::TagNames::iframe && element_ns == Namespace::HTML) {
interface = "HTMLIFrameElement"_string;
interface = "HTMLIFrameElement"_utf16;
} else if (local_name == HTML::TagNames::script && element_ns == Namespace::HTML) {
interface = "HTMLScriptElement"_string;
interface = "HTMLScriptElement"_utf16;
} else if (local_name == SVG::TagNames::script && element_ns == Namespace::SVG) {
interface = "SVGScriptElement"_string;
interface = "SVGScriptElement"_utf16;
} else {
interface = "Element"_string;
interface = "Element"_utf16;
}
// 6. Let expectedType be null.
Optional<String> expected_type {};
Optional<Utf16String> expected_type {};
// 7. Set attributeData to the result of Get Trusted Type data for attribute algorithm,
// with the following arguments, interface as element, attribute, attrNs
@ -84,38 +84,38 @@ Optional<String> TrustedTypePolicyFactory::get_attribute_type(String const& tag_
}
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-getpropertytype
Optional<String> TrustedTypePolicyFactory::get_property_type(String const& tag_name, String const& property, Optional<String> element_ns)
Optional<Utf16String> TrustedTypePolicyFactory::get_property_type(Utf16String const& tag_name, Utf16String const& property, Optional<Utf16String> element_ns)
{
// 1. Set localName to tagName in ASCII lowercase.
auto const local_name = tag_name.to_ascii_lowercase();
// 2. If elementNs is null or an empty string, set elementNs to HTML namespace.
if (!element_ns.has_value() || element_ns.value().is_empty())
element_ns = String { Namespace::HTML };
element_ns = Utf16String::from_utf8(Namespace::HTML);
// FIXME: We don't have a method in ElementFactory that can give us the interface name but these are all the cases
// we care about in the table in get_trusted_type_data_for_attribute function
// 3. Let interface be the element interface for localName and elementNs.
String interface;
Utf16String interface;
if (local_name == HTML::TagNames::iframe && element_ns == Namespace::HTML) {
interface = "HTMLIFrameElement"_string;
interface = "HTMLIFrameElement"_utf16;
} else if (local_name == HTML::TagNames::script && element_ns == Namespace::HTML) {
interface = "HTMLScriptElement"_string;
interface = "HTMLScriptElement"_utf16;
} else {
interface = "Element"_string;
interface = "Element"_utf16;
}
// 4. Let expectedType be null.
Optional<String> expected_type;
Optional<Utf16String> expected_type;
static Vector<Array<String, 3>> const table {
{ "HTMLIFrameElement"_string, "srcdoc"_string, "TrustedHTML"_string },
{ "HTMLScriptElement"_string, "innerText"_string, "TrustedScript"_string },
{ "HTMLScriptElement"_string, "src"_string, "TrustedScriptURL"_string },
{ "HTMLScriptElement"_string, "text"_string, "TrustedScript"_string },
{ "HTMLScriptElement"_string, "textContent"_string, "TrustedScript"_string },
{ "*"_string, "innerHTML"_string, "TrustedHTML"_string },
{ "*"_string, "outerHTML"_string, "TrustedHTML"_string },
static Vector<Array<Utf16String, 3>> const table {
{ "HTMLIFrameElement"_utf16, "srcdoc"_utf16, "TrustedHTML"_utf16 },
{ "HTMLScriptElement"_utf16, "innerText"_utf16, "TrustedScript"_utf16 },
{ "HTMLScriptElement"_utf16, "src"_utf16, "TrustedScriptURL"_utf16 },
{ "HTMLScriptElement"_utf16, "text"_utf16, "TrustedScript"_utf16 },
{ "HTMLScriptElement"_utf16, "textContent"_utf16, "TrustedScript"_utf16 },
{ "*"_utf16, "innerHTML"_utf16, "TrustedHTML"_utf16 },
{ "*"_utf16, "outerHTML"_utf16, "TrustedHTML"_utf16 },
};
// 5. Find the row in the following table, where the first column is "*" or interfaces name, and property is in the second column.
@ -150,7 +150,7 @@ void TrustedTypePolicyFactory::visit_edges(Visitor& visitor)
}
// 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)
WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> TrustedTypePolicyFactory::create_policy(Utf16String 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
@ -182,7 +182,7 @@ bool TrustedTypePolicyFactory::is_script_url(JS::Value value)
}
// 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& global)
WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> TrustedTypePolicyFactory::create_a_trusted_type_policy(Utf16String const& policy_name, TrustedTypePolicyOptions const& options, JS::Object& global)
{
auto& realm = this->realm();
@ -214,7 +214,7 @@ WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> TrustedTypePolicyFactory::create
}
// https://www.w3.org/TR/trusted-types/#should-block-create-policy
ContentSecurityPolicy::Directives::Directive::Result TrustedTypePolicyFactory::should_trusted_type_policy_be_blocked_by_content_security_policy(JS::Object& global, String const& policy_name, Vector<String> const& created_policy_names)
ContentSecurityPolicy::Directives::Directive::Result TrustedTypePolicyFactory::should_trusted_type_policy_be_blocked_by_content_security_policy(JS::Object& global, Utf16String const& policy_name, Vector<Utf16String> const& created_policy_names)
{
auto& realm = this->realm();
@ -248,7 +248,7 @@ ContentSecurityPolicy::Directives::Directive::Result TrustedTypePolicyFactory::s
}
// 6. If directives value does not contain a tt-policy-name, which value is policyName, and directives value does not contain a tt-wildcard, set createViolation to true.
auto directive_value_iterator = directive->value().find(policy_name);
auto directive_value_iterator = directive->value().find(policy_name.to_utf8());
if (directive_value_iterator.is_end()) {
auto maybe_wild_card = directive->value().find_if([](auto const& directive_value) {
return directive_value.equals_ignoring_ascii_case(ContentSecurityPolicy::Directives::KeywordTrustedTypes::WildCard);
@ -269,9 +269,8 @@ ContentSecurityPolicy::Directives::Directive::Result TrustedTypePolicyFactory::s
violation->set_resource(ContentSecurityPolicy::Violation::Resource::TrustedTypesPolicy);
// 10. Set violations sample to the substring of policyName, containing its first 40 characters.
Utf8View source_view { policy_name };
auto sample = source_view.unicode_substring_view(0, min(source_view.length(), 40));
violation->set_sample(String::from_utf8_without_validation(sample.as_string().bytes()));
auto sample = policy_name.substring_view(0, min(policy_name.length_in_code_points(), 40));
violation->set_sample(Utf16String::from_utf16(sample).to_utf8());
// 11. Execute Report a violation on violation.
violation->report_a_violation(realm);
@ -286,7 +285,7 @@ ContentSecurityPolicy::Directives::Directive::Result TrustedTypePolicyFactory::s
}
// 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)
Optional<TrustedTypeData> get_trusted_type_data_for_attribute(Utf16String const& element, Utf16String const& attribute, Optional<Utf16String> const& attribute_ns)
{
// 1. Let data be null.
Optional<TrustedTypeData const&> data {};
@ -294,10 +293,10 @@ Optional<TrustedTypeData> get_trusted_type_data_for_attribute(String const& elem
// 2. If attributeNs is null, and attribute is the name of an event handler content attribute, then:
if (!attribute_ns.has_value()) {
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
if (attribute == HTML::AttributeNames::attribute_name) { \
/* 1. Return (Element, null, attribute, TrustedScript, "Element " + attribute). */ \
return TrustedTypeData { "Element"_string, {}, attribute, "TrustedScript"_string, "Element " #attribute_name ""_string }; \
#define __ENUMERATE(attribute_name, event_name) \
if (attribute == HTML::AttributeNames::attribute_name) { \
/* 1. Return (Element, null, attribute, TrustedScript, "Element " + attribute). */ \
return TrustedTypeData { "Element"_utf16, {}, attribute, "TrustedScript"_utf16, "Element " #attribute_name ""_utf16 }; \
}
ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE)
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
@ -305,10 +304,10 @@ Optional<TrustedTypeData> get_trusted_type_data_for_attribute(String const& elem
}
static Vector<TrustedTypeData> const table {
{ "HTMLIFrameElement"_string, {}, "srcdoc"_string, "TrustedHTML"_string, "HTMLIFrameElement srcdoc"_string },
{ "HTMLScriptElement"_string, {}, "src"_string, "TrustedScriptURL"_string, "HTMLScriptElement src"_string },
{ "SVGScriptElement"_string, {}, "href"_string, "TrustedScriptURL"_string, "SVGScriptElement href"_string },
{ "SVGScriptElement"_string, Namespace::XLink.to_string(), "href"_string, "TrustedScriptURL"_string, "SVGScriptElement href"_string },
{ "HTMLIFrameElement"_utf16, {}, "srcdoc"_utf16, "TrustedHTML"_utf16, "HTMLIFrameElement srcdoc"_utf16 },
{ "HTMLScriptElement"_utf16, {}, "src"_utf16, "TrustedScriptURL"_utf16, "HTMLScriptElement src"_utf16 },
{ "SVGScriptElement"_utf16, {}, "href"_utf16, "TrustedScriptURL"_utf16, "SVGScriptElement href"_utf16 },
{ "SVGScriptElement"_utf16, Utf16String::from_utf8(Namespace::XLink), "href"_utf16, "TrustedScriptURL"_utf16, "SVGScriptElement href"_utf16 },
};
// 3. Find the row in the following table, where element is in the first column, attributeNs is in the second column,

View file

@ -23,14 +23,14 @@ public:
virtual ~TrustedTypePolicyFactory() override { }
WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> create_policy(String const&, TrustedTypePolicyOptions const&);
WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> create_policy(Utf16String const&, TrustedTypePolicyOptions const&);
bool is_html(JS::Value);
bool is_script(JS::Value);
bool is_script_url(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);
Optional<Utf16String> get_attribute_type(Utf16String const& tag_name, Utf16String& attribute, Optional<Utf16String> element_ns, Optional<Utf16String> attr_ns);
Optional<Utf16String> get_property_type(Utf16String const& tag_name, Utf16String const& property, Optional<Utf16String> element_ns);
GC::Ptr<TrustedTypePolicy> default_policy() const
{
@ -43,24 +43,24 @@ private:
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&);
ContentSecurityPolicy::Directives::Directive::Result should_trusted_type_policy_be_blocked_by_content_security_policy(JS::Object&, String const&, Vector<String> const&);
WebIDL::ExceptionOr<GC::Ref<TrustedTypePolicy>> create_a_trusted_type_policy(Utf16String const&, TrustedTypePolicyOptions const&, JS::Object&);
ContentSecurityPolicy::Directives::Directive::Result should_trusted_type_policy_be_blocked_by_content_security_policy(JS::Object&, Utf16String const&, Vector<Utf16String> const&);
// https://w3c.github.io/trusted-types/dist/spec/#trustedtypepolicyfactory-created-policy-names
Vector<String> m_created_policy_names;
Vector<Utf16String> m_created_policy_names;
// https://w3c.github.io/trusted-types/dist/spec/#trustedtypepolicyfactory-default-policy
GC::Ptr<TrustedTypePolicy> m_default_policy;
};
struct TrustedTypeData {
String element;
Optional<String> attribute_ns;
String attribute_local_name;
String trusted_type;
String sink;
Utf16String element;
Optional<Utf16String> attribute_ns;
Utf16String attribute_local_name;
Utf16String trusted_type;
Utf16String sink;
};
Optional<TrustedTypeData> get_trusted_type_data_for_attribute(String const&, String const&, Optional<String> const&);
Optional<TrustedTypeData> get_trusted_type_data_for_attribute(Utf16String const&, Utf16String const&, Optional<Utf16String> const&);
}

View file

@ -4,20 +4,20 @@
[Exposed=(Window,Worker)]
interface TrustedTypePolicyFactory {
TrustedTypePolicy createPolicy(
DOMString policyName, optional TrustedTypePolicyOptions policyOptions = {});
Utf16DOMString policyName, optional TrustedTypePolicyOptions policyOptions = {});
boolean isHTML(any value);
boolean isScript(any value);
boolean isScriptURL(any value);
[FIXME] readonly attribute TrustedHTML emptyHTML;
[FIXME] readonly attribute TrustedScript emptyScript;
DOMString? getAttributeType(
DOMString tagName,
DOMString attribute,
optional DOMString? elementNs = "",
optional DOMString? attrNs = "");
DOMString? getPropertyType(
DOMString tagName,
DOMString property,
optional DOMString? elementNs = "");
Utf16DOMString? getAttributeType(
Utf16DOMString tagName,
Utf16DOMString attribute,
optional Utf16DOMString? elementNs = "",
optional Utf16DOMString? attrNs = "");
Utf16DOMString? getPropertyType(
Utf16DOMString tagName,
Utf16DOMString property,
optional Utf16DOMString? elementNs = "");
readonly attribute TrustedTypePolicy? defaultPolicy;
};