[LIBXML2] Update to v2.9.3.
authorAmine Khaldi <amine.khaldi@reactos.org>
Wed, 2 Dec 2015 11:36:52 +0000 (11:36 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Wed, 2 Dec 2015 11:36:52 +0000 (11:36 +0000)
svn path=/trunk/; revision=70234

23 files changed:
reactos/include/reactos/libs/libxml/tree.h
reactos/include/reactos/libs/libxml/xmlversion.h
reactos/include/reactos/libs/libxml/xmlversion.h.in
reactos/lib/3rdparty/libxml2/HTMLparser.c
reactos/lib/3rdparty/libxml2/HTMLtree.c
reactos/lib/3rdparty/libxml2/buf.c
reactos/lib/3rdparty/libxml2/dict.c
reactos/lib/3rdparty/libxml2/error.c
reactos/lib/3rdparty/libxml2/parser.c
reactos/lib/3rdparty/libxml2/parserInternals.c
reactos/lib/3rdparty/libxml2/relaxng.c
reactos/lib/3rdparty/libxml2/threads.c
reactos/lib/3rdparty/libxml2/timsort.h
reactos/lib/3rdparty/libxml2/tree.c
reactos/lib/3rdparty/libxml2/valid.c
reactos/lib/3rdparty/libxml2/xmlIO.c
reactos/lib/3rdparty/libxml2/xmllint.c
reactos/lib/3rdparty/libxml2/xmlmemory.c
reactos/lib/3rdparty/libxml2/xmlreader.c
reactos/lib/3rdparty/libxml2/xmlschemas.c
reactos/lib/3rdparty/libxml2/xpath.c
reactos/lib/3rdparty/libxml2/xzlib.c
reactos/media/doc/3rd Party Files.txt

index 2f90717..4a9b3bc 100644 (file)
@@ -76,7 +76,8 @@ typedef enum {
     XML_BUFFER_ALLOC_EXACT,    /* grow only to the minimal size */
     XML_BUFFER_ALLOC_IMMUTABLE, /* immutable buffer */
     XML_BUFFER_ALLOC_IO,       /* special allocation scheme used for I/O */
-    XML_BUFFER_ALLOC_HYBRID    /* exact up to a threshold, and doubleit thereafter */
+    XML_BUFFER_ALLOC_HYBRID,   /* exact up to a threshold, and doubleit thereafter */
+    XML_BUFFER_ALLOC_BOUNDED   /* limit the upper size of the buffer */
 } xmlBufferAllocationScheme;
 
 /**
index 92f1352..0c4e1c3 100644 (file)
@@ -29,28 +29,28 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
  *
  * the version string like "1.2.3"
  */
-#define LIBXML_DOTTED_VERSION "2.9.2"
+#define LIBXML_DOTTED_VERSION "2.9.3"
 
 /**
  * LIBXML_VERSION:
  *
  * the version number: 1.2.3 value is 10203
  */
-#define LIBXML_VERSION 20902
+#define LIBXML_VERSION 20903
 
 /**
  * LIBXML_VERSION_STRING:
  *
  * the version number string, 1.2.3 value is "10203"
  */
-#define LIBXML_VERSION_STRING "20902"
+#define LIBXML_VERSION_STRING "20903"
 
 /**
  * LIBXML_VERSION_EXTRA:
  *
  * extra version information, used to show a CVS compilation
  */
-#define LIBXML_VERSION_EXTRA ""
+#define LIBXML_VERSION_EXTRA "-GITCVE-2015-8242"
 
 /**
  * LIBXML_TEST_VERSION:
@@ -58,7 +58,7 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
  * Macro to check that the libxml version in use is compatible with
  * the version the software has been compiled against
  */
-#define LIBXML_TEST_VERSION xmlCheckVersion(20902);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20903);
 
 #ifndef VMS
 #if 0
@@ -435,7 +435,7 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
  */
 
 #ifndef LIBXML_ATTR_ALLOC_SIZE
-# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+# if (!defined(__clang__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))))
 #  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
 # else
 #  define LIBXML_ATTR_ALLOC_SIZE(x)
index 00a836f..b173be9 100644 (file)
@@ -435,7 +435,7 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
  */
 
 #ifndef LIBXML_ATTR_ALLOC_SIZE
-# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+# if (!defined(__clang__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))))
 #  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
 # else
 #  define LIBXML_ATTR_ALLOC_SIZE(x)
index d329d3b..b729197 100644 (file)
@@ -2948,8 +2948,9 @@ htmlParseScript(htmlParserCtxtPtr ctxt) {
 
 
 /**
- * htmlParseCharData:
+ * htmlParseCharDataInternal:
  * @ctxt:  an HTML parser context
+ * @readahead: optional read ahead character in ascii range
  *
  * parse a CharData section.
  * if we are within a CDATA section ']]>' marks an end of section.
@@ -2958,12 +2959,15 @@ htmlParseScript(htmlParserCtxtPtr ctxt) {
  */
 
 static void
-htmlParseCharData(htmlParserCtxtPtr ctxt) {
-    xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 5];
+htmlParseCharDataInternal(htmlParserCtxtPtr ctxt, int readahead) {
+    xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 6];
     int nbchar = 0;
     int cur, l;
     int chunk = 0;
 
+    if (readahead)
+        buf[nbchar++] = readahead;
+
     SHRINK;
     cur = CUR_CHAR(l);
     while (((cur != '<') || (ctxt->token == '<')) &&
@@ -3042,6 +3046,21 @@ htmlParseCharData(htmlParserCtxtPtr ctxt) {
     }
 }
 
+/**
+ * htmlParseCharData:
+ * @ctxt:  an HTML parser context
+ *
+ * parse a CharData section.
+ * if we are within a CDATA section ']]>' marks an end of section.
+ *
+ * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
+ */
+
+static void
+htmlParseCharData(htmlParserCtxtPtr ctxt) {
+    htmlParseCharDataInternal(ctxt, 0);
+}
+
 /**
  * htmlParseExternalID:
  * @ctxt:  an HTML parser context
@@ -3245,12 +3264,17 @@ htmlParseComment(htmlParserCtxtPtr ctxt) {
        ctxt->instate = state;
        return;
     }
+    len = 0;
+    buf[len] = 0;
     q = CUR_CHAR(ql);
+    if (!IS_CHAR(q))
+        goto unfinished;
     NEXTL(ql);
     r = CUR_CHAR(rl);
+    if (!IS_CHAR(r))
+        goto unfinished;
     NEXTL(rl);
     cur = CUR_CHAR(l);
-    len = 0;
     while (IS_CHAR(cur) &&
            ((cur != '>') ||
            (r != '-') || (q != '-'))) {
@@ -3281,18 +3305,20 @@ htmlParseComment(htmlParserCtxtPtr ctxt) {
        }
     }
     buf[len] = 0;
-    if (!IS_CHAR(cur)) {
-       htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
-                    "Comment not terminated \n<!--%.50s\n", buf, NULL);
-       xmlFree(buf);
-    } else {
+    if (IS_CHAR(cur)) {
         NEXT;
        if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
            (!ctxt->disableSAX))
            ctxt->sax->comment(ctxt->userData, buf);
        xmlFree(buf);
+       ctxt->instate = state;
+       return;
     }
-    ctxt->instate = state;
+
+unfinished:
+    htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+                "Comment not terminated \n<!--%.50s\n", buf, NULL);
+    xmlFree(buf);
 }
 
 /**
@@ -3690,6 +3716,14 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
        htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
                     "htmlParseStartTag: invalid element name\n",
                     NULL, NULL);
+       /* if recover preserve text on classic misconstructs */
+       if ((ctxt->recovery) && ((IS_BLANK_CH(CUR)) || (CUR == '<') ||
+           (CUR == '=') || (CUR == '>') || (((CUR >= '0') && (CUR <= '9'))))) {
+           htmlParseCharDataInternal(ctxt, '<');
+           return(-1);
+       }
+
+
        /* Dump the bogus tag like browsers do */
        while ((IS_CHAR_CH(CUR)) && (CUR != '>') &&
                (ctxt->instate != XML_PARSER_EOF))
@@ -5701,17 +5735,17 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                                if (ctxt->keepBlanks) {
                                    if (ctxt->sax->characters != NULL)
                                        ctxt->sax->characters(
-                                               ctxt->userData, &cur, 1);
+                                               ctxt->userData, &in->cur[0], 1);
                                } else {
                                    if (ctxt->sax->ignorableWhitespace != NULL)
                                        ctxt->sax->ignorableWhitespace(
-                                               ctxt->userData, &cur, 1);
+                                               ctxt->userData, &in->cur[0], 1);
                                }
                            } else {
                                htmlCheckParagraph(ctxt);
                                if (ctxt->sax->characters != NULL)
                                    ctxt->sax->characters(
-                                           ctxt->userData, &cur, 1);
+                                           ctxt->userData, &in->cur[0], 1);
                            }
                        }
                        ctxt->token = 0;
