From 677a42645ef22b5a50741bad5facf9d8a8bc6d21 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 28 Jul 2022 20:21:24 +0200 Subject: [PATCH] Make XPath depth check work with recursive invocations EXSLT functions like dyn:map or dyn:evaluate invoke xmlXPathRunEval recursively. Don't set depth to zero but keep and restore the original value to avoid stack overflows when abusing these functions. Reference:https://github.com/GNOME/libxml2/commit/677a42645ef22b5a50741bad5facf9d8a8bc6d21 Conflict:NA --- xpath.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/xpath.c b/xpath.c index e79dcec..85d7919 100644 --- a/xpath.c +++ b/xpath.c @@ -13883,12 +13883,11 @@ static int xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool) { xmlXPathCompExprPtr comp; + int oldDepth; if ((ctxt == NULL) || (ctxt->comp == NULL)) return(-1); - ctxt->context->depth = 0; - if (ctxt->valueTab == NULL) { /* Allocate the value stack */ ctxt->valueTab = (xmlXPathObjectPtr *) @@ -13942,11 +13941,13 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool) "xmlXPathRunEval: last is less than zero\n"); return(-1); } + oldDepth = ctxt->context->depth; if (toBool) return(xmlXPathCompOpEvalToBoolean(ctxt, &comp->steps[comp->last], 0)); else xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]); + ctxt->context->depth = oldDepth; return(0); } @@ -14217,6 +14218,7 @@ xmlXPathCompExprPtr xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { xmlXPathParserContextPtr pctxt; xmlXPathCompExprPtr comp; + int oldDepth = 0; #ifdef XPATH_STREAMING comp = xmlXPathTryStreamCompile(ctxt, str); @@ -14230,8 +14232,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { if (pctxt == NULL) return NULL; if (ctxt != NULL) - ctxt->depth = 0; + oldDepth = ctxt->depth; xmlXPathCompileExpr(pctxt, 1); + if (ctxt != NULL) + ctxt->depth = oldDepth; if( pctxt->error != XPATH_EXPRESSION_OK ) { @@ -14252,8 +14256,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { comp = pctxt->comp; if ((comp->nbStep > 1) && (comp->last >= 0)) { if (ctxt != NULL) - ctxt->depth = 0; + oldDepth = ctxt->depth; xmlXPathOptimizeExpression(pctxt, &comp->steps[comp->last]); + if (ctxt != NULL) + ctxt->depth = oldDepth; } pctxt->comp = NULL; } @@ -14409,6 +14415,7 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { #ifdef XPATH_STREAMING xmlXPathCompExprPtr comp; #endif + int oldDepth = 0; if (ctxt == NULL) return; @@ -14422,8 +14429,10 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { #endif { if (ctxt->context != NULL) - ctxt->context->depth = 0; + oldDepth = ctxt->context->depth; xmlXPathCompileExpr(ctxt, 1); + if (ctxt->context != NULL) + ctxt->context->depth = oldDepth; CHECK_ERROR; /* Check for trailing characters. */ @@ -14432,9 +14441,11 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0)) { if (ctxt->context != NULL) - ctxt->context->depth = 0; + oldDepth = ctxt->context->depth; xmlXPathOptimizeExpression(ctxt, &ctxt->comp->steps[ctxt->comp->last]); + if (ctxt->context != NULL) + ctxt->context->depth = oldDepth; } } -- 2.27.0