Implement iframe.srcdoc trusted type sink (#36960)

Part of https://github.com/servo/servo/issues/36258

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-13 23:07:13 +02:00 committed by GitHub
parent 9f6a40e6aa
commit c985c08737
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 36 additions and 38 deletions

View file

@ -1996,6 +1996,15 @@ impl Element {
.unwrap_or_else(|_| TrustedScriptURLOrUSVString::USVString(USVString(value.to_owned())))
}
pub(crate) fn get_trusted_html_attribute(&self, local_name: &LocalName) -> TrustedHTMLOrString {
assert_eq!(*local_name, local_name.to_ascii_lowercase());
let value = match self.get_attribute(&ns!(), local_name) {
Some(attr) => (&**attr.value()).into(),
None => "".into(),
};
TrustedHTMLOrString::String(value)
}
pub(crate) fn get_string_attribute(&self, local_name: &LocalName) -> DOMString {
match self.get_attribute(&ns!(), local_name) {
Some(x) => x.Value(),

View file

@ -27,6 +27,8 @@ use crate::dom::attr::Attr;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
use crate::dom::bindings::codegen::Bindings::WindowBinding::Window_Binding::WindowMethods;
use crate::dom::bindings::codegen::UnionTypes::TrustedHTMLOrString;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::DomGlobal;
use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
@ -40,6 +42,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{Node, NodeDamage, NodeTraits, UnbindContext};
use crate::dom::trustedhtml::TrustedHTML;
use crate::dom::virtualmethods::VirtualMethods;
use crate::dom::windowproxy::WindowProxy;
use crate::script_runtime::CanGc;
@ -595,10 +598,29 @@ impl HTMLIFrameElementMethods<crate::DomTypeHolder> for HTMLIFrameElement {
make_url_setter!(SetSrc, "src");
// https://html.spec.whatwg.org/multipage/#dom-iframe-srcdoc
make_getter!(Srcdoc, "srcdoc");
fn Srcdoc(&self) -> TrustedHTMLOrString {
let element = self.upcast::<Element>();
element.get_trusted_html_attribute(&local_name!("srcdoc"))
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-srcdoc
make_setter!(SetSrcdoc, "srcdoc");
fn SetSrcdoc(&self, value: TrustedHTMLOrString, can_gc: CanGc) -> Fallible<()> {
// Step 1: Let compliantString be the result of invoking the
// Get Trusted Type compliant string algorithm with TrustedHTML,
// this's relevant global object, the given value, "HTMLIFrameElement srcdoc", and "script".
let element = self.upcast::<Element>();
let local_name = &local_name!("srcdoc");
let value = TrustedHTML::get_trusted_script_compliant_string(
&element.owner_global(),
value,
"HTMLIFrameElement",
local_name,
can_gc,
)?;
// Step 2: Set an attribute value given this, srcdoc's local name, and compliantString.
element.set_attribute(local_name, AttrValue::String(value), can_gc);
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-sandbox
fn Sandbox(&self, can_gc: CanGc) -> DomRoot<DOMTokenList> {

View file

@ -371,7 +371,7 @@ DOMInterfaces = {
},
'HTMLIFrameElement': {
'canGc': ['Sandbox'],
'canGc': ['Sandbox', 'SetSrcdoc'],
},
'HTMLImageElement': {

View file

@ -9,8 +9,8 @@ interface HTMLIFrameElement : HTMLElement {
[CEReactions]
attribute USVString src;
[CEReactions]
attribute DOMString srcdoc;
[CEReactions, SetterThrows]
attribute (TrustedHTML or DOMString) srcdoc;
[CEReactions]
attribute DOMString name;

View file

@ -1,12 +0,0 @@
[HTMLElement-generic.html]
[TT enabled: iframe.srcdoc\n = String on a\n connected element\n ]
expected: FAIL
[TT enabled: iframe.srcdoc\n = String on a\n non-connected element\n ]
expected: FAIL
[TT enabled: iframe.srcdoc\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
expected: FAIL
[TT enabled: iframe.srcdoc\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
expected: FAIL

View file

@ -20,9 +20,6 @@
[div.onclick's mutationobservers receive the default policy's value.]
expected: FAIL
[iframe.srcdoc accepts string and null after default policy was created.]
expected: FAIL
[div.onclick accepts string and null after default policy was created.]
expected: FAIL

View file

@ -1,6 +0,0 @@
[block-string-assignment-to-HTMLElement-generic.html]
[iframe.srcdoc accepts only TrustedHTML]
expected: FAIL
[iframe.srcdoc accepts string and null after default policy was created]
expected: FAIL

View file

@ -1,9 +0,0 @@
[block-string-assignment-to-HTMLIFrameElement-srcdoc.html]
[`iframe.srcdoc = string` throws.]
expected: FAIL
[`iframe.srcdoc = null` throws.]
expected: FAIL
[`iframe.srcdoc = string` assigned via default policy (successful HTML transformation).]
expected: FAIL

View file

@ -1,3 +0,0 @@
[trusted-types-reporting-for-HTMLIFrameElement-srcdoc.html]
[Violation report for plain string.]
expected: FAIL