index 5c57fc5..2fd0c9c 100644 (file)
@@ -668,7 +668,8 @@ htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
            xmlOutputBufferWriteString(buf, " ");
            xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
        }
-    }  else if (cur->SystemID != NULL) {
+    } else if (cur->SystemID != NULL &&
+              xmlStrcmp(cur->SystemID, BAD_CAST "about:legacy-compat")) {
        xmlOutputBufferWriteString(buf, " SYSTEM ");
        xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
     }
index 6efc7b6..07922ff 100644 (file)
@@ -27,6 +27,7 @@
 #include <libxml/tree.h>
 #include <libxml/globals.h>
 #include <libxml/tree.h>
+#include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
 #include "buf.h"
 
 #define WITH_BUFFER_COMPAT
@@ -299,7 +300,8 @@ xmlBufSetAllocationScheme(xmlBufPtr buf,
     if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
         (scheme == XML_BUFFER_ALLOC_EXACT) ||
         (scheme == XML_BUFFER_ALLOC_HYBRID) ||
-        (scheme == XML_BUFFER_ALLOC_IMMUTABLE)) {
+        (scheme == XML_BUFFER_ALLOC_IMMUTABLE) ||
+       (scheme == XML_BUFFER_ALLOC_BOUNDED)) {
        buf->alloc = scheme;
         if (buf->buffer)
             buf->buffer->alloc = scheme;
@@ -458,6 +460,18 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
     size = buf->use + len + 100;
 #endif
 
+    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+        /*
+        * Used to provide parsing limits
+        */
+        if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
+           (buf->size >= XML_MAX_TEXT_LENGTH)) {
+           xmlBufMemoryError(buf, "buffer error: text too long\n");
+           return(0);
+       }
+       if (size >= XML_MAX_TEXT_LENGTH)
+           size = XML_MAX_TEXT_LENGTH;
+    }
     if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
         size_t start_buf = buf->content - buf->contentIO;
 
@@ -739,6 +753,15 @@ xmlBufResize(xmlBufPtr buf, size_t size)
     CHECK_COMPAT(buf)
 
     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
+    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+        /*
+        * Used to provide parsing limits
+        */
+        if (size >= XML_MAX_TEXT_LENGTH) {
+           xmlBufMemoryError(buf, "buffer error: text too long\n");
+           return(0);
+       }
+    }
 
     /* Don't resize if we don't have to */
     if (size < buf->size)
