fix(js): surface a parsererror for malformed XML in DOMParser

DOMParser.parseFromString always HTML-parsed, even for XML mime types, so
malformed XML never produced the <parsererror> element Chrome emits and
error-detection code (doc.querySelector('parsererror')) never triggered. obscura
has no XML parser, so full XML semantics stay out of scope; instead, for XML
mime types run a conservative well-formedness check (tag balance, single root,
terminated comment/CDATA/PI, skipping quoted attribute regions) and, on a clear
error, make the document surface a <parsererror>. The check defaults to
well-formed when ambiguous, so valid XML is never falsely flagged.

Fixes #504
This commit is contained in:
Andrey Mnatsakanov committed 2026-08-04 08:43:45 +02:00
1 parent f0541f40a4
commit 53295faa59
2 files changed
+88 -1

No files matched your search

+28
View File
@@ -1676,6 +1676,34 @@ mod tests {
);
}
#[test]
fn dom_parser_flags_malformed_xml_with_parsererror() {
let mut rt = setup_runtime("<html><body></body></html>");
let has_err = rt
.evaluate("(function(){var d=new DOMParser().parseFromString('<a><b></a>','application/xml'); return d.querySelector('parsererror') ? true : false;})()")
.unwrap();
assert_eq!(has_err, serde_json::json!(true));
}
#[test]
fn dom_parser_accepts_well_formed_xml() {
let mut rt = setup_runtime("<html><body></body></html>");
let ok = rt
.evaluate("(function(){var d=new DOMParser().parseFromString('<root><child>x</child></root>','application/xml'); return d.querySelector('parsererror') ? 'ERR' : 'OK';})()")
.unwrap();
assert_eq!(ok, serde_json::json!("OK"));
}
#[test]
fn dom_parser_html_never_gets_parsererror() {
// HTML parsing is tolerant and must never synthesize a parsererror.
let mut rt = setup_runtime("<html><body></body></html>");
let ok = rt
.evaluate("(function(){var d=new DOMParser().parseFromString('<div><p>hi</a>','text/html'); return d.querySelector('parsererror') ? 'ERR' : 'OK';})()")
.unwrap();
assert_eq!(ok, serde_json::json!("OK"));
}
#[test]
fn test_document_title() {
let mut rt = setup_runtime("<html><head><title>Test</title></head><body></body></html>");