LibWeb: Set Document origin for DOMParser created documents

Previously, a crash would occur when accessing the origin of a document
created with DOMParser.
This commit is contained in:
Tim Ledbetter 2025-07-04 20:29:03 +01:00 committed by Shannon Booth
commit 66ca4496c3
Notes: github-actions[bot] 2025-07-06 01:41:13 +00:00
3 changed files with 67 additions and 3 deletions

View file

@ -43,18 +43,18 @@ GC::Ref<DOM::Document> DOMParser::parse_from_string(StringView string, Bindings:
// 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.
GC::Ptr<DOM::Document> document;
auto& associated_document = as<HTML::Window>(relevant_global_object(*this)).associated_document();
// 3. Switch on type:
if (type == Bindings::DOMParserSupportedType::Text_Html) {
// -> "text/html"
document = HTML::HTMLDocument::create(realm(), as<HTML::Window>(relevant_global_object(*this)).associated_document().url());
document->set_content_type(Bindings::idl_enum_to_string(type));
document = HTML::HTMLDocument::create(realm(), associated_document.url());
// 1. Parse HTML from a string given document and compliantString. FIXME: Use compliantString.
document->parse_html_from_a_string(string);
} else {
// -> Otherwise
document = DOM::XMLDocument::create(realm(), as<HTML::Window>(relevant_global_object(*this)).associated_document().url());
document = DOM::XMLDocument::create(realm(), associated_document.url());
document->set_content_type(Bindings::idl_enum_to_string(type));
document->set_document_type(DOM::Document::Type::XML);
@ -76,6 +76,11 @@ GC::Ref<DOM::Document> DOMParser::parse_from_string(StringView string, Bindings:
}
}
// AD-HOC: Setting the origin to match that of the associated document matches the behavior of existing browsers
// and avoids a crash, since we expect the origin to always be set.
// Spec issue: https://github.com/whatwg/html/issues/11429
document->set_origin(associated_document.origin());
// 3. Return document.
return *document;
}

View file

@ -0,0 +1,8 @@
Harness status: OK
Found 3 tests
3 Pass
Pass Created with the createDocument/createDocumentType
Pass Created with the createHTMLDocument
Pass Created with DOMParser

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Cloning of a document with a doctype</title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-node-clonenode">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-node-clone">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
"use strict";
test(() => {
const doctype = document.implementation.createDocumentType("name", "publicId", "systemId");
const doc = document.implementation.createDocument("namespace", "", doctype);
const clone = doc.cloneNode(true);
assert_equals(clone.childNodes.length, 1, "Only one child node");
assert_equals(clone.childNodes[0].nodeType, Node.DOCUMENT_TYPE_NODE, "Is a document fragment");
assert_equals(clone.childNodes[0].name, "name");
assert_equals(clone.childNodes[0].publicId, "publicId");
assert_equals(clone.childNodes[0].systemId, "systemId");
}, "Created with the createDocument/createDocumentType");
test(() => {
const doc = document.implementation.createHTMLDocument();
const clone = doc.cloneNode(true);
assert_equals(clone.childNodes.length, 2, "Two child nodes");
assert_equals(clone.childNodes[0].nodeType, Node.DOCUMENT_TYPE_NODE, "Is a document fragment");
assert_equals(clone.childNodes[0].name, "html");
assert_equals(clone.childNodes[0].publicId, "");
assert_equals(clone.childNodes[0].systemId, "");
}, "Created with the createHTMLDocument");
test(() => {
const parser = new window.DOMParser();
const doc = parser.parseFromString("<!DOCTYPE html><html></html>", "text/html");
const clone = doc.cloneNode(true);
assert_equals(clone.childNodes.length, 2, "Two child nodes");
assert_equals(clone.childNodes[0].nodeType, Node.DOCUMENT_TYPE_NODE, "Is a document fragment");
assert_equals(clone.childNodes[0].name, "html");
assert_equals(clone.childNodes[0].publicId, "");
assert_equals(clone.childNodes[0].systemId, "");
}, "Created with DOMParser");
</script>