@@ -867,6 +890,15 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
 
     needSize = buf->use + len + 2;
     if (needSize > buf->size){
+       if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+           /*
+            * Used to provide parsing limits
+            */
+           if (needSize >= XML_MAX_TEXT_LENGTH) {
+               xmlBufMemoryError(buf, "buffer error: text too long\n");
+               return(-1);
+           }
+       }
         if (!xmlBufResize(buf, needSize)){
            xmlBufMemoryError(buf, "growing buffer");
             return XML_ERR_NO_MEMORY;
@@ -938,6 +970,15 @@ xmlBufAddHead(xmlBufPtr buf, const xmlChar *str, int len) {
     }
     needSize = buf->use + len + 2;
     if (needSize > buf->size){
+       if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+           /*
+            * Used to provide parsing limits
+            */
+           if (needSize >= XML_MAX_TEXT_LENGTH) {
+               xmlBufMemoryError(buf, "buffer error: text too long\n");
+               return(-1);
+           }
+       }
         if (!xmlBufResize(buf, needSize)){
            xmlBufMemoryError(buf, "growing buffer");
             return XML_ERR_NO_MEMORY;
index 5f71d55..8c8f931 100644 (file)
@@ -486,7 +486,10 @@ xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
        value += 30 * (*prefix);
 
     if (len > 10) {
-        value += name[len - (plen + 1 + 1)];
+        int offset = len - (plen + 1 + 1);
+       if (offset < 0)
+           offset = len - (10 + 1);
+       value += name[offset];
         len = 10;
        if (plen > 10)
            plen = 10;
index cbcf5c9..9c45040 100644 (file)
@@ -177,7 +177,9 @@ xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
     xmlChar  content[81]; /* space for 80 chars + line terminator */
     xmlChar *ctnt;
 
-    if (input == NULL) return;
+    if ((input == NULL) || (input->cur == NULL) ||
+        (*input->cur == 0)) return;
+
     cur = input->cur;
     base = input->base;
     /* skip backwards over any end-of-lines */
index 1d93967..c5741e3 100644 (file)
@@ -94,6 +94,8 @@ static xmlParserCtxtPtr
 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
                          const xmlChar *base, xmlParserCtxtPtr pctx);
 
+static void xmlHaltParser(xmlParserCtxtPtr ctxt);
+
 /************************************************************************
  *                                                                     *
  *     Arbitrary limits set in the parser. See XML_PARSE_HUGE          *
@@ -1771,7 +1773,7 @@ nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
        xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
                 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
                          xmlParserMaxDepth);
-       ctxt->instate = XML_PARSER_EOF;
+       xmlHaltParser(ctxt);
        return(-1);
     }
     ctxt->nodeTab[ctxt->nodeNr] = value;
@@ -2073,9 +2075,16 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) {
          ((ctxt->input->buf) && (ctxt->input->buf->readcallback != (xmlInputReadCallback) xmlNop)) &&
         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
-        ctxt->instate = XML_PARSER_EOF;
+        xmlHaltParser(ctxt);
+       return;
     }
     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+    if ((ctxt->input->cur > ctxt->input->end) ||
+        (ctxt->input->cur < ctxt->input->base)) {
+        xmlHaltParser(ctxt);
+        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "cur index out of bound");
+       return;
+    }
     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
            xmlPopInput(ctxt);
@@ -2151,7 +2160,8 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
        int cur;
        do {
            cur = CUR;
-           while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
+           while ((IS_BLANK_CH(cur) && /* CHECKED tstblanks.xml */
+                  (ctxt->instate != XML_PARSER_EOF))) {
                NEXT;
                cur = CUR;
                res++;
@@ -2165,7 +2175,8 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
             * Need to handle support of entities branching here
             */
            if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
-       } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
+       } while ((IS_BLANK(cur)) && /* CHECKED tstblanks.xml */
+                (ctxt->instate != XML_PARSER_EOF));
     }
     return(res);
 }
@@ -2806,6 +2817,10 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                                              0, 0, 0);
                ctxt->depth--;
 
