fixed #129327 make sure parser flags get transmitted to the transformation
[platform/upstream/libxslt.git] / xsltproc / xsltproc.c
index f2a67f4..6131381 100644 (file)
@@ -8,12 +8,16 @@
 
 #include "libxslt/libxslt.h"
 #include "libexslt/exslt.h"
+#include <stdio.h>
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
 #include <libxml/debugXML.h>
 #include <libxml/HTMLtree.h>
 #include <libxml/xmlIO.h>
-#ifdef LIBXML_DOCB_ENABLED
-#include <libxml/DOCBparser.h>
-#endif
 #ifdef LIBXML_XINCLUDE_ENABLED
 #include <libxml/xinclude.h>
 #endif
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
+#include <libxml/parser.h>
 #include <libxml/parserInternals.h>
+#include <libxml/uri.h>
 
 #include <libxslt/xslt.h>
 #include <libxslt/xsltInternals.h>
 #include <libxslt/transform.h>
 #include <libxslt/xsltutils.h>
 #include <libxslt/extensions.h>
+#include <libxslt/security.h>
 
 #include <libexslt/exsltconfig.h>
 
 #if defined(WIN32) && !defined (__CYGWIN__)
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || defined(__MINGW32__)
 #include <winsock2.h>
-#pragma comment(lib, "ws2_32.lib")
 #define gettimeofday(p1,p2)
 #define HAVE_TIME_H
 #include <time.h>
 #define HAVE_STDARG_H
 #include <stdarg.h>
+#define snprintf _snprintf
 #endif /* _MS_VER */
 #else /* WIN32 */
 #if defined(HAVE_SYS_TIME_H)
 #endif
 #endif /* WIN32 */
 
+#ifdef HAVE_SYS_TIMEB_H
+#include <sys/timeb.h>
+#endif
+
 #ifndef HAVE_STAT
 #  ifdef HAVE__STAT
      /* MS C library seems to define stat and _stat. The definition
 #  endif
 #endif
 
-xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
-                                              const char *ID,
-                                              xmlParserCtxtPtr ctxt);
-
 static int debug = 0;
 static int repeat = 0;
 static int timing = 0;
+static int dumpextensions = 0;
 static int novalid = 0;
 static int noout = 0;
-#ifdef LIBXML_DOCB_ENABLED
-static int docbook = 0;
-#endif
 #ifdef LIBXML_HTML_ENABLED
 static int html = 0;
 #endif
+static int load_trace = 0;
 #ifdef LIBXML_XINCLUDE_ENABLED
 static int xinclude = 0;
 #endif
 static int profile = 0;
 
 #define MAX_PARAMETERS 64
+#define MAX_PATHS 64
 
+#if LIBXML_VERSION >= 20600
+static int options = XSLT_PARSE_OPTIONS;
+#endif
 static const char *params[MAX_PARAMETERS + 1];
 static int nbparams = 0;
 static xmlChar *strparams[MAX_PARAMETERS + 1];
 static int nbstrparams = 0;
-static const char *output = NULL;
+static xmlChar *paths[MAX_PATHS + 1];
+static int nbpaths = 0;
+static char *output = NULL;
 static int errorno = 0;
+static const char *writesubtree = NULL;
+
+/*
+ * Entity loading control and customization.
+ */
+static
+void parsePath(const xmlChar *path) {
+    const xmlChar *cur;
+
+    if (path == NULL)
+       return;
+    while (*path != 0) {
+       if (nbpaths >= MAX_PATHS) {
+           fprintf(stderr, "MAX_PATHS reached: too many paths\n");
+           return;
+       }
+       cur = path;
+       while ((*cur == ' ') || (*cur == ':'))
+           cur++;
+       path = cur;
+       while ((*cur != 0) && (*cur != ' ') && (*cur != ':'))
+           cur++;
+       if (cur != path) {
+           paths[nbpaths] = xmlStrndup(path, cur - path);
+           if (paths[nbpaths] != NULL)
+               nbpaths++;
+           path = cur;
+       }
+    }
+}
+
+xmlExternalEntityLoader defaultEntityLoader = NULL;
+
+static xmlParserInputPtr 
+xsltprocExternalEntityLoader(const char *URL, const char *ID,
+                            xmlParserCtxtPtr ctxt) {
+    xmlParserInputPtr ret;
+    warningSAXFunc warning = NULL;
+
+    int i;
+    const char *lastsegment = URL;
+    const char *iter = URL;
+
+    if (nbpaths > 0) {
+       while (*iter != 0) {
+           if (*iter == '/')
+               lastsegment = iter + 1;
+           iter++;
+       }
+    }
+
+    if ((ctxt != NULL) && (ctxt->sax != NULL)) {
+       warning = ctxt->sax->warning;
+       ctxt->sax->warning = NULL;
+    }
 
+    if (defaultEntityLoader != NULL) {
+       ret = defaultEntityLoader(URL, ID, ctxt);
+       if (ret != NULL) {
+           if (warning != NULL)
+               ctxt->sax->warning = warning;
+           if (load_trace) {
+               fprintf \
+                       (stderr,
+                        "Loaded URL=\"%s\" ID=\"%s\"\n",
+                        URL ? URL : "(null)",
+                        ID ? ID : "(null)");
+           }
+           return(ret);
+       }
+    }
+    for (i = 0;i < nbpaths;i++) {
+       xmlChar *newURL;
+
+       newURL = xmlStrdup((const xmlChar *) paths[i]);
+       newURL = xmlStrcat(newURL, (const xmlChar *) "/");
+       newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
+       if (newURL != NULL) {
+           ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
+           if (ret != NULL) {
+               if (warning != NULL)
+                   ctxt->sax->warning = warning;
+               if (load_trace) {
+                   fprintf \
+                       (stderr,
+                        "Loaded URL=\"%s\" ID=\"%s\"\n",
+                        newURL,
+                        ID ? ID : "(null)");
+               }
+               xmlFree(newURL);
+               return(ret);
+           }
+           xmlFree(newURL);
+       }
+    }
+    if (warning != NULL) {
+       ctxt->sax->warning = warning;
+       if (URL != NULL)
+           warning(ctxt, "failed to load external entity \"%s\"\n", URL);
+       else if (ID != NULL)
+           warning(ctxt, "failed to load external entity \"%s\"\n", ID);
+    }
+    return(NULL);
+}
 
 /*
  * Internal timing routines to remove the necessity to have unix-specific
  * function calls
  */
