Commit 1c8e0e55 authored by Nick Wellnhofer's avatar Nick Wellnhofer

Consolidate recursion checks

Move the check for potentially infinite recursion to
xsltApplySequenceConstructor. In this function, both template and
func:function calls can be handled. This also checks for the following
case of infinite recursion in attribute sets found with afl-fuzz:

<x:attribute-set name="set">
    <x:attribute name="attr">
        <elem x:use-attribute-sets="set"/>
    </x:attribute>
</x:attribute-set>

Rename funcLevel to depth and check against maxTemplateDepth. I hope it
isn't a problem to rename an internal struct item.
parent 5816849e
...@@ -56,8 +56,6 @@ static void exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, ...@@ -56,8 +56,6 @@ static void exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt,
int nargs); int nargs);
static exsltFuncFunctionData *exsltFuncNewFunctionData(void); static exsltFuncFunctionData *exsltFuncNewFunctionData(void);
#define MAX_FUNC_RECURSION 1000
/*static const xmlChar *exsltResultDataID = (const xmlChar *) "EXSLT Result";*/ /*static const xmlChar *exsltResultDataID = (const xmlChar *) "EXSLT Result";*/
/** /**
...@@ -332,14 +330,6 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) { ...@@ -332,14 +330,6 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
"param == NULL\n"); "param == NULL\n");
return; return;
} }
if (tctxt->funcLevel > MAX_FUNC_RECURSION) {
xsltGenericError(xsltGenericErrorContext,
"{%s}%s: detected a recursion\n",
ctxt->context->functionURI, ctxt->context->function);
ctxt->error = XPATH_MEMORY_ERROR;
return;
}
tctxt->funcLevel++;
/* /*
* We have a problem with the evaluation of function parameters. * We have a problem with the evaluation of function parameters.
...@@ -423,7 +413,7 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) { ...@@ -423,7 +413,7 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
xsltFreeStackElemList(params); xsltFreeStackElemList(params);
if (data->error != 0) if (data->error != 0)
goto error; return;
if (data->result != NULL) { if (data->result != NULL) {
ret = data->result; ret = data->result;
...@@ -451,13 +441,10 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) { ...@@ -451,13 +441,10 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
"executing a function\n", "executing a function\n",
ctxt->context->functionURI, ctxt->context->function); ctxt->context->functionURI, ctxt->context->function);
xmlFreeNode(fake); xmlFreeNode(fake);
goto error; return;
} }
xmlFreeNode(fake); xmlFreeNode(fake);
valuePush(ctxt, ret); valuePush(ctxt, ret);
error:
tctxt->funcLevel--;
} }
......
...@@ -2378,6 +2378,24 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt, ...@@ -2378,6 +2378,24 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
return; return;
CHECK_STOPPED; CHECK_STOPPED;
/*
* Check for infinite recursion: stop if the maximum of nested templates
* is excceeded. Adjust xsltMaxDepth if you need more.
*/
if (ctxt->depth >= ctxt->maxTemplateDepth) {
xsltTransformError(ctxt, NULL, list,
"xsltApplySequenceConstructor: A potential infinite template "
"recursion was detected.\n"
"You can adjust xsltMaxDepth (--maxdepth) in order to "
"raise the maximum number of nested template calls and "
"variables/params (currently set to %d).\n",
ctxt->maxTemplateDepth);
xsltDebug(ctxt, contextNode, list, NULL);
ctxt->state = XSLT_STATE_STOPPED;
return;
}
ctxt->depth++;
oldLocalFragmentTop = ctxt->localRVT; oldLocalFragmentTop = ctxt->localRVT;
oldInsert = insert = ctxt->insert; oldInsert = insert = ctxt->insert;
oldInst = oldCurInst = ctxt->inst; oldInst = oldCurInst = ctxt->inst;
...@@ -3010,6 +3028,8 @@ error: ...@@ -3010,6 +3028,8 @@ error:
ctxt->inst = oldInst; ctxt->inst = oldInst;
ctxt->insert = oldInsert; ctxt->insert = oldInsert;
ctxt->depth--;
#ifdef WITH_DEBUGGER #ifdef WITH_DEBUGGER
if ((ctxt->debugStatus != XSLT_DEBUG_NONE) && (addCallResult)) { if ((ctxt->debugStatus != XSLT_DEBUG_NONE) && (addCallResult)) {
xslDropCall(); xslDropCall();
...@@ -3076,24 +3096,6 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt, ...@@ -3076,24 +3096,6 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
return; return;
CHECK_STOPPED; CHECK_STOPPED;
/*
* Check for infinite recursion: stop if the maximum of nested templates
* is excceeded. Adjust xsltMaxDepth if you need more.
*/
if (ctxt->templNr >= ctxt->maxTemplateDepth)
{
xsltTransformError(ctxt, NULL, list,
"xsltApplyXSLTTemplate: A potential infinite template recursion "
"was detected.\n"
"You can adjust xsltMaxDepth (--maxdepth) in order to "
"raise the maximum number of nested template calls and "
"variables/params (currently set to %d).\n",
ctxt->maxTemplateDepth);
xsltDebug(ctxt, contextNode, list, NULL);
ctxt->state = XSLT_STATE_STOPPED;
return;
}
if (ctxt->varsNr >= ctxt->maxTemplateVars) if (ctxt->varsNr >= ctxt->maxTemplateVars)
{ {
xsltTransformError(ctxt, NULL, list, xsltTransformError(ctxt, NULL, list,
......
...@@ -1785,7 +1785,7 @@ struct _xsltTransformContext { ...@@ -1785,7 +1785,7 @@ struct _xsltTransformContext {
exits */ exits */
xmlDocPtr localRVTBase; /* Obsolete */ xmlDocPtr localRVTBase; /* Obsolete */
int keyInitLevel; /* Needed to catch recursive keys issues */ int keyInitLevel; /* Needed to catch recursive keys issues */
int funcLevel; /* Needed to catch recursive functions issues */ int depth; /* Needed to catch recursions */
int maxTemplateDepth; int maxTemplateDepth;
int maxTemplateVars; int maxTemplateVars;
}; };
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment