• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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