+#ifndef HAVE_GETTIMEOFDAY 
+#ifdef HAVE_SYS_TIMEB_H
+#ifdef HAVE_SYS_TIME_H
+#ifdef HAVE_FTIME
+
+int
+my_gettimeofday(struct timeval *tvp, void *tzp)
+{
+       struct timeb timebuffer;
+
+       ftime(&timebuffer);
+       if (tvp) {
+               tvp->tv_sec = timebuffer.time;
+               tvp->tv_usec = timebuffer.millitm * 1000L;
+       }
+       return (0);
+}
+#define HAVE_GETTIMEOFDAY 1
+#define gettimeofday my_gettimeofday
+
+#endif /* HAVE_FTIME */
+#endif /* HAVE_SYS_TIME_H */
+#endif /* HAVE_SYS_TIMEB_H */
+#endif /* !HAVE_GETTIMEOFDAY */
 
 #if defined(HAVE_GETTIMEOFDAY)
-static struct timeval begin, end;
+static struct timeval begin, endtime;
 /*
  * startTimer: call where you want to start timing
  */
@@ -132,10 +268,10 @@ static void endTimer(const char *format, ...)
     long msec;
     va_list ap;
 
-    gettimeofday(&end, NULL);
-    msec = end.tv_sec - begin.tv_sec;
+    gettimeofday(&endtime, NULL);
+    msec = endtime.tv_sec - begin.tv_sec;
     msec *= 1000;
-    msec += (end.tv_usec - begin.tv_usec) / 1000;
+    msec += (endtime.tv_usec - begin.tv_usec) / 1000;
 
 #ifndef HAVE_STDARG_H
 #error "endTimer required stdarg functions"
@@ -152,8 +288,11 @@ static void endTimer(const char *format, ...)
  * This is obviously less accurate, but there's little we can do about
  * that.
  */
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 100
+#endif
 
