[LIBXML2] Update to version 2.9.14. CORE-17766 4890/head
authorThomas Faber <thomas.faber@reactos.org>
Sat, 19 Nov 2022 20:10:55 +0000 (15:10 -0500)
committerThomas Faber <thomas.faber@reactos.org>
Tue, 22 Nov 2022 00:46:12 +0000 (19:46 -0500)
16 files changed:
media/doc/3rd Party Files.txt
sdk/include/reactos/libs/libxml/xmlversion.h
sdk/lib/3rdparty/libxml2/HTMLparser.c
sdk/lib/3rdparty/libxml2/NEWS
sdk/lib/3rdparty/libxml2/buf.c
sdk/lib/3rdparty/libxml2/config.h
sdk/lib/3rdparty/libxml2/encoding.c
sdk/lib/3rdparty/libxml2/globals.c
sdk/lib/3rdparty/libxml2/libxml.h
sdk/lib/3rdparty/libxml2/parser.c
sdk/lib/3rdparty/libxml2/tree.c
sdk/lib/3rdparty/libxml2/valid.c
sdk/lib/3rdparty/libxml2/xinclude.c
sdk/lib/3rdparty/libxml2/xmlregexp.c
sdk/lib/3rdparty/libxml2/xpath.c
sdk/lib/3rdparty/libxml2/xpointer.c

index 4d78112..68c6ab5 100644 (file)
@@ -239,7 +239,7 @@ URL: https://github.com/win-iconv/win-iconv
 
 Title: LibXML
 Path: sdk/lib/3rdparty/libxml2
