[libxml2] Optional recursion limit when parsing XPath expressions



commit 2d97a97aa515f1bd3efc35c8ea2aa68676c6f8e1
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Fri Mar 15 16:27:58 2019 +0100

    Optional recursion limit when parsing XPath expressions
    
    Useful to avoid call stack overflows when fuzzing. Note that parsing a
    parenthesized expression currently consumes more than 10 stack frames,
    so this limit should be set rather low.

 include/libxml/xpath.h |  1 +
 xpath.c                | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)
---
diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h
index 3d9b1cee..5137de55 100644
--- a/include/libxml/xpath.h
+++ b/include/libxml/xpath.h
@@ -360,6 +360,7 @@ struct _xmlXPathContext {
     unsigned long opCount;
     int depth;
     int maxDepth;
+    int maxParserDepth;
 };
 
 /*
diff --git a/xpath.c b/xpath.c
index 993e016f..a3a2aa62 100644
--- a/xpath.c
+++ b/xpath.c
@@ -6182,6 +6182,7 @@ xmlXPathNewContext(xmlDocPtr doc) {
     ret->proximityPosition = -1;
 
     ret->maxDepth = INT_MAX;
+    ret->maxParserDepth = INT_MAX;
 
 #ifdef XP_DEFAULT_CACHE_ON
     if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) {
@@ -10999,6 +11000,14 @@ xmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) {
  */
 static void
 xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
+    xmlXPathContextPtr xpctxt = ctxt->context;
+
+    if (xpctxt != NULL) {
+        if (xpctxt->depth >= xpctxt->maxParserDepth)
+            XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED);
+        xpctxt->depth += 1;
+    }
+
     xmlXPathCompAndExpr(ctxt);
     CHECK_ERROR;
     SKIP_BLANKS;
@@ -11020,6 +11029,9 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
        */
        PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0);
     }
+
+    if (xpctxt != NULL)
+        xpctxt->depth -= 1;
 }
 
 /**
@@ -14727,6 +14739,8 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
     pctxt = xmlXPathNewParserContext(str, ctxt);
     if (pctxt == NULL)
         return NULL;
+    if (ctxt != NULL)
+        ctxt->depth = 0;
     xmlXPathCompileExpr(pctxt, 1);
 
     if( pctxt->error != XPATH_EXPRESSION_OK )
@@ -14915,6 +14929,8 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
     } else
 #endif
     {
+        if (ctxt->context != NULL)
+            ctxt->context->depth = 0;
        xmlXPathCompileExpr(ctxt, 1);
         CHECK_ERROR;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]