+               if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
+                   (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
+                   goto int_error;
+
                if (rep != NULL) {
                    current = rep;
                    while (*current != 0) { /* non input consuming loop */
@@ -3491,7 +3506,14 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
        c = CUR_CHAR(l);
        if (c == 0) {
            count = 0;
+           /*
+            * when shrinking to extend the buffer we really need to preserve
+            * the part of the name we already parsed. Hence rolling back
+            * by current lenght.
+            */
+           ctxt->input->cur -= l;
            GROW;
+           ctxt->input->cur += l;
             if (ctxt->instate == XML_PARSER_EOF)
                 return(NULL);
            end = ctxt->input->cur;
@@ -3523,7 +3545,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
 
 static const xmlChar *
 xmlParseNCName(xmlParserCtxtPtr ctxt) {
-    const xmlChar *in;
+    const xmlChar *in, *e;
     const xmlChar *ret;
     int count = 0;
 
@@ -3535,16 +3557,19 @@ xmlParseNCName(xmlParserCtxtPtr ctxt) {
      * Accelerator for simple ASCII names
      */
     in = ctxt->input->cur;
-    if (((*in >= 0x61) && (*in <= 0x7A)) ||
-       ((*in >= 0x41) && (*in <= 0x5A)) ||
-       (*in == '_')) {
+    e = ctxt->input->end;
+    if ((((*in >= 0x61) && (*in <= 0x7A)) ||
+        ((*in >= 0x41) && (*in <= 0x5A)) ||
+        (*in == '_')) && (in < e)) {
        in++;
-       while (((*in >= 0x61) && (*in <= 0x7A)) ||
-              ((*in >= 0x41) && (*in <= 0x5A)) ||
-              ((*in >= 0x30) && (*in <= 0x39)) ||
-              (*in == '_') || (*in == '-') ||
-              (*in == '.'))
+       while ((((*in >= 0x61) && (*in <= 0x7A)) ||
+               ((*in >= 0x41) && (*in <= 0x5A)) ||
+               ((*in >= 0x30) && (*in <= 0x39)) ||
+               (*in == '_') || (*in == '-') ||
+               (*in == '.')) && (in < e))
            in++;
+       if (in >= e)
+           goto complex;
        if ((*in > 0) && (*in < 0x80)) {
            count = in - ctxt->input->cur;
             if ((count > XML_MAX_NAME_LENGTH) &&
@@ -3562,6 +3587,7 @@ xmlParseNCName(xmlParserCtxtPtr ctxt) {
            return(ret);
        }
     }
+complex:
     return(xmlParseNCNameComplex(ctxt));
 }
 
@@ -5658,6 +5684,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
        if (RAW != '>') {
            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
                    "xmlParseEntityDecl: entity %s not terminated\n", name);
+           xmlHaltParser(ctxt);
        } else {
            if (input != ctxt->input) {
                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6769,6 +6796,8 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
        SKIP_BLANKS;
        if (RAW != '[') {
            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+           xmlHaltParser(ctxt);
+           return;
        } else {
            if (ctxt->input->id != id) {
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6829,6 +6858,8 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
        SKIP_BLANKS;
        if (RAW != '[') {
            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+           xmlHaltParser(ctxt);
+           return;
        } else {
            if (ctxt->input->id != id) {
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6884,6 +6915,8 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
 
     } else {
        xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
+       xmlHaltParser(ctxt);
+       return;
     }
 
     if (RAW == 0)
@@ -6897,7 +6930,9 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
        "All markup of the conditional section is not in the same entity\n",
                                 NULL, NULL);
        }
-        SKIP(3);
+       if ((ctxt-> instate != XML_PARSER_EOF) &&
+           ((ctxt->input->cur + 3) <= ctxt->input->end))
+           SKIP(3);
     }
 }
 
@@ -6952,6 +6987,14 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
            xmlParsePI(ctxt);
        }
     }
+
+    /*
+     * detect requirement to exit there and act accordingly
+     * and avoid having instate overriden later on
+     */
+    if (ctxt->instate == XML_PARSER_EOF)
+        return;
+
     /*
      * This is only for internal subset. On external entities,
      * the replacement is done before parsing stage
@@ -7083,7 +7126,7 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
            /*
             * The XML REC instructs us to stop parsing right here
             */
-           ctxt->instate = XML_PARSER_EOF;
+           xmlHaltParser(ctxt);
            return;
        }
     }
@@ -7235,7 +7278,8 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
      * far more secure as the parser will only process data coming from
      * the document entity by default.
      */
-    if ((ent->checked == 0) &&
+    if (((ent->checked == 0) ||
+         ((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
         ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
          (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
        unsigned long oldnbent = ctxt->nbentities;
@@ -8069,7 +8113,7 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
                     * The XML REC instructs us to stop parsing
                     * right here
                     */
-                   ctxt->instate = XML_PARSER_EOF;
+                   xmlHaltParser(ctxt);
                    return;
                }
            }
@@ -9304,7 +9348,7 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
     const xmlChar **atts = ctxt->atts;
     int maxatts = ctxt->maxatts;
     int nratts, nbatts, nbdef;
-    int i, j, nbNs, attval, oldline, oldcol;
+    int i, j, nbNs, attval, oldline, oldcol, inputNr;
     const xmlChar *base;
     unsigned long cur;
     int nsNr = ctxt->nsNr;
@@ -9323,6 +9367,7 @@ reparse:
     SHRINK;
     base = ctxt->input->base;
     cur = ctxt->input->cur - ctxt->input->base;
+    inputNr = ctxt->inputNr;
     oldline = ctxt->input->line;
     oldcol = ctxt->input->col;
     nbatts = 0;
@@ -9348,7 +9393,8 @@ reparse:
      */
     SKIP_BLANKS;
     GROW;
-    if (ctxt->input->base != base) goto base_changed;
+    if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+        goto base_changed;
 
     while (((RAW != '>') &&
           ((RAW != '/') || (NXT(1) != '>')) &&
@@ -9359,7 +9405,7 @@ reparse:
 
        attname = xmlParseAttribute2(ctxt, prefix, localname,
                                     &aprefix, &attvalue, &len, &alloc);
-       if (ctxt->input->base != base) {
+       if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) {
            if ((attvalue != NULL) && (alloc != 0))
                xmlFree(attvalue);
            attvalue = NULL;
@@ -9508,7 +9554,8 @@ skip_ns:
                    break;
                }
                SKIP_BLANKS;
-               if (ctxt->input->base != base) goto base_changed;
+               if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+                   goto base_changed;
                continue;
            }
 
@@ -9545,7 +9592,8 @@ failed:
        GROW
         if (ctxt->instate == XML_PARSER_EOF)
             break;
-       if (ctxt->input->base != base) goto base_changed;
+       if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+           goto base_changed;
        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
            break;
        if (!IS_BLANK_CH(RAW)) {
@@ -9561,7 +9609,8 @@ failed:
            break;
        }
         GROW;
-       if (ctxt->input->base != base) goto base_changed;
+       if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+           goto base_changed;
     }
 
     /*
@@ -9728,6 +9777,17 @@ base_changed:
            if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
                xmlFree((xmlChar *) atts[i]);
     }
+
+    /*
+     * We can't switch from one entity to another in the middle
+     * of a start tag
+     */
+    if (inputNr != ctxt->inputNr) {
+        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                   "Start tag doesn't start and stop in the same entity\n");
+       return(NULL);
+    }
+
     ctxt->input->cur = ctxt->input->base + cur;
     ctxt->input->line = oldline;
     ctxt->input->col = oldcol;
@@ -10009,7 +10069,7 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
        if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                        "detected an error in element content\n");
-           ctxt->instate = XML_PARSER_EOF;
+           xmlHaltParser(ctxt);
             break;
        }
     }
@@ -10044,7 +10104,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
        xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
                 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
                          xmlParserMaxDepth);
-       ctxt->instate = XML_PARSER_EOF;
+       xmlHaltParser(ctxt);
        return;
     }
 
@@ -10396,6 +10456,8 @@ xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
            encoding = xmlParseEncName(ctxt);
            if (RAW != '"') {
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+               xmlFree((xmlChar *) encoding);
+               return(NULL);
            } else
                NEXT;
        } else if (RAW == '\''){
@@ -10403,6 +10465,8 @@ xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
            encoding = xmlParseEncName(ctxt);
            if (RAW != '\'') {
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+               xmlFree((xmlChar *) encoding);
+               return(NULL);
            } else
                NEXT;
        } else {
@@ -10459,7 +10523,11 @@ xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
 
             handler = xmlFindCharEncodingHandler((const char *) encoding);
            if (handler != NULL) {
-               xmlSwitchToEncoding(ctxt, handler);
+               if (xmlSwitchToEncoding(ctxt, handler) < 0) {
+                   /* failed to convert */
+                   ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
+                   return(NULL);
+               }
            } else {
                xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
                        "Unsupported encoding %s\n", encoding);
@@ -10628,7 +10696,8 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
     }
     xmlParseEncodingDecl(ctxt);
-    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+    if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
+         (ctxt->instate == XML_PARSER_EOF)) {
        /*
         * The XML REC instructs us to stop parsing right here
         */
@@ -10752,6 +10821,7 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
 
     if (CUR == 0) {
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
+       return(-1);
     }
 
     /*
@@ -10769,7 +10839,8 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
         * Note that we will switch encoding on the fly.
         */
        xmlParseXMLDecl(ctxt);
-       if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+       if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
+           (ctxt->instate == XML_PARSER_EOF)) {
            /*
             * The XML REC instructs us to stop parsing right here
             */
@@ -11165,7 +11236,7 @@ xmlCheckCdataPush(const xmlChar *utf, int len) {
            else
                return(-ix);
        } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
-           if (ix + 2 > len) return(ix);
+           if (ix + 2 > len) return(-ix);
            if ((utf[ix+1] & 0xc0 ) != 0x80)
                return(-ix);
            codepoint = (utf[ix] & 0x1f) << 6;
@@ -11174,7 +11245,7 @@ xmlCheckCdataPush(const xmlChar *utf, int len) {
                return(-ix);
            ix += 2;
        } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
-           if (ix + 3 > len) return(ix);
+           if (ix + 3 > len) return(-ix);
            if (((utf[ix+1] & 0xc0) != 0x80) ||
                ((utf[ix+2] & 0xc0) != 0x80))
                    return(-ix);
@@ -11185,7 +11256,7 @@ xmlCheckCdataPush(const xmlChar *utf, int len) {
                return(-ix);
            ix += 3;
        } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
-           if (ix + 4 > len) return(ix);
+           if (ix + 4 > len) return(-ix);
            if (((utf[ix+1] & 0xc0) != 0x80) ||
                ((utf[ix+2] & 0xc0) != 0x80) ||
                ((utf[ix+3] & 0xc0) != 0x80))
@@ -11363,7 +11434,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                        ctxt->sax->setDocumentLocator(ctxt->userData,
                                                      &xmlDefaultSAXLocator);
                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
-                   ctxt->instate = XML_PARSER_EOF;
+                   xmlHaltParser(ctxt);
 #ifdef DEBUG_PUSH
                    xmlGenericError(xmlGenericErrorContext,
                            "PP: entering EOF\n");
@@ -11396,7 +11467,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                             * The XML REC instructs us to stop parsing right
                             * here
                             */
-                           ctxt->instate = XML_PARSER_EOF;
+                           xmlHaltParser(ctxt);
                            return(0);
                        }
                        ctxt->standalone = ctxt->input->standalone;
