CVE-2026-91719
Overview
Background
- "Already started" flag
- a per-
<script>-element flag defined by the HTML spec that, when set, makes the script inert so it will never execute even after being inserted into a live document. - XML scripting support disabled
- a spec mode that requires script elements produced by an XML parse to be created with their “already started” flag set, so parsed scripts cannot run; it is mandated for both
DOMParser.parseFromStringandXMLHttpRequest.responseXML. - `CreateElementFlags`
- the Blink parameter object passed into element creation whose
SetAlreadyStarted(true)propagates the “already started” state onto newly created script elements at parse time. - `IsDOMParserDocument()` / `IsXHRDocument()`
Documentpredicates that identify whether a document was produced byDOMParser.parseFromStringor byXMLHttpRequest.responseXML, respectively.
Root Cause Analysis
Blink parses XML through two backends, XMLDocumentParser (libxml2) in xml_document_parser.cc and XMLDocumentParserRs (Rust) in xml_document_parser_rs.cc, both of which build elements via a CreateElementFlags object at the element-creation site. Before the patch, that site set flags.SetAlreadyStarted(true) only when the feature was enabled AND document_->IsDOMParserDocument() was true AND the tag was an HTML or SVG script, so the “XML scripting support disabled” mode was applied only to DOMParser.parseFromString and not to XMLHttpRequest.responseXML. Because responseXML documents (IsXHRDocument()) never received the flag, script elements parsed out of an XHR XML/XHTML response were created without “already started” set and therefore remained live scripts. When such a script node was subsequently moved into the rendered document — directly, or via importNode, adoptNode, or cloneNode, all of which copy the flag — it would execute, violating the invariant that XML parsed with scripting support disabled yields inert scripts.
The fix consolidates the decision into ShouldMarkScriptAlreadyStarted(), which returns true for both IsDOMParserDocument() and IsXHRDocument(), so responseXML-parsed scripts are now marked inert at creation time and can no longer run.
DOMParser documents (and to script-tag matches) only, leaving XMLHttpRequest.responseXML scripts live; the fix replaces that narrow inline condition with ShouldMarkScriptAlreadyStarted(), which also covers IsXHRDocument(), restoring the spec-required inertness for both parse entry points.Attack Path
- Deliver scripted XML via XHR
A page issues an
XMLHttpRequestfortext/xmlorapplication/xhtml+xmlcontent (attacker-influenced, e.g. a server response or adata:URL) that contains a<script>element, and readsxhr.responseXML. - Parser skips the inertness marking
The XML backend creates the script element, but because the document is an XHR document rather than a
DOMParserdocument, the pre-patch condition is false andSetAlreadyStarted(true)is never called, leaving the script “not started” and runnable. - Script node is inserted into the live DOM
The page appends the parsed node to
document.bodydirectly, or throughimportNode/adoptNode/cloneNode, each of which carries the (unset) “already started” flag onto the inserted node. - Script executes
On insertion into the live document the still-live script runs, injecting and executing attacker script in the page’s context (code injection). Escalation beyond in-context script execution is not demonstrated by the patch
(inferred).
Impact Assessment
XMLHttpRequest.responseXML consumer can achieve script execution in the renderer/page context when that page moves a parsed script node into its live DOM, i.e. code injection in XML as the advisory titles it. The precondition is that the victim page fetch attacker-influenced XML via XHR and insert nodes from responseXML into a rendered document while relying on the spec guarantee that such scripts are inert. The vendor advisory rates this low severity and does not report in-the-wild exploitation; NVD scores it CVSS 8.1. Any escalation past in-context script execution is (inferred).Files Changed
third_party/blink/renderer/core/xml/parser/xml_document_parser.hthird_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.htmlthird_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.htmlthird_party/blink/renderer/core/xml/parser/xml_document_parser_rs.ccthird_party/blink/renderer/core/xml/parser/xml_document_parser.ccthird_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h
Audit Directions
- Divergent entry points to one parse routineWherever a spec behavior (like “scripting support disabled”) must hold for several API entry points, audit that the shared parser applies it via a document-type predicate rather than an inline check keyed to only one caller such as
IsDOMParserDocument(). - Flag-at-creation invariants that survive node movementReview element-creation flags (e.g. “already started”) that must be set at parse time because they are copied by
importNode/adoptNode/cloneNode; a missed set at creation cannot be recovered later and yields active nodes. - Duplicated logic across parser backendsWhen two implementations exist (
XMLDocumentParserandXMLDocumentParserRs), confirm every security-relevant condition is mirrored in both, since a fix or check applied to only one leaves the other exploitable.
Patch
From e83ada016b472defeff1ce6fbba96813c59a39ae Mon Sep 17 00:00:00 2001 From: Daniel Vogelheim <[email protected]> Date: Tue, 01 Sep 2026 10:02:30 -0700 Subject: [PATCH] Consistently set XML parser "already started" flag. The HTML spec & friends ask for XML parsing with "XML scripting support disabled" in several instances, specifically for DOMParser.parseFromString and XMLHttpResponse.responseXML. Previously, this was only done for DOMParser.parseFromString. This change also sets "already started" for XMLHttpResponse.responseXML. In addition to the behavioural change above, we also simplify and unify those two mechanisms: - Move the decision into a separate method, ShouldMarkScriptAlreadyStarted, analogous to HTMLConstructionSite. - Include spec links to justify their behaviour. - Set CreateElementFlags for all elements, since CreateElement will read only the flag it needs, so there is no need to restrict it to scripts. - We also add tests for the new cases. Bug: 542115030, 540021703 Change-Id: I1b5e16fc63733b023d21cc3b5fd37b2c6b18f532 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8314690 Reviewed-by: David Baron <[email protected]> Commit-Queue: Daniel Vogelheim <[email protected]> Cr-Commit-Position: refs/heads/main@{#1689914} --- diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc index 004a812..52cee17b 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc @@ -1227,10 +1227,7 @@ CreateElementFlags flags = parsing_fragment_ ? CreateElementFlags::ByFragmentParser(document_) : CreateElementFlags::ByParser(document_); - if (RuntimeEnabledFeatures::DOMParserXmlScriptAlreadyStartedEnabled() && - document_->IsDOMParserDocument() && - (q_name.Matches(html_names::kScriptTag) || - q_name.Matches(svg_names::kScriptTag))) { + if (ShouldMarkScriptAlreadyStarted()) { flags.SetAlreadyStarted(true); } @@ -1954,6 +1951,24 @@ PauseParsing(); } +bool XMLDocumentParser::ShouldMarkScriptAlreadyStarted() const { + if (!RuntimeEnabledFeatures::DOMParserXmlScriptAlreadyStartedEnabled()) { + return false; + } + + // The cases below parse XML documents with "XML scripting support disabled": + // See: + // https://html.spec.whatwg.org/multipage/xhtml.html#xml-scripting-support-disabled + return + // DOMParser.parseFromString parses with XML scripting support disabled: + // See: https://html.spec.whatwg.org/#dom-domparser-parsefromstring + // step 3, "Otherwise", step 1. + document_->IsDOMParserDocument() || + // XMLHTTPRequest.responseXML parses with XML scripting support disabled: + // See: https://xhr.spec.whatwg.org/#document-response, step 6 + document_->IsXHRDocument(); +} + void XMLDocumentParser::ExecuteScriptsWaitingForResources() { if (!IsWaitingForScripts() && !waiting_for_stylesheets_ && parser_paused_ && IsParsing()) { diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.h b/third_party/blink/renderer/core/xml/parser/xml_document_parser.h index 00d6e6f4..d6fa920c 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.h +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.h @@ -201,6 +201,8 @@ void CheckIfBlockingStyleSheetAdded(); + bool ShouldMarkScriptAlreadyStarted() const; + SegmentedString original_source_for_transform_; xmlParserCtxtPtr Context() const { diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.cc index 64c16076..5cc44bc9 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.cc @@ -506,10 +506,7 @@ CreateElementFlags flags = parsing_fragment_ ? CreateElementFlags::ByFragmentParser(document_) : CreateElementFlags::ByParser(document_); - if (RuntimeEnabledFeatures::DOMParserXmlScriptAlreadyStartedEnabled() && - document_->IsDOMParserDocument() && - (q_name.Matches(html_names::kScriptTag) || - q_name.Matches(svg_names::kScriptTag))) { + if (ShouldMarkScriptAlreadyStarted()) { flags.SetAlreadyStarted(true); } @@ -843,6 +840,24 @@ PauseParsing(); } +bool XMLDocumentParserRs::ShouldMarkScriptAlreadyStarted() const { + if (!RuntimeEnabledFeatures::DOMParserXmlScriptAlreadyStartedEnabled()) { + return false; + } + + // The cases below parse XML documents with "XML scripting support disabled": + // See: + // https://html.spec.whatwg.org/multipage/xhtml.html#xml-scripting-support-disabled + return + // DOMParser.parseFromString parses with XML scripting support disabled: + // See: https://html.spec.whatwg.org/#dom-domparser-parsefromstring + // step 3, "Otherwise", step 1. + document_->IsDOMParserDocument() || + // XMLHTTPRequest.responseXML parses with XML scripting support disabled: + // See: https://xhr.spec.whatwg.org/#document-response, step 6 + document_->IsXHRDocument(); +} + void XMLDocumentParserRs::ExecuteScriptsWaitingForResources() { if (!IsWaitingForScripts() && !waiting_for_stylesheets_ && parser_paused_ && IsParsing()) { diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h b/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h index 1258c5c..b57e355d 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser_rs.h @@ -110,6 +110,8 @@ void CheckIfBlockingStyleSheetAdded(); + bool ShouldMarkScriptAlreadyStarted() const; + Member<XMLParserScriptRunner> script_runner_; TextPosition script_start_position_; bool saw_error_ = false; diff --git a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html index 6494ae5..22138a8 100644 --- a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html +++ b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html @@ -70,6 +70,57 @@ document.body.appendChild(document.importNode(d.rootElement, true)); assert_equals(window.mark, 0); }, "parseFromString as XML, svg script, append importNode result, but with namespace prefix"); + +test(_ => { + window.mark = 0; + const d = new DOMParser().parseFromString( + "<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", "text/xml"); + document.body.appendChild(document.adoptNode(d.rootElement)); + assert_equals(window.mark, 0); +}, "parseFromString as XML, svg script, append adoptNode result"); + +test(_ => { + window.mark = 0; + const d = new DOMParser().parseFromString( + "<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", "text/xml"); + document.body.appendChild(d.rootElement.cloneNode(true)); + assert_equals(window.mark, 0); +}, "parseFromString as XML, svg script, append cloneNode result"); + +test(_ => { + window.mark = 0; + const d = new DOMParser().parseFromString( + "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml"); + document.body.appendChild(document.importNode(d.documentElement, true)); + assert_equals(window.mark, 0); +}, "parseFromString as XHTML, whole root, append importNode result"); + +test(_ => { + window.mark = 0; + const d = new DOMParser().parseFromString( + "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml"); + const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0]; + document.body.appendChild(document.importNode(script, true)); + assert_equals(window.mark, 0); +}, "parseFromString as XHTML, script, append importNode result"); + +test(_ => { + window.mark = 0; + const d = new DOMParser().parseFromString( + "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml"); + const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0]; + document.body.appendChild(document.adoptNode(script)); + assert_equals(window.mark, 0); +}, "parseFromString as XHTML, script, append adoptNode result"); + +test(_ => { + window.mark = 0; + const d = new DOMParser().parseFromString( + "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml"); + const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0]; + document.body.appendChild(script.cloneNode(true)); + assert_equals(window.mark, 0); +}, "parseFromString as XHTML, script, append cloneNode result"); </script> </body> </html> diff --git a/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html b/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html new file mode 100644 index 0000000..65a1903 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html @@ -0,0 +1,71 @@ +<!doctype html> +<html> +<head> +<title>XMLHttpRequest: script already started</title> +<link rel="help" href="https://xhr.spec.whatwg.org/#document-response"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body> +<script> +// XMLHttpRequest.responseXML creates an XML parser with +// XML scripting support disabled. This test tests that various +// responseXML-parsed script elements are inactive ("already started"). +// +// See: +// https://xhr.spec.whatwg.org/#document-response +// step 6, "with the XML scripting support disabled flag set." +test(_ => { + window.mark = 0; + const xhr = new XMLHttpRequest(); + xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false); + xhr.send(); + assert_not_equals(xhr.responseXML, null); + document.body.appendChild(xhr.responseXML.rootElement); + assert_equals(window.mark, 0); +}, "XMLHttpRequest responseXML, svg script, appendChild"); + +test(_ => { + window.mark = 0; + const xhr = new XMLHttpRequest(); + xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false); + xhr.send(); + assert_not_equals(xhr.responseXML, null); + document.body.appendChild(document.importNode(xhr.responseXML.rootElement, true)); + assert_equals(window.mark, 0); +}, "XMLHttpRequest responseXML, svg script, append importNode result"); + +test(_ => { + window.mark = 0; + const xhr = new XMLHttpRequest(); + xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false); + xhr.send(); + assert_not_equals(xhr.responseXML, null); + document.body.appendChild(document.adoptNode(xhr.responseXML.rootElement)); + assert_equals(window.mark, 0); +}, "XMLHttpRequest responseXML, svg script, append adoptNode result"); + +test(_ => { + window.mark = 0; + const xhr = new XMLHttpRequest(); + xhr.open("GET", "data:application/xhtml+xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", false); + xhr.send(); + assert_not_equals(xhr.responseXML, null); + const script = xhr.responseXML.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0]; + document.body.appendChild(document.importNode(script, true)); + assert_equals(window.mark, 0); +}, "XMLHttpRequest responseXML, xhtml script, append importNode result"); + +test(_ => { + window.mark = 0; + const xhr = new XMLHttpRequest(); + xhr.open("GET", "data:application/xhtml+xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", false); + xhr.send(); + assert_not_equals(xhr.responseXML, null); + const script = xhr.responseXML.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0]; + document.body.appendChild(document.adoptNode(script)); + assert_equals(window.mark, 0); +}, "XMLHttpRequest responseXML, xhtml script, append adoptNode result"); +</script> +</body> +</html>
Regression Test / PoC
diff --git a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
index 6494ae5..22138a8 100644
--- a/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
+++ b/third_party/blink/web_tests/external/wpt/domparsing/DOMParser-parseFromString-xml-scripting-support-disabled.html
@@ -70,6 +70,57 @@
document.body.appendChild(document.importNode(d.rootElement, true));
assert_equals(window.mark, 0);
}, "parseFromString as XML, svg script, append importNode result, but with namespace prefix");
+
+test(_ => {
+ window.mark = 0;
+ const d = new DOMParser().parseFromString(
+ "<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", "text/xml");
+ document.body.appendChild(document.adoptNode(d.rootElement));
+ assert_equals(window.mark, 0);
+}, "parseFromString as XML, svg script, append adoptNode result");
+
+test(_ => {
+ window.mark = 0;
+ const d = new DOMParser().parseFromString(
+ "<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", "text/xml");
+ document.body.appendChild(d.rootElement.cloneNode(true));
+ assert_equals(window.mark, 0);
+}, "parseFromString as XML, svg script, append cloneNode result");
+
+test(_ => {
+ window.mark = 0;
+ const d = new DOMParser().parseFromString(
+ "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+ document.body.appendChild(document.importNode(d.documentElement, true));
+ assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, whole root, append importNode result");
+
+test(_ => {
+ window.mark = 0;
+ const d = new DOMParser().parseFromString(
+ "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+ const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+ document.body.appendChild(document.importNode(script, true));
+ assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, script, append importNode result");
+
+test(_ => {
+ window.mark = 0;
+ const d = new DOMParser().parseFromString(
+ "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+ const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+ document.body.appendChild(document.adoptNode(script));
+ assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, script, append adoptNode result");
+
+test(_ => {
+ window.mark = 0;
+ const d = new DOMParser().parseFromString(
+ "<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", "application/xhtml+xml");
+ const script = d.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+ document.body.appendChild(script.cloneNode(true));
+ assert_equals(window.mark, 0);
+}, "parseFromString as XHTML, script, append cloneNode result");
</script>
</body>
</html>
diff --git a/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html b/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html
new file mode 100644
index 0000000..65a1903
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/xhr/responseXML-xml-scripting-support-disabled.html
@@ -0,0 +1,71 @@
+<!doctype html>
+<html>
+<head>
+<title>XMLHttpRequest: script already started</title>
+<link rel="help" href="https://xhr.spec.whatwg.org/#document-response">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+// XMLHttpRequest.responseXML creates an XML parser with
+// XML scripting support disabled. This test tests that various
+// responseXML-parsed script elements are inactive ("already started").
+//
+// See:
+// https://xhr.spec.whatwg.org/#document-response
+// step 6, "with the XML scripting support disabled flag set."
+test(_ => {
+ window.mark = 0;
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false);
+ xhr.send();
+ assert_not_equals(xhr.responseXML, null);
+ document.body.appendChild(xhr.responseXML.rootElement);
+ assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, svg script, appendChild");
+
+test(_ => {
+ window.mark = 0;
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false);
+ xhr.send();
+ assert_not_equals(xhr.responseXML, null);
+ document.body.appendChild(document.importNode(xhr.responseXML.rootElement, true));
+ assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, svg script, append importNode result");
+
+test(_ => {
+ window.mark = 0;
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", "data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><script>window.mark = 1;</sc" + "ript></svg>", false);
+ xhr.send();
+ assert_not_equals(xhr.responseXML, null);
+ document.body.appendChild(document.adoptNode(xhr.responseXML.rootElement));
+ assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, svg script, append adoptNode result");
+
+test(_ => {
+ window.mark = 0;
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", "data:application/xhtml+xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", false);
+ xhr.send();
+ assert_not_equals(xhr.responseXML, null);
+ const script = xhr.responseXML.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+ document.body.appendChild(document.importNode(script, true));
+ assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, xhtml script, append importNode result");
+
+test(_ => {
+ window.mark = 0;
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", "data:application/xhtml+xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><script>window.mark = 1;</sc" + "ript></body></html>", false);
+ xhr.send();
+ assert_not_equals(xhr.responseXML, null);
+ const script = xhr.responseXML.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "script")[0];
+ document.body.appendChild(document.adoptNode(script));
+ assert_equals(window.mark, 0);
+}, "XMLHttpRequest responseXML, xhtml script, append adoptNode result");
+</script>
+</body>
+</html>