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 {
|
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)
|
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOM::Document>> load_markdown_document(HTML::NavigationParams const& navigation_params)
|
||||||
{
|
{
|
||||||
auto extra_head_contents = R"~~~(
|
auto extra_head_contents = R"~~~(
|
||||||
|
@ -108,8 +119,10 @@ bool build_xml_document(DOM::Document& document, ByteBuffer const& data, Optiona
|
||||||
}
|
}
|
||||||
VERIFY(decoder.has_value());
|
VERIFY(decoder.has_value());
|
||||||
// Well-formed XML documents contain only properly encoded characters
|
// 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;
|
return false;
|
||||||
|
}
|
||||||
auto source = decoder->to_utf8(data).release_value_but_fixme_should_propagate_errors();
|
auto source = decoder->to_utf8(data).release_value_but_fixme_should_propagate_errors();
|
||||||
XML::Parser parser(source, { .resolve_external_resource = resolve_xml_resource });
|
XML::Parser parser(source, { .resolve_external_resource = resolve_xml_resource });
|
||||||
XMLDocumentBuilder builder { document };
|
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.
|
// 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;
|
Optional<String> content_encoding;
|
||||||
if (auto maybe_encoding = type.parameters().get("charset"sv); maybe_encoding.has_value())
|
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)) {
|
if (!decoder->validate(data)) {
|
||||||
// FIXME: Insert error message into the document.
|
// FIXME: Insert error message into the document.
|
||||||
dbgln("XML Document contains improperly-encoded characters");
|
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();
|
document->completely_finish_loading();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -226,6 +242,9 @@ static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOM::Document>> load_xml_document(HT
|
||||||
if (source.is_error()) {
|
if (source.is_error()) {
|
||||||
// FIXME: Insert error message into the document.
|
// FIXME: Insert error message into the document.
|
||||||
dbgln("Failed to decode XML document: {}", source.error());
|
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();
|
document->completely_finish_loading();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -235,6 +254,9 @@ static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOM::Document>> load_xml_document(HT
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
// FIXME: Insert error message into the document.
|
// FIXME: Insert error message into the document.
|
||||||
dbgln("Failed to parse XML document: {}", result.error());
|
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