Implement all trusted sinks in HTMLScriptElement (#36668)

As a follow-up to the recent introduction of `script.src`
as trusted sink, this PR refactors machinery to also
support `TrustedScript`. In doing so, all trusted sinks
in `HTMLScriptElement` are now covered.

Instead of calling the callbacks in `policy.createX`,
we now have a `TrustedType` enum that specifies which callback
to invoke. Unfortunately we still have the `USVString` vs
`DOMString` problem, which is why we need to `.map` twice
to retrieve the backing `String` and avoid two different
types.

Additionally, I saw that `script.text` should have called
the "String replace all" algorithm rather than setting the
child contents. So that's also now fixed.

Part of #36258
Requires servo/html5ever#608

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
Tim van der Lippe 2025-05-03 10:35:46 +02:00 committed by GitHub
parent dd63325f50
commit 4164f76769
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 320 additions and 353 deletions

View file

@ -149,7 +149,6 @@ use crate::dom::raredata::ElementRareData;
use crate::dom::servoparser::ServoParser;
use crate::dom::shadowroot::{IsUserAgentWidget, ShadowRoot};
use crate::dom::text::Text;
use crate::dom::types::TrustedTypePolicyFactory;
use crate::dom::validation::Validatable;
use crate::dom::validitystate::ValidationFlags;
use crate::dom::virtualmethods::{VirtualMethods, vtable_for};
@ -1961,35 +1960,6 @@ impl Element {
.unwrap_or_else(|_| TrustedScriptURLOrUSVString::USVString(USVString(value.to_owned())))
}
pub(crate) fn set_trusted_type_url_attribute(
&self,
local_name: &LocalName,
value: TrustedScriptURLOrUSVString,
can_gc: CanGc,
) -> Fallible<()> {
assert_eq!(*local_name, local_name.to_ascii_lowercase());
let value = match value {
TrustedScriptURLOrUSVString::USVString(url) => {
let global = self.owner_global();
// TODO(36258): Reflectively get the name of the class
let sink = format!("{} {}", "HTMLScriptElement", &local_name);
let result = TrustedTypePolicyFactory::get_trusted_type_compliant_string(
&global,
url.to_string(),
&sink,
"'script'",
can_gc,
);
result?
},
// This partially implements <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm>
// Step 1: If input is an instance of expectedType, return stringified input and abort these steps.
TrustedScriptURLOrUSVString::TrustedScriptURL(script_url) => script_url.to_string(),
};
self.set_attribute(local_name, AttrValue::String(value), can_gc);
Ok(())
}
pub(crate) fn get_string_attribute(&self, local_name: &LocalName) -> DOMString {
match self.get_attribute(&ns!(), local_name) {
Some(x) => x.Value(),