1From 677a42645ef22b5a50741bad5facf9d8a8bc6d21 Mon Sep 17 00:00:00 2001 2From: Nick Wellnhofer <wellnhofer@aevum.de> 3Date: Thu, 28 Jul 2022 20:21:24 +0200 4Subject: [PATCH] Make XPath depth check work with recursive invocations 5 6EXSLT functions like dyn:map or dyn:evaluate invoke xmlXPathRunEval 7recursively. Don't set depth to zero but keep and restore the original 8value to avoid stack overflows when abusing these functions. 9 10Reference:https://github.com/GNOME/libxml2/commit/677a42645ef22b5a50741bad5facf9d8a8bc6d21 11Conflict:NA 12--- 13 xpath.c | 23 +++++++++++++++++------ 14 1 file changed, 17 insertions(+), 6 deletions(-) 15 16diff --git a/xpath.c b/xpath.c 17index e79dcec..85d7919 100644 18--- a/xpath.c 19+++ b/xpath.c 20@@ -13883,12 +13883,11 @@ static int 21 xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool) 22 { 23 xmlXPathCompExprPtr comp; 24+ int oldDepth; 25 26 if ((ctxt == NULL) || (ctxt->comp == NULL)) 27 return(-1); 28 29- ctxt->context->depth = 0; 30- 31 if (ctxt->valueTab == NULL) { 32 /* Allocate the value stack */ 33 ctxt->valueTab = (xmlXPathObjectPtr *) 34@@ -13942,11 +13941,13 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool) 35 "xmlXPathRunEval: last is less than zero\n"); 36 return(-1); 37 } 38+ oldDepth = ctxt->context->depth; 39 if (toBool) 40 return(xmlXPathCompOpEvalToBoolean(ctxt, 41 &comp->steps[comp->last], 0)); 42 else 43 xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]); 44+ ctxt->context->depth = oldDepth; 45 46 return(0); 47 } 48@@ -14217,6 +14218,7 @@ xmlXPathCompExprPtr 49 xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { 50 xmlXPathParserContextPtr pctxt; 51 xmlXPathCompExprPtr comp; 52+ int oldDepth = 0; 53 54 #ifdef XPATH_STREAMING 55 comp = xmlXPathTryStreamCompile(ctxt, str); 56@@ -14230,8 +14232,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { 57 if (pctxt == NULL) 58 return NULL; 59 if (ctxt != NULL) 60- ctxt->depth = 0; 61+ oldDepth = ctxt->depth; 62 xmlXPathCompileExpr(pctxt, 1); 63+ if (ctxt != NULL) 64+ ctxt->depth = oldDepth; 65 66 if( pctxt->error != XPATH_EXPRESSION_OK ) 67 { 68@@ -14252,8 +14256,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { 69 comp = pctxt->comp; 70 if ((comp->nbStep > 1) && (comp->last >= 0)) { 71 if (ctxt != NULL) 72- ctxt->depth = 0; 73+ oldDepth = ctxt->depth; 74 xmlXPathOptimizeExpression(pctxt, &comp->steps[comp->last]); 75+ if (ctxt != NULL) 76+ ctxt->depth = oldDepth; 77 } 78 pctxt->comp = NULL; 79 } 80@@ -14409,6 +14415,7 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { 81 #ifdef XPATH_STREAMING 82 xmlXPathCompExprPtr comp; 83 #endif 84+ int oldDepth = 0; 85 86 if (ctxt == NULL) return; 87 88@@ -14422,8 +14429,10 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { 89 #endif 90 { 91 if (ctxt->context != NULL) 92- ctxt->context->depth = 0; 93+ oldDepth = ctxt->context->depth; 94 xmlXPathCompileExpr(ctxt, 1); 95+ if (ctxt->context != NULL) 96+ ctxt->context->depth = oldDepth; 97 CHECK_ERROR; 98 99 /* Check for trailing characters. */ 100@@ -14432,9 +14441,11 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { 101 102 if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0)) { 103 if (ctxt->context != NULL) 104- ctxt->context->depth = 0; 105+ oldDepth = ctxt->context->depth; 106 xmlXPathOptimizeExpression(ctxt, 107 &ctxt->comp->steps[ctxt->comp->last]); 108+ if (ctxt->context != NULL) 109+ ctxt->context->depth = oldDepth; 110 } 111 } 112 113-- 1142.27.0 115 116