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-le...@netsurf-browser.org