Re: [xslt] [lxml-dev] XSLT - xsltMaxDepth setting



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]