diff --git a/fuzz/xpath.c b/fuzz/xpath.c index 097eb8ea..767acb98 100644 --- a/fuzz/xpath.c +++ b/fuzz/xpath.c @@ -33,8 +33,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) { if (doc != NULL) { xmlXPathContextPtr xpctxt = xmlXPathNewContext(doc); - /* Resource limits to avoid timeouts and call stack overflows */ - xpctxt->maxDepth = 500; + /* Operation limit to avoid timeout */ xpctxt->opLimit = 500000; xmlXPathFreeObject(xmlXPtrEval(BAD_CAST expr, xpctxt)); diff --git a/xpath.c b/xpath.c index c018d031..2850a1ac 100644 --- a/xpath.c +++ b/xpath.c @@ -135,6 +135,17 @@ */ #define XPATH_MAX_NODESET_LENGTH 10000000 +/* + * XPATH_MAX_RECRUSION_DEPTH: + * Maximum amount of nested functions calls when parsing or evaluating + * expressions + */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +#define XPATH_MAX_RECURSION_DEPTH 500 +#else +#define XPATH_MAX_RECURSION_DEPTH 5000 +#endif + /* * TODO: * There are a few spots where some tests are done which depend upon ascii @@ -6118,8 +6129,6 @@ 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); @@ -10947,7 +10956,7 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) { xmlXPathContextPtr xpctxt = ctxt->context; if (xpctxt != NULL) { - if (xpctxt->depth >= xpctxt->maxDepth) + if (xpctxt->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED); /* * Parsing a single '(' pushes about 10 functions on the call stack @@ -11883,7 +11892,7 @@ xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt, "xmlXPathCompOpEvalPredicate: Expected a predicate\n"); XP_ERROR(XPATH_INVALID_OPERAND); } - if (ctxt->context->depth >= ctxt->context->maxDepth) + if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED); ctxt->context->depth += 1; xmlXPathCompOpEvalPredicate(ctxt, &comp->steps[op->ch1], set, @@ -12599,7 +12608,7 @@ xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, CHECK_ERROR0; if (OP_LIMIT_EXCEEDED(ctxt, 1)) return(0); - if (ctxt->context->depth >= ctxt->context->maxDepth) + if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); ctxt->context->depth += 1; comp = ctxt->comp; @@ -12740,7 +12749,7 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, CHECK_ERROR0; if (OP_LIMIT_EXCEEDED(ctxt, 1)) return(0); - if (ctxt->context->depth >= ctxt->context->maxDepth) + if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); ctxt->context->depth += 1; comp = ctxt->comp; @@ -12958,7 +12967,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) CHECK_ERROR0; if (OP_LIMIT_EXCEEDED(ctxt, 1)) return(0); - if (ctxt->context->depth >= ctxt->context->maxDepth) + if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); ctxt->context->depth += 1; comp = ctxt->comp; @@ -14192,7 +14201,7 @@ xmlXPathOptimizeExpression(xmlXPathParserContextPtr pctxt, /* Recurse */ ctxt = pctxt->context; if (ctxt != NULL) { - if (ctxt->depth >= ctxt->maxDepth) + if (ctxt->depth >= XPATH_MAX_RECURSION_DEPTH) return; ctxt->depth += 1; }