LibWeb: Ensure XML error documents always finish loading

In some cases, the XML error document would never be marked as ready for
post-load tasks, even though a load event got fired. This caused
intermittent timeouts on our iframe-load-event-for-bad-xml.html test.

Make XML error document conversion finish loading when the parser has
not already queued post-load tasks. This lets bad XML iframe loads fire
load instead of leaving the parent parser waiting indefinitely.

Also install the test's iframe load handler before assigning src to
avoid a potential race condition there.
This commit is contained in:
Sam Atkins 2026-05-21 17:41:48 +01:00
parent c1f38f92fe
commit 16f7333586
2 changed files with 9 additions and 9 deletions

View file

@ -46,6 +46,14 @@ static void convert_to_xml_error_document(DOM::Document& document, Utf16String e
MUST(body_element->append_child(document.realm().create<DOM::Text>(document, move(error_string))));
document.remove_all_children();
MUST(document.append_child(html_element));
if (document.ready_for_post_load_tasks())
return;
if (!document.is_completely_loaded())
document.completely_finish_loading();
document.set_ready_for_post_load_tasks(true);
}
bool build_xml_document(DOM::Document& document, ByteBuffer const& data, Optional<String> content_encoding)
@ -185,9 +193,6 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_xml_document(HTML::Navig
// FIXME: Insert error message into the document.
dbgln("XML Document contains improperly-encoded characters");
convert_to_xml_error_document(document, "XML Document contains improperly-encoded characters"_utf16);
// NB: This ensures that the `load` event gets fired for the frame loading this document.
document->completely_finish_loading();
return;
}
auto source = decoder->to_utf8(data);
@ -195,9 +200,6 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_xml_document(HTML::Navig
// FIXME: Insert error message into the document.
dbgln("Failed to decode XML document: {}", source.error());
convert_to_xml_error_document(document, Utf16String::formatted("Failed to decode XML document: {}", source.error()));
// NB: This ensures that the `load` event gets fired for the frame loading this document.
document->completely_finish_loading();
return;
}
auto run_xml_parser = [document, source_string = source.release_value()] {
@ -208,8 +210,6 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_xml_document(HTML::Navig
// FIXME: Insert error message into the document.
dbgln("Failed to parse XML document: {}", result.error());
convert_to_xml_error_document(document, Utf16String::formatted("Failed to parse XML document: {}", result.error()));
// NB: XMLDocumentBuilder ensures that the `load` event gets fired. We don't need to do anything else here.
}
};
if (document->ready_to_run_scripts()) {

View file

@ -3,10 +3,10 @@
<script src="../include.js"></script>
<script>
asyncTest((done) => {
i1.src = "data:application/xml;charset=utf-8;base64,vwo=";
i1.onload = function() {
println("OK");
done();
}
i1.src = "data:application/xml;charset=utf-8;base64,vwo=";
});
</script>