From adff7c36bde51aee2c1f12d1a85282e9302aa40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Carretero?= Date: Mon, 19 Mar 2012 15:06:53 +0800 Subject: [PATCH] Allow per-context override of xsltMaxDepth, introduce xsltMaxVars We also add a maxTemplateVars parameter --- doc/APIfiles.html | 1 + doc/libxslt-api.xml | 2 ++ doc/libxslt-decl.txt | 4 ++++ doc/libxslt-refs.xml | 3 +++ doc/symbols.xml | 1 + libxslt/libxslt.syms | 1 + libxslt/transform.c | 20 +++++++++++++++++--- libxslt/xslt.h | 7 +++++++ libxslt/xsltInternals.h | 2 ++ win32/libxslt.def.src | 1 + win32/libxslt/libxslt.def | 1 + xsltproc/xsltproc.c | 15 ++++++++++++++- 12 files changed, 54 insertions(+), 4 deletions(-) diff --git a/doc/APIfiles.html b/doc/APIfiles.html index 4c312dc6..d199166d 100644 --- a/doc/APIfiles.html +++ b/doc/APIfiles.html @@ -221,6 +221,7 @@ A:link, A:visited, A:active { text-decoration: underline } xsltLibxmlVersion
xsltLibxsltVersion
xsltMaxDepth
+xsltMaxVars

Module xsltInternals:

CHECK_STOPPED
CHECK_STOPPED0
CHECK_STOPPEDE
diff --git a/doc/libxslt-api.xml b/doc/libxslt-api.xml index d0ed1a22..fbc32de9 100644 --- a/doc/libxslt-api.xml +++ b/doc/libxslt-api.xml @@ -291,6 +291,7 @@ + @@ -1560,6 +1561,7 @@ exits'/> + Add template "call" to call stack diff --git a/doc/libxslt-decl.txt b/doc/libxslt-decl.txt index f0182741..423230ec 100644 --- a/doc/libxslt-decl.txt +++ b/doc/libxslt-decl.txt @@ -238,6 +238,10 @@ extern const xmlChar *xsltExtMarker; extern int xsltMaxDepth; +xsltMaxVars +extern int xsltMaxVars; + + xsltEngineVersion extern const char *xsltEngineVersion; diff --git a/doc/libxslt-refs.xml b/doc/libxslt-refs.xml index c21e6d23..33adb261 100644 --- a/doc/libxslt-refs.xml +++ b/doc/libxslt-refs.xml @@ -352,6 +352,7 @@ + @@ -937,6 +938,7 @@ + @@ -2169,6 +2171,7 @@ + diff --git a/doc/symbols.xml b/doc/symbols.xml index 2eea92c2..9e199e86 100644 --- a/doc/symbols.xml +++ b/doc/symbols.xml @@ -221,6 +221,7 @@ xsltLibxmlVersion xsltLibxsltVersion xsltMaxDepth + xsltMaxVars xsltParseStylesheetImportedDoc xsltSetCtxtSortFunc xsltSetSortFunc diff --git a/libxslt/libxslt.syms b/libxslt/libxslt.syms index 45fa74bf..7a7e6c34 100644 --- a/libxslt/libxslt.syms +++ b/libxslt/libxslt.syms @@ -307,6 +307,7 @@ LIBXML2_1.0.24 { xsltLibxmlVersion; # variable xsltLibxsltVersion; # variable xsltMaxDepth; # variable + xsltMaxVars; # variable # xsltInternals xsltParseStylesheetImportedDoc; diff --git a/libxslt/transform.c b/libxslt/transform.c index 948d7d04..53eefcc3 100644 --- a/libxslt/transform.c +++ b/libxslt/transform.c @@ -64,6 +64,7 @@ static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID, #endif int xsltMaxDepth = 3000; +int xsltMaxVars = 15000; /* * Useful macros @@ -504,6 +505,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { cur->templNr = 0; cur->templMax = 5; cur->templ = NULL; + cur->maxTemplateDepth = xsltMaxDepth; /* * initialize the variables stack @@ -519,6 +521,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { cur->varsMax = 10; cur->vars = NULL; cur->varsBase = 0; + cur->maxTemplateVars = xsltMaxVars; /* * the profiling stack is not initialized by default @@ -2983,8 +2986,7 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt, * Check for infinite recursion: stop if the maximum of nested templates * is excceeded. Adjust xsltMaxDepth if you need more. */ - if (((ctxt->templNr >= xsltMaxDepth) || - (ctxt->varsNr >= 5 * xsltMaxDepth))) + if (ctxt->templNr >= ctxt->maxTemplateDepth) { xsltTransformError(ctxt, NULL, list, "xsltApplyXSLTTemplate: A potential infinite template recursion " @@ -2992,11 +2994,23 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt, "You can adjust xsltMaxDepth (--maxdepth) in order to " "raise the maximum number of nested template calls and " "variables/params (currently set to %d).\n", - xsltMaxDepth); + ctxt->maxTemplateDepth); xsltDebug(ctxt, contextNode, list, NULL); return; } + if (ctxt->varsNr >= ctxt->maxTemplateVars) + { + xsltTransformError(ctxt, NULL, list, + "xsltApplyXSLTTemplate: A potential infinite template recursion " + "was detected.\n" + "You can adjust maxTemplateVars (--maxvars) in order to " + "raise the maximum number of variables/params (currently set to %d).\n", + ctxt->maxTemplateVars); + xsltDebug(ctxt, contextNode, list, NULL); + return; + } + oldUserFragmentTop = ctxt->tmpRVT; ctxt->tmpRVT = NULL; oldLocalFragmentTop = ctxt->localRVT; diff --git a/libxslt/xslt.h b/libxslt/xslt.h index 849b03c4..13a68be6 100644 --- a/libxslt/xslt.h +++ b/libxslt/xslt.h @@ -61,6 +61,13 @@ extern "C" { */ XSLTPUBVAR int xsltMaxDepth; +/** + * * xsltMaxVars: + * * + * * This value is used to detect templates loops. + * */ +XSLTPUBVAR int xsltMaxVars; + /** * xsltEngineVersion: * diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h index 764fe8c3..afb2a2c4 100644 --- a/libxslt/xsltInternals.h +++ b/libxslt/xsltInternals.h @@ -1780,6 +1780,8 @@ struct _xsltTransformContext { xmlDocPtr localRVTBase; int keyInitLevel; /* Needed to catch recursive keys issues */ int funcLevel; /* Needed to catch recursive functions issues */ + int maxTemplateDepth; + int maxTemplateVars; }; /** diff --git a/win32/libxslt.def.src b/win32/libxslt.def.src index 892d34be..1d17bac5 100644 --- a/win32/libxslt.def.src +++ b/win32/libxslt.def.src @@ -12,6 +12,7 @@ xsltGenericErrorContext DATA xsltLibxmlVersion DATA xsltLibxsltVersion DATA xsltMaxDepth DATA +xsltMaxVars DATA xsltXSLTAttrMarker DATA xslAddCall xslDropCall diff --git a/win32/libxslt/libxslt.def b/win32/libxslt/libxslt.def index 0992b4aa..dc6f1a05 100644 --- a/win32/libxslt/libxslt.def +++ b/win32/libxslt/libxslt.def @@ -134,6 +134,7 @@ EXPORTS xsltSaveResultToFd xsltMaxDepth + xsltMaxVars xsltSetXIncludeDefault xsltLibxmlVersion xsltLibxsltVersion diff --git a/xsltproc/xsltproc.c b/xsltproc/xsltproc.c index 3e1a5406..e9381061 100644 --- a/xsltproc/xsltproc.c +++ b/xsltproc/xsltproc.c @@ -466,6 +466,9 @@ xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) { if (xinclude) ctxt->xinclude = 1; #endif + ctxt->maxTemplateDepth = xsltMaxDepth; + ctxt->maxTemplateVars = xsltMaxVars; + if (profile) { ret = xsltRunStylesheetUser(cur, doc, params, output, NULL, NULL, stderr, ctxt); @@ -501,7 +504,8 @@ static void usage(const char *name) { printf("\t--novalid skip the DTD loading phase\n"); printf("\t--nodtdattr do not default attributes from the DTD\n"); printf("\t--noout: do not dump the result\n"); - printf("\t--maxdepth val : increase the maximum depth\n"); + printf("\t--maxdepth val : increase the maximum depth (default %d)\n", xsltMaxDepth); + printf("\t--maxvars val : increase the maximum variables (default %d)\n", xsltMaxVars); printf("\t--maxparserdepth val : increase the maximum parser depth\n"); #ifdef LIBXML_HTML_ENABLED printf("\t--html: the input document is(are) an HTML file(s)\n"); @@ -721,6 +725,15 @@ main(int argc, char **argv) if (value > 0) xsltMaxDepth = value; } + } else if ((!strcmp(argv[i], "-maxvars")) || + (!strcmp(argv[i], "--maxvars"))) { + int value; + + i++; + if (sscanf(argv[i], "%d", &value) == 1) { + if (value > 0) + xsltMaxVars = value; + } } else if ((!strcmp(argv[i], "-maxparserdepth")) || (!strcmp(argv[i], "--maxparserdepth"))) { int value;