File libxml2-CVE-2025-9714-2.patch of Package libxml2.41582

From 64115ed62dd01dab81a9157a54738523fe117333 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 18 Mar 2019 11:34:26 +0100
Subject: [PATCH] Optional recursion limit when evaluating XPath expressions

Useful to avoid call stack overflows when fuzzing.
---
 include/libxml/xpath.h |  5 ++++-
 xpath.c                | 17 +++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

Index: libxml2-2.9.7/include/libxml/xpath.h
===================================================================
--- libxml2-2.9.7.orig/include/libxml/xpath.h
+++ libxml2-2.9.7/include/libxml/xpath.h
@@ -71,7 +71,8 @@ typedef enum {
     XPATH_INVALID_CTXT,
     XPATH_STACK_ERROR,
     XPATH_FORBID_VARIABLE_ERROR,
-    XPATH_OP_LIMIT_EXCEEDED
+    XPATH_OP_LIMIT_EXCEEDED,
+    XPATH_RECURSION_LIMIT_EXCEEDED
 } xmlXPathError;
 
 /*
@@ -357,6 +358,8 @@ struct _xmlXPathContext {
     /* Resource limits */
     unsigned long opLimit;
     unsigned long opCount;
+    int depth;
+    int maxDepth;
 };
 
 /*
Index: libxml2-2.9.7/xpath.c
===================================================================
--- libxml2-2.9.7.orig/xpath.c
+++ libxml2-2.9.7/xpath.c
@@ -646,6 +646,7 @@ static const char *xmlXPathErrorMessages
     "Stack usage error\n",
     "Forbidden variable\n",
     "Operation limit exceeded\n",
+    "Recursion limit exceeded\n",
     "?? Unknown error ??\n"	/* Must be last in the list! */
 };
 #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) /	\
@@ -6205,6 +6206,8 @@ xmlXPathNewContext(xmlDocPtr doc) {
     ret->contextSize = -1;
     ret->proximityPosition = -1;
 
+    ret->maxDepth = INT_MAX;
+
 #ifdef XP_DEFAULT_CACHE_ON
     if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) {
 	xmlXPathFreeContext(ret);
@@ -12806,6 +12809,9 @@ xmlXPathCompOpEvalFirst(xmlXPathParserCo
     CHECK_ERROR0;
     if (OP_LIMIT_EXCEEDED(ctxt, 1))
         return(0);
+    if (ctxt->context->depth >= ctxt->context->maxDepth)
+        XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED);
+    ctxt->context->depth += 1;
     comp = ctxt->comp;
     switch (op->op) {
         case XPATH_OP_END:
@@ -12926,6 +12932,7 @@ xmlXPathCompOpEvalFirst(xmlXPathParserCo
             break;
     }
 
+    ctxt->context->depth -= 1;
     return(total);
 }
 
@@ -12955,6 +12962,9 @@ xmlXPathCompOpEvalLast(xmlXPathParserCon
     CHECK_ERROR0;
     if (OP_LIMIT_EXCEEDED(ctxt, 1))
         return(0);
+    if (ctxt->context->depth >= ctxt->context->maxDepth)
+        XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED);
+    ctxt->context->depth += 1;
     comp = ctxt->comp;
     switch (op->op) {
         case XPATH_OP_END:
@@ -13077,6 +13087,7 @@ xmlXPathCompOpEvalLast(xmlXPathParserCon
             break;
     }
 
+    ctxt->context->depth -= 1;
     return (total);
 }
 
@@ -13396,6 +13407,9 @@ xmlXPathCompOpEval(xmlXPathParserContext
     CHECK_ERROR0;
     if (OP_LIMIT_EXCEEDED(ctxt, 1))
         return(0);
+    if (ctxt->context->depth >= ctxt->context->maxDepth)
+        XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED);
+    ctxt->context->depth += 1;
     comp = ctxt->comp;
     switch (op->op) {
         case XPATH_OP_END:
@@ -14279,6 +14293,7 @@ xmlXPathCompOpEval(xmlXPathParserContext
         break;
     }
 
+    ctxt->context->depth -= 1;
     return (total);
 }
 
@@ -14632,6 +14647,8 @@ xmlXPathRunEval(xmlXPathParserContextPtr
     if ((ctxt == NULL) || (ctxt->comp == NULL))
 	return(-1);
 
+    ctxt->context->depth = 0;
+
     if (ctxt->valueTab == NULL) {
 	/* Allocate the value stack */
 	ctxt->valueTab = (xmlXPathObjectPtr *)
openSUSE Build Service is sponsored by