Friday, 11 August 2023

[PATCH 2/2] bindings/xml/libxml_xmlparser.c: fix segfault on malformed document

At the end of xml_parser_start_element_ns(), we try to iterate from
some previous node "n" up to the current one, adding elements to the
DOM one-at-a-time:

/* Now, mirror nodes in the DOM */
for (; n != parser->xml_ctx->node; n = n->next) {
xml_parser_add_node(parser, parent->_private, n);
}

In at least one case, test/ns-afl-svg/2495.svg from the libsvgtiny
test suite, we find ourselves in this situation when n is equal to
parent->children, but n->next is NULL. Thus we wind up passing NULL to
xml_parser_add_node(), and ultimately, segfaulting.

Checking for n != NULL in the loop avoids the crash, causing the
libsvgtiny test to return svgtiny_LIBDOM_ERROR instead.
---
bindings/xml/libxml_xmlparser.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/bindings/xml/libxml_xmlparser.c b/bindings/xml/libxml_xmlparser.c
index 57f3f47..13e4858 100644
--- a/bindings/xml/libxml_xmlparser.c
+++ b/bindings/xml/libxml_xmlparser.c
@@ -449,11 +449,16 @@ void xml_parser_start_element_ns(void *ctx, const xmlChar *localname,
n = n->next;
}

- /* Now, mirror nodes in the DOM */
- for (; n != parser->xml_ctx->node; n = n->next) {
+ /* Now, mirror nodes in the DOM. We check for n !=
+ NULL because in pathological cases, we can have a
+ valid n == parent->children pointer from above
+ having n->next == NULL; we would never reach
+ parser->xml_ctx->node by iterating forward. */
+ while (n != NULL && n != parser->xml_ctx->node) {
xml_parser_add_node(parser,
(struct dom_node *) parent->_private,
n);
+ n = n->next;
}
}

--
2.41.0
_______________________________________________
netsurf-dev mailing list -- netsurf-dev@netsurf-browser.org
To unsubscribe send an email to netsurf-dev-leave@netsurf-browser.org

No comments:

Post a Comment