mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibWeb: Generate a simple error page when XML decode/parse fails
This fixes a regression on Acid3, since we are not expected to "best effort" parse XML. The test specifically checks that you don't create an incomplete, incorrect DOM.
This commit is contained in:
parent
5a3efb8842
commit
5ef6df79ed
Notes:
sideshowbarker
2024-07-16 23:38:54 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/5ef6df79ed Pull-request: https://github.com/SerenityOS/serenity/pull/24023
4 changed files with 41 additions and 2 deletions
1
Tests/LibWeb/Text/data/bad.xml
Normal file
1
Tests/LibWeb/Text/data/bad.xml
Normal file
|
@ -0,0 +1 @@
|
|||
<this-will-not-parse
|
3
Tests/LibWeb/Text/expected/XML/error-page.txt
Normal file
3
Tests/LibWeb/Text/expected/XML/error-page.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Got load event
|
||||
[object HTMLDocument]
|
||||
Failed to parse XML document: Expected '>' at offset 21
|
13
Tests/LibWeb/Text/input/XML/error-page.html
Normal file
13
Tests/LibWeb/Text/input/XML/error-page.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<script src="../include.js"></script>
|
||||
<iframe id="i1"></iframe>
|
||||
<script>
|
||||
asyncTest((done) => {
|
||||
i1.src = '../../data/bad.xml';
|
||||
i1.onload = function() {
|
||||
println("Got load event");
|
||||
println(i1.contentDocument);
|
||||
println(i1.contentDocument.documentElement.innerText);
|
||||
done();
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -26,6 +26,17 @@
|
|||
|
||||
namespace Web {
|
||||
|
||||
// Replaces a document's content with a simple error message.
|
||||
static void convert_to_xml_error_document(DOM::Document& document, String error_string)
|
||||
{
|
||||
auto html_element = MUST(DOM::create_element(document, HTML::TagNames::html, Namespace::HTML));
|
||||
auto body_element = MUST(DOM::create_element(document, HTML::TagNames::body, Namespace::HTML));
|
||||
MUST(html_element->append_child(body_element));
|
||||
MUST(body_element->append_child(document.heap().allocate<DOM::Text>(document.realm(), document, error_string)));
|
||||
document.remove_all_children();
|
||||
MUST(document.append_child(html_element));
|
||||
}
|
||||
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOM::Document>> load_markdown_document(HTML::NavigationParams const& navigation_params)
|
||||
{
|
||||
auto extra_head_contents = R"~~~(
|
||||
|
@ -108,8 +119,10 @@ bool build_xml_document(DOM::Document& document, ByteBuffer const& data, Optiona
|
|||
}
|
||||
VERIFY(decoder.has_value());
|
||||
// Well-formed XML documents contain only properly encoded characters
|
||||
if (!decoder->validate(data))
|
||||
if (!decoder->validate(data)) {
|
||||
convert_to_xml_error_document(document, "XML Document contains improperly-encoded characters"_string);
|
||||
return false;
|
||||
}
|
||||
auto source = decoder->to_utf8(data).release_value_but_fixme_should_propagate_errors();
|
||||
XML::Parser parser(source, { .resolve_external_resource = resolve_xml_resource });
|
||||
XMLDocumentBuilder builder { document };
|
||||
|
@ -198,7 +211,7 @@ static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOM::Document>> load_xml_document(HT
|
|||
|
||||
// FIXME: Actually follow the spec! This is just the ad-hoc code we had before, modified somewhat.
|
||||
|
||||
auto document = TRY(DOM::Document::create_and_initialize(DOM::Document::Type::XML, "application/xhtml+xml"_string, navigation_params));
|
||||
auto document = TRY(DOM::Document::create_and_initialize(DOM::Document::Type::XML, type.essence(), navigation_params));
|
||||
|
||||
Optional<String> content_encoding;
|
||||
if (auto maybe_encoding = type.parameters().get("charset"sv); maybe_encoding.has_value())
|
||||
|
@ -219,6 +232,9 @@ static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOM::Document>> load_xml_document(HT
|
|||
if (!decoder->validate(data)) {
|
||||
// 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"_string);
|
||||
|
||||
// NOTE: This ensures that the `load` event gets fired for the frame loading this document.
|
||||
document->completely_finish_loading();
|
||||
return;
|
||||
}
|
||||
|
@ -226,6 +242,9 @@ static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOM::Document>> load_xml_document(HT
|
|||
if (source.is_error()) {
|
||||
// FIXME: Insert error message into the document.
|
||||
dbgln("Failed to decode XML document: {}", source.error());
|
||||
convert_to_xml_error_document(document, MUST(String::formatted("Failed to decode XML document: {}", source.error())));
|
||||
|
||||
// NOTE: This ensures that the `load` event gets fired for the frame loading this document.
|
||||
document->completely_finish_loading();
|
||||
return;
|
||||
}
|
||||
|
@ -235,6 +254,9 @@ static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOM::Document>> load_xml_document(HT
|
|||
if (result.is_error()) {
|
||||
// FIXME: Insert error message into the document.
|
||||
dbgln("Failed to parse XML document: {}", result.error());
|
||||
convert_to_xml_error_document(document, MUST(String::formatted("Failed to parse XML document: {}", result.error())));
|
||||
|
||||
// NOTE: XMLDocumentBuilder ensures that the `load` event gets fired. We don't need to do anything else here.
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue