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
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;