From 0e50b31902cdb1eb242eb361c123e9e033b2af87 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Moreno Date: Wed, 8 Oct 2025 09:18:51 +0200 Subject: [PATCH] Ignore next/prev of documents when traversing XPath See https://gitlab.gnome.org/GNOME/libxml2/-/issues/996 --- xpath.c | 66 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 17 deletions(-) Index: libxml2-2.14.5/xpath.c =================================================================== --- libxml2-2.14.5.orig/xpath.c +++ libxml2-2.14.5/xpath.c @@ -6814,12 +6814,18 @@ xmlNodePtr xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || - (ctxt->context->node->type == XML_NAMESPACE_DECL)) - return(NULL); + (ctxt->context->node->type == XML_NAMESPACE_DECL)) + return(NULL); + if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); + if (cur == NULL) - return(ctxt->context->node->next); + cur = ctxt->context->node; + + if (cur->type == XML_DOCUMENT_NODE) + return(NULL); + return(cur->next); } @@ -6839,17 +6845,23 @@ xmlNodePtr xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) || - (ctxt->context->node->type == XML_NAMESPACE_DECL)) - return(NULL); + (ctxt->context->node->type == XML_NAMESPACE_DECL)) + return(NULL); + if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); - if (cur == NULL) - return(ctxt->context->node->prev); - if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) { - cur = cur->prev; - if (cur == NULL) - return(ctxt->context->node->prev); + + if (cur == NULL) { + cur = ctxt->context->node; + } else if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) { + cur = cur->prev; + if (cur == NULL) + cur = ctxt->context->node; } + + if (cur->type == XML_DOCUMENT_NODE) + return(NULL); + return(cur->prev); } @@ -6886,14 +6898,27 @@ xmlXPathNextFollowing(xmlXPathParserCont cur = (xmlNodePtr) ns->next; } } - if (cur == NULL) return(NULL) ; /* ERROR */ - if (cur->next != NULL) return(cur->next) ; + + /* ERROR */ + if (cur == NULL) + return(NULL); + + if (cur->type == XML_DOCUMENT_NODE) + return(NULL); + + if (cur->next != NULL) + return(cur->next); + do { cur = cur->parent; - if (cur == NULL) break; - if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); - if (cur->next != NULL) return(cur->next); + if (cur == NULL) + break; + if (cur == (xmlNodePtr) ctxt->context->doc) + return(NULL); + if (cur->next != NULL && cur->type != XML_DOCUMENT_NODE) + return(cur->next); } while (cur != NULL); + return(cur); } @@ -7011,10 +7036,13 @@ xmlXPathNextPrecedingInternal(xmlXPathPa } ctxt->ancestor = cur->parent; } - if (cur->type == XML_NAMESPACE_DECL) + + if (cur->type == XML_NAMESPACE_DECL || cur->type == XML_DOCUMENT_NODE) return(NULL); + if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) cur = cur->prev; + while (cur->prev == NULL) { cur = cur->parent; if (cur == NULL) @@ -7025,6 +7053,10 @@ xmlXPathNextPrecedingInternal(xmlXPathPa return (cur); ctxt->ancestor = cur->parent; } + + if (cur->type == XML_DOCUMENT_NODE) + return(NULL); + cur = cur->prev; while (cur->last != NULL) cur = cur->last;