From dd4c0f62fa1fd9650aae6b718dd9964a4ffa69b9 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Tue, 18 Mar 2025 11:11:20 +0100 Subject: [PATCH] tree: Fix xmlTextMerge with NULL args Restore pre-2.13 behavior. Fixes #875. --- fuzz/api.c | 15 +++++++++------ tree.c | 14 ++++++++++---- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/fuzz/api.c b/fuzz/api.c index ff3cfd72..ba738db4 100644 --- a/fuzz/api.c +++ b/fuzz/api.c @@ -2461,11 +2461,14 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) { first = getNode(0); second = getNode(1); argsOk = - (first != NULL && first->type == XML_TEXT_NODE && - second != NULL && second->type == XML_TEXT_NODE && - first != second && - first->name == second->name); - if (argsOk) { + first == NULL ? + second != NULL : + second == NULL || + (first->type == XML_TEXT_NODE && + second->type == XML_TEXT_NODE && + first != second && + first->name == second->name); + if (argsOk && second != NULL) { if (second->parent != NULL) parent = second->parent; else @@ -2474,7 +2477,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) { } res = xmlTextMerge(first, second); oomReport = (argsOk && res == NULL); - if (res != NULL) { + if (res != NULL && first != NULL) { removeNode(second); dropNode(parent); checkContent(first); diff --git a/tree.c b/tree.c index 246470a4..7454b07e 100644 --- a/tree.c +++ b/tree.c @@ -5790,15 +5790,21 @@ xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content) { * @first: the first text node * @second: the second text node being merged * - * Merge the second text node into the first. The second node is - * unlinked and freed. + * Merge the second text node into the first. If @first is NULL, + * @second is returned. Otherwise, the second node is unlinked and + * freed. * * Returns the first text node augmented or NULL in case of error. */ xmlNodePtr xmlTextMerge(xmlNodePtr first, xmlNodePtr second) { - if ((first == NULL) || (first->type != XML_TEXT_NODE) || - (second == NULL) || (second->type != XML_TEXT_NODE) || + if (first == NULL) + return(second); + if (second == NULL) + return(first); + + if ((first->type != XML_TEXT_NODE) || + (second->type != XML_TEXT_NODE) || (first == second) || (first->name != second->name)) return(NULL);