-Used Version: 2.9.13
+Used Version: 2.9.14
 License: MIT (https://spdx.org/licenses/MIT.htmlf)
 URL: http://xmlsoft.org, ftp://xmlsoft.org/libxml2/
 
index 1c8a855..9cd054d 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.13"
+#define LIBXML_DOTTED_VERSION "2.9.14"
 
 /**
  * LIBXML_VERSION:
  *
  * the version number: 1.2.3 value is 10203
  */
-#define LIBXML_VERSION 20913
+#define LIBXML_VERSION 20914
 
 /**
  * LIBXML_VERSION_STRING:
  *
  * the version number string, 1.2.3 value is "10203"
  */
-#define LIBXML_VERSION_STRING "20913"
+#define LIBXML_VERSION_STRING "20914"
 
 /**
  * LIBXML_VERSION_EXTRA:
  *
  * extra version information, used to show a git commit description
  */
-#define LIBXML_VERSION_EXTRA "-GITv2.9.12-115-ga075d256f"
+#define LIBXML_VERSION_EXTRA "-GITv2.9.13-22-g7846b0a67"
 
 /**
  * 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(20913);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20914);
 
 #ifndef VMS
 #if 0
index 3e8a165..e720bb2 100644 (file)
@@ -614,7 +614,8 @@ htmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
            if (*ctxt->input->cur == 0)
                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
        }
-       res++;
+       if (res < INT_MAX)
+           res++;
     }
     return(res);
 }
@@ -3960,26 +3961,6 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
        htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
                     "htmlParseStartTag: invalid element name\n",
                     NULL, NULL);
-        /*
-         * The recovery code is disabled for now as it can result in
-         * quadratic behavior with the push parser. htmlParseStartTag
-         * must consume all content up to the final '>' in order to avoid
-         * rescanning for this terminator.
-         *
-         * For a proper fix in line with HTML5, htmlParseStartTag and
-         * htmlParseElement should only be called when there's an ASCII
-         * alpha character following the initial '<'. Otherwise, the '<'
-         * should be emitted as text (unless followed by '!', '/' or '?').
-         */
-#if 0
-       /* 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);
-       }
-#endif
-
        /* Dump the bogus tag like browsers do */
        while ((CUR != 0) && (CUR != '>') &&
                (ctxt->instate != XML_PARSER_EOF))
@@ -4432,9 +4413,15 @@ htmlParseContent(htmlParserCtxtPtr ctxt) {
            /*
             * Third case :  a sub-element.
             */
-           else if (CUR == '<') {
+           else if ((CUR == '<') && IS_ASCII_LETTER(NXT(1))) {
                htmlParseElement(ctxt);
            }
+           else if (CUR == '<') {
+                if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+                    (ctxt->sax->characters != NULL))
+                    ctxt->sax->characters(ctxt->userData, BAD_CAST "<", 1);
+                NEXT;
+           }
 
            /*
             * Fourth case : a reference. If if has not been resolved,
@@ -4831,13 +4818,19 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
            /*
             * Third case :  a sub-element.
             */
-           else if (CUR == '<') {
+           else if ((CUR == '<') && IS_ASCII_LETTER(NXT(1))) {
                htmlParseElementInternal(ctxt);
                if (currentNode != NULL) xmlFree(currentNode);
 
                currentNode = xmlStrdup(ctxt->name);
                depth = ctxt->nameNr;
            }
+           else if (CUR == '<') {
+                if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+                    (ctxt->sax->characters != NULL))
+                    ctxt->sax->characters(ctxt->userData, BAD_CAST "<", 1);
+                NEXT;
+            }
 
            /*
             * Fourth case : a reference. If if has not been resolved,
@@ -6004,7 +5997,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                                "HPP: entering END_TAG\n");
 #endif
                        break;
-                   } else if (cur == '<') {
+                   } else if ((cur == '<') && IS_ASCII_LETTER(next)) {
                         if ((!terminate) && (next == 0))
                             goto done;
                         ctxt->instate = XML_PARSER_START_TAG;
@@ -6014,6 +6007,12 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                                 "HPP: entering START_TAG\n");
 #endif
                        break;
+                   } else if (cur == '<') {
+                        if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+                            (ctxt->sax->characters != NULL))
+                           ctxt->sax->characters(ctxt->userData,
+                                                 BAD_CAST "<", 1);
+                        NEXT;
                    } else {
                        /*
                         * check that the text sequence is complete
index 2ccdc10..c33d32a 100644 (file)
@@ -1,12 +1,36 @@
 
         NEWS file for libxml2
 
-The change log at 
-ChangeLog.html
- describes the recents commits
-to the GIT at 
-https://gitlab.gnome.org/GNOME/libxml2
- code base.Here is the list of public releases:
+v2.9.14: May 02 2022:
+   - Security:
+  [CVE-2022-29824] Integer overflow in xmlBuf and xmlBuffer
+  Fix potential double-free in xmlXPtrStringRangeFunction
+  Fix memory leak in xmlFindCharEncodingHandler
+  Normalize XPath strings in-place
+  Prevent integer-overflow in htmlSkipBlankChars() and xmlSkipBlankChars()
+    (David Kilzer)
+  Fix leak of xmlElementContent (David Kilzer)
+
+   - Bug fixes:
+  Fix parsing of subtracted regex character classes
+  Fix recursion check in xinclude.c
+  Reset last error in xmlCleanupGlobals
+  Fix certain combinations of regex range quantifiers
+  Fix range quantifier on subregex
+
+   - Improvements:
+  Fix recovery from invalid HTML start tags
+
+   - Build system, portability:
+  Define LFS macros before including system headers
+  Initialize XPath floating-point globals
+  configure: check for icu DEFS (James Hilliard)
+  configure.ac: produce tar.xz only (GNOME policy) (David Seifert)
+  CMakeLists.txt: Fix LIBXML_VERSION_NUMBER
+  Fix build with older Python versions
+  Fix --without-valid build
+
+
 v2.9.13: Feb 19 2022:
    - Security:
   [CVE-2022-23308] Use-after-free of ID and IDREF attributes
index 24368d3..40a5ee0 100644 (file)
 #include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
 #include "buf.h"
 
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) -1)
+#endif
+
 #define WITH_BUFFER_COMPAT
 
 /**
@@ -156,6 +160,8 @@ xmlBufPtr
 xmlBufCreateSize(size_t size) {
     xmlBufPtr ret;
 
+    if (size == SIZE_MAX)
+        return(NULL);
     ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
     if (ret == NULL) {
        xmlBufMemoryError(NULL, "creating buffer");
@@ -166,8 +172,8 @@ xmlBufCreateSize(size_t size) {
     ret->error = 0;
     ret->buffer = NULL;
     ret->alloc = xmlBufferAllocScheme;
-    ret->size = (size ? size+2 : 0);         /* +1 for ending null */
-    ret->compat_size = (int) ret->size;
+    ret->size = (size ? size + 1 : 0);         /* +1 for ending null */
+    ret->compat_size = (ret->size > INT_MAX ? INT_MAX : ret->size);
     if (ret->size){
         ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
         if (ret->content == NULL) {
@@ -442,23 +448,17 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
     CHECK_COMPAT(buf)
 
     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
-    if (buf->use + len < buf->size)
+    if (len < buf->size - buf->use)
         return(buf->size - buf->use);
+    if (len > SIZE_MAX - buf->use)
+        return(0);
 
-    /*
-     * Windows has a BIG problem on realloc timing, so we try to double
-     * the buffer size (if that's enough) (bug 146697)
-     * Apparently BSD too, and it's probably best for linux too
-     * On an embedded system this may be something to change
-     */
-#if 1
-    if (buf->size > (size_t) len)
-        size = buf->size * 2;
-    else
-        size = buf->use + len + 100;
-#else
-    size = buf->use + len + 100;
-#endif
+    if (buf->size > (size_t) len) {
+        size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2;
+    } else {
+        size = buf->use + len;
+        size = size > SIZE_MAX - 100 ? SIZE_MAX : size + 100;
+    }
 
     if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
         /*
@@ -744,7 +744,7 @@ xmlBufIsEmpty(const xmlBufPtr buf)
 int
 xmlBufResize(xmlBufPtr buf, size_t size)
 {
-    unsigned int newSize;
+    size_t newSize;
     xmlChar* rebuf = NULL;
     size_t start_buf;
 
@@ -772,9 +772,13 @@ xmlBufResize(xmlBufPtr buf, size_t size)
        case XML_BUFFER_ALLOC_IO:
        case XML_BUFFER_ALLOC_DOUBLEIT:
            /*take care of empty case*/
-           newSize = (buf->size ? buf->size*2 : size + 10);
+            if (buf->size == 0) {
+                newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
+            } else {
+                newSize = buf->size;
+            }
            while (size > newSize) {
-               if (newSize > UINT_MAX / 2) {
+               if (newSize > SIZE_MAX / 2) {
                    xmlBufMemoryError(buf, "growing buffer");
                    return 0;
                }
@@ -782,15 +786,15 @@ xmlBufResize(xmlBufPtr buf, size_t size)
            }
            break;
        case XML_BUFFER_ALLOC_EXACT:
-           newSize = size+10;
+            newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
            break;
         case XML_BUFFER_ALLOC_HYBRID:
             if (buf->use < BASE_BUFFER_SIZE)
                 newSize = size;
             else {
-                newSize = buf->size * 2;
+                newSize = buf->size;
                 while (size > newSize) {
-                    if (newSize > UINT_MAX / 2) {
+                    if (newSize > SIZE_MAX / 2) {
                         xmlBufMemoryError(buf, "growing buffer");
                         return 0;
                     }
@@ -800,7 +804,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
             break;
 
        default:
-           newSize = size+10;
+            newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
            break;
     }
 
@@ -866,7 +870,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
  */
 int
 xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
-    unsigned int needSize;
+    size_t needSize;
 
     if ((str == NULL) || (buf == NULL) || (buf->error))
        return -1;
@@ -888,8 +892,10 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
     if (len < 0) return -1;
     if (len == 0) return 0;
 
-    needSize = buf->use + len + 2;
-    if (needSize > buf->size){
+    if ((size_t) len >= buf->size - buf->use) {
+        if ((size_t) len >= SIZE_MAX - buf->use)
+            return(-1);
+        needSize = buf->use + len + 1;
        if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
            /*
             * Used to provide parsing limits
@@ -1025,31 +1031,7 @@ xmlBufCat(xmlBufPtr buf, const xmlChar *str) {
  */
 int
 xmlBufCCat(xmlBufPtr buf, const char *str) {
-    const char *cur;
-
-    if ((buf == NULL) || (buf->error))
-        return(-1);
-    CHECK_COMPAT(buf)
-    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
-    if (str == NULL) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufCCat: str == NULL\n");
-#endif
-       return -1;
-    }
-    for (cur = str;*cur != 0;cur++) {
-        if (buf->use  + 10 >= buf->size) {
-            if (!xmlBufResize(buf, buf->use+10)){
-               xmlBufMemoryError(buf, "growing buffer");
-                return XML_ERR_NO_MEMORY;
-            }
-        }
-        buf->content[buf->use++] = *cur;
-    }
-    buf->content[buf->use] = 0;
-    UPDATE_COMPAT(buf)
-    return 0;
+    return xmlBufCat(buf, (const xmlChar *) str);
 }
 
 /**
index ef0b883..596556c 100644 (file)
 /* #undef VA_LIST_IS_ARRAY */
 
 /* Version number of package */
-#define VERSION "2.9.13"
+#define VERSION "2.9.14"
 
 /* Determine what socket length (socklen_t) data type is */
 #define XML_SOCKLEN_T int
index 3741c94..c14c9ff 100644 (file)
@@ -1738,6 +1738,10 @@ xmlFindCharEncodingHandler(const char *name) {
     } else if ((icv_in != (iconv_t) -1) || icv_out != (iconv_t) -1) {
            xmlEncodingErr(XML_ERR_INTERNAL_ERROR,
                    "iconv : problems with filters for '%s'\n", name);
+           if (icv_in != (iconv_t) -1)
+               iconv_close(icv_in);
+           else
+               iconv_close(icv_out);
     }
 #endif /* LIBXML_ICONV_ENABLED */
 #ifdef LIBXML_ICU_ENABLED
index 0c0bdb4..893fb73 100644 (file)
@@ -50,20 +50,6 @@ void xmlInitGlobals(void)
         xmlThrDefMutex = xmlNewMutex();
 }
 
-/**
- * xmlCleanupGlobals:
- *
- * Additional cleanup for multi-threading
- */
-void xmlCleanupGlobals(void)
-{
-    if (xmlThrDefMutex != NULL) {
-       xmlFreeMutex(xmlThrDefMutex);
-       xmlThrDefMutex = NULL;
-    }
-    __xmlGlobalInitMutexDestroy();
-}
-
 /************************************************************************
  *                                                                     *
  *     All the user accessible global variables of the library         *
@@ -577,6 +563,22 @@ xmlInitializeGlobalState(xmlGlobalStatePtr gs)
     xmlMutexUnlock(xmlThrDefMutex);
 }
 
+/**
+ * xmlCleanupGlobals:
+ *
+ * Additional cleanup for multi-threading
+ */
+void xmlCleanupGlobals(void)
+{
+    xmlResetError(&xmlLastError);
+
+    if (xmlThrDefMutex != NULL) {
+       xmlFreeMutex(xmlThrDefMutex);
+       xmlThrDefMutex = NULL;
+    }
+    __xmlGlobalInitMutexDestroy();
+}
+
 /**
  * DOC_DISABLE : we ignore missing doc for the xmlThrDef functions,
  *               those are really internal work
index 1090729..d40fcf8 100644 (file)
@@ -9,8 +9,10 @@
 #ifndef __XML_LIBXML_H__
 #define __XML_LIBXML_H__
 
-#include <libxml/xmlstring.h>
-
+/*
+ * These macros must be defined before including system headers.
+ * Do not add any #include directives above this block.
+ */
 #ifndef NO_LARGEFILE_SOURCE
 #ifndef _LARGEFILE_SOURCE
 #define _LARGEFILE_SOURCE
@@ -39,6 +41,7 @@
 #include "config.h"
 #include <libxml/xmlversion.h>
 #endif
+#include <libxml/xmlstring.h>
 
 #if defined(__Lynx__)
 #include <stdio.h> /* pull definition of size_t */
index 8ca9b2d..1bc3713 100644 (file)
@@ -2208,7 +2208,8 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
                ctxt->input->col++;
            }
            cur++;
-           res++;
+           if (res < INT_MAX)
+               res++;
            if (*cur == 0) {
                ctxt->input->cur = cur;
                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
@@ -2244,7 +2245,8 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
              * by the attachment of one leading and one following space (#x20)
              * character."
              */
-           res++;
+           if (res < INT_MAX)
+               res++;
         }
     }
     return(res);
@@ -14749,7 +14751,6 @@ xmlCleanupParser(void) {
     xmlSchemaCleanupTypes();
     xmlRelaxNGCleanupTypes();
 #endif
-    xmlResetLastError();
     xmlCleanupGlobals();
     xmlCleanupThreads(); /* must be last if called not from the main thread */
     xmlCleanupMemory();
index 9d94aa4..86afb7d 100644 (file)
@@ -7104,6 +7104,8 @@ xmlBufferPtr
 xmlBufferCreateSize(size_t size) {
     xmlBufferPtr ret;
 
+    if (size >= UINT_MAX)
+        return(NULL);
     ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
     if (ret == NULL) {
        xmlTreeErrMemory("creating buffer");
@@ -7111,7 +7113,7 @@ xmlBufferCreateSize(size_t size) {
     }
     ret->use = 0;
     ret->alloc = xmlBufferAllocScheme;
-    ret->size = (size ? size+2 : 0);         /* +1 for ending null */
+    ret->size = (size ? size + 1 : 0);         /* +1 for ending null */
     if (ret->size){
         ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
         if (ret->content == NULL) {
@@ -7171,6 +7173,8 @@ xmlBufferCreateStatic(void *mem, size_t size) {
 
     if ((mem == NULL) || (size == 0))
         return(NULL);
+    if (size > UINT_MAX)
+        return(NULL);
 
     ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
     if (ret == NULL) {
@@ -7318,28 +7322,23 @@ xmlBufferShrink(xmlBufferPtr buf, unsigned int len) {
  */
 int
 xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
-    int size;
+    unsigned int size;
     xmlChar *newbuf;
 
     if (buf == NULL) return(-1);
 
     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
-    if (len + buf->use < buf->size) return(0);
+    if (len < buf->size - buf->use)
+        return(0);
+    if (len > UINT_MAX - buf->use)
+        return(-1);
 
-    /*
-     * Windows has a BIG problem on realloc timing, so we try to double
-     * the buffer size (if that's enough) (bug 146697)
-     * Apparently BSD too, and it's probably best for linux too
-     * On an embedded system this may be something to change
-     */
-#if 1
-    if (buf->size > len)
-        size = buf->size * 2;
-    else
-        size = buf->use + len + 100;
-#else
-    size = buf->use + len + 100;
-#endif
+    if (buf->size > (size_t) len) {
+        size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2;
+    } else {
+        size = buf->use + len;
+        size = size > UINT_MAX - 100 ? UINT_MAX : size + 100;
+    }
 
     if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
         size_t start_buf = buf->content - buf->contentIO;
@@ -7466,7 +7465,10 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
        case XML_BUFFER_ALLOC_IO:
        case XML_BUFFER_ALLOC_DOUBLEIT:
            /*take care of empty case*/
-           newSize = (buf->size ? buf->size : size + 10);
+            if (buf->size == 0)
+                newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);
+            else
+                newSize = buf->size;
            while (size > newSize) {
                if (newSize > UINT_MAX / 2) {
                    xmlTreeErrMemory("growing buffer");
@@ -7476,7 +7478,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
            }
            break;
        case XML_BUFFER_ALLOC_EXACT:
-           newSize = size+10;
+           newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);;
            break;
         case XML_BUFFER_ALLOC_HYBRID:
             if (buf->use < BASE_BUFFER_SIZE)
@@ -7494,7 +7496,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
             break;
 
        default:
-           newSize = size+10;
+           newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);;
            break;
     }
 
@@ -7580,8 +7582,10 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
     if (len < 0) return -1;
     if (len == 0) return 0;
 
-    needSize = buf->use + len + 2;
-    if (needSize > buf->size){
+    if ((unsigned) len >= buf->size - buf->use) {
+        if ((unsigned) len >= UINT_MAX - buf->use)
+            return XML_ERR_NO_MEMORY;
+        needSize = buf->use + len + 1;
         if (!xmlBufferResize(buf, needSize)){
            xmlTreeErrMemory("growing buffer");
             return XML_ERR_NO_MEMORY;
@@ -7694,29 +7698,7 @@ xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
  */
 int
 xmlBufferCCat(xmlBufferPtr buf, const char *str) {
-    const char *cur;
-
-    if (buf == NULL)
-        return(-1);
-    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
-    if (str == NULL) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufferCCat: str == NULL\n");
-#endif
-       return -1;
-    }
-    for (cur = str;*cur != 0;cur++) {
-        if (buf->use  + 10 >= buf->size) {
-            if (!xmlBufferResize(buf, buf->use+10)){
-               xmlTreeErrMemory("growing buffer");
-                return XML_ERR_NO_MEMORY;
-            }
-        }
-        buf->content[buf->use++] = *cur;
-    }
-    buf->content[buf->use] = 0;
-    return 0;
+    return xmlBufferCat(buf, (const xmlChar *) str);
 }
 
 /**
index 8e596f1..ed3c850 100644 (file)
@@ -479,35 +479,6 @@ nodeVPop(xmlValidCtxtPtr ctxt)
     return (ret);
 }
 
-/**
- * xmlValidNormalizeString:
- * @str: a string
- *
- * Normalize a string in-place.
- */
-static void
-xmlValidNormalizeString(xmlChar *str) {
-    xmlChar *dst;
-    const xmlChar *src;
-
-    if (str == NULL)
-        return;
-    src = str;
-    dst = str;
-
-    while (*src == 0x20) src++;
-    while (*src != 0) {
-       if (*src == 0x20) {
-           while (*src == 0x20) src++;
-           if (*src != 0)
-               *dst++ = 0x20;
-       } else {
-           *dst++ = *src++;
-       }
-    }
-    *dst = 0;
-}
-
 #ifdef DEBUG_VALID_ALGO
 static void
 xmlValidPrintNode(xmlNodePtr cur) {
@@ -1081,6 +1052,7 @@ xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
            tmp->type = cur->type;
            tmp->ocur = cur->ocur;
            prev->c2 = tmp;
+           tmp->parent = prev;
            if (cur->name != NULL) {
                if (dict)
                    tmp->name = xmlDictLookup(dict, cur->name, -1);
@@ -2636,6 +2608,35 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
            (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
            xmlFree((char *)(str));
 
+/**
+ * xmlValidNormalizeString:
+ * @str: a string
+ *
+ * Normalize a string in-place.
+ */
+static void
+xmlValidNormalizeString(xmlChar *str) {
+    xmlChar *dst;
+    const xmlChar *src;
+
+    if (str == NULL)
+        return;
+    src = str;
+    dst = str;
+
+    while (*src == 0x20) src++;
+    while (*src != 0) {
+       if (*src == 0x20) {
+           while (*src == 0x20) src++;
+           if (*src != 0)
+               *dst++ = 0x20;
+       } else {
+           *dst++ = *src++;
+       }
+    }
+    *dst = 0;
+}
+
 static int
 xmlIsStreaming(xmlValidCtxtPtr ctxt) {
     xmlParserCtxtPtr pctxt;
index 2a0614d..e5fdf0f 100644 (file)
@@ -525,8 +525,6 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
        if (href == NULL)
            return(-1);
     }
-    if ((href[0] == '#') || (href[0] == 0))
-       local = 1;
     parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
     if (parse != NULL) {
        if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
@@ -623,6 +621,9 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
        return(-1);
     }
 
+    if (xmlStrEqual(URL, ctxt->doc->URL))
+       local = 1;
+
     /*
      * If local and xml then we need a fragment
      */
index 8d01c2b..657912e 100644 (file)
@@ -1693,12 +1693,12 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
                    counter = xmlRegGetCounter(ctxt);
                    ctxt->counters[counter].min = atom->min - 1;
                    ctxt->counters[counter].max = atom->max - 1;
-                   /* count the number of times we see it again */
-                   xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop,
-                                                  atom->start, counter);
                    /* allow a way out based on the count */
                    xmlFAGenerateCountedTransition(ctxt, atom->stop,
                                                   newstate, counter);
+                   /* count the number of times we see it again */
+                   xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop,
+                                                  atom->start, counter);
                    /* and if needed allow a direct exit for 0 */
                    if (atom->min == 0)
                        xmlFAGenerateEpsilonTransition(ctxt, atom->start0,
@@ -3364,7 +3364,6 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                    /*
                     * this is a multiple input sequence
                     * If there is a counter associated increment it now.
-                    * before potentially saving and rollback
                     * do not increment if the counter is already over the
                     * maximum limit in which case get to next transition
                     */
@@ -3380,15 +3379,17 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                        counter = &exec->comp->counters[trans->counter];
                        if (exec->counts[trans->counter] >= counter->max)
                            continue; /* for loop on transitions */
-
+                    }
+                    /* Save before incrementing */
+                   if (exec->state->nbTrans > exec->transno + 1) {
+                       xmlFARegExecSave(exec);
+                   }
+                   if (trans->counter >= 0) {
 #ifdef DEBUG_REGEXP_EXEC
                        printf("Increasing count %d\n", trans->counter);
 #endif
                        exec->counts[trans->counter]++;
                    }
-                   if (exec->state->nbTrans > exec->transno + 1) {
-                       xmlFARegExecSave(exec);
-                   }
                    exec->transcount = 1;
                    do {
                        /*
@@ -5107,7 +5108,7 @@ xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) {
     }
     NEXTL(len);
     cur = CUR;
-    if ((cur != '-') || (NXT(1) == ']')) {
+    if ((cur != '-') || (NXT(1) == '[') || (NXT(1) == ']')) {
         xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
                              XML_REGEXP_CHARVAL, start, end, NULL);
        return;
index 2da591c..c2d8458 100644 (file)
@@ -488,9 +488,9 @@ int wrap_cmp( xmlNodePtr x, xmlNodePtr y );
  *                                                                     *
  ************************************************************************/
 
-double xmlXPathNAN;
-double xmlXPathPINF;
-double xmlXPathNINF;
+double xmlXPathNAN = 0.0;
+double xmlXPathPINF = 0.0;
+double xmlXPathNINF = 0.0;
 
 /**
  * xmlXPathInit:
@@ -9260,52 +9260,45 @@ xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
  */
 void
 xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
-  xmlXPathObjectPtr obj = NULL;
-  xmlChar *source = NULL;
-  xmlBufPtr target;
-  xmlChar blank;
-
-  if (ctxt == NULL) return;
-  if (nargs == 0) {
-    /* Use current context node */
-      valuePush(ctxt,
-         xmlXPathCacheWrapString(ctxt->context,
-           xmlXPathCastNodeToString(ctxt->context->node)));
-    nargs = 1;
-  }
+    xmlChar *source, *target;
+    int blank;
 
-  CHECK_ARITY(1);
-  CAST_TO_STRING;
-  CHECK_TYPE(XPATH_STRING);
-  obj = valuePop(ctxt);
-  source = obj->stringval;
+    if (ctxt == NULL) return;
+    if (nargs == 0) {
+        /* Use current context node */
+        valuePush(ctxt,
+            xmlXPathCacheWrapString(ctxt->context,
+                xmlXPathCastNodeToString(ctxt->context->node)));
+        nargs = 1;
+    }
 
-  target = xmlBufCreate();
-  if (target && source) {
+    CHECK_ARITY(1);
+    CAST_TO_STRING;
+    CHECK_TYPE(XPATH_STRING);
+    source = ctxt->value->stringval;
+    if (source == NULL)
+        return;
+    target = source;
 
     /* Skip leading whitespaces */
     while (IS_BLANK_CH(*source))
-      source++;
+        source++;
 
     /* Collapse intermediate whitespaces, and skip trailing whitespaces */
     blank = 0;
     while (*source) {
-      if (IS_BLANK_CH(*source)) {
-       blank = 0x20;
-      } else {
-       if (blank) {
-         xmlBufAdd(target, &blank, 1);
-         blank = 0;
-       }
-       xmlBufAdd(target, source, 1);
-      }
-      source++;
+        if (IS_BLANK_CH(*source)) {
+           blank = 1;
+        } else {
+            if (blank) {
+                *target++ = 0x20;
+                blank = 0;
+            }
+            *target++ = *source;
+        }
+        source++;
     }
-    valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
-       xmlBufContent(target)));
-    xmlBufFree(target);
-  }
-  xmlXPathReleaseObject(ctxt->context, obj);
+    *target = 0;
 }
 
 /**
index afeaa2e..e9c783c 100644 (file)
@@ -2756,6 +2756,7 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
         */
        tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
        xmlXPathFreeObject(set);
+        set = NULL;
        if (tmp == NULL) {
             xmlXPathErr(ctxt, XPATH_MEMORY_ERROR);
             goto error;