LibXML: Add parser hooks for CDATASection and ProcessingInstructions

This allows listeners to be notified when a CDATASection or
ProcessingInstruction is encountered during parsing. The non-listener
path still has the incorrect behavior of silently treating CDATASection
as Text nodes, but this allows listeners to handle them correctly.
This commit is contained in:
Andrew Kaster 2025-07-18 12:32:50 -06:00 committed by Ali Mohammad Pur
commit d9976b98b9
Notes: github-actions[bot] 2025-07-19 12:57:43 +00:00
2 changed files with 28 additions and 2 deletions

View file

@ -136,6 +136,27 @@ void Parser::append_comment(StringView text, LineTrackingLexer::Position positio
});
}
void Parser::append_cdata_section(StringView text, LineTrackingLexer::Position position)
{
if (m_listener) {
m_listener->cdata_section(text);
return;
}
// FIXME: Non-listener parsing should probably expect a CDATA node as well
append_text(text, position);
}
void Parser::append_processing_instruction(StringView target, StringView data)
{
if (m_listener) {
m_listener->processing_instruction(target, data);
return;
}
m_processing_instructions.set(target, data);
}
void Parser::enter_node(Node& node)
{
if (m_listener) {
@ -505,7 +526,8 @@ ErrorOr<void, ParseError> Parser::parse_processing_instruction()
data = m_lexer.consume_until("?>");
TRY(expect("?>"sv));
m_processing_instructions.set(target, data);
append_processing_instruction(target, data);
rollback.disarm();
return {};
}
@ -898,7 +920,7 @@ ErrorOr<void, ParseError> Parser::parse_content()
}
if (auto result = parse_cdata_section(); !result.is_error()) {
if (m_options.preserve_cdata)
append_text(result.release_value(), m_lexer.position_for(node_start));
append_cdata_section(result.release_value(), m_lexer.position_for(node_start));
goto try_char_data;
}
if (auto result = parse_processing_instruction(); !result.is_error())

View file

@ -40,6 +40,8 @@ struct Listener {
virtual void element_start(Name const&, HashMap<Name, ByteString> const&) { }
virtual void element_end(Name const&) { }
virtual void text(StringView) { }
virtual void cdata_section(StringView) { }
virtual void processing_instruction(StringView, StringView) { }
virtual void comment(StringView) { }
virtual void error(ParseError const&) { }
};
@ -82,6 +84,8 @@ private:
void append_node(NonnullOwnPtr<Node>);
void append_text(StringView, LineTrackingLexer::Position);
void append_comment(StringView, LineTrackingLexer::Position);
void append_cdata_section(StringView, LineTrackingLexer::Position);
void append_processing_instruction(StringView target, StringView data);
void enter_node(Node&);
void leave_node();