From d94929dbed8352bca867f4612fb9132718471189 Mon Sep 17 00:00:00 2001 From: Tim van der Lippe Date: Wed, 27 Aug 2025 08:10:16 +0200 Subject: [PATCH] script: Implement trusted types for `DOMParser.parseFromString` (#38872) Part of #36258 Signed-off-by: Tim van der Lippe --- components/script/dom/domparser.rs | 39 ++++++++++++++----- components/script/dom/servoparser/mod.rs | 11 +++++- .../script_bindings/webidls/DOMParser.webidl | 4 +- ...ment-to-DOMParser-parseFromString.html.ini | 9 ----- ...ing-for-DOMParser-parseFromString.html.ini | 3 -- 5 files changed, 41 insertions(+), 25 deletions(-) delete mode 100644 tests/wpt/meta/trusted-types/block-string-assignment-to-DOMParser-parseFromString.html.ini delete mode 100644 tests/wpt/meta/trusted-types/trusted-types-reporting-for-DOMParser-parseFromString.html.ini diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs index 85d7cd0870f..a201ed8a9e3 100644 --- a/components/script/dom/domparser.rs +++ b/components/script/dom/domparser.rs @@ -14,12 +14,13 @@ use crate::dom::bindings::codegen::Bindings::DOMParserBinding::SupportedType::{ }; use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentReadyState; use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; +use crate::dom::bindings::codegen::UnionTypes::TrustedHTMLOrString; use crate::dom::bindings::error::Fallible; use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto}; use crate::dom::bindings::root::{Dom, DomRoot}; -use crate::dom::bindings::str::DOMString; use crate::dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument}; use crate::dom::servoparser::ServoParser; +use crate::dom::trustedhtml::TrustedHTML; use crate::dom::window::Window; use crate::script_runtime::CanGc; @@ -60,10 +61,19 @@ impl DOMParserMethods for DOMParser { /// fn ParseFromString( &self, - s: DOMString, + s: TrustedHTMLOrString, ty: DOMParserBinding::SupportedType, 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, string, "DOMParser parseFromString", and "script". + let compliant_string = TrustedHTML::get_trusted_script_compliant_string( + self.window.as_global_scope(), + s, + "DOMParser parseFromString", + can_gc, + )?; let url = self.window.get_url(); let content_type = ty .as_str() @@ -71,8 +81,11 @@ impl DOMParserMethods for DOMParser { .expect("Supported type is not a MIME type"); let doc = self.window.Document(); let loader = DocumentLoader::new(&doc.loader()); - match ty { + // Step 3. Switch on type: + let document = match ty { Text_html => { + // Step 2. Let document be a new Document, whose content type is type + // and URL is this's relevant global object's associated Document's URL. let document = Document::new( &self.window, HasBrowsingContext::No, @@ -93,11 +106,13 @@ impl DOMParserMethods for DOMParser { doc.has_trustworthy_ancestor_or_current_origin(), can_gc, ); - ServoParser::parse_html_document(&document, Some(s), url, can_gc); - document.set_ready_state(DocumentReadyState::Complete, can_gc); - Ok(document) + // Step switch-1. Parse HTML from a string given document and compliantString. + ServoParser::parse_html_document(&document, Some(compliant_string), url, can_gc); + document }, Text_xml | Application_xml | Application_xhtml_xml | Image_svg_xml => { + // Step 2. Let document be a new Document, whose content type is type + // and URL is this's relevant global object's associated Document's URL. let document = Document::new( &self.window, HasBrowsingContext::No, @@ -118,10 +133,14 @@ impl DOMParserMethods for DOMParser { doc.has_trustworthy_ancestor_or_current_origin(), can_gc, ); - ServoParser::parse_xml_document(&document, Some(s), url, can_gc); - document.set_ready_state(DocumentReadyState::Complete, can_gc); - Ok(document) + // Step switch-1. Create an XML parser parser, associated with document, + // and with XML scripting support disabled. + ServoParser::parse_xml_document(&document, Some(compliant_string), url, can_gc); + document }, - } + }; + // Step 4. Return document. + document.set_ready_state(DocumentReadyState::Complete, can_gc); + Ok(document) } } diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index b049397d502..6979f31e367 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -165,12 +165,18 @@ impl ServoParser { self.can_write() } + /// pub(crate) fn parse_html_document( document: &Document, input: Option, url: ServoUrl, can_gc: CanGc, ) { + // Step 1. Set document's type to "html". + // + // Set by callers of this function and asserted here + assert!(document.is_html_document()); + // Step 2. Create an HTML parser parser, associated with document. let parser = if pref!(dom_servoparser_async_html_tokenizer_enabled) { ServoParser::new( document, @@ -191,7 +197,10 @@ impl ServoParser { can_gc, ) }; - + // Step 3. Place html into the input stream for parser. The encoding confidence is irrelevant. + // Step 4. Start parser and let it run until it has consumed all the + // characters just inserted into the input stream. + // // Set as the document's current parser and initialize with `input`, if given. if let Some(input) = input { parser.parse_complete_string_chunk(String::from(input), can_gc); diff --git a/components/script_bindings/webidls/DOMParser.webidl b/components/script_bindings/webidls/DOMParser.webidl index 90b3b6a8ff6..9d5b0e8fa17 100644 --- a/components/script_bindings/webidls/DOMParser.webidl +++ b/components/script_bindings/webidls/DOMParser.webidl @@ -17,6 +17,6 @@ enum SupportedType { [Exposed=Window] interface DOMParser { [Throws] constructor(); - [Throws] - Document parseFromString(DOMString str, SupportedType type); + [NewObject, Throws] + Document parseFromString((TrustedHTML or DOMString) string, SupportedType type); }; diff --git a/tests/wpt/meta/trusted-types/block-string-assignment-to-DOMParser-parseFromString.html.ini b/tests/wpt/meta/trusted-types/block-string-assignment-to-DOMParser-parseFromString.html.ini deleted file mode 100644 index e179b108038..00000000000 --- a/tests/wpt/meta/trusted-types/block-string-assignment-to-DOMParser-parseFromString.html.ini +++ /dev/null @@ -1,9 +0,0 @@ -[block-string-assignment-to-DOMParser-parseFromString.html] - [`document.innerText = string` throws.] - expected: FAIL - - ['document.innerText = null' throws] - expected: FAIL - - ['document.innerText = string' assigned via default policy (successful HTML transformation).] - expected: FAIL diff --git a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-DOMParser-parseFromString.html.ini b/tests/wpt/meta/trusted-types/trusted-types-reporting-for-DOMParser-parseFromString.html.ini deleted file mode 100644 index 90311696ac8..00000000000 --- a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-DOMParser-parseFromString.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[trusted-types-reporting-for-DOMParser-parseFromString.html] - [Violation report for plain string.] - expected: FAIL