Re: [xslt] [lxml-dev] XSLT - xsltMaxDepth setting
- From: Jérôme Carretero <cJ-lxml zougloub eu>
- To: Stefan Behnel <stefan_ml behnel de>
- Cc: xslt gnome org, lxml-dev codespeak net, flameeyes+libxslt gmail com
- Subject: Re: [xslt] [lxml-dev] XSLT - xsltMaxDepth setting
- Date: Thu, 4 Nov 2010 08:42:01 -0400
On Mon, 01 Nov 2010 17:14:30 +0100
Stefan Behnel <stefan_ml behnel de> wrote:
> Jérôme Carretero, 01.11.2010 13:38:
> > libxslt uses a xsltMaxDepth variable (global...) to limit recursion,
> > and I used to increase it when processing some big files (for instance, DocBook containing tables spanning over dozens of pages).
> > xsltproc --maxdepth 10000 ....
> >
> > At the moment, lxml does not touch this value.
> >
> > Maybe providing a lxml.etree.XSLT.maxdepth property would not be too complicated ?
>
> Such a local property doesn't work well for a global setting, and global
> settings are always evil. Isn't there a per-call setting for this?
Attached is a libxslt patch that makes the max template depth an attribute of the transform context and not a global variable.
Comments ?
Regards,
--
cJ
PS: the patch was applied onto the master branch of Diego's git://gitorious.org/libxslt/libxslt.git mirror, I was too lazy to dig the real libxslt repository.
diff --git a/libxslt/libxslt.syms b/libxslt/libxslt.syms
index 45fa74b..63cacf0 100644
--- a/libxslt/libxslt.syms
+++ b/libxslt/libxslt.syms
@@ -306,7 +306,6 @@ LIBXML2_1.0.24 {
# xslt
xsltLibxmlVersion; # variable
xsltLibxsltVersion; # variable
- xsltMaxDepth; # variable
# xsltInternals
xsltParseStylesheetImportedDoc;
diff --git a/libxslt/transform.c b/libxslt/transform.c
index 948d7d0..3f1d990 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -63,8 +63,6 @@ static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID,
const xmlChar **systemID);
#endif
-int xsltMaxDepth = 3000;
-
/*
* Useful macros
*/
@@ -504,6 +502,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
cur->templNr = 0;
cur->templMax = 5;
cur->templ = NULL;
+ cur->maxTemplateDepth = 3000;
/*
* initialize the variables stack
@@ -519,6 +518,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
cur->varsMax = 10;
cur->vars = NULL;
cur->varsBase = 0;
+ cur->maxTemplateVars = 15000;
/*
* the profiling stack is not initialized by default
@@ -2983,20 +2983,31 @@ 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 "
"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",
- xsltMaxDepth);
+ "You can adjust maxTemplateDepth (--maxdepth) in order to "
+ "raise the maximum number of nested template calls "
+ " (currently set to %d).\n",
+ ctxt->maxTemplateDepth);
xsltDebug(ctxt, contextNode, list, NULL);
return;
}
+ if (ctxt->varsNr >= 5 * ctxt->maxTemplateDepth)
+ {
+ 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 849b03c..fa8bb32 100644
--- a/libxslt/xslt.h
+++ b/libxslt/xslt.h
@@ -55,13 +55,6 @@ extern "C" {
XML_PARSE_NOENT | XML_PARSE_DTDLOAD | XML_PARSE_DTDATTR | XML_PARSE_NOCDATA
/**
- * xsltMaxDepth:
- *
- * This value is used to detect templates loops.
- */
-XSLTPUBVAR int xsltMaxDepth;
-
-/**
* xsltEngineVersion:
*
* The version string for libxslt.
diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
index 764fe8c..f5eb309 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/xsltproc/xsltproc.c b/xsltproc/xsltproc.c
index e978a63..f8ee129 100644
--- a/xsltproc/xsltproc.c
+++ b/xsltproc/xsltproc.c
@@ -103,6 +103,8 @@ static int nbpaths = 0;
static char *output = NULL;
static int errorno = 0;
static const char *writesubtree = NULL;
+static int xsltMaxDepth = 3000;
+static int xsltMaxVars = 15000;
/*
* Entity loading control and customization.
@@ -466,6 +468,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);
[Date Prev][
Date Next] [Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]