Allow per-context override of xsltMaxDepth, introduce xsltMaxVars
authorJérôme Carretero <cJ-xslt@zougloub.eu>
Mon, 19 Mar 2012 07:06:53 +0000 (15:06 +0800)
committerDaniel Veillard <veillard@redhat.com>
Tue, 20 Mar 2012 13:18:59 +0000 (21:18 +0800)
We also add a maxTemplateVars parameter

12 files changed:
doc/APIfiles.html
doc/libxslt-api.xml
doc/libxslt-decl.txt
doc/libxslt-refs.xml
doc/symbols.xml
libxslt/libxslt.syms
libxslt/transform.c
libxslt/xslt.h
libxslt/xsltInternals.h
win32/libxslt.def.src
win32/libxslt/libxslt.def
xsltproc/xsltproc.c

index 4c312dc..d199166 100644 (file)
@@ -221,6 +221,7 @@ A:link, A:visited, A:active { text-decoration: underline }
 <a href="html/libxslt-xslt.html#xsltLibxmlVersion">xsltLibxmlVersion</a><br />
 <a href="html/libxslt-xslt.html#xsltLibxsltVersion">xsltLibxsltVersion</a><br />
 <a href="html/libxslt-xslt.html#xsltMaxDepth">xsltMaxDepth</a><br />
+<a href="html/libxslt-xslt.html#xsltMaxVars">xsltMaxVars</a><br />
 </p><h2><a name="xsltInternals" id="xsltInternals">Module xsltInternals</a>:</h2><p><a href="html/libxslt-xsltInternals.html#CHECK_STOPPED">CHECK_STOPPED</a><br />
 <a href="html/libxslt-xsltInternals.html#CHECK_STOPPED0">CHECK_STOPPED0</a><br />
 <a href="html/libxslt-xsltInternals.html#CHECK_STOPPEDE">CHECK_STOPPEDE</a><br />
index d0ed1a2..fbc32de 100644 (file)
      <exports symbol='xsltEngineVersion' type='variable'/>
      <exports symbol='xsltLibxsltVersion' type='variable'/>
      <exports symbol='xsltMaxDepth' type='variable'/>
+     <exports symbol='xsltMaxVars' type='variable'/>
      <exports symbol='xsltCleanupGlobals' type='function'/>
      <exports symbol='xsltInit' type='function'/>
     </file>
@@ -1560,6 +1561,7 @@ exits'/>
     <variable name='xsltLibxmlVersion' file='xslt' type='const int'/>
     <variable name='xsltLibxsltVersion' file='xslt' type='const int'/>
     <variable name='xsltMaxDepth' file='xslt' type='int'/>
+    <variable name='xsltMaxVars' file='xslt' type='int'/>
     <variable name='xsltXSLTAttrMarker' file='xsltInternals' type='const xmlChar *'/>
     <function name='xslAddCall' file='xsltutils'>
       <info>Add template &quot;call&quot; to call stack</info>
index f018274..423230e 100644 (file)
@@ -238,6 +238,10 @@ extern const xmlChar *xsltExtMarker;
 extern int xsltMaxDepth;
 </VARIABLE>
 <VARIABLE>
+<NAME>xsltMaxVars</NAME>
+extern int xsltMaxVars;
+</VARIABLE>
+<VARIABLE>
 <NAME>xsltEngineVersion</NAME>
 extern const char *xsltEngineVersion;
 </VARIABLE>
index c21e6d2..33adb26 100644 (file)
     <reference name='xsltLocaleStrcmp' href='html/libxslt-xsltlocale.html#xsltLocaleStrcmp'/>
     <reference name='xsltMatchPattern' href='html/libxslt-pattern.html#xsltMatchPattern'/>
     <reference name='xsltMaxDepth' href='html/libxslt-xslt.html#xsltMaxDepth'/>
+    <reference name='xsltMaxVars' href='html/libxslt-xslt.html#xsltMaxVars'/>
     <reference name='xsltMessage' href='html/libxslt-xsltutils.html#xsltMessage'/>
     <reference name='xsltNamespaceAlias' href='html/libxslt-namespaces.html#xsltNamespaceAlias'/>
     <reference name='xsltNeedElemSpaceHandling' href='html/libxslt-imports.html#xsltNeedElemSpaceHandling'/>
       <ref name='xsltLocaleStrcmp'/>
       <ref name='xsltMatchPattern'/>
       <ref name='xsltMaxDepth'/>
+      <ref name='xsltMaxVars'/>
       <ref name='xsltMessage'/>
       <ref name='xsltNamespaceAlias'/>
       <ref name='xsltNeedElemSpaceHandling'/>
       <ref name='xsltLibxmlVersion'/>
       <ref name='xsltLibxsltVersion'/>
       <ref name='xsltMaxDepth'/>
+      <ref name='xsltMaxVars'/>
     </file>
     <file name='xsltInternals'>
       <ref name='CHECK_STOPPED'/>
index 2eea92c..9e199e8 100644 (file)
     <symbol file="xslt">xsltLibxmlVersion</symbol>
     <symbol file="xslt">xsltLibxsltVersion</symbol>
     <symbol file="xslt">xsltMaxDepth</symbol>
+    <symbol file="xslt">xsltMaxVars</symbol>
     <symbol file="xsltInternals">xsltParseStylesheetImportedDoc</symbol>
     <symbol file="xsltutils">xsltSetCtxtSortFunc</symbol>
     <symbol file="xsltutils">xsltSetSortFunc</symbol>
index 45fa74b..7a7e6c3 100644 (file)
@@ -307,6 +307,7 @@ LIBXML2_1.0.24 {
   xsltLibxmlVersion; # variable
   xsltLibxsltVersion; # variable
   xsltMaxDepth; # variable
+  xsltMaxVars; # variable
 
 # xsltInternals
   xsltParseStylesheetImportedDoc;
index 948d7d0..53eefcc 100644 (file)
@@ -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;
index 849b03c..13a68be 100644 (file)
@@ -62,6 +62,13 @@ extern "C" {
 XSLTPUBVAR int xsltMaxDepth;
 
 /**
+ *  * xsltMaxVars:
+ *   *
+ *    * This value is used to detect templates loops.
+ *     */
+XSLTPUBVAR int xsltMaxVars;
+
+/**
  * xsltEngineVersion:
  *
  * The version string for libxslt.
index 764fe8c..afb2a2c 100644 (file)
@@ -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;
 };
 
 /**
index 892d34b..1d17bac 100644 (file)
@@ -12,6 +12,7 @@ xsltGenericErrorContext DATA
 xsltLibxmlVersion DATA
 xsltLibxsltVersion DATA
 xsltMaxDepth DATA
+xsltMaxVars DATA
 xsltXSLTAttrMarker DATA
 xslAddCall
 xslDropCall
index 0992b4a..dc6f1a0 100644 (file)
@@ -134,6 +134,7 @@ EXPORTS
        xsltSaveResultToFd\r
 \r
        xsltMaxDepth\r
+       xsltMaxVars\r
        xsltSetXIncludeDefault\r
        xsltLibxmlVersion\r
        xsltLibxsltVersion\r
index 3e1a540..e938106 100644 (file)
@@ -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;