From 8ee72e493542cc61a0d539143195979adefb5890 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Mon, 16 Jan 2017 14:53:00 +0100 Subject: [PATCH] Detect infinite recursion when evaluating function arguments This fixes a regression introduced when consolidating recursion checks in commit 1c8e0e5. When a function is called recursively during evaluation of its arguments, the recursion check in xsltApplySequenceConstructor is never reached. Readd recursion check in exsltFuncFunctionFunction but use the template depth counter. Fixes bug #777293: https://bugzilla.gnome.org/show_bug.cgi?id=777293 --- libexslt/functions.c | 22 ++++++++++++++++++++-- tests/docs/bug-201.xml | 1 + tests/general/bug-201.err | 6 ++++++ tests/general/bug-201.out | 0 tests/general/bug-201.xsl | 16 ++++++++++++++++ 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 tests/docs/bug-201.xml create mode 100644 tests/general/bug-201.err create mode 100644 tests/general/bug-201.out create mode 100644 tests/general/bug-201.xsl diff --git a/libexslt/functions.c b/libexslt/functions.c index b49fbe6c..c20ca16b 100644 --- a/libexslt/functions.c +++ b/libexslt/functions.c @@ -331,6 +331,21 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) { return; } + /* + * When a function is called recursively during evaluation of its + * arguments, the recursion check in xsltApplySequenceConstructor + * isn't reached. + */ + if (tctxt->depth >= tctxt->maxTemplateDepth) { + xsltTransformError(tctxt, NULL, NULL, + "exsltFuncFunctionFunction: Potentially infinite recursion " + "detected in function {%s}%s.\n", + ctxt->context->functionURI, ctxt->context->function); + tctxt->state = XSLT_STATE_STOPPED; + return; + } + tctxt->depth++; + /* * We have a problem with the evaluation of function parameters. * The original library code did not evaluate XPath expressions until @@ -413,7 +428,7 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) { xsltFreeStackElemList(params); if (data->error != 0) - return; + goto error; if (data->result != NULL) { ret = data->result; @@ -441,10 +456,13 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) { "executing a function\n", ctxt->context->functionURI, ctxt->context->function); xmlFreeNode(fake); - return; + goto error; } xmlFreeNode(fake); valuePush(ctxt, ret); + +error: + tctxt->depth--; } diff --git a/tests/docs/bug-201.xml b/tests/docs/bug-201.xml new file mode 100644 index 00000000..69d62f2c --- /dev/null +++ b/tests/docs/bug-201.xml @@ -0,0 +1 @@ + diff --git a/tests/general/bug-201.err b/tests/general/bug-201.err new file mode 100644 index 00000000..cc563c6c --- /dev/null +++ b/tests/general/bug-201.err @@ -0,0 +1,6 @@ +runtime error: file ./bug-201.xsl line 13 element copy-of +exsltFuncFunctionFunction: Potentially infinite recursion detected in function {test}func. +xmlXPathCompiledEval: evaluation failed +runtime error: file ./bug-201.xsl line 8 element param +Failed to evaluate the expression of variable 'var'. +no result for ./../docs/bug-201.xml diff --git a/tests/general/bug-201.out b/tests/general/bug-201.out new file mode 100644 index 00000000..e69de29b diff --git a/tests/general/bug-201.xsl b/tests/general/bug-201.xsl new file mode 100644 index 00000000..fb2a6c27 --- /dev/null +++ b/tests/general/bug-201.xsl @@ -0,0 +1,16 @@ + + + + + + + + + + + +