-clock_t begin, end;
+clock_t begin, endtime;
 static void startTimer(void)
 {
     begin=clock();
@@ -163,8 +302,8 @@ static void endTimer(char *format, ...)
     long msec;
     va_list ap;
 
-    end=clock();
-    msec = ((end-begin) * 1000) / CLOCKS_PER_SEC;
+    endtime=clock();
+    msec = ((endtime-begin) * 1000) / CLOCKS_PER_SEC;
 
 #ifndef HAVE_STDARG_H
 #error "endTimer required stdarg functions"
@@ -202,16 +341,44 @@ static void endTimer(char *format, ...)
 }
 #endif
 
+/*
+ * xsltSubtreeCheck:
+ *
+ * allow writes only on a subtree specified on the command line
+ */
+static int
+xsltSubtreeCheck(xsltSecurityPrefsPtr sec ATTRIBUTE_UNUSED,
+                 xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
+                 const char *value ATTRIBUTE_UNUSED) {
+    int len, ret;
+
+    if (writesubtree == NULL)
+       return(0);
+    if (value == NULL)
+       return(-1);
+
+    len = xmlStrlen(BAD_CAST writesubtree);
+    ret = xmlStrncmp(BAD_CAST writesubtree, BAD_CAST value, len);
+    if (ret == 0)
+       return(1);
+    return(0);
+}
+
 static void
 xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
     xmlDocPtr res;
     xsltTransformContextPtr ctxt;
+   
 
 #ifdef LIBXML_XINCLUDE_ENABLED
     if (xinclude) {
        if (timing)
            startTimer();
+#if LIBXML_VERSION >= 20603
+       xmlXIncludeProcessFlags(doc, XSLT_PARSE_OPTIONS);
+#else
        xmlXIncludeProcess(doc);
+#endif
        if (timing) {
            endTimer("XInclude processing %s", filename);
        }
@@ -227,22 +394,27 @@ xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
                res = xsltApplyStylesheet(cur, doc, params);
                xmlFreeDoc(res);
                xmlFreeDoc(doc);
+#if LIBXML_VERSION >= 20600
 #ifdef LIBXML_HTML_ENABLED
                if (html)
-                   doc = htmlParseFile(filename, NULL);
+                   doc = htmlReadFile(filename, NULL, options);
                else
 #endif
-#ifdef LIBXML_DOCB_ENABLED
-               if (docbook)
-                   doc = docbParseFile(filename, NULL);
+                   doc = xmlReadFile(filename, NULL, options);
+#else
+#ifdef LIBXML_HTML_ENABLED
+               if (html)
+                   doc = htmlParseFile(filename, NULL);
                else
 #endif
                    doc = xmlParseFile(filename);
+#endif
            }
        }
        ctxt = xsltNewTransformContext(cur, doc);
        if (ctxt == NULL)
            return;
+       xsltSetCtxtParseOptions(ctxt, options);
        if (profile) {
            res = xsltApplyStylesheetUser(cur, doc, params, NULL,
                                          stderr, ctxt);
@@ -252,6 +424,8 @@ xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
        }
        if (ctxt->state == XSLT_STATE_ERROR)
            errorno = 9;