@@ -11452,7 +11523,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                cur = ctxt->input->cur[0];
                if (cur != '<') {
                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
-                   ctxt->instate = XML_PARSER_EOF;
+                   xmlHaltParser(ctxt);
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                        ctxt->sax->endDocument(ctxt->userData);
                    goto done;
@@ -11484,7 +11555,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                    goto done;
                if (name == NULL) {
                    spacePop(ctxt);
-                   ctxt->instate = XML_PARSER_EOF;
+                   xmlHaltParser(ctxt);
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                        ctxt->sax->endDocument(ctxt->userData);
                    goto done;
@@ -11651,7 +11722,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
                    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                                "detected an error in element content\n");
-                   ctxt->instate = XML_PARSER_EOF;
+                   xmlHaltParser(ctxt);
                    break;
                }
                break;
@@ -11972,7 +12043,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                    goto done;
                } else {
                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
-                   ctxt->instate = XML_PARSER_EOF;
+                   xmlHaltParser(ctxt);
 #ifdef DEBUG_PUSH
                    xmlGenericError(xmlGenericErrorContext,
                            "PP: entering EOF\n");
@@ -12336,7 +12407,7 @@ xmldecl_done:
        res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
        if (res < 0) {
            ctxt->errNo = XML_PARSER_EOF;
-           ctxt->disableSAX = 1;
+           xmlHaltParser(ctxt);
            return (XML_PARSER_EOF);
        }
         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
@@ -12390,7 +12461,7 @@ xmldecl_done:
          ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
-        ctxt->instate = XML_PARSER_EOF;
+        xmlHaltParser(ctxt);
     }
     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
         return(ctxt->errNo);
@@ -12578,24 +12649,46 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
 #endif /* LIBXML_PUSH_ENABLED */
 
 /**
- * xmlStopParser:
+ * xmlHaltParser:
  * @ctxt:  an XML parser context
  *
- * Blocks further parser processing
+ * Blocks further parser processing don't override error
+ * for internal use
  */
-void
-xmlStopParser(xmlParserCtxtPtr ctxt) {
+static void
+xmlHaltParser(xmlParserCtxtPtr ctxt) {
     if (ctxt == NULL)
         return;
     ctxt->instate = XML_PARSER_EOF;
-    ctxt->errNo = XML_ERR_USER_STOP;
     ctxt->disableSAX = 1;
     if (ctxt->input != NULL) {
+        /*
+        * in case there was a specific allocation deallocate before
+        * overriding base
+        */
+        if (ctxt->input->free != NULL) {
+           ctxt->input->free((xmlChar *) ctxt->input->base);
+           ctxt->input->free = NULL;
+       }
        ctxt->input->cur = BAD_CAST"";
        ctxt->input->base = ctxt->input->cur;
     }
 }
 
+/**
+ * xmlStopParser:
+ * @ctxt:  an XML parser context
+ *
+ * Blocks further parser processing
+ */
+void
+xmlStopParser(xmlParserCtxtPtr ctxt) {
+    if (ctxt == NULL)
+        return;
+    xmlHaltParser(ctxt);
+    ctxt->errNo = XML_ERR_USER_STOP;
+}
+
 /**
  * xmlCreateIOParserCtxt:
  * @sax:  a SAX handler
@@ -13340,7 +13433,7 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
     /*
      * Also record the size of the entity parsed
      */
-    if (ctxt->input != NULL) {
+    if (ctxt->input != NULL && oldctxt != NULL) {
        oldctxt->sizeentities += ctxt->input->consumed;
        oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
     }
@@ -13352,9 +13445,11 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
 
     if (sax != NULL)
        ctxt->sax = oldsax;
-    oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
-    oldctxt->node_seq.length = ctxt->node_seq.length;
-    oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
+    if (oldctxt != NULL) {
+        oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
+        oldctxt->node_seq.length = ctxt->node_seq.length;
+        oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
+    }
     ctxt->node_seq.maximum = 0;
     ctxt->node_seq.length = 0;
     ctxt->node_seq.buffer = NULL;
@@ -14829,9 +14924,6 @@ xmlInitParser(void) {
 #endif
 #ifdef LIBXML_XPATH_ENABLED
        xmlXPathInit();
-#endif
-#ifdef LIBXML_CATALOG_ENABLED
-        xmlInitializeCatalog();
 #endif
        xmlParserInitialized = 1;
 #ifdef LIBXML_THREAD_ENABLED
index df204fd..2b8646c 100644 (file)
@@ -937,6 +937,7 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
 {
     xmlCharEncodingHandlerPtr handler;
     int len = -1;
+    int ret;
 
     if (ctxt == NULL) return(-1);
     switch (enc) {
@@ -1097,7 +1098,15 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
     if (handler == NULL)
        return(-1);
     ctxt->charset = XML_CHAR_ENCODING_UTF8;
-    return(xmlSwitchToEncodingInt(ctxt, handler, len));
+    ret = xmlSwitchToEncodingInt(ctxt, handler, len);
+    if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) {
+        /*
+        * on encoding conversion errors, stop the parser
+        */
+        xmlStopParser(ctxt);
+       ctxt->errNo = XML_I18N_CONV_FAILED;
+    }
+    return(ret);
 }
 
 /**
@@ -1450,6 +1459,8 @@ xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
     if (entity->URI != NULL)
        input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
     input->base = entity->content;
+    if (entity->length == 0)
+        entity->length = xmlStrlen(entity->content);
     input->cur = entity->content;
     input->length = entity->length;
     input->end = &entity->content[input->length];
index 8d88e95..5779e7f 100644 (file)
@@ -3819,7 +3819,11 @@ xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
             return (0);
         return (1);
     } else if (def1->type == XML_RELAXNG_EXCEPT) {
-        TODO ret = 0;
+        ret = xmlRelaxNGCompareNameClasses(def1->content, def2);
+       if (ret == 0)
+           ret = 1;
+       else if (ret == 1)
+           ret = 0;
     } else {
         TODO ret = 0;
     }
@@ -9859,7 +9863,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
     ctxt->depth++;
     switch (define->type) {
         case XML_RELAXNG_EMPTY:
-            node = xmlRelaxNGSkipIgnored(ctxt, node);
+            xmlRelaxNGSkipIgnored(ctxt, node);
             ret = 0;
             break;
         case XML_RELAXNG_NOT_ALLOWED:
index c0188f2..ddbb138 100644 (file)
@@ -47,7 +47,7 @@
 #ifdef HAVE_PTHREAD_H
 
 static int libxml_is_threaded = -1;
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(__GLIBC__)
 #ifdef linux
 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
 extern int pthread_once (pthread_once_t *__once_control,
@@ -89,7 +89,7 @@ extern int pthread_cond_signal ()
           __attribute((weak));
 #endif
 #endif /* linux */
-#endif /* __GNUC__ */
+#endif /* defined(__GNUC__) && defined(__GLIBC__) */
 #endif /* HAVE_PTHREAD_H */
 
 /*
@@ -415,8 +415,8 @@ xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
     pthread_mutex_unlock(&tok->lock);
 #elif defined HAVE_WIN32_THREADS
     if (tok->count > 0) {
-        LeaveCriticalSection(&tok->cs);
        tok->count--;
+        LeaveCriticalSection(&tok->cs);
     }
 #elif defined HAVE_BEOS_THREADS
     if (tok->lock->tid == find_thread(NULL)) {
index efa3aab..795f272 100644 (file)
@@ -392,62 +392,66 @@ static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const in
 
 static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_curr, TEMP_STORAGE_T *store, const size_t size)
 {
-  while (1)
-  {
-    int64_t A, B, C;
+  while (1) {
+    int64_t A, B, C, D;
+    int ABC, BCD, BD, CD;
+
     /* if the stack only has one thing on it, we are done with the collapse */
-    if (stack_curr <= 1) break;
+    if (stack_curr <= 1) {
+      break;
+    }
+
     /* if this is the last merge, just do it */
-    if ((stack_curr == 2) &&
-        (stack[0].length + stack[1].length == (int64_t) size))
-    {
+    if ((stack_curr == 2) && (stack[0].length + stack[1].length == size)) {
       TIM_SORT_MERGE(dst, stack, stack_curr, store);
       stack[0].length += stack[1].length;
       stack_curr--;
       break;
     }
     /* check if the invariant is off for a stack of 2 elements */
-    else if ((stack_curr == 2) && (stack[0].length <= stack[1].length))
-    {
+    else if ((stack_curr == 2) && (stack[0].length <= stack[1].length)) {
       TIM_SORT_MERGE(dst, stack, stack_curr, store);
       stack[0].length += stack[1].length;
       stack_curr--;
       break;
-    }
-    else if (stack_curr == 2)
+    } else if (stack_curr == 2) {
       break;
+    }
 
-    A = stack[stack_curr - 3].length;
-    B = stack[stack_curr - 2].length;
-    C = stack[stack_curr - 1].length;
+    B = stack[stack_curr - 3].length;
+    C = stack[stack_curr - 2].length;
+    D = stack[stack_curr - 1].length;
 
-    /* check first invariant */
-    if (A <= B + C)
-    {
-      if (A < C)
-      {
-        TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
-        stack[stack_curr - 3].length += stack[stack_curr - 2].length;
-        stack[stack_curr - 2] = stack[stack_curr - 1];
-        stack_curr--;
-      }
-      else
-      {
-        TIM_SORT_MERGE(dst, stack, stack_curr, store);
-        stack[stack_curr - 2].length += stack[stack_curr - 1].length;
-        stack_curr--;
-      }
+    if (stack_curr >= 4) {
+      A = stack[stack_curr - 4].length;
+      ABC = (A <= B + C);
+    } else {
+      ABC = 0;
     }
-    /* check second invariant */
-    else if (B <= C)
-    {
+
+    BCD = (B <= C + D) || ABC;
+    CD = (C <= D);
+    BD = (B < D);
+
+    /* Both invariants are good */
+    if (!BCD && !CD) {
+      break;
+    }
+
+    /* left merge */
+    if (BCD && !CD) {
+      TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
+      stack[stack_curr - 3].length += stack[stack_curr - 2].length;
+      stack[stack_curr - 2] = stack[stack_curr - 1];
+      stack_curr--;
+    } else {
+      /* right merge */
       TIM_SORT_MERGE(dst, stack, stack_curr, store);
       stack[stack_curr - 2].length += stack[stack_curr - 1].length;
       stack_curr--;
     }
-    else
-      break;
   }
+
   return stack_curr;
 }
 
index 307782c..6a158ce 100644 (file)
@@ -1451,9 +1451,9 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
        node->content = xmlBufDetach(buf);
 
        if (last == NULL) {
-           last = ret = node;
+           ret = node;
        } else {
-           last = xmlAddNextSibling(last, node);
+           xmlAddNextSibling(last, node);
        }
     } else if (ret == NULL) {
         ret = xmlNewDocText(doc, BAD_CAST "");
@@ -1639,9 +1639,9 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
        node->content = xmlBufDetach(buf);
 
        if (last == NULL) {
-           last = ret = node;
+           ret = node;
        } else {
-           last = xmlAddNextSibling(last, node);
+           xmlAddNextSibling(last, node);
        }
     }
 
@@ -2799,8 +2799,27 @@ xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
        if(tree->type == XML_ELEMENT_NODE) {
            prop = tree->properties;
            while (prop != NULL) {
+                if (prop->atype == XML_ATTRIBUTE_ID) {
+                    xmlRemoveID(tree->doc, prop);
+                }
+
                prop->doc = doc;
                xmlSetListDoc(prop->children, doc);
+
+                /*
+                 * TODO: ID attributes should be also added to the new
+                 * document, but this breaks things like xmlReplaceNode.
+                 * The underlying problem is that xmlRemoveID is only called
+                 * if a node is destroyed, not if it's unlinked.
+                 */
+#if 0
+                if (xmlIsID(doc, tree, prop)) {
+                    xmlChar *idVal = xmlNodeListGetString(doc, prop->children,
+                                                          1);
+                    xmlAddID(NULL, doc, idVal, prop);
+                }
+#endif
+
                prop = prop->next;
            }
        }
index 409aa81..45a3f70 100644 (file)
@@ -2634,8 +2634,10 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
        /*
         * The id is already defined in this DTD.
         */
-       xmlErrValidNode(ctxt, attr->parent, XML_DTD_ID_REDEFINED,
-                       "ID %s already defined\n", value, NULL, NULL);
+       if (ctxt != NULL) {
+           xmlErrValidNode(ctxt, attr->parent, XML_DTD_ID_REDEFINED,
+                           "ID %s already defined\n", value, NULL, NULL);
+       }
 #endif /* LIBXML_VALID_ENABLED */
        xmlFreeID(ret);
        return(NULL);
index 2a2dd3b..069b425 100644 (file)
@@ -1335,7 +1335,7 @@ xmlGzfileClose (void * context) {
 }
 #endif /* HAVE_ZLIB_H */
 
-#ifdef HAVE_LZMA_H
+#ifdef LIBXML_LZMA_ENABLED
 /************************************************************************
  *                                                                     *
  *             I/O for compressed file accesses                        *
@@ -1452,7 +1452,7 @@ xmlXzfileClose (void * context) {
     if (ret < 0) xmlIOErr(0, "xzclose()");
     return(ret);
 }
-#endif /* HAVE_LZMA_H */
+#endif /* LIBXML_LZMA_ENABLED */
 
 #ifdef LIBXML_HTTP_ENABLED
 /************************************************************************
@@ -2329,10 +2329,10 @@ xmlRegisterDefaultInputCallbacks(void) {
     xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
                              xmlGzfileRead, xmlGzfileClose);
 #endif /* HAVE_ZLIB_H */
-#ifdef HAVE_LZMA_H
+#ifdef LIBXML_LZMA_ENABLED
     xmlRegisterInputCallbacks(xmlXzfileMatch, xmlXzfileOpen,
                              xmlXzfileRead, xmlXzfileClose);
-#endif /* HAVE_ZLIB_H */
+#endif /* LIBXML_LZMA_ENABLED */
 
 #ifdef LIBXML_HTTP_ENABLED
     xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
@@ -2684,7 +2684,7 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
 #endif
        }
 #endif
-#ifdef HAVE_LZMA_H
+#ifdef LIBXML_LZMA_ENABLED
        if ((xmlInputCallbackTable[i].opencallback == xmlXzfileOpen) &&
                (strcmp(URI, "-") != 0)) {
             ret->compressed = __libxml2_xzcompressed(context);
@@ -3351,7 +3351,7 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
      * try to establish compressed status of input if not done already
      */
     if (in->compressed == -1) {
-#ifdef HAVE_LZMA_H
+#ifdef LIBXML_LZMA_ENABLED
        if (in->readcallback == xmlXzfileRead)
             in->compressed = __libxml2_xzcompressed(in->context);
 #endif
index b297ded..1e2eb4a 100644 (file)
@@ -3046,7 +3046,7 @@ static void usage(const char *name) {
     printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
     printf("\t--nocdata : replace cdata section with text nodes\n");
 #ifdef LIBXML_OUTPUT_ENABLED
-    printf("\t--format : reformat/reindent the input\n");
+    printf("\t--format : reformat/reindent the output\n");
     printf("\t--encode encoding : output in the given encoding\n");
     printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
     printf("\t--pretty STYLE : pretty-print in a particular style\n");
index a3dc737..f24fd6d 100644 (file)
@@ -554,7 +554,12 @@ xmlMemoryStrdup(const char *str) {
 
 int
 xmlMemUsed(void) {
-     return(debugMemSize);
+    int res;
+
+    xmlMutexLock(xmlMemMutex);
+    res = debugMemSize;
+    xmlMutexUnlock(xmlMemMutex);
+    return(res);
 }
 
 /**
@@ -567,7 +572,12 @@ xmlMemUsed(void) {
 
 int
 xmlMemBlocks(void) {
-     return(debugMemBlocks);
+    int res;
+
+    xmlMutexLock(xmlMemMutex);
+    res = debugMemBlocks;
+    xmlMutexUnlock(xmlMemMutex);
+    return(res);
 }
 
 #ifdef MEM_LIST
index f19e123..471e7e2 100644 (file)
@@ -2091,6 +2091,9 @@ xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
                "xmlNewTextReader : malloc failed\n");
        return(NULL);
     }
+    /* no operation on a reader should require a huge buffer */
+    xmlBufSetAllocationScheme(ret->buffer,
+                             XML_BUFFER_ALLOC_BOUNDED);
     ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
     if (ret->sax == NULL) {
        xmlBufFree(ret->buffer);
@@ -3616,6 +3619,7 @@ xmlTextReaderConstValue(xmlTextReaderPtr reader) {
            return(((xmlNsPtr) node)->href);
         case XML_ATTRIBUTE_NODE:{
            xmlAttrPtr attr = (xmlAttrPtr) node;
+           const xmlChar *ret;
 
            if ((attr->children != NULL) &&
                (attr->children->type == XML_TEXT_NODE) &&
@@ -3629,10 +3633,21 @@ xmlTextReaderConstValue(xmlTextReaderPtr reader) {
                                         "xmlTextReaderSetup : malloc failed\n");
                         return (NULL);
                     }
+                   xmlBufSetAllocationScheme(reader->buffer,
+                                             XML_BUFFER_ALLOC_BOUNDED);
                 } else
                     xmlBufEmpty(reader->buffer);
                xmlBufGetNodeContent(reader->buffer, node);
-               return(xmlBufContent(reader->buffer));
+               ret = xmlBufContent(reader->buffer);
+               if (ret == NULL) {
+                   /* error on the buffer best to reallocate */
+                   xmlBufFree(reader->buffer);
+                   reader->buffer = xmlBufCreateSize(100);
+                   xmlBufSetAllocationScheme(reader->buffer,
+                                             XML_BUFFER_ALLOC_BOUNDED);
+                   ret = BAD_CAST "";
+               }
+               return(ret);
            }
            break;
        }
@@ -5131,6 +5146,9 @@ xmlTextReaderSetup(xmlTextReaderPtr reader,
                         "xmlTextReaderSetup : malloc failed\n");
         return (-1);
     }
+    /* no operation on a reader should require a huge buffer */
+    xmlBufSetAllocationScheme(reader->buffer,
+                             XML_BUFFER_ALLOC_BOUNDED);
     if (reader->sax == NULL)
        reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
     if (reader->sax == NULL) {
index 0657b66..fe533e6 100644 (file)
@@ -24186,6 +24186,7 @@ xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
        else
            goto pattern_and_enum;
     }
+
     /*
     * Whitespace handling is only of importance for string-based
     * types.
@@ -24196,14 +24197,13 @@ xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
        ws = xmlSchemaGetWhiteSpaceFacetValue(type);
     } else
        ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
+
     /*
     * If the value was not computed (for string or
     * anySimpleType based types), then use the provided
     * type.
     */
-    if (val == NULL)
-       valType = valType;
-    else
+    if (val != NULL)
        valType = xmlSchemaGetValType(val);
 
     ret = 0;
@@ -25546,7 +25546,7 @@ xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
                    if (xmlNewProp(defAttrOwnerElem,
                        iattr->localName, value) == NULL) {
                        VERROR_INT("xmlSchemaVAttributesComplex",
-                           "callling xmlNewProp()");
+                           "calling xmlNewProp()");
                        if (normValue != NULL)
                            xmlFree(normValue);
                        goto internal_error;
index dc41ce6..935fcff 100644 (file)
@@ -361,14 +361,14 @@ turtle_comparison:
     /*
      * compute depth to root
      */
-    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
-       if (cur == node1)
+    for (depth2 = 0, cur = node2; cur->parent != NULL; cur = cur->parent) {
+       if (cur->parent == node1)
            return(1);
        depth2++;
     }
     root = cur;
-    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
-       if (cur == node2)
+    for (depth1 = 0, cur = node1; cur->parent != NULL; cur = cur->parent) {
+       if (cur->parent == node2)
            return(-1);
        depth1++;
     }
@@ -7933,14 +7933,14 @@ xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
 xmlNodePtr
 xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
     if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
-    if (cur == NULL) {
-       if (ctxt->context->node == NULL)
-           return(NULL);
-       if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-           (ctxt->context->node->type == XML_NAMESPACE_DECL))
-           return(NULL);
+    if (cur == NULL)
         return(ctxt->context->node);
-    }
+
+    if (ctxt->context->node == NULL)
+        return(NULL);
+    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
+        (ctxt->context->node->type == XML_NAMESPACE_DECL))
+        return(NULL);
 
     return(xmlXPathNextDescendant(ctxt, cur));
 }
index 0dcb9f4..782957f 100644 (file)
@@ -8,7 +8,7 @@
  */
 #define IN_LIBXML
 #include "libxml.h"
-#ifdef HAVE_LZMA_H
+#ifdef LIBXML_LZMA_ENABLED
 
 #include <string.h>
 #ifdef HAVE_ERRNO_H
@@ -34,7 +34,9 @@
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
 #endif
+#ifdef HAVE_LZMA_H
 #include <lzma.h>
+#endif
 
 #include "xzlib.h"
 #include <libxml/xmlmemory.h>
@@ -581,6 +583,10 @@ xz_decomp(xz_statep state)
             xz_error(state, LZMA_DATA_ERROR, "compressed data error");
             return -1;
         }
+        if (ret == LZMA_PROG_ERROR) {
+            xz_error(state, LZMA_PROG_ERROR, "compression error");
+            return -1;
+        }
     } while (strm->avail_out && ret != LZMA_STREAM_END);
 
     /* update available output and crc check value */
@@ -795,4 +801,4 @@ __libxml2_xzclose(xzFile file)
     xmlFree(state);
     return ret ? ret : LZMA_OK;
 }
-#endif /* HAVE_LZMA_H */
+#endif /* LIBXML_LZMA_ENABLED */
index 527fe0e..40d1b46 100644 (file)
@@ -43,7 +43,7 @@ Used Version: 1.0.6
 Website: http://www.bzip.org
 
 Title: LibXML
-Used Version: 2.9.2
+Used Version: 2.9.3
 Website: http://xmlsoft.org | ftp://xmlsoft.org/libxml2/
 
 Title: ZLib