+       if (ctxt->state == XSLT_STATE_STOPPED)
+           errorno = 10;
        xsltFreeTransformContext(ctxt);
        if (timing) {
            if (repeat)
@@ -301,7 +475,20 @@ xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
 
        xmlFreeDoc(res);
     } else {
-       xsltRunStylesheet(cur, doc, params, output, NULL, NULL);
+
+       ctxt = xsltNewTransformContext(cur, doc);
+       if (ctxt == NULL)
+           return;
+       if (profile) {
+           xsltRunStylesheetUser(cur, doc, params, output,
+                                       NULL, NULL, stderr, ctxt);
+       } else {
+           xsltRunStylesheetUser(cur, doc, params, output,
+                                       NULL, NULL, NULL, ctxt);
+       }
+       if (ctxt->state == XSLT_STATE_ERROR)
+           errorno = 9;
+       xsltFreeTransformContext(ctxt);
        if (timing)
            endTimer("Running stylesheet and saving result");
        xmlFreeDoc(doc);
@@ -316,22 +503,29 @@ static void usage(const char *name) {
     printf("\t--output file or -o file: save to a given file\n");
     printf("\t--timing: display the time used\n");
     printf("\t--repeat: run the transformation 20 times\n");
+#ifdef LIBXML_DEBUG_ENABLED
     printf("\t--debug: dump the tree of the result instead\n");
+#endif
+    printf("\t--dumpextensions: dump the registered extension elements and functions to stdout\n");
     printf("\t--novalid skip the Dtd loading phase\n");
     printf("\t--noout: do not dump the result\n");
     printf("\t--maxdepth val : increase the maximum depth\n");
+#if LIBXML_VERSION >= 20600
+    printf("\t--maxparserdepth val : increase the maximum parser depth\n");
+#endif
 #ifdef LIBXML_HTML_ENABLED
     printf("\t--html: the input document is(are) an HTML file(s)\n");
 #endif
-#ifdef LIBXML_DOCB_ENABLED
-    printf("\t--docbook: the input document is SGML docbook\n");
-#endif
     printf("\t--param name value : pass a (parameter,value) pair\n");
-    printf("\t       value is an XPath expression.\n");
+    printf("\t       value is an UTF8 XPath expression.\n");
     printf("\t       string values must be quoted like \"'string'\"\n or");
     printf("\t       use stringparam to avoid it\n");
-    printf("\t--stringparam name value : pass a (parameter,string value) pair\n");
-    printf("\t--nonet refuse to fetch DTDs or entities over network\n");
+    printf("\t--stringparam name value : pass a (parameter, UTF8 string value) pair\n");
+    printf("\t--path 'paths': provide a set of paths for resources\n");
+    printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
+    printf("\t--nowrite : refuse to write to any file or resource\n");
+    printf("\t--nomkdir : refuse to create directories\n");
+    printf("\t--writesubtree path : allow file write only with the path subtree\n");
 #ifdef LIBXML_CATALOG_ENABLED
     printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
     printf("\t             otherwise XML Catalogs starting from \n");
@@ -340,7 +534,10 @@ static void usage(const char *name) {
 #ifdef LIBXML_XINCLUDE_ENABLED
     printf("\t--xinclude : do XInclude processing on document intput\n");
 #endif
+    printf("\t--load-trace : print trace of all external entites loaded\n");
     printf("\t--profile or --norman : dump profiling informations \n");
+    printf("\nProject libxslt home page: http://xmlsoft.org/XSLT/\n");
+    printf("To report bugs and get help: http://xmlsoft.org/XSLT/bugs.html\n");
 }
 
 int
@@ -349,6 +546,7 @@ main(int argc, char **argv)
     int i;
     xsltStylesheetPtr cur = NULL;
     xmlDocPtr doc, style;
+    xsltSecurityPrefsPtr sec = NULL;
 
     if (argc <= 1) {
         usage(argv[0]);
@@ -359,7 +557,10 @@ main(int argc, char **argv)
 
     LIBXML_TEST_VERSION
 
-    xmlLineNumbersDefault(1);
+    sec = xsltNewSecurityPrefs();
+    xsltSetDefaultSecurityPrefs(sec);
+    defaultEntityLoader = xmlGetExternalEntityLoader();
+    xmlSetExternalEntityLoader(xsltprocExternalEntityLoader);
 
     for (i = 1; i < argc; i++) {
         if (!strcmp(argv[i], "-"))
@@ -380,7 +581,11 @@ main(int argc, char **argv)
                    (!strcmp(argv[i], "-output")) ||
                    (!strcmp(argv[i], "--output"))) {
             i++;
-            output = argv[i];
+#if defined(WIN32) || defined (__CYGWIN__)
+           output = xmlCanonicPath(argv[i]);
+            if (output == NULL)
+#endif
+               output = (char *) xmlStrdup((xmlChar *) argv[i]);
         } else if ((!strcmp(argv[i], "-V")) ||
                    (!strcmp(argv[i], "-version")) ||
                    (!strcmp(argv[i], "--version"))) {
@@ -405,11 +610,6 @@ main(int argc, char **argv)
         } else if ((!strcmp(argv[i], "-noout")) ||
                    (!strcmp(argv[i], "--noout"))) {
             noout++;
-#ifdef LIBXML_DOCB_ENABLED
-        } else if ((!strcmp(argv[i], "-docbook")) ||
-                   (!strcmp(argv[i], "--docbook"))) {
-            docbook++;
-#endif
 #ifdef LIBXML_HTML_ENABLED
         } else if ((!strcmp(argv[i], "-html")) ||
                    (!strcmp(argv[i], "--html"))) {
@@ -426,7 +626,29 @@ main(int argc, char **argv)
             profile++;
         } else if ((!strcmp(argv[i], "-nonet")) ||
                    (!strcmp(argv[i], "--nonet"))) {
-            xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
+           defaultEntityLoader = xmlNoNetExternalEntityLoader;
+        } else if ((!strcmp(argv[i], "-nowrite")) ||
+                   (!strcmp(argv[i], "--nowrite"))) {
+           xsltSetSecurityPrefs(sec, XSLT_SECPREF_WRITE_FILE,
+                                xsltSecurityForbid);
+           xsltSetSecurityPrefs(sec, XSLT_SECPREF_CREATE_DIRECTORY,
+                                xsltSecurityForbid);
+           xsltSetSecurityPrefs(sec, XSLT_SECPREF_WRITE_NETWORK,
+                                xsltSecurityForbid);
+        } else if ((!strcmp(argv[i], "-nomkdir")) ||
+                   (!strcmp(argv[i], "--nomkdir"))) {
+           xsltSetSecurityPrefs(sec, XSLT_SECPREF_CREATE_DIRECTORY,
+                                xsltSecurityForbid);
+        } else if ((!strcmp(argv[i], "-writesubtree")) ||
+                   (!strcmp(argv[i], "--writesubtree"))) {
+           i++;
+           writesubtree = argv[i];
+           xsltSetSecurityPrefs(sec, XSLT_SECPREF_WRITE_FILE,
+                                xsltSubtreeCheck);
+        } else if ((!strcmp(argv[i], "-path")) ||
+                   (!strcmp(argv[i], "--path"))) {
+           i++;
+           parsePath(BAD_CAST argv[i]);
 #ifdef LIBXML_CATALOG_ENABLED
         } else if ((!strcmp(argv[i], "-catalogs")) ||
                    (!strcmp(argv[i], "--catalogs"))) {
@@ -445,6 +667,9 @@ main(int argc, char **argv)
             xinclude++;
             xsltSetXIncludeDefault(1);
 #endif
+        } else if ((!strcmp(argv[i], "-load-trace")) ||
+                   (!strcmp(argv[i], "--load-trace"))) {
+            load_trace++;
         } else if ((!strcmp(argv[i], "-param")) ||
                    (!strcmp(argv[i], "--param"))) {
             i++;
@@ -458,12 +683,10 @@ main(int argc, char **argv)
                    (!strcmp(argv[i], "--stringparam"))) {
            const xmlChar *string;
            xmlChar *value;
-           int len;
 
             i++;
             params[nbparams++] = argv[i++];
            string = (const xmlChar *) argv[i];
-           len = xmlStrlen(string);
            if (xmlStrchr(string, '"')) {
                if (xmlStrchr(string, '\'')) {
                    fprintf(stderr,
@@ -494,7 +717,22 @@ main(int argc, char **argv)
                 if (value > 0)
                     xsltMaxDepth = value;
             }
-        } else {
+#if LIBXML_VERSION >= 20600
+        } else if ((!strcmp(argv[i], "-maxparserdepth")) ||
+                   (!strcmp(argv[i], "--maxparserdepth"))) {
+            int value;
+
+            i++;
+            if (sscanf(argv[i], "%d", &value) == 1) {
+                if (value > 0)
+                    xmlParserMaxDepth = value;
+            }
+#endif
+        } else if ((!strcmp(argv[i],"-dumpextensions"))||
+                       (!strcmp(argv[i],"--dumpextensions"))) {
+               dumpextensions++;
+               
+       } else {
             fprintf(stderr, "Unknown option %s\n", argv[i]);
             usage(argv[0]);
             return (3);
@@ -502,16 +740,20 @@ main(int argc, char **argv)
     }
     params[nbparams] = NULL;
 
+#if LIBXML_VERSION < 20600
+    /*
+     * The old parser interfaces uses the global variables
+     */
     if (novalid == 0)
         xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
     else
         xmlLoadExtDtdDefaultValue = 0;
-
-
-    /*
-     * Replace entities with their content.
-     */
     xmlSubstituteEntitiesDefault(1);
+    xmlLineNumbersDefault(1);
+#else
+    if (novalid != 0)
+       options = XML_PARSE_NOENT | XML_PARSE_NOCDATA;
+#endif
 
     /*
      * Register the EXSLT extensions and the test module
@@ -519,25 +761,51 @@ main(int argc, char **argv)
     exsltRegisterAll();
     xsltRegisterTestModule();
 
+    if (dumpextensions) 
+       xsltDebugDumpExtensions(NULL);
+
     for (i = 1; i < argc; i++) {
         if ((!strcmp(argv[i], "-maxdepth")) ||
             (!strcmp(argv[i], "--maxdepth"))) {
             i++;
             continue;
+#if LIBXML_VERSION >= 20600
+        } else if ((!strcmp(argv[i], "-maxparserdepth")) ||
+            (!strcmp(argv[i], "--maxparserdepth"))) {
+            i++;
+            continue;
+#endif
         } else if ((!strcmp(argv[i], "-o")) ||
                    (!strcmp(argv[i], "-output")) ||
                    (!strcmp(argv[i], "--output"))) {
             i++;
            continue;
+        } else if ((!strcmp(argv[i], "-writesubtree")) ||
+                   (!strcmp(argv[i], "--writesubtree"))) {
+            i++;
+           continue;
+        } else if ((!strcmp(argv[i], "-path")) ||
+                   (!strcmp(argv[i], "--path"))) {
+            i++;
+           continue;
        }
         if ((!strcmp(argv[i], "-param")) || (!strcmp(argv[i], "--param"))) {
             i += 2;
             continue;
         }
+        if ((!strcmp(argv[i], "-stringparam")) ||
+            (!strcmp(argv[i], "--stringparam"))) {
+            i += 2;
+            continue;
+        }
         if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
             if (timing)
                 startTimer();
+#if LIBXML_VERSION >= 20600
+           style = xmlReadFile((const char *) argv[i], NULL, options);
+#else
            style = xmlParseFile((const char *) argv[i]);
+#endif
             if (timing) 
                endTimer("Parsing stylesheet %s", argv[i]);
            if (style == NULL) {
@@ -550,14 +818,15 @@ main(int argc, char **argv)
                    /* it is an embedded stylesheet */
                    xsltProcess(style, cur, argv[i]);
                    xsltFreeStylesheet(cur);
+                   cur = NULL;
                    goto done;
                }
                cur = xsltParseStylesheetDoc(style);
                if (cur != NULL) {
-                   if (cur->indent == 1)
-                       xmlIndentTreeOutput = 1;
-                   else
-                       xmlIndentTreeOutput = 0;
+                   if (cur->errors != 0) {
+                       errorno = 5;
+                       goto done;
+                   }
                    i++;
                } else {
                    xmlFreeDoc(style);
@@ -570,28 +839,35 @@ main(int argc, char **argv)
         }
     }
 
+#if LIBXML_VERSION < 20600
     /*
+     * The old parser interfaces uses the global variables
      * disable CDATA from being built in the document tree
      */
     xmlDefaultSAXHandlerInit();
     xmlDefaultSAXHandler.cdataBlock = NULL;
+#endif
 
     if ((cur != NULL) && (cur->errors == 0)) {
         for (; i < argc; i++) {
            doc = NULL;
             if (timing)
                 startTimer();
+#if LIBXML_VERSION >= 20600
 #ifdef LIBXML_HTML_ENABLED
             if (html)
-                doc = htmlParseFile(argv[i], NULL);
+                doc = htmlReadFile(argv[i], NULL, options);
             else
 #endif
-#ifdef LIBXML_DOCB_ENABLED
-            if (docbook)
-                doc = docbParseFile(argv[i], NULL);
+                doc = xmlReadFile(argv[i], NULL, options);
+#else
+#ifdef LIBXML_HTML_ENABLED
+            if (html)
+                doc = htmlParseFile(argv[i], NULL);
             else
 #endif
                 doc = xmlParseFile(argv[i]);
+#endif
             if (doc == NULL) {
                 fprintf(stderr, "unable to parse %s\n", argv[i]);
                errorno = 6;
@@ -602,11 +878,14 @@ main(int argc, char **argv)
            xsltProcess(doc, cur, argv[i]);
         }
     }
+done:
     if (cur != NULL)
         xsltFreeStylesheet(cur);
     for (i = 0;i < nbstrparams;i++)
        xmlFree(strparams[i]);
-done:
+    if (output != NULL)
+       xmlFree(output);
+    xsltFreeSecurityPrefs(sec);
     xsltCleanupGlobals();
     xmlCleanupParser();
     xmlMemoryDump();