[LIBXML2] Update to version 2.9.7. CORE-14291
authorThomas Faber <thomas.faber@reactos.org>
Sun, 4 Feb 2018 16:15:47 +0000 (17:15 +0100)
committerThomas Faber <thomas.faber@reactos.org>
Mon, 5 Feb 2018 17:55:48 +0000 (18:55 +0100)
52 files changed:
sdk/include/reactos/libs/libxml/HTMLparser.h
sdk/include/reactos/libs/libxml/nanoftp.h
sdk/include/reactos/libs/libxml/schemasInternals.h
sdk/include/reactos/libs/libxml/threads.h
sdk/include/reactos/libs/libxml/xmlreader.h
sdk/include/reactos/libs/libxml/xmlversion.h
sdk/lib/3rdparty/libxml2/ChangeLog
sdk/lib/3rdparty/libxml2/HTMLparser.c
sdk/lib/3rdparty/libxml2/SAX2.c
sdk/lib/3rdparty/libxml2/buf.c
sdk/lib/3rdparty/libxml2/c14n.c
sdk/lib/3rdparty/libxml2/catalog.c
sdk/lib/3rdparty/libxml2/config.h
sdk/lib/3rdparty/libxml2/debugXML.c
sdk/lib/3rdparty/libxml2/dict.c
sdk/lib/3rdparty/libxml2/elfgcchack.h
sdk/lib/3rdparty/libxml2/encoding.c
sdk/lib/3rdparty/libxml2/entities.c
sdk/lib/3rdparty/libxml2/error.c
sdk/lib/3rdparty/libxml2/hash.c
sdk/lib/3rdparty/libxml2/include/win32config.h
sdk/lib/3rdparty/libxml2/include/wsockcompat.h
sdk/lib/3rdparty/libxml2/libxml.h
sdk/lib/3rdparty/libxml2/list.c
sdk/lib/3rdparty/libxml2/nanoftp.c
sdk/lib/3rdparty/libxml2/nanohttp.c
sdk/lib/3rdparty/libxml2/parser.c
sdk/lib/3rdparty/libxml2/parserInternals.c
sdk/lib/3rdparty/libxml2/pattern.c
sdk/lib/3rdparty/libxml2/relaxng.c
sdk/lib/3rdparty/libxml2/threads.c
sdk/lib/3rdparty/libxml2/timsort.h
sdk/lib/3rdparty/libxml2/tree.c
sdk/lib/3rdparty/libxml2/trionan.c
sdk/lib/3rdparty/libxml2/uri.c
sdk/lib/3rdparty/libxml2/valid.c
sdk/lib/3rdparty/libxml2/xmlIO.c
sdk/lib/3rdparty/libxml2/xmlcatalog.c
sdk/lib/3rdparty/libxml2/xmllint.c
sdk/lib/3rdparty/libxml2/xmlmemory.c
sdk/lib/3rdparty/libxml2/xmlmodule.c
sdk/lib/3rdparty/libxml2/xmlreader.c
sdk/lib/3rdparty/libxml2/xmlregexp.c
sdk/lib/3rdparty/libxml2/xmlsave.c
sdk/lib/3rdparty/libxml2/xmlschemas.c
sdk/lib/3rdparty/libxml2/xmlschemastypes.c
sdk/lib/3rdparty/libxml2/xmlstring.c
sdk/lib/3rdparty/libxml2/xmlunicode.c
sdk/lib/3rdparty/libxml2/xmlwriter.c
sdk/lib/3rdparty/libxml2/xpath.c
sdk/lib/3rdparty/libxml2/xpointer.c
sdk/lib/3rdparty/libxml2/xzlib.c

index 551186c..1d4fec2 100644 (file)
@@ -115,12 +115,12 @@ XMLPUBFUN htmlParserCtxtPtr XMLCALL
 XMLPUBFUN int XMLCALL
                        htmlParseDocument(htmlParserCtxtPtr ctxt);
 XMLPUBFUN htmlDocPtr XMLCALL
-                       htmlSAXParseDoc (xmlChar *cur,
+                       htmlSAXParseDoc (const xmlChar *cur,
                                         const char *encoding,
                                         htmlSAXHandlerPtr sax,
                                         void *userData);
 XMLPUBFUN htmlDocPtr XMLCALL
-                       htmlParseDoc    (xmlChar *cur,
+                       htmlParseDoc    (const xmlChar *cur,
                                         const char *encoding);
 XMLPUBFUN htmlDocPtr XMLCALL
                        htmlSAXParseFile(const char *filename,
index abb4bf7..7335faf 100644 (file)
@@ -16,7 +16,7 @@
 #ifdef LIBXML_FTP_ENABLED
 
 /* Needed for portability to Windows 64 bits */
-#if defined(__MINGW32__) || defined(_WIN32_WCE)
+#if defined(_WIN32) && !defined(__CYGWIN__)
 #include <winsock2.h>
 #else
 /**
index c7cf552..6fb7113 100644 (file)
@@ -3,7 +3,7 @@
  * Description: internal interfaces for the XML Schemas handling
  *              and schema validity checking
  *             The Schemas development is a Work In Progress.
- *              Some of those interfaces are not garanteed to be API or ABI stable !
+ *              Some of those interfaces are not guaranteed to be API or ABI stable !
  *
  * Copy: See Copyright for the status of this software.
  *
index d31f16a..9969ae7 100644 (file)
@@ -72,8 +72,13 @@ XMLPUBFUN void XMLCALL
 XMLPUBFUN xmlGlobalStatePtr XMLCALL
                        xmlGetGlobalState(void);
 
-#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC_FOR_DLL)
-int XMLCALL xmlDllMain(void *hinstDLL, unsigned long fdwReason, void *lpvReserved);
+#ifdef HAVE_PTHREAD_H
+#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+#if defined(LIBXML_STATIC_FOR_DLL)
+int XMLCALL
+xmlDllMain(void *hinstDLL, unsigned long fdwReason,
+           void *lpvReserved);
+#endif
 #endif
 
 #ifdef __cplusplus
index 2c99e3a..e8a8bcc 100644 (file)
@@ -393,7 +393,7 @@ typedef void *  xmlTextReaderLocatorPtr;
  * @arg: the user argument
  * @msg: the message
  * @severity: the severity of the error
- * @locator: a locator indicating where the error occured
+ * @locator: a locator indicating where the error occurred
  *
  * Signature of an error callback from a reader parser
  */
index 7f20005..90d61f5 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.4"
+#define LIBXML_DOTTED_VERSION "2.9.7"
 
 /**
  * LIBXML_VERSION:
  *
  * the version number: 1.2.3 value is 10203
  */
-#define LIBXML_VERSION 20904
+#define LIBXML_VERSION 20907
 
 /**
  * LIBXML_VERSION_STRING:
  *
  * the version number string, 1.2.3 value is "10203"
  */
-#define LIBXML_VERSION_STRING "20904"
+#define LIBXML_VERSION_STRING "20907"
 
 /**
  * LIBXML_VERSION_EXTRA:
  *
  * extra version information, used to show a CVS compilation
  */
-#define LIBXML_VERSION_EXTRA "-GITCVE-2016-1834-21-g502f6a6"
+#define LIBXML_VERSION_EXTRA "-GITv2.9.7-rc1"
 
 /**
  * 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(20904);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20907);
 
 #ifndef VMS
 #if 0
index ef6cb8e..896fbbb 100644 (file)
@@ -1929,7 +1929,7 @@ Mon Jun 12 12:54:25 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
 
        * tree.c: Fixed xmlGetNodePath() to generate the node test "*"
          for elements in the default namespace, rather than generating
-         an unprefixed named node test and loosing the namespace
+         an unprefixed named node test and losing the namespace
          information.
 
 Fri Jun  9 21:45:02 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
@@ -2305,7 +2305,7 @@ Mon Mar  6 14:21:08 CET 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
        * tree.c: Simplified usage of the internal xmlNsMap. Added a
          "strict" lookup for namespaces based on a prefix. Fixed a
          namespace processing issue in the clone-node function, which
-         occured if a @ctxt argument was given.
+         occurred if a @ctxt argument was given.
          
 Fri Mar  3 17:44:10 CET 2006 Rob Richards <rrichards@ctindustries.net>
 
@@ -3951,7 +3951,7 @@ Thu Jun 30 15:01:52 CEST 2005 Daniel Veillard <daniel@veillard.com>
        * README: updated 
        * debugXML.c: fix a bug raised by bill on IRC
        * relaxng.c: fix a leak in weird circumstances
-       * runsuite.c Makefile.am: standalone test tool agaisnt
+       * runsuite.c Makefile.am: standalone test tool against
          the regression suites, work in progress
 
 Tue Jun 28 08:30:26 CEST 2005 Daniel Veillard <daniel@veillard.com>
@@ -4356,7 +4356,7 @@ Fri Apr  8 21:58:04 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
        * xmlschemas.c: Added substitution group constraints; changed
          the build of the pre-computed substitution groups. Channeled
          errors during xsi assembling of schemas to the validation
-         context. Fixed a big memory leak, which occured when using
+         context. Fixed a big memory leak, which occurred when using
          IDCs: the precomputed value of attributes was not freed if
          the attribute did not resolve to an IDC field (discovered
          with the help of Randy J. Ray's schema, posted to the
@@ -4551,7 +4551,7 @@ Mon Mar 21 22:58:37 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
 
 Mon Mar 21 21:09:07 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
 
-       * xmlschemas.c: Fixed a segfault, which occured during bubbling
+       * xmlschemas.c: Fixed a segfault, which occurred during bubbling
          of IDC nodes (bug #170779 and #170778, reported by GUY Fabrice):
          a variable was missed to be reset in a loop. Deactivated bubbling,
          if not referenced by a keyref.
@@ -11220,7 +11220,7 @@ Fri Mar  7 19:29:40 CET 2003 Daniel Veillard <daniel@veillard.com>
        * test/xsdtest/xsdtest.xml uri.c: after and exchange with James
          Clark it appeared I had bug in URI parsing code ...
        * relaxng.c include/libxml/relaxng.h: completely revamped error
-         reporting to not loose message from optional parts.
+         reporting to not lose message from optional parts.
        * xmllint.c: added timing for RNG validation steps
        * result/relaxng/*: updated the result, all error messages changed
 
@@ -13182,7 +13182,7 @@ Thu Aug  1 12:17:30 CEST 2002 Daniel Veillard <daniel@veillard.com>
          xmlNewCharEncodingHandler as requested in #89415
        * python/generator.py python/setup.py.in: applied cleanup
          patches from Marc-Andre Lemburg
-       * tree.c: fixing bug #89332 on a specific case of loosing 
+       * tree.c: fixing bug #89332 on a specific case of losing 
          the XML-1.0 namespace on xml:xxx attributes
 
 Wed Jul 31 23:27:42 2002  Aleksey Sanin  <aleksey@aleksey.com>
@@ -15356,7 +15356,7 @@ Sat Oct  6 15:27:12 CEST 2001 Daniel Veillard <daniel@veillard.com>
 
 Sat Oct  6 15:07:14 CEST 2001 Daniel Veillard <daniel@veillard.com>
 
-       * xpath.c: fixing #61673 part I, do not loose doc information
+       * xpath.c: fixing #61673 part I, do not lose doc information
          when copying result value trees.
 
 Sat Oct  6 11:58:58 CEST 2001 Daniel Veillard <daniel@veillard.com>
@@ -15970,7 +15970,7 @@ Tue Jul 10 17:47:09 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 Mon Jul  9 22:06:53 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
        * valid.c: fixed "Internal: MIXED struct bad" when #CDATA elements
-         validation occured on content with element child
+         validation occurred on content with element child
 
 Mon Jul  9 17:59:08 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
index d1395fa..e4f816e 100644 (file)
@@ -2528,8 +2528,12 @@ htmlParseNameComplex(xmlParserCtxtPtr ctxt) {
        }
     }
 
-    if (ctxt->input->base > ctxt->input->cur - len)
-       return(NULL);
+    if (ctxt->input->cur - ctxt->input->base < len) {
+        /* Sanity check */
+       htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+                     "unexpected change of input buffer", NULL, NULL);
+        return (NULL);
+    }
 
     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
 }
@@ -4444,7 +4448,7 @@ static void
 htmlParseElementInternal(htmlParserCtxtPtr ctxt) {
     const xmlChar *name;
     const htmlElemDesc * info;
-    htmlParserNodeInfo node_info = { 0, };
+    htmlParserNodeInfo node_info = { NULL, 0, 0, 0, 0 };
     int failed;
 
     if ((ctxt == NULL) || (ctxt->input == NULL)) {
@@ -4941,6 +4945,7 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
     ctxt->wellFormed = 1;
     ctxt->replaceEntities = 0;
     ctxt->linenumbers = xmlLineNumbersDefaultValue;
+    ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
     ctxt->html = 1;
     ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0;
     ctxt->vctxt.userData = ctxt;
@@ -6273,7 +6278,8 @@ htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
  */
 
 htmlDocPtr
-htmlSAXParseDoc(xmlChar *cur, const char *encoding, htmlSAXHandlerPtr sax, void *userData) {
+htmlSAXParseDoc(const xmlChar *cur, const char *encoding,
+                htmlSAXHandlerPtr sax, void *userData) {
     htmlDocPtr ret;
     htmlParserCtxtPtr ctxt;
 
@@ -6312,7 +6318,7 @@ htmlSAXParseDoc(xmlChar *cur, const char *encoding, htmlSAXHandlerPtr sax, void
  */
 
 htmlDocPtr
-htmlParseDoc(xmlChar *cur, const char *encoding) {
+htmlParseDoc(const xmlChar *cur, const char *encoding) {
     return(htmlSAXParseDoc(cur, encoding, NULL, NULL));
 }
 
index 5cbb700..0f261b7 100644 (file)
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
+#include <stddef.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/tree.h>
 #include <libxml/parser.h>
@@ -1181,6 +1182,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
                xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
                if (name != NULL)
                    xmlFree(name);
+                if (nval != NULL)
+                    xmlFree(nval);
                return;
            }
        } else {
@@ -1242,6 +1245,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
                xmlFree(ns);
                if (name != NULL)
                    xmlFree(name);
+                if (nval != NULL)
+                    xmlFree(nval);
                return;
            }
        } else {
@@ -1311,6 +1316,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
                                              name, namespace->href);
                         ctxt->wellFormed = 0;
                         if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+                        if (name != NULL)
+                            xmlFree(name);
                         goto error;
                     }
                 }
@@ -1908,7 +1915,7 @@ skip:
            else {
                ret->line = 65535;
                if (ctxt->options & XML_PARSE_BIG_LINES)
-                   ret->psvi = (void *) (long) ctxt->input->line;
+                   ret->psvi = (void *) (ptrdiff_t) ctxt->input->line;
            }
        }
     }
@@ -2311,7 +2318,7 @@ xmlSAX2StartElementNs(void *ctx,
        } else {
             /*
              * any out of memory error would already have been raised
-             * but we can't be garanteed it's the actual error due to the
+             * but we can't be guaranteed it's the actual error due to the
              * API, best is to skip in this case
              */
            continue;
@@ -2805,7 +2812,8 @@ xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
        xmlTextConcat(lastChild, value, len);
     } else {
        ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
-       xmlAddChild(ctxt->node, ret);
+       if (xmlAddChild(ctxt->node, ret) == NULL)
+               xmlFreeNode(ret);
     }
 }
 
index 07922ff..21cb9d8 100644 (file)
@@ -49,7 +49,7 @@ struct _xmlBuf {
     size_t use;                        /* The buffer size used */
     size_t size;               /* The buffer size */
     xmlBufferPtr buffer;        /* wrapper for an old buffer */
-    int error;                  /* an error code if a failure occured */
+    int error;                  /* an error code if a failure occurred */
 };
 
 #ifdef WITH_BUFFER_COMPAT
@@ -231,7 +231,7 @@ xmlBufPtr
 xmlBufCreateStatic(void *mem, size_t size) {
     xmlBufPtr ret;
 
-    if ((mem == NULL) || (size == 0))
+    if (mem == NULL)
         return(NULL);
 
     ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
@@ -701,7 +701,7 @@ xmlBufUse(const xmlBufPtr buf)
  * used in the buffer. It does not account for the terminating zero
  * usually needed
  *
- * Returns the amount or 0 if none or an error occured
+ * Returns the amount or 0 if none or an error occurred
  */
 
 size_t
index ca77f92..be687ea 100644 (file)
@@ -1375,13 +1375,6 @@ xmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur)
                 xmlFreeURI(uri);
                 return (-1);
             }
-            if ((xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "urn") != 0)
-                && (xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "dav") !=0)
-                && (xmlStrlen((const xmlChar *) uri->server) == 0)) {
-                xmlC14NErrRelativeNamespace(uri->scheme);
-                xmlFreeURI(uri);
-                return (-1);
-            }
             xmlFreeURI(uri);
         }
         ns = ns->next;
index 6dfdfbb..f6186a1 100644 (file)
@@ -2396,6 +2396,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value,
                case SGML_CATA_ENTITY:
                    if (*cur == '%')
                        type = SGML_CATA_PENTITY;
+                    /* Falls through. */
                case SGML_CATA_PENTITY:
                case SGML_CATA_DOCTYPE:
                case SGML_CATA_LINKTYPE:
index 9818139..9e23531 100644 (file)
 /* Define as const if the declaration of iconv() needs const. */
 /* #undef ICONV_CONST */
 
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
 /* #undef LT_OBJDIR */
 
 /* Name of package */
    #define below would cause a syntax error. */
 /* #undef _UINT32_T */
 
-/* Using the Win32 Socket implementation */
-//#define _WINSOCKAPI_ 1
-
 /* ss_family is not defined here, use __ss_family instead */
 /* #undef ss_family */
 
index a1b550a..a8ec8a4 100644 (file)
@@ -2931,7 +2931,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
                  fprintf(ctxt->output, "\tvalidate     check the document for errors\n");
 #endif /* LIBXML_VALID_ENABLED */
 #ifdef LIBXML_SCHEMAS_ENABLED
-                 fprintf(ctxt->output, "\trelaxng rng  validate the document agaisnt the Relax-NG schemas\n");
+                 fprintf(ctxt->output, "\trelaxng rng  validate the document against the Relax-NG schemas\n");
 #endif
                  fprintf(ctxt->output, "\tgrep string  search for a string in the subtree\n");
 #ifdef LIBXML_VALID_ENABLED
index c0585fe..0ef3718 100644 (file)
@@ -48,7 +48,7 @@
 #else
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
-#elif defined(WIN32)
+#elif defined(_WIN32)
 typedef unsigned __int32 uint32_t;
 #endif
 #endif
@@ -249,7 +249,7 @@ xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen) {
 #endif
     pool = dict->strings;
     while (pool != NULL) {
-       if (pool->end - pool->free > namelen)
+       if ((size_t)(pool->end - pool->free) > namelen)
            goto found_pool;
        if (pool->size > size) size = pool->size;
         limit += pool->size;
@@ -317,7 +317,7 @@ xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen,
 #endif
     pool = dict->strings;
     while (pool != NULL) {
-       if (pool->end - pool->free > namelen + plen + 1)
+       if ((size_t)(pool->end - pool->free) > namelen + plen + 1)
            goto found_pool;
        if (pool->size > size) size = pool->size;
         limit += pool->size;
@@ -453,14 +453,23 @@ xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
     }
     switch (namelen) {
         case 10: value += name[9];
+        /* Falls through. */
         case 9: value += name[8];
+        /* Falls through. */
         case 8: value += name[7];
+        /* Falls through. */
         case 7: value += name[6];
+        /* Falls through. */
         case 6: value += name[5];
+        /* Falls through. */
         case 5: value += name[4];
+        /* Falls through. */
         case 4: value += name[3];
+        /* Falls through. */
         case 3: value += name[2];
+        /* Falls through. */
         case 2: value += name[1];
+        /* Falls through. */
         default: break;
     }
     return(value);
@@ -496,15 +505,25 @@ xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
     }
     switch (plen) {
         case 10: value += prefix[9];
+        /* Falls through. */
         case 9: value += prefix[8];
+        /* Falls through. */
         case 8: value += prefix[7];
+        /* Falls through. */
         case 7: value += prefix[6];
+        /* Falls through. */
         case 6: value += prefix[5];
+        /* Falls through. */
         case 5: value += prefix[4];
+        /* Falls through. */
         case 4: value += prefix[3];
+        /* Falls through. */
         case 3: value += prefix[2];
+        /* Falls through. */
         case 2: value += prefix[1];
+        /* Falls through. */
         case 1: value += prefix[0];
+        /* Falls through. */
         default: break;
     }
     len -= plen;
@@ -514,15 +533,25 @@ xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
     }
     switch (len) {
         case 10: value += name[9];
+        /* Falls through. */
         case 9: value += name[8];
+        /* Falls through. */
         case 8: value += name[7];
+        /* Falls through. */
         case 7: value += name[6];
+        /* Falls through. */
         case 6: value += name[5];
+        /* Falls through. */
         case 5: value += name[4];
+        /* Falls through. */
         case 4: value += name[3];
+        /* Falls through. */
         case 3: value += name[2];
+        /* Falls through. */
         case 2: value += name[1];
+        /* Falls through. */
         case 1: value += name[0];
+        /* Falls through. */
         default: break;
     }
     return(value);
@@ -533,7 +562,7 @@ xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
  *
  * Create a new dictionary
  *
- * Returns the newly created dictionary, or NULL if an error occured.
+ * Returns the newly created dictionary, or NULL if an error occurred.
  */
 xmlDictPtr
 xmlDictCreate(void) {
@@ -580,7 +609,7 @@ xmlDictCreate(void) {
  * new dictionary, then in @sub, and if not found are created in the
  * new dictionary.
  *
- * Returns the newly created dictionary, or NULL if an error occured.
+ * Returns the newly created dictionary, or NULL if an error occurred.
  */
 xmlDictPtr
 xmlDictCreateSub(xmlDictPtr sub) {
@@ -699,7 +728,7 @@ xmlDictGrow(xmlDictPtr dict, size_t size) {
            } else {
                /*
                 * we don't have much ways to alert from herei
-                * result is loosing an entry and unicity garantee
+                * result is losing an entry and unicity guarantee
                 */
                ret = -1;
            }
index 8c52884..5ac93bf 100644 (file)
@@ -11,7 +11,7 @@
 #ifdef IN_LIBXML
 #ifdef __GNUC__
 #ifdef PIC
-#ifdef linux
+#ifdef __linux__
 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
 
 #include "libxml/c14n.h"
index e49c7f8..cd019c5 100644 (file)
@@ -354,8 +354,14 @@ UTF8ToUTF8(unsigned char* out, int *outlen,
 {
     int len;
 
-    if ((out == NULL) || (inb == NULL) || (outlen == NULL) || (inlenb == NULL))
+    if ((out == NULL) || (outlen == NULL) || (inlenb == NULL))
        return(-1);
+    if (inb == NULL) {
+        /* inb == NULL means output is initialized. */
+        *outlen = 0;
+        *inlenb = 0;
+        return(0);
+    }
     if (*outlen > *inlenb) {
        len = *inlenb;
     } else {
@@ -1904,6 +1910,61 @@ xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen,
  *                                                                     *
  ************************************************************************/
 
+static int
+xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out,
+                 int *outlen, const unsigned char *in, int *inlen) {
+    int ret;
+
+    if (handler->input != NULL) {
+        ret = handler->input(out, outlen, in, inlen);
+    }
+#ifdef LIBXML_ICONV_ENABLED
+    else if (handler->iconv_in != NULL) {
+        ret = xmlIconvWrapper(handler->iconv_in, out, outlen, in, inlen);
+    }
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef LIBXML_ICU_ENABLED
+    else if (handler->uconv_in != NULL) {
+        ret = xmlUconvWrapper(handler->uconv_in, 1, out, outlen, in, inlen);
+    }
+#endif /* LIBXML_ICU_ENABLED */
+    else {
+        *outlen = 0;
+        *inlen = 0;
+        ret = -2;
+    }
+
+    return(ret);
+}
+
+/* Returns -4 if no output function was found. */
+static int
+xmlEncOutputChunk(xmlCharEncodingHandler *handler, unsigned char *out,
+                  int *outlen, const unsigned char *in, int *inlen) {
+    int ret;
+
+    if (handler->output != NULL) {
+        ret = handler->output(out, outlen, in, inlen);
+    }
+#ifdef LIBXML_ICONV_ENABLED
+    else if (handler->iconv_out != NULL) {
+        ret = xmlIconvWrapper(handler->iconv_out, out, outlen, in, inlen);
+    }
+#endif /* LIBXML_ICONV_ENABLED */
+#ifdef LIBXML_ICU_ENABLED
+    else if (handler->uconv_out != NULL) {
+        ret = xmlUconvWrapper(handler->uconv_out, 0, out, outlen, in, inlen);
+    }
+#endif /* LIBXML_ICU_ENABLED */
+    else {
+        *outlen = 0;
+        *inlen = 0;
+        ret = -4;
+    }
+
+    return(ret);
+}
+
 /**
  * xmlCharEncFirstLineInt:
  * @handler:   char enconding transformation data structure
@@ -1922,7 +1983,7 @@ xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen,
 int
 xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
                        xmlBufferPtr in, int len) {
-    int ret = -2;
+    int ret;
     int written;
     int toconv;
 
@@ -1953,33 +2014,13 @@ xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
        written = out->size - out->use - 1;
     }
 
-    if (handler->input != NULL) {
-       ret = handler->input(&out->content[out->use], &written,
-                            in->content, &toconv);
-       xmlBufferShrink(in, toconv);
-       out->use += written;
-       out->content[out->use] = 0;
-    }
-#ifdef LIBXML_ICONV_ENABLED
-    else if (handler->iconv_in != NULL) {
-       ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
-                             &written, in->content, &toconv);
-       xmlBufferShrink(in, toconv);
-       out->use += written;
-       out->content[out->use] = 0;
-       if (ret == -1) ret = -3;
-    }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
-    else if (handler->uconv_in != NULL) {
-       ret = xmlUconvWrapper(handler->uconv_in, 1, &out->content[out->use],
-                             &written, in->content, &toconv);
-       xmlBufferShrink(in, toconv);
-       out->use += written;
-       out->content[out->use] = 0;
-       if (ret == -1) ret = -3;
-    }
-#endif /* LIBXML_ICU_ENABLED */
+    ret = xmlEncInputChunk(handler, &out->content[out->use], &written,
+                           in->content, &toconv);
+    xmlBufferShrink(in, toconv);
+    out->use += written;
+    out->content[out->use] = 0;
+    if (ret == -1) ret = -3;
+
 #ifdef DEBUG_ENCODING
     switch (ret) {
         case 0:
@@ -2049,7 +2090,7 @@ xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out,
 int
 xmlCharEncFirstLineInput(xmlParserInputBufferPtr input, int len)
 {
-    int ret = -2;
+    int ret;
     size_t written;
     size_t toconv;
     int c_in;
@@ -2091,32 +2132,13 @@ xmlCharEncFirstLineInput(xmlParserInputBufferPtr input, int len)
 
     c_in = toconv;
     c_out = written;
-    if (input->encoder->input != NULL) {
-        ret = input->encoder->input(xmlBufEnd(out), &c_out,
-                                    xmlBufContent(in), &c_in);
-        xmlBufShrink(in, c_in);
-        xmlBufAddLen(out, c_out);
-    }
-#ifdef LIBXML_ICONV_ENABLED
-    else if (input->encoder->iconv_in != NULL) {
-        ret = xmlIconvWrapper(input->encoder->iconv_in, xmlBufEnd(out),
-                              &c_out, xmlBufContent(in), &c_in);
-        xmlBufShrink(in, c_in);
-        xmlBufAddLen(out, c_out);
-        if (ret == -1)
-            ret = -3;
-    }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
-    else if (input->encoder->uconv_in != NULL) {
-        ret = xmlUconvWrapper(input->encoder->uconv_in, 1, xmlBufEnd(out),
-                              &c_out, xmlBufContent(in), &c_in);
-        xmlBufShrink(in, c_in);
-        xmlBufAddLen(out, c_out);
-        if (ret == -1)
-            ret = -3;
-    }
-#endif /* LIBXML_ICU_ENABLED */
+    ret = xmlEncInputChunk(input->encoder, xmlBufEnd(out), &c_out,
+                           xmlBufContent(in), &c_in);
+    xmlBufShrink(in, c_in);
+    xmlBufAddLen(out, c_out);
+    if (ret == -1)
+        ret = -3;
+
     switch (ret) {
         case 0:
 #ifdef DEBUG_ENCODING
@@ -2175,7 +2197,7 @@ xmlCharEncFirstLineInput(xmlParserInputBufferPtr input, int len)
 int
 xmlCharEncInput(xmlParserInputBufferPtr input, int flush)
 {
-    int ret = -2;
+    int ret;
     size_t written;
     size_t toconv;
     int c_in;
@@ -2208,32 +2230,13 @@ xmlCharEncInput(xmlParserInputBufferPtr input, int flush)
 
     c_in = toconv;
     c_out = written;
-    if (input->encoder->input != NULL) {
-        ret = input->encoder->input(xmlBufEnd(out), &c_out,
-                                    xmlBufContent(in), &c_in);
-        xmlBufShrink(in, c_in);
-        xmlBufAddLen(out, c_out);
-    }
-#ifdef LIBXML_ICONV_ENABLED
-    else if (input->encoder->iconv_in != NULL) {
-        ret = xmlIconvWrapper(input->encoder->iconv_in, xmlBufEnd(out),
-                              &c_out, xmlBufContent(in), &c_in);
-        xmlBufShrink(in, c_in);
-        xmlBufAddLen(out, c_out);
-        if (ret == -1)
-            ret = -3;
-    }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
-    else if (input->encoder->uconv_in != NULL) {
-        ret = xmlUconvWrapper(input->encoder->uconv_in, 1, xmlBufEnd(out),
-                              &c_out, xmlBufContent(in), &c_in);
-        xmlBufShrink(in, c_in);
-        xmlBufAddLen(out, c_out);
-        if (ret == -1)
-            ret = -3;
-    }
-#endif /* LIBXML_ICU_ENABLED */
+    ret = xmlEncInputChunk(input->encoder, xmlBufEnd(out), &c_out,
+                           xmlBufContent(in), &c_in);
+    xmlBufShrink(in, c_in);
+    xmlBufAddLen(out, c_out);
+    if (ret == -1)
+        ret = -3;
+
     switch (ret) {
         case 0:
 #ifdef DEBUG_ENCODING
@@ -2294,7 +2297,7 @@ int
 xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
                  xmlBufferPtr in)
 {
-    int ret = -2;
+    int ret;
     int written;
     int toconv;
 
@@ -2313,35 +2316,14 @@ xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
         xmlBufferGrow(out, out->size + toconv * 2);
         written = out->size - out->use - 1;
     }
-    if (handler->input != NULL) {
-        ret = handler->input(&out->content[out->use], &written,
-                             in->content, &toconv);
-        xmlBufferShrink(in, toconv);
-        out->use += written;
-        out->content[out->use] = 0;
-    }
-#ifdef LIBXML_ICONV_ENABLED
-    else if (handler->iconv_in != NULL) {
-        ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
-                              &written, in->content, &toconv);
-        xmlBufferShrink(in, toconv);
-        out->use += written;
-        out->content[out->use] = 0;
-        if (ret == -1)
-            ret = -3;
-    }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
-    else if (handler->uconv_in != NULL) {
-        ret = xmlUconvWrapper(handler->uconv_in, 1, &out->content[out->use],
-                              &written, in->content, &toconv);
-        xmlBufferShrink(in, toconv);
-        out->use += written;
-        out->content[out->use] = 0;
-        if (ret == -1)
-            ret = -3;
-    }
-#endif /* LIBXML_ICU_ENABLED */
+    ret = xmlEncInputChunk(handler, &out->content[out->use], &written,
+                           in->content, &toconv);
+    xmlBufferShrink(in, toconv);
+    out->use += written;
+    out->content[out->use] = 0;
+    if (ret == -1)
+        ret = -3;
+
     switch (ret) {
         case 0:
 #ifdef DEBUG_ENCODING
@@ -2405,7 +2387,7 @@ xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
 int
 xmlCharEncOutput(xmlOutputBufferPtr output, int init)
 {
-    int ret = -2;
+    int ret;
     size_t written;
     size_t writtentot = 0;
     size_t toconv;
@@ -2413,7 +2395,6 @@ xmlCharEncOutput(xmlOutputBufferPtr output, int init)
     int c_out;
     xmlBufPtr in;
     xmlBufPtr out;
-    int charref_len = 0;
 
     if ((output == NULL) || (output->encoder == NULL) ||
         (output->buffer == NULL) || (output->conv == NULL))
@@ -2433,26 +2414,10 @@ retry:
     if (init) {
         c_in = 0;
         c_out = written;
-        if (output->encoder->output != NULL) {
-            ret = output->encoder->output(xmlBufEnd(out), &c_out,
-                                          NULL, &c_in);
-            if (ret > 0) /* Gennady: check return value */
-                xmlBufAddLen(out, c_out);
-        }
-#ifdef LIBXML_ICONV_ENABLED
-        else if (output->encoder->iconv_out != NULL) {
-            ret = xmlIconvWrapper(output->encoder->iconv_out, xmlBufEnd(out),
-                                  &c_out, NULL, &c_in);
-            xmlBufAddLen(out, c_out);
-        }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
-        else if (output->encoder->uconv_out != NULL) {
-            ret = xmlUconvWrapper(output->encoder->uconv_out, 0, xmlBufEnd(out),
-                                  &c_out, NULL, &c_in);
-            xmlBufAddLen(out, c_out);
-        }
-#endif /* LIBXML_ICU_ENABLED */
+        /* TODO: Check return value. */
+        xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out,
+                          NULL, &c_in);
+        xmlBufAddLen(out, c_out);
 #ifdef DEBUG_ENCODING
        xmlGenericError(xmlGenericErrorContext,
                "initialized encoder\n");
@@ -2477,57 +2442,17 @@ retry:
 
     c_in = toconv;
     c_out = written;
-    if (output->encoder->output != NULL) {
-        ret = output->encoder->output(xmlBufEnd(out), &c_out,
-                                      xmlBufContent(in), &c_in);
+    ret = xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out,
+                            xmlBufContent(in), &c_in);
+    xmlBufShrink(in, c_in);
+    xmlBufAddLen(out, c_out);
+    writtentot += c_out;
+    if (ret == -1) {
         if (c_out > 0) {
-            xmlBufShrink(in, c_in);
-            xmlBufAddLen(out, c_out);
-            writtentot += c_out;
-        }
-    }
-#ifdef LIBXML_ICONV_ENABLED
-    else if (output->encoder->iconv_out != NULL) {
-        ret = xmlIconvWrapper(output->encoder->iconv_out, xmlBufEnd(out),
-                              &c_out, xmlBufContent(in), &c_in);
-        xmlBufShrink(in, c_in);
-        xmlBufAddLen(out, c_out);
-        writtentot += c_out;
-        if (ret == -1) {
-            if (c_out > 0) {
-                /*
-                 * Can be a limitation of iconv
-                 */
-                charref_len = 0;
-                goto retry;
-            }
-            ret = -3;
-        }
-    }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
-    else if (output->encoder->uconv_out != NULL) {
-        ret = xmlUconvWrapper(output->encoder->uconv_out, 0, xmlBufEnd(out),
-                              &c_out, xmlBufContent(in), &c_in);
-        xmlBufShrink(in, c_in);
-        xmlBufAddLen(out, c_out);
-        writtentot += c_out;
-        if (ret == -1) {
-            if (c_out > 0) {
-                /*
-                 * Can be a limitation of uconv
-                 */
-                charref_len = 0;
-                goto retry;
-            }
-            ret = -3;
+            /* Can be a limitation of iconv or uconv */
+            goto retry;
         }
-    }
-#endif /* LIBXML_ICU_ENABLED */
-    else {
-        xmlEncodingErr(XML_I18N_NO_OUTPUT,
-                       "xmlCharEncOutFunc: no output function !\n", NULL);
-        return(-1);
+        ret = -3;
     }
 
     if (ret >= 0) output += ret;
@@ -2555,47 +2480,44 @@ retry:
                    c_in, c_out, (int) xmlBufUse(in));
 #endif
            break;
+        case -4:
+            xmlEncodingErr(XML_I18N_NO_OUTPUT,
+                           "xmlCharEncOutFunc: no output function !\n", NULL);
+            ret = -1;
+            break;
         case -2: {
+           xmlChar charref[20];
            int len = (int) xmlBufUse(in);
             xmlChar *content = xmlBufContent(in);
-           int cur;
+           int cur, charrefLen;
 
            cur = xmlGetUTF8Char(content, &len);
-           if ((charref_len != 0) && (c_out < charref_len)) {
-               /*
-                * We attempted to insert a character reference and failed.
-                * Undo what was written and skip the remaining charref.
-                */
-                xmlBufErase(out, c_out);
-               writtentot -= c_out;
-               xmlBufShrink(in, charref_len - c_out);
-               charref_len = 0;
-
-               ret = -1;
+           if (cur <= 0)
                 break;
-           } else if (cur > 0) {
-               xmlChar charref[20];
 
 #ifdef DEBUG_ENCODING
-               xmlGenericError(xmlGenericErrorContext,
-                       "handling output conversion error\n");
-               xmlGenericError(xmlGenericErrorContext,
-                       "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-                       content[0], content[1],
-                       content[2], content[3]);
+            xmlGenericError(xmlGenericErrorContext,
+                    "handling output conversion error\n");
+            xmlGenericError(xmlGenericErrorContext,
+                    "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+                    content[0], content[1],
+                    content[2], content[3]);
 #endif
-               /*
-                * Removes the UTF8 sequence, and replace it by a charref
-                * and continue the transcoding phase, hoping the error
-                * did not mangle the encoder state.
-                */
-               charref_len = snprintf((char *) &charref[0], sizeof(charref),
-                                "&#%d;", cur);
-               xmlBufShrink(in, len);
-               xmlBufAddHead(in, charref, -1);
-
-               goto retry;
-           } else {
+            /*
+             * Removes the UTF8 sequence, and replace it by a charref
+             * and continue the transcoding phase, hoping the error
+             * did not mangle the encoder state.
+             */
+            charrefLen = snprintf((char *) &charref[0], sizeof(charref),
+                             "&#%d;", cur);
+            xmlBufShrink(in, len);
+            xmlBufGrow(out, charrefLen * 4);
+            c_out = xmlBufAvail(out) - 1;
+            c_in = charrefLen;
+            ret = xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out,
+                                    charref, &c_in);
+
+           if ((ret < 0) || (c_in != charrefLen)) {
                char buf[50];
 
                snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
@@ -2607,8 +2529,12 @@ retry:
                               buf);
                if (xmlBufGetAllocationScheme(in) != XML_BUFFER_ALLOC_IMMUTABLE)
                    content[0] = ' ';
+                break;
            }
-           break;
+
+            xmlBufAddLen(out, c_out);
+            writtentot += c_out;
+            goto retry;
        }
     }
     return(ret);
@@ -2636,12 +2562,11 @@ retry:
 int
 xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
                   xmlBufferPtr in) {
-    int ret = -2;
+    int ret;
     int written;
     int writtentot = 0;
     int toconv;
     int output = 0;
-    int charref_len = 0;
 
     if (handler == NULL) return(-1);
     if (out == NULL) return(-1);
@@ -2658,31 +2583,11 @@ retry:
      */
     if (in == NULL) {
         toconv = 0;
-       if (handler->output != NULL) {
-           ret = handler->output(&out->content[out->use], &written,
-                                 NULL, &toconv);
-           if (ret >= 0) { /* Gennady: check return value */
-               out->use += written;
-               out->content[out->use] = 0;
-           }
-       }
-#ifdef LIBXML_ICONV_ENABLED
-       else if (handler->iconv_out != NULL) {
-           ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
-                                 &written, NULL, &toconv);
-           out->use += written;
-           out->content[out->use] = 0;
-       }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
-       else if (handler->uconv_out != NULL) {
-           ret = xmlUconvWrapper(handler->uconv_out, 0,
-                              &out->content[out->use],
-                                             &written, NULL, &toconv);
-           out->use += written;
-           out->content[out->use] = 0;
-       }
-#endif /* LIBXML_ICU_ENABLED */
+        /* TODO: Check return value. */
+        xmlEncOutputChunk(handler, &out->content[out->use], &written,
+                          NULL, &toconv);
+        out->use += written;
+        out->content[out->use] = 0;
 #ifdef DEBUG_ENCODING
        xmlGenericError(xmlGenericErrorContext,
                "initialized encoder\n");
@@ -2700,61 +2605,18 @@ retry:
         xmlBufferGrow(out, toconv * 4);
        written = out->size - out->use - 1;
     }
-    if (handler->output != NULL) {
-       ret = handler->output(&out->content[out->use], &written,
-                             in->content, &toconv);
-       if (written > 0) {
-           xmlBufferShrink(in, toconv);
-           out->use += written;
-           writtentot += written;
-       }
-       out->content[out->use] = 0;
-    }
-#ifdef LIBXML_ICONV_ENABLED
-    else if (handler->iconv_out != NULL) {
-       ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
-                             &written, in->content, &toconv);
-       xmlBufferShrink(in, toconv);
-       out->use += written;
-       writtentot += written;
-       out->content[out->use] = 0;
-       if (ret == -1) {
-           if (written > 0) {
-               /*
-                * Can be a limitation of iconv
-                */
-                charref_len = 0;
-               goto retry;
-           }
-           ret = -3;
-       }
-    }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef LIBXML_ICU_ENABLED
-    else if (handler->uconv_out != NULL) {
-       ret = xmlUconvWrapper(handler->uconv_out, 0,
-                              &out->content[out->use],
-                             &written, in->content, &toconv);
-       xmlBufferShrink(in, toconv);
-       out->use += written;
-       writtentot += written;
-       out->content[out->use] = 0;
-       if (ret == -1) {
-           if (written > 0) {
-               /*
-                * Can be a limitation of iconv
-                */
-                charref_len = 0;
-               goto retry;
-           }
-           ret = -3;
-       }
-    }
-#endif /* LIBXML_ICU_ENABLED */
-    else {
-       xmlEncodingErr(XML_I18N_NO_OUTPUT,
-                      "xmlCharEncOutFunc: no output function !\n", NULL);
-       return(-1);
+    ret = xmlEncOutputChunk(handler, &out->content[out->use], &written,
+                            in->content, &toconv);
+    xmlBufferShrink(in, toconv);
+    out->use += written;
+    writtentot += written;
+    out->content[out->use] = 0;
+    if (ret == -1) {
+        if (written > 0) {
+            /* Can be a limitation of iconv or uconv */
+            goto retry;
+        }
+        ret = -3;
     }
 
     if (ret >= 0) output += ret;
@@ -2782,47 +2644,44 @@ retry:
                    toconv, written, in->use);
 #endif
            break;
+        case -4:
+           xmlEncodingErr(XML_I18N_NO_OUTPUT,
+                          "xmlCharEncOutFunc: no output function !\n", NULL);
+           ret = -1;
+            break;
         case -2: {
+           xmlChar charref[20];
            int len = in->use;
            const xmlChar *utf = (const xmlChar *) in->content;
-           int cur;
+           int cur, charrefLen;
 
            cur = xmlGetUTF8Char(utf, &len);
-           if ((charref_len != 0) && (written < charref_len)) {
-               /*
-                * We attempted to insert a character reference and failed.
-                * Undo what was written and skip the remaining charref.
-                */
-               out->use -= written;
-               writtentot -= written;
-               xmlBufferShrink(in, charref_len - written);
-               charref_len = 0;
-
-               ret = -1;
+           if (cur <= 0)
                 break;
-           } else if (cur > 0) {
-               xmlChar charref[20];
 
 #ifdef DEBUG_ENCODING
-               xmlGenericError(xmlGenericErrorContext,
-                       "handling output conversion error\n");
-               xmlGenericError(xmlGenericErrorContext,
-                       "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-                       in->content[0], in->content[1],
-                       in->content[2], in->content[3]);
+            xmlGenericError(xmlGenericErrorContext,
+                    "handling output conversion error\n");
+            xmlGenericError(xmlGenericErrorContext,
+                    "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
+                    in->content[0], in->content[1],
+                    in->content[2], in->content[3]);
 #endif
-               /*
-                * Removes the UTF8 sequence, and replace it by a charref
-                * and continue the transcoding phase, hoping the error
-                * did not mangle the encoder state.
-                */
-               charref_len = snprintf((char *) &charref[0], sizeof(charref),
-                                "&#%d;", cur);
-               xmlBufferShrink(in, len);
-               xmlBufferAddHead(in, charref, -1);
-
-               goto retry;
-           } else {
+            /*
+             * Removes the UTF8 sequence, and replace it by a charref
+             * and continue the transcoding phase, hoping the error
+             * did not mangle the encoder state.
+             */
+            charrefLen = snprintf((char *) &charref[0], sizeof(charref),
+                             "&#%d;", cur);
+            xmlBufferShrink(in, len);
+            xmlBufferGrow(out, charrefLen * 4);
+           written = out->size - out->use - 1;
+            toconv = charrefLen;
+            ret = xmlEncOutputChunk(handler, &out->content[out->use], &written,
+                                    charref, &toconv);
+
+           if ((ret < 0) || (toconv != charrefLen)) {
                char buf[50];
 
                snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
@@ -2834,8 +2693,13 @@ retry:
                               buf);
                if (in->alloc != XML_BUFFER_ALLOC_IMMUTABLE)
                    in->content[0] = ' ';
+               break;
            }
-           break;
+
+            out->use += written;
+            writtentot += written;
+            out->content[out->use] = 0;
+            goto retry;
        }
     }
     return(ret);
@@ -2954,54 +2818,20 @@ xmlByteConsumed(xmlParserCtxtPtr ctxt) {
 
            int ret;
 
-           if (handler->output != NULL) {
-               do {
-                   toconv = in->end - cur;
-                   written = 32000;
-                   ret = handler->output(&convbuf[0], &written,
-                                     cur, &toconv);
-                   if (ret == -1) return(-1);
-                   unused += written;
-                   cur += toconv;
-               } while (ret == -2);
-#ifdef LIBXML_ICONV_ENABLED
-           } else if (handler->iconv_out != NULL) {
-               do {
-                   toconv = in->end - cur;
-                   written = 32000;
-                   ret = xmlIconvWrapper(handler->iconv_out, &convbuf[0],
-                             &written, cur, &toconv);
-                   if (ret < 0) {
-                       if (written > 0)
-                           ret = -2;
-                       else
-                           return(-1);
-                   }
-                   unused += written;
-                   cur += toconv;
-               } while (ret == -2);
-#endif
-#ifdef LIBXML_ICU_ENABLED
-           } else if (handler->uconv_out != NULL) {
-               do {
-                   toconv = in->end - cur;
-                   written = 32000;
-                   ret = xmlUconvWrapper(handler->uconv_out, 0, &convbuf[0],
-                             &written, cur, &toconv);
-                   if (ret < 0) {
-                       if (written > 0)
-                           ret = -2;
-                       else
-                           return(-1);
-                   }
-                   unused += written;
-                   cur += toconv;
-               } while (ret == -2);
-#endif
-            } else {
-               /* could not find a converter */
-               return(-1);
-           }
+            do {
+                toconv = in->end - cur;
+                written = 32000;
+                ret = xmlEncOutputChunk(handler, &convbuf[0], &written,
+                                        cur, &toconv);
+                if (ret < 0) {
+                    if (written > 0)
+                        ret = -2;
+                    else
+                        return(-1);
+                }
+                unused += written;
+                cur += toconv;
+            } while (ret == -2);
        }
        if (in->buf->rawconsumed < unused)
            return(-1);
index c40e2cf..c819337 100644 (file)
@@ -6,6 +6,11 @@
  * daniel@veillard.com
  */
 
+/* To avoid EBCDIC trouble when parsing on zOS */
+#if defined(__MVS__)
+#pragma convert("ISO8859-1")
+#endif
+
 #define IN_LIBXML
 #include "libxml.h"
 
@@ -649,7 +654,7 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) {
        } else if (*cur >= 0x80) {
            if (((doc != NULL) && (doc->encoding != NULL)) || (html)) {
                /*
-                * Bjørn Reese <br@sseusa.com> provided the patch
+                * Bjørn Reese <br@sseusa.com> provided the patch
                xmlChar xc;
                xc = (*cur & 0x3F) << 6;
                if (cur[1] != 0) {
index 9606f13..50e9e6f 100644 (file)
@@ -853,7 +853,7 @@ xmlParserValidityWarning(void *ctx, const char *msg, ...)
  * Get the last global error registered. This is per thread if compiled
  * with thread support.
  *
- * Returns NULL if no error occured or a pointer to the error
+ * Returns NULL if no error occurred or a pointer to the error
  */
 xmlErrorPtr
 xmlGetLastError(void)
@@ -910,7 +910,7 @@ xmlResetLastError(void)
  *
  * Get the last parsing error registered.
  *
- * Returns NULL if no error occured or a pointer to the error
+ * Returns NULL if no error occurred or a pointer to the error
  */
 xmlErrorPtr
 xmlCtxtGetLastError(void *ctx)
index f9a2017..5dcaeb4 100644 (file)
@@ -168,7 +168,7 @@ xmlHashComputeQKey(xmlHashTablePtr table,
  *
  * Create a new xmlHashTablePtr.
  *
- * Returns the newly created object, or NULL if an error occured.
+ * Returns the newly created object, or NULL if an error occurred.
  */
 xmlHashTablePtr
 xmlHashCreate(int size) {
@@ -202,7 +202,7 @@ xmlHashCreate(int size) {
  *
  * Create a new xmlHashTablePtr which will use @dict as the internal dictionary
  *
- * Returns the newly created object, or NULL if an error occured.
+ * Returns the newly created object, or NULL if an error occurred.
  */
 xmlHashTablePtr
 xmlHashCreateDict(int size, xmlDictPtr dict) {
index 40cf7df..8596755 100644 (file)
@@ -10,7 +10,6 @@
 
 #if defined(_WIN32_WCE)
 #undef HAVE_ERRNO_H
-#include <windows.h>
 #include "wincecompat.h"
 #else
 #define HAVE_SYS_STAT_H
 #define ICONV_CONST const
 #endif
 
-#ifdef NEED_SOCKETS
-#include <wsockcompat.h>
-#endif
-
 /*
  * Windows platforms may define except 
  */
index fbe8d06..0484ee3 100644 (file)
@@ -8,7 +8,7 @@
 #ifdef _WIN32_WCE
 #include <winsock.h>
 #else
-#undef HAVE_ERRNO_H
+#include <errno.h>
 #include <winsock2.h>
 
 /* the following is a workaround a problem for 'inline' keyword in said
 #endif
 #endif
 
-#if defined( __MINGW32__ ) || defined( _MSC_VER )
-/* Include <errno.h> here to ensure that it doesn't get included later
- * (e.g. by iconv.h) and overwrites the definition of EWOULDBLOCK. */
-#include <errno.h>
-#undef EWOULDBLOCK
-#endif
+#undef XML_SOCKLEN_T
+#define XML_SOCKLEN_T int
 
-#if !defined SOCKLEN_T
-#define SOCKLEN_T int
+#ifndef ECONNRESET
+#define ECONNRESET WSAECONNRESET
+#endif
+#ifndef EINPROGRESS
+#define EINPROGRESS WSAEINPROGRESS
+#endif
+#ifndef EINTR
+#define EINTR WSAEINTR
+#endif
+#ifndef ESHUTDOWN
+#define ESHUTDOWN WSAESHUTDOWN
+#endif
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK WSAEWOULDBLOCK
 #endif
-
-#define EWOULDBLOCK             WSAEWOULDBLOCK
-#define ESHUTDOWN               WSAESHUTDOWN
-
-#if (!defined(_MSC_VER) || (_MSC_VER < 1600)) || defined(__REACTOS__)
-#define EINPROGRESS             WSAEINPROGRESS
-#define EALREADY                WSAEALREADY
-#define ENOTSOCK                WSAENOTSOCK
-#define EDESTADDRREQ            WSAEDESTADDRREQ
-#define EMSGSIZE                WSAEMSGSIZE
-#define EPROTOTYPE              WSAEPROTOTYPE
-#define ENOPROTOOPT             WSAENOPROTOOPT
-#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
-#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
-#define EOPNOTSUPP              WSAEOPNOTSUPP
-#define EPFNOSUPPORT            WSAEPFNOSUPPORT
-#define EAFNOSUPPORT            WSAEAFNOSUPPORT
-#define EADDRINUSE              WSAEADDRINUSE
-#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
-#define ENETDOWN                WSAENETDOWN
-#define ENETUNREACH             WSAENETUNREACH
-#define ENETRESET               WSAENETRESET
-#define ECONNABORTED            WSAECONNABORTED
-#define ECONNRESET              WSAECONNRESET
-#define ENOBUFS                 WSAENOBUFS
-#define EISCONN                 WSAEISCONN
-#define ENOTCONN                WSAENOTCONN
-#define ETOOMANYREFS            WSAETOOMANYREFS
-#define ETIMEDOUT               WSAETIMEDOUT
-#define ECONNREFUSED            WSAECONNREFUSED
-#define ELOOP                   WSAELOOP
-#define EHOSTDOWN               WSAEHOSTDOWN
-#define EHOSTUNREACH            WSAEHOSTUNREACH
-#define EPROCLIM                WSAEPROCLIM
-#define EUSERS                  WSAEUSERS
-#define EDQUOT                  WSAEDQUOT
-#define ESTALE                  WSAESTALE
-#define EREMOTE                 WSAEREMOTE
-/* These cause conflicts with the codes from errno.h. Since they are 
-   not used in the relevant code (nanoftp, nanohttp), we can leave 
-   them disabled.
-#define ENAMETOOLONG            WSAENAMETOOLONG
-#define ENOTEMPTY               WSAENOTEMPTY
-*/
-#endif /* _MSC_VER */
 
 #endif /* __XML_WSOCKCOMPAT_H__ */
index c3e2748..4fe56d2 100644 (file)
@@ -101,7 +101,7 @@ int xmlNop(void);
 #ifdef IN_LIBXML
 #ifdef __GNUC__
 #ifdef PIC
-#ifdef linux
+#ifdef __linux__
 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
 #include "elfgcchack.h"
 #endif
index d33d928..caa8333 100644 (file)
@@ -347,7 +347,7 @@ void xmlListDelete(xmlListPtr l)
  *
  * Remove the first instance associated to data in the list
  *
- * Returns 1 if a deallocation occured, or 0 if not found
+ * Returns 1 if a deallocation occurred, or 0 if not found
  */
 int
 xmlListRemoveFirst(xmlListPtr l, void *data)
@@ -372,7 +372,7 @@ xmlListRemoveFirst(xmlListPtr l, void *data)
  *
  * Remove the last instance associated to data in the list
  *
- * Returns 1 if a deallocation occured, or 0 if not found
+ * Returns 1 if a deallocation occurred, or 0 if not found
  */
 int
 xmlListRemoveLast(xmlListPtr l, void *data)
index 2135ab9..54fa026 100644 (file)
@@ -12,8 +12,6 @@
 #define HAVE_NETINET_IN_H
 #define HAVE_NETDB_H
 #define HAVE_SYS_TIME_H
-#else /* TESTING */
-#define NEED_SOCKETS
 #endif /* TESTING */
 
 #define IN_LIBXML
 #endif
 
 
-#if defined(__MINGW32__) || defined(_WIN32_WCE)
-#ifndef _WINSOCKAPI_
-#define _WINSOCKAPI_
-#endif
+#if defined(_WIN32) && !defined(__CYGWIN__)
 #include <wsockcompat.h>
-#include <winsock2.h>
-#undef XML_SOCKLEN_T
-#define XML_SOCKLEN_T unsigned int
 #endif
 
 /**
@@ -511,6 +503,8 @@ xmlNanoFTPFreeCtxt(void * ctx) {
     if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
     if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
     if (ctxt->path != NULL) xmlFree(ctxt->path);
+    if (ctxt->user != NULL) xmlFree(ctxt->user);
+    if (ctxt->passwd != NULL) xmlFree(ctxt->passwd);
     ctxt->passive = 1;
     if (ctxt->controlFd != INVALID_SOCKET) closesocket(ctxt->controlFd);
     ctxt->controlFd = INVALID_SOCKET;
@@ -907,7 +901,7 @@ xmlNanoFTPConnect(void *ctx) {
            __xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");
            return (-1);
        }
-       if (tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) {
+       if ((size_t)tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) {
            if (result)
                freeaddrinfo (result);
            __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch");
@@ -1042,6 +1036,7 @@ xmlNanoFTPConnect(void *ctx) {
                case 2:
                    if (proxyPasswd == NULL)
                        break;
+                    /* Falls through. */
                case 3:
                    if (proxyPasswd != NULL)
                        snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);
@@ -1111,6 +1106,7 @@ xmlNanoFTPConnect(void *ctx) {
                    ctxt->controlFd = INVALID_SOCKET;
                    return(-1);
                }
+                /* Falls through. */
            case 2:
                /* USER user@host command */
                if (ctxt->user == NULL)
@@ -1164,6 +1160,7 @@ xmlNanoFTPConnect(void *ctx) {
                    ctxt->controlFd = INVALID_SOCKET;
                    return(-1);
                }
+                /* Falls through. */
            case 3:
                /*
                 * If you need support for other Proxy authentication scheme
@@ -1212,6 +1209,7 @@ xmlNanoFTPConnect(void *ctx) {
        case 3:
            __xmlIOErr(XML_FROM_FTP, XML_FTP_ACCNT,
                       "FTP server asking for ACCNT on anonymous\n");
+           /* Falls through. */
        case 1:
        case 4:
        case 5:
index 4593eb3..9cd2292 100644 (file)
@@ -11,7 +11,6 @@
  * daniel@veillard.com
  */
 
-#define NEED_SOCKETS
 #define IN_LIBXML
 #include "libxml.h"
 
 #define XML_SOCKLEN_T unsigned int
 #endif
 
-#if defined(__MINGW32__) || defined(_WIN32_WCE)
-/*#ifndef _WINSOCKAPI_
-#define _WINSOCKAPI_
-#endif*/
+#if defined(_WIN32) && !defined(__CYGWIN__)
 #include <wsockcompat.h>
-#include <winsock2.h>
-#undef XML_SOCKLEN_T
-#define XML_SOCKLEN_T unsigned int
 #endif
 
 #include <libxml/globals.h>
@@ -182,7 +175,21 @@ xmlHTTPErrMemory(const char *extra)
  */
 static int socket_errno(void) {
 #ifdef _WINSOCKAPI_
-    return(WSAGetLastError());
+    int err = WSAGetLastError();
+    switch(err) {
+        case WSAECONNRESET:
+            return(ECONNRESET);
+        case WSAEINPROGRESS:
+            return(EINPROGRESS);
+        case WSAEINTR:
+            return(EINTR);
+        case WSAESHUTDOWN:
+            return(ESHUTDOWN);
+        case WSAEWOULDBLOCK:
+            return(EWOULDBLOCK);
+        default:
+            return(err);
+    }
 #else
     return(errno);
 #endif
@@ -629,7 +636,7 @@ xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt)
 
         if ((select(ctxt->fd + 1, &rfd, NULL, NULL, &tv) < 1)
 #if defined(EINTR)
-            && (errno != EINTR)
+            && (socket_errno() != EINTR)
 #endif
             )
             return (0);
@@ -1038,16 +1045,13 @@ xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
 static SOCKET
 xmlNanoHTTPConnectHost(const char *host, int port)
 {
-    struct hostent *h;
     struct sockaddr *addr = NULL;
-    struct in_addr ia;
     struct sockaddr_in sockin;
 
 #ifdef SUPPORT_IP6
     struct in6_addr ia6;
     struct sockaddr_in6 sockin6;
 #endif
-    int i;
     SOCKET s;
 
     memset (&sockin, 0, sizeof(sockin));
@@ -1084,7 +1088,7 @@ xmlNanoHTTPConnectHost(const char *host, int port)
 
        for (res = result; res; res = res->ai_next) {
            if (res->ai_family == AF_INET) {
-               if (res->ai_addrlen > sizeof(sockin)) {
+               if ((size_t)res->ai_addrlen > sizeof(sockin)) {
                    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
                    freeaddrinfo (result);
                    return INVALID_SOCKET;
@@ -1094,7 +1098,7 @@ xmlNanoHTTPConnectHost(const char *host, int port)
                addr = (struct sockaddr *)&sockin;
 #ifdef SUPPORT_IP6
            } else if (have_ipv6 () && (res->ai_family == AF_INET6)) {
-               if (res->ai_addrlen > sizeof(sockin6)) {
+               if ((size_t)res->ai_addrlen > sizeof(sockin6)) {
                    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
                    freeaddrinfo (result);
                    return INVALID_SOCKET;
@@ -1122,6 +1126,10 @@ xmlNanoHTTPConnectHost(const char *host, int port)
 #endif
 #if !defined(HAVE_GETADDRINFO) || !defined(_WIN32)
     {
+        struct hostent *h;
+        struct in_addr ia;
+        int i;
+
        h = gethostbyname (GETHOSTBYNAME_ARG_CAST host);
        if (h == NULL) {
 
@@ -1130,7 +1138,7 @@ xmlNanoHTTPConnectHost(const char *host, int port)
  * extraction code. it work on Linux, if it work on your platform
  * and one want to enable it, send me the defined(foobar) needed
  */
-#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(linux)
+#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(__linux__)
            const char *h_err_txt = "";
 
            switch (h_errno) {
@@ -1423,9 +1431,9 @@ retry:
     if (ctxt->port != 80) {
        /* reserve space for ':xxxxx', incl. potential proxy */
        if (proxy)
-           blen += 12;
+           blen += 17;
        else
-           blen += 6;
+           blen += 11;
     }
     bp = (char*)xmlMallocAtomic(blen);
     if ( bp == NULL ) {
@@ -1534,7 +1542,8 @@ retry:
        xmlGenericError(xmlGenericErrorContext,
                "\nRedirect to: %s\n", ctxt->location);
 #endif
-       while ( xmlNanoHTTPRecv(ctxt) > 0 ) ;
+       while ( xmlNanoHTTPRecv(ctxt) > 0 )
+            ;
         if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) {
            nbRedirects++;
            if (redirURL != NULL)
index 53a6b7f..1c5e036 100644 (file)
  * daniel@veillard.com
  */
 
+/* To avoid EBCDIC trouble when parsing on zOS */
+#if defined(__MVS__)
+#pragma convert("ISO8859-1")
+#endif
+
 #define IN_LIBXML
 #include "libxml.h"
 
-#if defined(WIN32) && !defined (__CYGWIN__)
+#if defined(_WIN32) && !defined (__CYGWIN__)
 #define XML_DIR_SEP '\\'
 #else
 #define XML_DIR_SEP '/'
@@ -43,6 +48,7 @@
 #include <limits.h>
 #include <string.h>
 #include <stdarg.h>
+#include <stddef.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/threads.h>
 #include <libxml/globals.h>
@@ -1087,7 +1093,12 @@ typedef xmlDefAttrs *xmlDefAttrsPtr;
 struct _xmlDefAttrs {
     int nbAttrs;       /* number of defaulted attributes on that element */
     int maxAttrs;       /* the size of the array */
-    const xmlChar *values[5]; /* array of localname/prefix/values/external */
+#if __STDC_VERSION__ >= 199901L
+    /* Using a C99 flexible array member avoids UBSan errors. */
+    const xmlChar *values[]; /* array of localname/prefix/values/external */
+#else
+    const xmlChar *values[5];
+#endif
 };
 
 /**
@@ -1324,7 +1335,7 @@ xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
         return;
 
     xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
-                     (void *) (long) type);
+                     (void *) (ptrdiff_t) type);
     return;
 
 mem_error:
@@ -1343,7 +1354,7 @@ xmlCleanSpecialAttrCallback(void *payload, void *data,
                             const xmlChar *unused ATTRIBUTE_UNUSED) {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
 
-    if (((long) payload) == XML_ATTRIBUTE_CDATA) {
+    if (((ptrdiff_t) payload) == XML_ATTRIBUTE_CDATA) {
         xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
     }
 }
@@ -1855,7 +1866,7 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
     ctxt->name = value;
     ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
     ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
-    ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
+    ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (ptrdiff_t) nsNr;
     return (ctxt->nameNr++);
 mem_error:
     xmlErrMemory(ctxt, NULL);
@@ -2037,10 +2048,8 @@ static int spacePop(xmlParserCtxtPtr ctxt) {
 
 #define SKIP(val) do {                                                 \
     ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);                  \
-    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
-    if ((*ctxt->input->cur == 0) &&                                    \
-        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))           \
-           xmlPopInput(ctxt);                                          \
+    if (*ctxt->input->cur == 0)                                                \
+        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);                  \
   } while (0)
 
 #define SKIPL(val) do {                                                        \
@@ -2052,10 +2061,8 @@ static int spacePop(xmlParserCtxtPtr ctxt) {
        ctxt->nbChars++;                                                \
        ctxt->input->cur++;                                             \
     }                                                                  \
-    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
-    if ((*ctxt->input->cur == 0) &&                                    \
-        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))           \
-           xmlPopInput(ctxt);                                          \
+    if (*ctxt->input->cur == 0)                                                \
+        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);                  \
   } while (0)
 
 #define SHRINK if ((ctxt->progressive == 0) &&                         \
@@ -2065,10 +2072,9 @@ static int spacePop(xmlParserCtxtPtr ctxt) {
 
 static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
     xmlParserInputShrink(ctxt->input);
-    if ((*ctxt->input->cur == 0) &&
-        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
-           xmlPopInput(ctxt);
-  }
+    if (*ctxt->input->cur == 0)
+        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+}
 
 #define GROW if ((ctxt->progressive == 0) &&                           \
                 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
@@ -2093,9 +2099,8 @@ static void xmlGROW (xmlParserCtxtPtr 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);
+    if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0))
+        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
 }
 
 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
@@ -2115,7 +2120,6 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) {
        ctxt->input->line++; ctxt->input->col = 1;                      \
     } else ctxt->input->col++;                                         \
     ctxt->input->cur += l;                             \
-    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);    \
   } while (0)
 
 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
@@ -2165,26 +2169,35 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
        }
        ctxt->input->cur = cur;
     } else {
-       int cur;
-       do {
-           cur = CUR;
-           while ((IS_BLANK_CH(cur) && /* CHECKED tstblanks.xml */
-                  (ctxt->instate != XML_PARSER_EOF))) {
+        int expandPE = ((ctxt->external != 0) || (ctxt->inputNr != 1));
+
+       while (1) {
+            if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */
                NEXT;
-               cur = CUR;
-               res++;
-           }
-           while ((cur == 0) && (ctxt->inputNr > 1) &&
-                  (ctxt->instate != XML_PARSER_COMMENT)) {
-               xmlPopInput(ctxt);
-               cur = CUR;
-           }
-           /*
-            * Need to handle support of entities branching here
-            */
-           if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
-       } while ((IS_BLANK(cur)) && /* CHECKED tstblanks.xml */
-                (ctxt->instate != XML_PARSER_EOF));
+           } else if (CUR == '%') {
+                /*
+                 * Need to handle support of entities branching here
+                 */
+               if ((expandPE == 0) || (IS_BLANK_CH(NXT(1))) || (NXT(1) == 0))
+                    break;
+               xmlParsePEReference(ctxt);
+            } else if (CUR == 0) {
+                if (ctxt->inputNr <= 1)
+                    break;
+                xmlPopInput(ctxt);
+            } else {
+                break;
+            }
+
+            /*
+             * Also increase the counter when entering or exiting a PERef.
+             * The spec says: "When a parameter-entity reference is recognized
+             * in the DTD and included, its replacement text MUST be enlarged
+             * by the attachment of one leading and one following space (#x20)
+             * character."
+             */
+           res++;
+        }
     }
     return(res);
 }
@@ -2210,10 +2223,13 @@ xmlPopInput(xmlParserCtxtPtr ctxt) {
     if (xmlParserDebugEntities)
        xmlGenericError(xmlGenericErrorContext,
                "Popping input %d\n", ctxt->inputNr);
+    if ((ctxt->inputNr > 1) && (ctxt->inSubset == 0) &&
+        (ctxt->instate != XML_PARSER_EOF))
+        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+                    "Unfinished entity outside the DTD");
     xmlFreeInputStream(inputPop(ctxt));
-    if ((*ctxt->input->cur == 0) &&
-        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
-           return(xmlPopInput(ctxt));
+    if (*ctxt->input->cur == 0)
+        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
     return(CUR);
 }
 
@@ -2239,6 +2255,13 @@ xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
        xmlGenericError(xmlGenericErrorContext,
                "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
     }
+    if (((ctxt->inputNr > 40) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
+        (ctxt->inputNr > 1024)) {
+        xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
+        while (ctxt->inputNr > 1)
+            xmlFreeInputStream(inputPop(ctxt));
+       return(-1);
+    }
     ret = inputPush(ctxt, input);
     if (ctxt->instate == XML_PARSER_EOF)
         return(-1);
@@ -2443,57 +2466,6 @@ xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
     return(0);
 }
 
-/**
- * xmlNewBlanksWrapperInputStream:
- * @ctxt:  an XML parser context
- * @entity:  an Entity pointer
- *
- * Create a new input stream for wrapping
- * blanks around a PEReference
- *
- * Returns the new input stream or NULL
- */
-
-static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
-
-static xmlParserInputPtr
-xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
-    xmlParserInputPtr input;
-    xmlChar *buffer;
-    size_t length;
-    if (entity == NULL) {
-       xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                   "xmlNewBlanksWrapperInputStream entity\n");
-       return(NULL);
-    }
-    if (xmlParserDebugEntities)
-       xmlGenericError(xmlGenericErrorContext,
-               "new blanks wrapper for entity: %s\n", entity->name);
-    input = xmlNewInputStream(ctxt);
-    if (input == NULL) {
-       return(NULL);
-    }
-    length = xmlStrlen(entity->name) + 5;
-    buffer = xmlMallocAtomic(length);
-    if (buffer == NULL) {
-       xmlErrMemory(ctxt, NULL);
-        xmlFree(input);
-       return(NULL);
-    }
-    buffer [0] = ' ';
-    buffer [1] = '%';
-    buffer [length-3] = ';';
-    buffer [length-2] = ' ';
-    buffer [length-1] = 0;
-    memcpy(buffer + 2, entity->name, length - 5);
-    input->free = deallocblankswrapper;
-    input->base = buffer;
-    input->cur = buffer;
-    input->length = length;
-    input->end = &buffer[length];
-    return(input);
-}
-
 /**
  * xmlParserHandlePEReference:
  * @ctxt:  the parser context
@@ -2528,11 +2500,6 @@ xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
  */
 void
 xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
-    const xmlChar *name;
-    xmlEntityPtr entity = NULL;
-    xmlParserInputPtr input;
-
-    if (RAW != '%') return;
     switch(ctxt->instate) {
        case XML_PARSER_CDATA_SECTION:
            return;
@@ -2587,128 +2554,7 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
             return;
     }
 
-    NEXT;
-    name = xmlParseName(ctxt);
-    if (xmlParserDebugEntities)
-       xmlGenericError(xmlGenericErrorContext,
-               "PEReference: %s\n", name);
-    if (name == NULL) {
-       xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
-    } else {
-       if (RAW == ';') {
-           NEXT;
-           if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
-               entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
-           if (ctxt->instate == XML_PARSER_EOF)
-               return;
-           if (entity == NULL) {
-
-               /*
-                * [ WFC: Entity Declared ]
-                * In a document without any DTD, a document with only an
-                * internal DTD subset which contains no parameter entity
-                * references, or a document with "standalone='yes'", ...
-                * ... The declaration of a parameter entity must precede
-                * any reference to it...
-                */
-               if ((ctxt->standalone == 1) ||
-                   ((ctxt->hasExternalSubset == 0) &&
-                    (ctxt->hasPErefs == 0))) {
-                   xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
-                        "PEReference: %%%s; not found\n", name);
-               } else {
-                   /*
-                    * [ VC: Entity Declared ]
-                    * In a document with an external subset or external
-                    * parameter entities with "standalone='no'", ...
-                    * ... The declaration of a parameter entity must precede
-                    * any reference to it...
-                    */
-                   if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
-                       xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
-                                        "PEReference: %%%s; not found\n",
-                                        name, NULL);
-                   } else
-                       xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
-                                     "PEReference: %%%s; not found\n",
-                                     name, NULL);
-                   ctxt->valid = 0;
-               }
-               xmlParserEntityCheck(ctxt, 0, NULL, 0);
-           } else if (ctxt->input->free != deallocblankswrapper) {
-                   input = xmlNewBlanksWrapperInputStream(ctxt, entity);
-                   if (xmlPushInput(ctxt, input) < 0)
-                       return;
-           } else {
-               if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
-                   (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
-                   xmlChar start[4];
-                   xmlCharEncoding enc;
-
-                   /*
-                    * Note: external parameter entities will not be loaded, it
-                    * is not required for a non-validating parser, unless the
-                    * option of validating, or substituting entities were
-                    * given. Doing so is far more secure as the parser will
-                    * only process data coming from the document entity by
-                    * default.
-                    */
-                    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
-                       ((ctxt->options & XML_PARSE_NOENT) == 0) &&
-                       ((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
-                       ((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
-                       ((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
-                       (ctxt->replaceEntities == 0) &&
-                       (ctxt->validate == 0))
-                       return;
-
-                   /*
-                    * handle the extra spaces added before and after
-                    * c.f. http://www.w3.org/TR/REC-xml#as-PE
-                    * this is done independently.
-                    */
-                   input = xmlNewEntityInputStream(ctxt, entity);
-                   if (xmlPushInput(ctxt, input) < 0)
-                       return;
-
-                   /*
-                    * Get the 4 first bytes and decode the charset
-                    * if enc != XML_CHAR_ENCODING_NONE
-                    * plug some encoding conversion routines.
-                    * Note that, since we may have some non-UTF8
-                    * encoding (like UTF16, bug 135229), the 'length'
-                    * is not known, but we can calculate based upon
-                    * the amount of data in the buffer.
-                    */
-                   GROW
-                    if (ctxt->instate == XML_PARSER_EOF)
-                        return;
-                   if ((ctxt->input->end - ctxt->input->cur)>=4) {
-                       start[0] = RAW;
-                       start[1] = NXT(1);
-                       start[2] = NXT(2);
-                       start[3] = NXT(3);
-                       enc = xmlDetectCharEncoding(start, 4);
-                       if (enc != XML_CHAR_ENCODING_NONE) {
-                           xmlSwitchEncoding(ctxt, enc);
-                       }
-                   }
-
-                   if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
-                       (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
-                       (IS_BLANK_CH(NXT(5)))) {
-                       xmlParseTextDecl(ctxt);
-                   }
-               } else {
-                   xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
-                            "PEReference: %s is not a parameter entity\n",
-                                     name);
-               }
-           }
-       } else {
-           xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
-       }
-    }
+    xmlParsePEReference(ctxt);
 }
 
 /*
@@ -2790,9 +2636,9 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
        if (c == 0) break;
         if ((c == '&') && (str[1] == '#')) {
            int val = xmlParseStringCharRef(ctxt, &str);
-           if (val != 0) {
-               COPY_BUF(0,buffer,nbchars,val);
-           }
+           if (val == 0)
+                goto int_error;
+           COPY_BUF(0,buffer,nbchars,val);
            if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
            }
@@ -2802,9 +2648,6 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                        "String decoding Entity Reference: %.30s\n",
                        str);
            ent = xmlParseStringEntityRef(ctxt, &str);
-           if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
-               (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
-               goto int_error;
            xmlParserEntityCheck(ctxt, 0, ent, 0);
            if (ent != NULL)
                ctxt->nbentities += ent->checked / 2;
@@ -2818,30 +2661,27 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                } else {
                    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
                            "predefined entity has no content\n");
+                    goto int_error;
                }
            } else if ((ent != NULL) && (ent->content != NULL)) {
                ctxt->depth++;
                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
                                              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 */
-                       buffer[nbchars++] = *current++;
-                       if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
-                           if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
-                               goto int_error;
-                           growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
-                       }
-                   }
-                   xmlFree(rep);
-                   rep = NULL;
-               }
+               if (rep == NULL)
+                    goto int_error;
+
+                current = rep;
+                while (*current != 0) { /* non input consuming loop */
+                    buffer[nbchars++] = *current++;
+                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
+                        if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
+                            goto int_error;
+                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+                    }
+                }
+                xmlFree(rep);
+                rep = NULL;
            } else if (ent != NULL) {
                int i = xmlStrlen(ent->name);
                const xmlChar *cur = ent->name;
@@ -2859,8 +2699,6 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                xmlGenericError(xmlGenericErrorContext,
                        "String decoding PE Reference: %.30s\n", str);
            ent = xmlParseStringPEReference(ctxt, &str);
-           if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
-               goto int_error;
            xmlParserEntityCheck(ctxt, 0, ent, 0);
            if (ent != NULL)
                ctxt->nbentities += ent->checked / 2;
@@ -2886,19 +2724,19 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
                                              0, 0, 0);
                ctxt->depth--;
-               if (rep != NULL) {
-                   current = rep;
-                   while (*current != 0) { /* non input consuming loop */
-                       buffer[nbchars++] = *current++;
-                       if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
-                           if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
-                               goto int_error;
-                           growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
-                       }
-                   }
-                   xmlFree(rep);
-                   rep = NULL;
-               }
+               if (rep == NULL)
+                    goto int_error;
+                current = rep;
+                while (*current != 0) { /* non input consuming loop */
+                    buffer[nbchars++] = *current++;
+                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
+                        if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
+                            goto int_error;
+                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+                    }
+                }
+                xmlFree(rep);
+                rep = NULL;
            }
        } else {
            COPY_BUF(l,buffer,nbchars,c);
@@ -3406,13 +3244,6 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
            len += l;
            NEXTL(l);
            c = CUR_CHAR(l);
-           if (c == 0) {
-               count = 0;
-               GROW;
-                if (ctxt->instate == XML_PARSER_EOF)
-                    return(NULL);
-               c = CUR_CHAR(l);
-           }
        }
     }
     if ((len > XML_MAX_NAME_LENGTH) &&
@@ -3420,6 +3251,16 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
         return(NULL);
     }
+    if (ctxt->input->cur - ctxt->input->base < len) {
+        /*
+         * There were a couple of bugs where PERefs lead to to a change
+         * of the buffer. Check the buffer size to avoid passing an invalid
+         * pointer to xmlDictLookup.
+         */
+        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+                    "unexpected change of input buffer");
+        return (NULL);
+    }
     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
@@ -3892,10 +3733,8 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
     ctxt->instate = XML_PARSER_ENTITY_VALUE;
     input = ctxt->input;
     GROW;
-    if (ctxt->instate == XML_PARSER_EOF) {
-        xmlFree(buf);
-        return(NULL);
-    }
+    if (ctxt->instate == XML_PARSER_EOF)
+        goto error;
     NEXT;
     c = CUR_CHAR(l);
     /*
@@ -3916,18 +3755,12 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
            if (tmp == NULL) {
                xmlErrMemory(ctxt, NULL);
-               xmlFree(buf);
-               return(NULL);
+                goto error;
            }
            buf = tmp;
        }
        COPY_BUF(l,buf,len,c);
        NEXTL(l);
-       /*
-        * Pop-up of finished entities.
-        */
-       while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
-           xmlPopInput(ctxt);
 
        GROW;
        c = CUR_CHAR(l);
@@ -3937,10 +3770,13 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
        }
     }
     buf[len] = 0;
-    if (ctxt->instate == XML_PARSER_EOF) {
-        xmlFree(buf);
-        return(NULL);
+    if (ctxt->instate == XML_PARSER_EOF)
+        goto error;
+    if (c != stop) {
+        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
+        goto error;
     }
+    NEXT;
 
     /*
      * Raise problem w.r.t. '&' and '%' being used in non-entities
@@ -3952,20 +3788,25 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
        if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
            xmlChar *name;
            xmlChar tmp = *cur;
+            int nameOk = 0;
 
            cur++;
            name = xmlParseStringName(ctxt, &cur);
-            if ((name == NULL) || (*cur != ';')) {
+            if (name != NULL) {
+                nameOk = 1;
+                xmlFree(name);
+            }
+            if ((nameOk == 0) || (*cur != ';')) {
                xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
            "EntityValue: '%c' forbidden except for entities references\n",
                                  tmp);
+                goto error;
            }
            if ((tmp == '%') && (ctxt->inSubset == 1) &&
                (ctxt->inputNr == 1)) {
                xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
+                goto error;
            }
-           if (name != NULL)
-               xmlFree(name);
            if (*cur == 0)
                break;
        }
@@ -3974,28 +3815,24 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
 
     /*
      * Then PEReference entities are substituted.
+     *
+     * NOTE: 4.4.7 Bypassed
+     * When a general entity reference appears in the EntityValue in
+     * an entity declaration, it is bypassed and left as is.
+     * so XML_SUBSTITUTE_REF is not set here.
      */
-    if (c != stop) {
-       xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
-       xmlFree(buf);
-    } else {
-       NEXT;
-       /*
-        * NOTE: 4.4.7 Bypassed
-        * When a general entity reference appears in the EntityValue in
-        * an entity declaration, it is bypassed and left as is.
-        * so XML_SUBSTITUTE_REF is not set here.
-        */
-        ++ctxt->depth;
-       ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
-                                     0, 0, 0);
-        --ctxt->depth;
-       if (orig != NULL)
-           *orig = buf;
-       else
-           xmlFree(buf);
+    ++ctxt->depth;
+    ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
+                                  0, 0, 0);
+    --ctxt->depth;
+    if (orig != NULL) {
+        *orig = buf;
+        buf = NULL;
     }
 
+error:
+    if (buf != NULL)
+        xmlFree(buf);
     return(ret);
 }
 
@@ -4165,7 +4002,9 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
                                ent->checked |= 1;
                            xmlFree(rep);
                            rep = NULL;
-                       }
+                       } else {
+                            ent->content[0] = 0;
+                        }
                    }
 
                    /*
@@ -4589,7 +4428,7 @@ get_more:
            if (*in == ']') {
                if ((in[1] == ']') && (in[2] == '>')) {
                    xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
-                   ctxt->input->cur = in;
+                   ctxt->input->cur = in + 1;
                    return;
                }
                in++;
@@ -4782,22 +4621,20 @@ xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
     *publicID = NULL;
     if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
         SKIP(6);
-       if (!IS_BLANK_CH(CUR)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "Space required after 'SYSTEM'\n");
        }
-        SKIP_BLANKS;
        URI = xmlParseSystemLiteral(ctxt);
        if (URI == NULL) {
            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
         }
     } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
         SKIP(6);
-       if (!IS_BLANK_CH(CUR)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                    "Space required after 'PUBLIC'\n");
        }
-        SKIP_BLANKS;
        *publicID = xmlParsePubidLiteral(ctxt);
        if (*publicID == NULL) {
            xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
@@ -4806,26 +4643,20 @@ xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
            /*
             * We don't handle [83] so "S SystemLiteral" is required.
             */
-           if (!IS_BLANK_CH(CUR)) {
+           if (SKIP_BLANKS == 0) {
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                        "Space required after the Public Identifier\n");
            }
        } else {
            /*
             * We handle [83] so we return immediately, if
-            * "S SystemLiteral" is not detected. From a purely parsing
-            * point of view that's a nice mess.
+            * "S SystemLiteral" is not detected. We skip blanks if no
+             * system literal was found, but this is harmless since we must
+             * be at the end of a NotationDecl.
             */
-           const xmlChar *ptr;
-           GROW;
-
-           ptr = CUR_PTR;
-           if (!IS_BLANK_CH(*ptr)) return(NULL);
-
-           while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
-           if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
+           if (SKIP_BLANKS == 0) return(NULL);
+           if ((CUR != '\'') && (CUR != '"')) return(NULL);
        }
-        SKIP_BLANKS;
        URI = xmlParseSystemLiteral(ctxt);
        if (URI == NULL) {
            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
@@ -4955,7 +4786,8 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
     } else {
        if (inputid != ctxt->input->id) {
            xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
-               "Comment doesn't start and stop in the same entity\n");
+                          "Comment doesn't start and stop in the same"
+                           " entity\n");
        }
         NEXT;
        if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
@@ -5103,7 +4935,8 @@ get_more:
                if (in[2] == '>') {
                    if (ctxt->input->id != inputid) {
                        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
-                       "comment doesn't start and stop in the same entity\n");
+                                      "comment doesn't start and stop in the"
+                                       " same entity\n");
                    }
                    SKIP(3);
                    if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
@@ -5271,7 +5104,7 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
     int count = 0;
 
     if ((RAW == '<') && (NXT(1) == '?')) {
-       xmlParserInputPtr input = ctxt->input;
+       int inputid = ctxt->input->id;
        state = ctxt->instate;
         ctxt->instate = XML_PARSER_PI;
        /*
@@ -5287,9 +5120,10 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
         target = xmlParsePITarget(ctxt);
        if (target != NULL) {
            if ((RAW == '?') && (NXT(1) == '>')) {
-               if (input != ctxt->input) {
+               if (inputid != ctxt->input->id) {
                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
-           "PI declaration doesn't start and stop in the same entity\n");
+                                  "PI declaration doesn't start and stop in"
+                                   " the same entity\n");
                }
                SKIP(2);
 
@@ -5310,12 +5144,10 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
                ctxt->instate = state;
                return;
            }
-           cur = CUR;
-           if (!IS_BLANK(cur)) {
+           if (SKIP_BLANKS == 0) {
                xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
                          "ParsePI: PI %s space expected\n", target);
            }
-            SKIP_BLANKS;
            cur = CUR_CHAR(l);
            while (IS_CHAR(cur) && /* checked */
                   ((cur != '?') || (NXT(1) != '>'))) {
@@ -5371,9 +5203,10 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
                xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
                      "ParsePI: PI %s never end ...\n", target);
            } else {
-               if (input != ctxt->input) {
-                   xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
-           "PI declaration doesn't start and stop in the same entity\n");
+               if (inputid != ctxt->input->id) {
+                   xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                                  "PI declaration doesn't start and stop in"
+                                   " the same entity\n");
                }
                SKIP(2);
 
@@ -5429,32 +5262,30 @@ xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
     xmlChar *Systemid;
 
     if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
-       xmlParserInputPtr input = ctxt->input;
+       int inputid = ctxt->input->id;
        SHRINK;
        SKIP(10);
-       if (!IS_BLANK_CH(CUR)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "Space required after '<!NOTATION'\n");
            return;
        }
-       SKIP_BLANKS;
 
         name = xmlParseName(ctxt);
        if (name == NULL) {
            xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
            return;
        }
-       if (!IS_BLANK_CH(CUR)) {
-           xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
-                    "Space required after the NOTATION name'\n");
-           return;
-       }
        if (xmlStrchr(name, ':') != NULL) {
            xmlNsErr(ctxt, XML_NS_ERR_COLON,
                     "colons are forbidden from notation names '%s'\n",
                     name, NULL, NULL);
        }
-       SKIP_BLANKS;
+       if (SKIP_BLANKS == 0) {
+           xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+                    "Space required after the NOTATION name'\n");
+           return;
+       }
 
        /*
         * Parse the IDs.
@@ -5463,9 +5294,10 @@ xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
        SKIP_BLANKS;
 
        if (RAW == '>') {
-           if (input != ctxt->input) {
-               xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
-       "Notation declaration doesn't start and stop in the same entity\n");
+           if (inputid != ctxt->input->id) {
+               xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                              "Notation declaration doesn't start and stop"
+                               " in the same entity\n");
            }
            NEXT;
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
@@ -5509,23 +5341,20 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
     const xmlChar *ndata = NULL;
     int isParameter = 0;
     xmlChar *orig = NULL;
-    int skipped;
 
     /* GROW; done in the caller */
     if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
-       xmlParserInputPtr input = ctxt->input;
+       int inputid = ctxt->input->id;
        SHRINK;
        SKIP(8);
-       skipped = SKIP_BLANKS;
-       if (skipped == 0) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "Space required after '<!ENTITY'\n");
        }
 
        if (RAW == '%') {
            NEXT;
-           skipped = SKIP_BLANKS;
-           if (skipped == 0) {
+           if (SKIP_BLANKS == 0) {
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                               "Space required after '%%'\n");
            }
@@ -5543,8 +5372,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
                     "colons are forbidden from entities names '%s'\n",
                     name, NULL, NULL);
        }
-        skipped = SKIP_BLANKS;
-       if (skipped == 0) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "Space required after the entity name\n");
        }
@@ -5655,18 +5483,16 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
                        xmlFreeURI(uri);
                    }
                }
-               if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
+               if ((RAW != '>') && (SKIP_BLANKS == 0)) {
                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                                   "Space required before 'NDATA'\n");
                }
-               SKIP_BLANKS;
                if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
                    SKIP(5);
-                   if (!IS_BLANK_CH(CUR)) {
+                   if (SKIP_BLANKS == 0) {
                        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                                       "Space required after 'NDATA'\n");
                    }
-                   SKIP_BLANKS;
                    ndata = xmlParseName(ctxt);
                    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                        (ctxt->sax->unparsedEntityDecl != NULL))
@@ -5705,16 +5531,17 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
            }
        }
        if (ctxt->instate == XML_PARSER_EOF)
-           return;
+           goto done;
        SKIP_BLANKS;
        if (RAW != '>') {
            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
                    "xmlParseEntityDecl: entity %s not terminated\n", name);
            xmlHaltParser(ctxt);
        } else {
-           if (input != ctxt->input) {
+           if (inputid != ctxt->input->id) {
                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
-       "Entity declaration doesn't start and stop in the same entity\n");
+                              "Entity declaration doesn't start and stop in"
+                               " the same entity\n");
            }
            NEXT;
        }
@@ -5736,17 +5563,17 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
                    cur = xmlSAX2GetEntity(ctxt, name);
                }
            }
-            if (cur != NULL) {
-               if (cur->orig != NULL)
-                   xmlFree(orig);
-               else
-                   cur->orig = orig;
-           } else
-               xmlFree(orig);
+            if ((cur != NULL) && (cur->orig == NULL)) {
+               cur->orig = orig;
+                orig = NULL;
+           }
        }
+
+done:
        if (value != NULL) xmlFree(value);
        if (URI != NULL) xmlFree(URI);
        if (literal != NULL) xmlFree(literal);
+        if (orig != NULL) xmlFree(orig);
     }
 }
 
@@ -5797,11 +5624,10 @@ xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
     if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
        SKIP(6);
        val = XML_ATTRIBUTE_FIXED;
-       if (!IS_BLANK_CH(CUR)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "Space required after '#FIXED'\n");
        }
-       SKIP_BLANKS;
     }
     ret = xmlParseAttValue(ctxt);
     ctxt->instate = XML_PARSER_DTD;
@@ -5973,12 +5799,11 @@ int
 xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
     if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
        SKIP(8);
-       if (!IS_BLANK_CH(CUR)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "Space required after 'NOTATION'\n");
            return(0);
        }
-        SKIP_BLANKS;
        *tree = xmlParseNotationType(ctxt);
        if (*tree == NULL) return(0);
        return(XML_ATTRIBUTE_NOTATION);
@@ -6082,14 +5907,13 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
     xmlEnumerationPtr tree;
 
     if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
-       xmlParserInputPtr input = ctxt->input;
+       int inputid = ctxt->input->id;
 
        SKIP(9);
-       if (!IS_BLANK_CH(CUR)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                                 "Space required after '<!ATTLIST'\n");
        }
-        SKIP_BLANKS;
         elemName = xmlParseName(ctxt);
        if (elemName == NULL) {
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
@@ -6099,7 +5923,6 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
        SKIP_BLANKS;
        GROW;
        while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
-           const xmlChar *check = CUR_PTR;
            int type;
            int def;
            xmlChar *defaultValue = NULL;
@@ -6113,12 +5936,11 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
                break;
            }
            GROW;
-           if (!IS_BLANK_CH(CUR)) {
+           if (SKIP_BLANKS == 0) {
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                        "Space required after the attribute name\n");
                break;
            }
-           SKIP_BLANKS;
 
            type = xmlParseAttributeType(ctxt, &tree);
            if (type <= 0) {
@@ -6126,14 +5948,13 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
            }
 
            GROW;
-           if (!IS_BLANK_CH(CUR)) {
+           if (SKIP_BLANKS == 0) {
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                               "Space required after the attribute type\n");
                if (tree != NULL)
                    xmlFreeEnumeration(tree);
                break;
            }
-           SKIP_BLANKS;
 
            def = xmlParseDefaultDecl(ctxt, &defaultValue);
            if (def <= 0) {
@@ -6148,7 +5969,7 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
 
            GROW;
             if (RAW != '>') {
-               if (!IS_BLANK_CH(CUR)) {
+               if (SKIP_BLANKS == 0) {
                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                        "Space required after the attribute default value\n");
                    if (defaultValue != NULL)
@@ -6157,16 +5978,6 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
                        xmlFreeEnumeration(tree);
                    break;
                }
-               SKIP_BLANKS;
-           }
-           if (check == CUR_PTR) {
-               xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                           "in xmlParseAttributeListDecl\n");
-               if (defaultValue != NULL)
-                   xmlFree(defaultValue);
-               if (tree != NULL)
-                   xmlFreeEnumeration(tree);
-               break;
            }
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
                (ctxt->sax->attributeDecl != NULL))
@@ -6188,10 +5999,10 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
            GROW;
        }
        if (RAW == '>') {
-           if (input != ctxt->input) {
-               xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
-    "Attribute list declaration doesn't start and stop in the same entity\n",
-                                 NULL, NULL);
+           if (inputid != ctxt->input->id) {
+               xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                               "Attribute list declaration doesn't start and"
+                               " stop in the same entity\n");
            }
            NEXT;
        }
@@ -6228,10 +6039,10 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
        SKIP_BLANKS;
        SHRINK;
        if (RAW == ')') {
-           if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
-               xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
-"Element content declaration doesn't start and stop in the same entity\n",
-                                 NULL, NULL);
+           if (ctxt->input->id != inputchk) {
+               xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                               "Element content declaration doesn't start and"
+                               " stop in the same entity\n");
            }
            NEXT;
            ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
@@ -6272,7 +6083,7 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
            if (elem == NULL) {
                xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                        "xmlParseElementMixedContentDecl : Name expected\n");
-               xmlFreeDocElementContent(ctxt->myDoc, cur);
+               xmlFreeDocElementContent(ctxt->myDoc, ret);
                return(NULL);
            }
            SKIP_BLANKS;
@@ -6287,10 +6098,10 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
             }
             if (ret != NULL)
                 ret->ocur = XML_ELEMENT_CONTENT_MULT;
-           if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
-               xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
-"Element content declaration doesn't start and stop in the same entity\n",
-                                NULL, NULL);
+           if (ctxt->input->id != inputchk) {
+               xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                               "Element content declaration doesn't start and"
+                               " stop in the same entity\n");
            }
            SKIP(2);
        } else {
@@ -6530,10 +6341,10 @@ xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
        if (last != NULL)
            last->parent = cur;
     }
-    if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
-       xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
-"Element content declaration doesn't start and stop in the same entity\n",
-                        NULL, NULL);
+    if (ctxt->input->id != inputchk) {
+       xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                       "Element content declaration doesn't start and stop in"
+                       " the same entity\n");
     }
     NEXT;
     if (RAW == '?') {
@@ -6706,28 +6517,24 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
 
     /* GROW; done in the caller */
     if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
-       xmlParserInputPtr input = ctxt->input;
+       int inputid = ctxt->input->id;
 
        SKIP(9);
-       if (!IS_BLANK_CH(CUR)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "Space required after 'ELEMENT'\n");
            return(-1);
        }
-        SKIP_BLANKS;
         name = xmlParseName(ctxt);
        if (name == NULL) {
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                           "xmlParseElementDecl: no name for Element\n");
            return(-1);
        }
-       while ((RAW == 0) && (ctxt->inputNr > 1))
-           xmlPopInput(ctxt);
-       if (!IS_BLANK_CH(CUR)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "Space required after the element name\n");
        }
-        SKIP_BLANKS;
        if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
            SKIP(5);
            /*
@@ -6759,12 +6566,6 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
        }
 
        SKIP_BLANKS;
-       /*
-        * Pop-up of finished entities.
-        */
-       while ((RAW == 0) && (ctxt->inputNr > 1))
-           xmlPopInput(ctxt);
-       SKIP_BLANKS;
 
        if (RAW != '>') {
            xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
@@ -6772,9 +6573,10 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
                xmlFreeDocElementContent(ctxt->myDoc, content);
            }
        } else {
-           if (input != ctxt->input) {
+           if (inputid != ctxt->input->id) {
                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
-    "Element declaration doesn't start and stop in the same entity\n");
+                               "Element declaration doesn't start and stop in"
+                               " the same entity\n");
            }
 
            NEXT;
@@ -6827,9 +6629,9 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
            return;
        } else {
            if (ctxt->input->id != id) {
-               xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
-           "All markup of the conditional section is not in the same entity\n",
-                                    NULL, NULL);
+               xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                              "All markup of the conditional section is not"
+                               " in the same entity\n");
            }
            NEXT;
        }
@@ -6842,6 +6644,8 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
                    "Entering INCLUDE Conditional Section\n");
        }
 
+        SKIP_BLANKS;
+        GROW;
        while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
                (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
            const xmlChar *check = CUR_PTR;
@@ -6849,18 +6653,11 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
 
            if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
                xmlParseConditionalSections(ctxt);
-           } else if (IS_BLANK_CH(CUR)) {
-               NEXT;
-           } else if (RAW == '%') {
-               xmlParsePEReference(ctxt);
            } else
                xmlParseMarkupDecl(ctxt);
 
-           /*
-            * Pop-up of finished entities.
-            */
-           while ((RAW == 0) && (ctxt->inputNr > 1))
-               xmlPopInput(ctxt);
+            SKIP_BLANKS;
+            GROW;
 
            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
                xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
@@ -6890,9 +6687,9 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
            return;
        } else {
            if (ctxt->input->id != id) {
-               xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
-           "All markup of the conditional section is not in the same entity\n",
-                                    NULL, NULL);
+               xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                              "All markup of the conditional section is not"
+                               " in the same entity\n");
            }
            NEXT;
        }
@@ -6954,9 +6751,9 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
        xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
     } else {
        if (ctxt->input->id != id) {
-           xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
-       "All markup of the conditional section is not in the same entity\n",
-                                NULL, NULL);
+           xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                          "All markup of the conditional section is not in"
+                           " the same entity\n");
        }
        if ((ctxt-> instate != XML_PARSER_EOF) &&
            ((ctxt->input->cur + 3) <= ctxt->input->end))
@@ -7023,13 +6820,6 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
     if (ctxt->instate == XML_PARSER_EOF)
         return;
 
-    /*
-     * This is only for internal subset. On external entities,
-     * the replacement is done before parsing stage
-     */
-    if ((ctxt->external == 0) && (ctxt->inputNr == 1))
-       xmlParsePEReference(ctxt);
-
     /*
      * Conditional sections are allowed from entities included
      * by PE References in the internal subset.
@@ -7067,11 +6857,10 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
        return;
     }
 
-    if (!IS_BLANK_CH(CUR)) {
+    if (SKIP_BLANKS == 0) {
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                       "Space needed after '<?xml'\n");
     }
-    SKIP_BLANKS;
 
     /*
      * We may have the VersionInfo here.
@@ -7080,7 +6869,7 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
     if (version == NULL)
        version = xmlCharStrdup(XML_DEFAULT_VERSION);
     else {
-       if (!IS_BLANK_CH(CUR)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "Space needed here\n");
        }
@@ -7171,27 +6960,19 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
 
     ctxt->instate = XML_PARSER_DTD;
     ctxt->external = 1;
+    SKIP_BLANKS;
     while (((RAW == '<') && (NXT(1) == '?')) ||
            ((RAW == '<') && (NXT(1) == '!')) ||
-          (RAW == '%') || IS_BLANK_CH(CUR)) {
+          (RAW == '%')) {
        const xmlChar *check = CUR_PTR;
        unsigned int cons = ctxt->input->consumed;
 
        GROW;
         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
            xmlParseConditionalSections(ctxt);
-       } else if (IS_BLANK_CH(CUR)) {
-           NEXT;
-       } else if (RAW == '%') {
-            xmlParsePEReference(ctxt);
        } else
            xmlParseMarkupDecl(ctxt);
-
-       /*
-        * Pop-up of finished entities.
-        */
-       while ((RAW == 0) && (ctxt->inputNr > 1))
-           xmlPopInput(ctxt);
+        SKIP_BLANKS;
 
        if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
            xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
@@ -7420,6 +7201,9 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
        }
        if (ent->checked == 0)
            ent->checked = 2;
+
+        /* Prevent entity from being parsed and expanded twice (Bug 760367). */
+        was_checked = 0;
     } else if (ent->checked != 1) {
        ctxt->nbentities += ent->checked / 2;
     }
@@ -8056,12 +7840,14 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
     NEXT;
     name = xmlParseName(ctxt);
     if (name == NULL) {
-       xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
-                      "xmlParsePEReference: no name\n");
+       xmlFatalErrMsg(ctxt, XML_ERR_PEREF_NO_NAME, "PEReference: no name\n");
        return;
     }
+    if (xmlParserDebugEntities)
+       xmlGenericError(xmlGenericErrorContext,
+               "PEReference: %s\n", name);
     if (RAW != ';') {
-       xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
+       xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
         return;
     }
 
@@ -8103,10 +7889,15 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
             * ... The declaration of a parameter entity must
             * precede any reference to it...
             */
-           xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
-                         "PEReference: %%%s; not found\n",
-                         name, NULL);
-           ctxt->valid = 0;
+            if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
+                xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
+                                 "PEReference: %%%s; not found\n",
+                                 name, NULL);
+            } else
+                xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
+                              "PEReference: %%%s; not found\n",
+                              name, NULL);
+            ctxt->valid = 0;
        }
        xmlParserEntityCheck(ctxt, 0, NULL, 0);
     } else {
@@ -8118,33 +7909,54 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
                  "Internal: %%%s; is not a parameter entity\n",
                          name, NULL);
-       } else if (ctxt->input->free != deallocblankswrapper) {
-           input = xmlNewBlanksWrapperInputStream(ctxt, entity);
-           if (xmlPushInput(ctxt, input) < 0)
-               return;
        } else {
-           /*
-            * TODO !!!
-            * handle the extra spaces added before and after
-            * c.f. http://www.w3.org/TR/REC-xml#as-PE
-            */
+            xmlChar start[4];
+            xmlCharEncoding enc;
+
+           if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
+               ((ctxt->options & XML_PARSE_NOENT) == 0) &&
+               ((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
+               ((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
+               ((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
+               (ctxt->replaceEntities == 0) &&
+               (ctxt->validate == 0))
+               return;
+
            input = xmlNewEntityInputStream(ctxt, entity);
-           if (xmlPushInput(ctxt, input) < 0)
+           if (xmlPushInput(ctxt, input) < 0) {
+                xmlFreeInputStream(input);
                return;
-           if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
-               (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
-               (IS_BLANK_CH(NXT(5)))) {
-               xmlParseTextDecl(ctxt);
-               if (ctxt->errNo ==
-                   XML_ERR_UNSUPPORTED_ENCODING) {
-                   /*
-                    * The XML REC instructs us to stop parsing
-                    * right here
-                    */
-                   xmlHaltParser(ctxt);
-                   return;
-               }
-           }
+            }
+
+           if (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) {
+                /*
+                 * Get the 4 first bytes and decode the charset
+                 * if enc != XML_CHAR_ENCODING_NONE
+                 * plug some encoding conversion routines.
+                 * Note that, since we may have some non-UTF8
+                 * encoding (like UTF16, bug 135229), the 'length'
+                 * is not known, but we can calculate based upon
+                 * the amount of data in the buffer.
+                 */
+                GROW
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return;
+                if ((ctxt->input->end - ctxt->input->cur)>=4) {
+                    start[0] = RAW;
+                    start[1] = NXT(1);
+                    start[2] = NXT(2);
+                    start[3] = NXT(3);
+                    enc = xmlDetectCharEncoding(start, 4);
+                    if (enc != XML_CHAR_ENCODING_NONE) {
+                        xmlSwitchEncoding(ctxt, enc);
+                    }
+                }
+
+                if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
+                    (IS_BLANK_CH(NXT(5)))) {
+                    xmlParseTextDecl(ctxt);
+                }
+            }
        }
     }
     ctxt->hasPErefs = 1;
@@ -8320,6 +8132,7 @@ xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
        entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
     if (ctxt->instate == XML_PARSER_EOF) {
        xmlFree(name);
+       *str = ptr;
        return(NULL);
     }
     if (entity == NULL) {
@@ -8458,6 +8271,7 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
      * Is there any DTD definition ?
      */
     if (RAW == '[') {
+        int baseInputNr = ctxt->inputNr;
         ctxt->instate = XML_PARSER_DTD;
         NEXT;
        /*
@@ -8465,7 +8279,8 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
         * PEReferences.
         * Subsequence (markupdecl | PEReference | S)*
         */
-       while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) {
+       while (((RAW != ']') || (ctxt->inputNr > baseInputNr)) &&
+               (ctxt->instate != XML_PARSER_EOF)) {
            const xmlChar *check = CUR_PTR;
            unsigned int cons = ctxt->input->consumed;
 
@@ -8473,16 +8288,13 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
            xmlParseMarkupDecl(ctxt);
            xmlParsePEReference(ctxt);
 
-           /*
-            * Pop-up of finished entities.
-            */
-           while ((RAW == 0) && (ctxt->inputNr > 1))
-               xmlPopInput(ctxt);
-
            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
             "xmlParseInternalSubset: error detected in Markup declaration\n");
-               break;
+                if (ctxt->inputNr > baseInputNr)
+                    xmlPopInput(ctxt);
+                else
+                   break;
            }
        }
        if (RAW == ']') {
@@ -8560,7 +8372,7 @@ xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
        ctxt->instate = XML_PARSER_CONTENT;
     } else {
        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
-              "Specification mandate value for attribute %s\n", name);
+              "Specification mandates value for attribute %s\n", name);
        return(NULL);
     }
 
@@ -8717,11 +8529,10 @@ failed:
        GROW
        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
            break;
-       if (!IS_BLANK_CH(RAW)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "attributes construct error\n");
        }
-       SKIP_BLANKS;
         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
             (attname == NULL) && (attvalue == NULL)) {
            xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
@@ -9259,8 +9070,8 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt,
     if (ctxt->attsSpecial != NULL) {
         int type;
 
-        type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
-                                            pref, elem, *prefix, name);
+        type = (int) (ptrdiff_t) xmlHashQLookup2(ctxt->attsSpecial,
+                                                 pref, elem, *prefix, name);
         if (type != 0)
             normalize = 1;
     }
@@ -9293,7 +9104,7 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt,
         ctxt->instate = XML_PARSER_CONTENT;
     } else {
         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
-                          "Specification mandate value for attribute %s\n",
+                          "Specification mandates value for attribute %s\n",
                           name);
         return (NULL);
     }
@@ -9376,9 +9187,8 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
     xmlChar *attvalue;
     const xmlChar **atts = ctxt->atts;
     int maxatts = ctxt->maxatts;
-    int nratts, nbatts, nbdef;
-    int i, j, nbNs, attval, oldline, oldcol, inputNr;
-    const xmlChar *base;
+    int nratts, nbatts, nbdef, inputid;
+    int i, j, nbNs, attval;
     unsigned long cur;
     int nsNr = ctxt->nsNr;
 
@@ -9392,13 +9202,9 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
      *       The Shrinking is only possible once the full set of attribute
      *       callbacks have been done.
      */
-reparse:
     SHRINK;
-    base = ctxt->input->base;
     cur = ctxt->input->cur - ctxt->input->base;
-    inputNr = ctxt->inputNr;
-    oldline = ctxt->input->line;
-    oldcol = ctxt->input->col;
+    inputid = ctxt->input->id;
     nbatts = 0;
     nratts = 0;
     nbdef = 0;
@@ -9422,8 +9228,6 @@ reparse:
      */
     SKIP_BLANKS;
     GROW;
-    if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
-        goto base_changed;
 
     while (((RAW != '>') &&
           ((RAW != '/') || (NXT(1) != '>')) &&
@@ -9434,211 +9238,181 @@ reparse:
 
        attname = xmlParseAttribute2(ctxt, prefix, localname,
                                     &aprefix, &attvalue, &len, &alloc);
-       if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) {
-           if ((attvalue != NULL) && (alloc != 0))
-               xmlFree(attvalue);
-           attvalue = NULL;
-           goto base_changed;
-       }
-        if ((attname != NULL) && (attvalue != NULL)) {
-           if (len < 0) len = xmlStrlen(attvalue);
-            if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
-               const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
-               xmlURIPtr uri;
-
-                if (URL == NULL) {
-                   xmlErrMemory(ctxt, "dictionary allocation failure");
-                   if ((attvalue != NULL) && (alloc != 0))
-                       xmlFree(attvalue);
-                   return(NULL);
-               }
-                if (*URL != 0) {
-                   uri = xmlParseURI((const char *) URL);
-                   if (uri == NULL) {
-                       xmlNsErr(ctxt, XML_WAR_NS_URI,
-                                "xmlns: '%s' is not a valid URI\n",
-                                          URL, NULL, NULL);
-                   } else {
-                       if (uri->scheme == NULL) {
-                           xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
-                                     "xmlns: URI %s is not absolute\n",
-                                     URL, NULL, NULL);
-                       }
-                       xmlFreeURI(uri);
-                   }
-                   if (URL == ctxt->str_xml_ns) {
-                       if (attname != ctxt->str_xml) {
-                           xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
-                        "xml namespace URI cannot be the default namespace\n",
-                                    NULL, NULL, NULL);
-                       }
-                       goto skip_default_ns;
-                   }
-                   if ((len == 29) &&
-                       (xmlStrEqual(URL,
-                                BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
-                       xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
-                            "reuse of the xmlns namespace name is forbidden\n",
-                                NULL, NULL, NULL);
-                       goto skip_default_ns;
-                   }
-               }
-               /*
-                * check that it's not a defined namespace
-                */
-               for (j = 1;j <= nbNs;j++)
-                   if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
-                       break;
-               if (j <= nbNs)
-                   xmlErrAttributeDup(ctxt, NULL, attname);
-               else
-                   if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
-skip_default_ns:
-               if ((attvalue != NULL) && (alloc != 0)) {
-                   xmlFree(attvalue);
-                   attvalue = NULL;
-               }
-               if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
-                   break;
-               if (!IS_BLANK_CH(RAW)) {
-                   xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
-                                  "attributes construct error\n");
-                   break;
-               }
-               SKIP_BLANKS;
-               if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
-                   goto base_changed;
-               continue;
-           }
-            if (aprefix == ctxt->str_xmlns) {
-               const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
-               xmlURIPtr uri;
-
-                if (attname == ctxt->str_xml) {
-                   if (URL != ctxt->str_xml_ns) {
-                       xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
-                                "xml namespace prefix mapped to wrong URI\n",
-                                NULL, NULL, NULL);
-                   }
-                   /*
-                    * Do not keep a namespace definition node
-                    */
-                   goto skip_ns;
-               }
+        if ((attname == NULL) || (attvalue == NULL))
+            goto next_attr;
+       if (len < 0) len = xmlStrlen(attvalue);
+
+        if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
+            const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
+            xmlURIPtr uri;
+
+            if (URL == NULL) {
+                xmlErrMemory(ctxt, "dictionary allocation failure");
+                if ((attvalue != NULL) && (alloc != 0))
+                    xmlFree(attvalue);
+                return(NULL);
+            }
+            if (*URL != 0) {
+                uri = xmlParseURI((const char *) URL);
+                if (uri == NULL) {
+                    xmlNsErr(ctxt, XML_WAR_NS_URI,
+                             "xmlns: '%s' is not a valid URI\n",
+                                       URL, NULL, NULL);
+                } else {
+                    if (uri->scheme == NULL) {
+                        xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
+                                  "xmlns: URI %s is not absolute\n",
+                                  URL, NULL, NULL);
+                    }
+                    xmlFreeURI(uri);
+                }
                 if (URL == ctxt->str_xml_ns) {
-                   if (attname != ctxt->str_xml) {
-                       xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
-                                "xml namespace URI mapped to wrong prefix\n",
-                                NULL, NULL, NULL);
-                   }
-                   goto skip_ns;
-               }
-                if (attname == ctxt->str_xmlns) {
-                   xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
-                            "redefinition of the xmlns prefix is forbidden\n",
-                            NULL, NULL, NULL);
-                   goto skip_ns;
-               }
-               if ((len == 29) &&
-                   (xmlStrEqual(URL,
-                                BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
-                   xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
-                            "reuse of the xmlns namespace name is forbidden\n",
-                            NULL, NULL, NULL);
-                   goto skip_ns;
-               }
-               if ((URL == NULL) || (URL[0] == 0)) {
-                   xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
-                            "xmlns:%s: Empty XML namespace is not allowed\n",
-                                 attname, NULL, NULL);
-                   goto skip_ns;
-               } else {
-                   uri = xmlParseURI((const char *) URL);
-                   if (uri == NULL) {
-                       xmlNsErr(ctxt, XML_WAR_NS_URI,
-                            "xmlns:%s: '%s' is not a valid URI\n",
-                                          attname, URL, NULL);
-                   } else {
-                       if ((ctxt->pedantic) && (uri->scheme == NULL)) {
-                           xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
-                                     "xmlns:%s: URI %s is not absolute\n",
-                                     attname, URL, NULL);
-                       }
-                       xmlFreeURI(uri);
-                   }
-               }
-
-               /*
-                * check that it's not a defined namespace
-                */
-               for (j = 1;j <= nbNs;j++)
-                   if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
-                       break;
-               if (j <= nbNs)
-                   xmlErrAttributeDup(ctxt, aprefix, attname);
-               else
-                   if (nsPush(ctxt, attname, URL) > 0) nbNs++;
-skip_ns:
-               if ((attvalue != NULL) && (alloc != 0)) {
-                   xmlFree(attvalue);
-                   attvalue = NULL;
-               }
-               if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
-                   break;
-               if (!IS_BLANK_CH(RAW)) {
-                   xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
-                                  "attributes construct error\n");
-                   break;
-               }
-               SKIP_BLANKS;
-               if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
-                   goto base_changed;
-               continue;
-           }
+                    if (attname != ctxt->str_xml) {
+                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+                     "xml namespace URI cannot be the default namespace\n",
+                                 NULL, NULL, NULL);
+                    }
+                    goto next_attr;
+                }
+                if ((len == 29) &&
+                    (xmlStrEqual(URL,
+                             BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
+                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+                         "reuse of the xmlns namespace name is forbidden\n",
+                             NULL, NULL, NULL);
+                    goto next_attr;
+                }
+            }
+            /*
+             * check that it's not a defined namespace
+             */
+            for (j = 1;j <= nbNs;j++)
+                if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
+                    break;
+            if (j <= nbNs)
+                xmlErrAttributeDup(ctxt, NULL, attname);
+            else
+                if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
+
+        } else if (aprefix == ctxt->str_xmlns) {
+            const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
+            xmlURIPtr uri;
+
+            if (attname == ctxt->str_xml) {
+                if (URL != ctxt->str_xml_ns) {
+                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+                             "xml namespace prefix mapped to wrong URI\n",
+                             NULL, NULL, NULL);
+                }
+                /*
+                 * Do not keep a namespace definition node
+                 */
+                goto next_attr;
+            }
+            if (URL == ctxt->str_xml_ns) {
+                if (attname != ctxt->str_xml) {
+                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+                             "xml namespace URI mapped to wrong prefix\n",
+                             NULL, NULL, NULL);
+                }
+                goto next_attr;
+            }
+            if (attname == ctxt->str_xmlns) {
+                xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+                         "redefinition of the xmlns prefix is forbidden\n",
+                         NULL, NULL, NULL);
+                goto next_attr;
+            }
+            if ((len == 29) &&
+                (xmlStrEqual(URL,
+                             BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
+                xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+                         "reuse of the xmlns namespace name is forbidden\n",
+                         NULL, NULL, NULL);
+                goto next_attr;
+            }
+            if ((URL == NULL) || (URL[0] == 0)) {
+                xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
+                         "xmlns:%s: Empty XML namespace is not allowed\n",
+                              attname, NULL, NULL);
+                goto next_attr;
+            } else {
+                uri = xmlParseURI((const char *) URL);
+                if (uri == NULL) {
+                    xmlNsErr(ctxt, XML_WAR_NS_URI,
+                         "xmlns:%s: '%s' is not a valid URI\n",
+                                       attname, URL, NULL);
+                } else {
+                    if ((ctxt->pedantic) && (uri->scheme == NULL)) {
+                        xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
+                                  "xmlns:%s: URI %s is not absolute\n",
+                                  attname, URL, NULL);
+                    }
+                    xmlFreeURI(uri);
+                }
+            }
 
-           /*
-            * Add the pair to atts
-            */
-           if ((atts == NULL) || (nbatts + 5 > maxatts)) {
-               if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
-                   if (attvalue[len] == 0)
-                       xmlFree(attvalue);
-                   goto failed;
-               }
-               maxatts = ctxt->maxatts;
-               atts = ctxt->atts;
-           }
-           ctxt->attallocs[nratts++] = alloc;
-           atts[nbatts++] = attname;
-           atts[nbatts++] = aprefix;
-           atts[nbatts++] = NULL; /* the URI will be fetched later */
-           atts[nbatts++] = attvalue;
-           attvalue += len;
-           atts[nbatts++] = attvalue;
-           /*
-            * tag if some deallocation is needed
-            */
-           if (alloc != 0) attval = 1;
-       } else {
-           if ((attvalue != NULL) && (attvalue[len] == 0))
-               xmlFree(attvalue);
-       }
+            /*
+             * check that it's not a defined namespace
+             */
+            for (j = 1;j <= nbNs;j++)
+                if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
+                    break;
+            if (j <= nbNs)
+                xmlErrAttributeDup(ctxt, aprefix, attname);
+            else
+                if (nsPush(ctxt, attname, URL) > 0) nbNs++;
+
+        } else {
+            /*
+             * Add the pair to atts
+             */
+            if ((atts == NULL) || (nbatts + 5 > maxatts)) {
+                if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
+                    goto next_attr;
+                }
+                maxatts = ctxt->maxatts;
+                atts = ctxt->atts;
+            }
+            ctxt->attallocs[nratts++] = alloc;
+            atts[nbatts++] = attname;
+            atts[nbatts++] = aprefix;
+            /*
+             * The namespace URI field is used temporarily to point at the
+             * base of the current input buffer for non-alloced attributes.
+             * When the input buffer is reallocated, all the pointers become
+             * invalid, but they can be reconstructed later.
+             */
+            if (alloc)
+                atts[nbatts++] = NULL;
+            else
+                atts[nbatts++] = ctxt->input->base;
+            atts[nbatts++] = attvalue;
+            attvalue += len;
+            atts[nbatts++] = attvalue;
+            /*
+             * tag if some deallocation is needed
+             */
+            if (alloc != 0) attval = 1;
+            attvalue = NULL; /* moved into atts */
+        }
 
-failed:
+next_attr:
+        if ((attvalue != NULL) && (alloc != 0)) {
+            xmlFree(attvalue);
+            attvalue = NULL;
+        }
 
        GROW
         if (ctxt->instate == XML_PARSER_EOF)
             break;
-       if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
-           goto base_changed;
        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
            break;
-       if (!IS_BLANK_CH(RAW)) {
+       if (SKIP_BLANKS == 0) {
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "attributes construct error\n");
            break;
        }
-       SKIP_BLANKS;
         if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
             (attname == NULL) && (attvalue == NULL)) {
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
@@ -9646,8 +9420,27 @@ failed:
            break;
        }
         GROW;
-       if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
-           goto base_changed;
+    }
+
+    if (ctxt->input->id != inputid) {
+        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
+                    "Unexpected change of input\n");
+        localname = NULL;
+        goto done;
+    }
+
+    /* Reconstruct attribute value pointers. */
+    for (i = 0, j = 0; j < nratts; i += 5, j++) {
+        if (atts[i+2] != NULL) {
+            /*
+             * Arithmetic on dangling pointers is technically undefined
+             * behavior, but well...
+             */
+            ptrdiff_t offset = ctxt->input->base - atts[i+2];
+            atts[i+2]  = NULL;    /* Reset repurposed namespace URI */
+            atts[i+3] += offset;  /* value */
+            atts[i+4] += offset;  /* valuend */
+        }
     }
 
     /*
@@ -9794,6 +9587,7 @@ failed:
                          nsname, 0, NULL, nbatts / 5, nbdef, atts);
     }
 
+done:
     /*
      * Free up attribute allocated strings if needed
      */
@@ -9804,34 +9598,6 @@ failed:
     }
 
     return(localname);
-
-base_changed:
-    /*
-     * the attribute strings are valid iif the base didn't changed
-     */
-    if (attval != 0) {
-       for (i = 3,j = 0; j < nratts;i += 5,j++)
-           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;
-    if (ctxt->wellFormed == 1) {
-       goto reparse;
-    }
-    return(NULL);
 }
 
 /**
@@ -10100,11 +9866,6 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
        }
 
        GROW;
-       /*
-        * Pop-up of finished entities.
-        */
-       while ((RAW == 0) && (ctxt->inputNr > 1))
-           xmlPopInput(ctxt);
        SHRINK;
 
        if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
@@ -11257,7 +11018,7 @@ xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
  * Check that the block of characters is okay as SCdata content [20]
  *
  * Returns the number of bytes to pass if okay, a negative index where an
- *         UTF-8 error occured otherwise
+ *         UTF-8 error occurred otherwise
  */
 static int
 xmlCheckCdataPush(const xmlChar *utf, int len, int complete) {
@@ -11399,13 +11160,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
        if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
            return(0);
 
-
-       /*
-        * Pop-up of finished entities.
-        */
-       while ((RAW == 0) && (ctxt->inputNr > 1))
-           xmlPopInput(ctxt);
-
        if (ctxt->input == NULL) break;
        if (ctxt->input->buf == NULL)
            avail = ctxt->input->length -
@@ -11756,11 +11510,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                    ctxt->checkIndex = 0;
                    xmlParseCharData(ctxt, 0);
                }
-               /*
-                * Pop-up of finished entities.
-                */
-               while ((RAW == 0) && (ctxt->inputNr > 1))
-                   xmlPopInput(ctxt);
                if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
                    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                                "detected an error in element content\n");
@@ -11783,9 +11532,10 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                }
                if (ctxt->sax2) {
                    xmlParseEndTag2(ctxt,
-                          (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
-                          (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
-                      (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
+                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
+                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
+                           (int) (ptrdiff_t)
+                                ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
                    nameNsPop(ctxt);
                }
 #ifdef LIBXML_SAX1_ENABLED
@@ -12703,6 +12453,8 @@ xmlHaltParser(xmlParserCtxtPtr ctxt) {
         return;
     ctxt->instate = XML_PARSER_EOF;
     ctxt->disableSAX = 1;
+    while (ctxt->inputNr > 1)
+        xmlFreeInputStream(inputPop(ctxt));
     if (ctxt->input != NULL) {
         /*
         * in case there was a specific allocation deallocate before
@@ -12714,6 +12466,7 @@ xmlHaltParser(xmlParserCtxtPtr ctxt) {
        }
        ctxt->input->cur = BAD_CAST"";
        ctxt->input->base = ctxt->input->cur;
+        ctxt->input->end = ctxt->input->cur;
     }
 }
 
@@ -13482,7 +13235,7 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
     /*
      * And record the last error if any
      */
-    if (ctxt->lastError.code != XML_ERR_OK)
+    if ((oldctxt != NULL) && (ctxt->lastError.code != XML_ERR_OK))
         xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
 
     if (sax != NULL)
index bfc778a..efb2387 100644 (file)
@@ -10,7 +10,7 @@
 #define IN_LIBXML
 #include "libxml.h"
 
-#if defined(WIN32) && !defined (__CYGWIN__)
+#if defined(_WIN32) && !defined (__CYGWIN__)
 #define XML_DIR_SEP '\\'
 #else
 #define XML_DIR_SEP '/'
@@ -435,8 +435,6 @@ xmlNextChar(xmlParserCtxtPtr ctxt)
 
     if ((*ctxt->input->cur == 0) &&
         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
-        if ((ctxt->instate != XML_PARSER_COMMENT))
-            xmlPopInput(ctxt);
         return;
     }
 
@@ -470,8 +468,8 @@ xmlNextChar(xmlParserCtxtPtr ctxt)
 
         c = *cur;
         if (c & 0x80) {
-        if (c == 0xC0)
-           goto encoding_error;
+            if (c == 0xC0)
+               goto encoding_error;
             if (cur[1] == 0) {
                 xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
                 cur = ctxt->input->cur;
@@ -523,8 +521,6 @@ xmlNextChar(xmlParserCtxtPtr ctxt)
             ctxt->input->cur++;
 
         ctxt->nbChars++;
-        if (*ctxt->input->cur == 0)
-            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
     } else {
         /*
          * Assume it's a fixed length encoding (1) with
@@ -538,14 +534,9 @@ xmlNextChar(xmlParserCtxtPtr ctxt)
             ctxt->input->col++;
         ctxt->input->cur++;
         ctxt->nbChars++;
-        if (*ctxt->input->cur == 0)
-            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
     }
-    if ((*ctxt->input->cur == '%') && (!ctxt->html))
-        xmlParserHandlePEReference(ctxt);
-    if ((*ctxt->input->cur == 0) &&
-        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
-        xmlPopInput(ctxt);
+    if (*ctxt->input->cur == 0)
+        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
     return;
 encoding_error:
     /*
@@ -1101,8 +1092,15 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
                break;
        }
     }
-    if (handler == NULL)
+    /*
+     * TODO: We could recover from errors in external entites if we
+     * didn't stop the parser. But most callers of this function don't
+     * check the return value.
+     */
+    if (handler == NULL) {
+        xmlStopParser(ctxt);
        return(-1);
+    }
     ctxt->charset = XML_CHAR_ENCODING_UTF8;
     ret = xmlSwitchToEncodingInt(ctxt, handler, len);
     if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) {
@@ -1226,6 +1224,7 @@ xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
                  */
                 nbchars = xmlCharEncFirstLineInput(input->buf, len);
             }
+            xmlBufResetInput(input->buf->buffer, input);
             if (nbchars < 0) {
                 xmlErrInternal(ctxt,
                                "switching encoding: encoder error\n",
@@ -1233,7 +1232,6 @@ xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
                 return (-1);
             }
            input->buf->rawconsumed += use - xmlBufUse(input->buf->raw);
-            xmlBufResetInput(input->buf->buffer, input);
         }
         return (0);
     } else if (input->length == 0) {
index 33dee3a..0eb8d81 100644 (file)
@@ -969,6 +969,7 @@ xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
                ERROR5(NULL, NULL, NULL,
                    "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
                    prefix);
+               XML_PAT_FREE_STRING(ctxt, prefix);
                ctxt->error = 1;
                goto error;
            }
index 3d3e69c..b12e1ae 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <stddef.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/parser.h>
 #include <libxml/parserInternals.h>
@@ -4404,7 +4405,7 @@ xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def,
                 if ((*tmp)->type == XML_RELAXNG_TEXT) {
                     res = xmlHashAddEntry2(partitions->triage,
                                            BAD_CAST "#text", NULL,
-                                           (void *) (long) (i + 1));
+                                           (void *) (ptrdiff_t) (i + 1));
                     if (res != 0)
                         is_determinist = -1;
                 } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
@@ -4412,22 +4413,22 @@ xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def,
                     if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
                         res = xmlHashAddEntry2(partitions->triage,
                                                (*tmp)->name, NULL,
-                                               (void *) (long) (i + 1));
+                                               (void *) (ptrdiff_t) (i + 1));
                     else
                         res = xmlHashAddEntry2(partitions->triage,
                                                (*tmp)->name, (*tmp)->ns,
-                                               (void *) (long) (i + 1));
+                                               (void *) (ptrdiff_t) (i + 1));
                     if (res != 0)
                         is_determinist = -1;
                 } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
                     if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
                         res = xmlHashAddEntry2(partitions->triage,
                                                BAD_CAST "#any", NULL,
-                                               (void *) (long) (i + 1));
+                                               (void *) (ptrdiff_t) (i + 1));
                     else
                         res = xmlHashAddEntry2(partitions->triage,
                                                BAD_CAST "#any", (*tmp)->ns,
-                                               (void *) (long) (i + 1));
+                                               (void *) (ptrdiff_t) (i + 1));
                     if ((*tmp)->nameClass != NULL)
                         is_determinist = 2;
                     if (res != 0)
@@ -8890,7 +8891,7 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
             if (ret != 0) {
                 break;
             }
-            /* no break on purpose */
+            /* Falls through. */
         case XML_RELAXNG_ZEROORMORE:{
                 xmlChar *cur, *temp;
 
@@ -9387,7 +9388,7 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
             if (tmp == NULL) {
                 i = nbgroups;
             } else {
-                i = ((long) tmp) - 1;
+                i = ((ptrdiff_t) tmp) - 1;
                 if (partitions->flags & IS_NEEDCHECK) {
                     group = partitions->groups[i];
                     if (!xmlRelaxNGNodeMatchesList(cur, group->defs))
@@ -10167,7 +10168,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
             }
             if (ctxt->errNr > errNr)
                 xmlRelaxNGPopErrors(ctxt, errNr);
-            /* no break on purpose */
+            /* Falls through. */
         case XML_RELAXNG_ZEROORMORE:{
                 int progress;
                 xmlRelaxNGStatesPtr states = NULL, res = NULL;
index ddbb138..95432d0 100644 (file)
@@ -27,6 +27,7 @@
 #ifdef HAVE_PTHREAD_H
 #include <pthread.h>
 #elif defined HAVE_WIN32_THREADS
+//#define WIN32_LEAN_AND_MEAN
 //#include <windows.h>
 #ifndef HAVE_COMPILER_TLS
 #include <process.h>
 
 static int libxml_is_threaded = -1;
 #if defined(__GNUC__) && defined(__GLIBC__)
-#ifdef linux
+#ifdef __linux__
 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
-extern int pthread_once (pthread_once_t *__once_control,
-                         void (*__init_routine) (void))
-          __attribute((weak));
-extern void *pthread_getspecific (pthread_key_t __key)
-          __attribute((weak));
-extern int pthread_setspecific (pthread_key_t __key,
-                                __const void *__pointer)
-          __attribute((weak));
-extern int pthread_key_create (pthread_key_t *__key,
-                               void (*__destr_function) (void *))
-          __attribute((weak));
-extern int pthread_key_delete (pthread_key_t __key)
-          __attribute((weak));
-extern int pthread_mutex_init ()
-          __attribute((weak));
-extern int pthread_mutex_destroy ()
-          __attribute((weak));
-extern int pthread_mutex_lock ()
-          __attribute((weak));
-extern int pthread_mutex_unlock ()
-          __attribute((weak));
-extern int pthread_cond_init ()
-          __attribute((weak));
-extern int pthread_cond_destroy ()
-          __attribute((weak));
-extern int pthread_cond_wait ()
-          __attribute((weak));
-extern int pthread_equal ()
-          __attribute((weak));
-extern pthread_t pthread_self ()
-          __attribute((weak));
-extern int pthread_key_create ()
-          __attribute((weak));
-extern int pthread_key_delete ()
-          __attribute((weak));
-extern int pthread_cond_signal ()
-          __attribute((weak));
+#pragma weak pthread_once
+#pragma weak pthread_getspecific
+#pragma weak pthread_setspecific
+#pragma weak pthread_key_create
+#pragma weak pthread_key_delete
+#pragma weak pthread_mutex_init
+#pragma weak pthread_mutex_destroy
+#pragma weak pthread_mutex_lock
+#pragma weak pthread_mutex_unlock
+#pragma weak pthread_cond_init
+#pragma weak pthread_cond_destroy
+#pragma weak pthread_cond_wait
+#pragma weak pthread_equal
+#pragma weak pthread_self
+#pragma weak pthread_key_create
+#pragma weak pthread_key_delete
+#pragma weak pthread_cond_signal
 #endif
-#endif /* linux */
+#endif /* __linux__ */
 #endif /* defined(__GNUC__) && defined(__GLIBC__) */
 #endif /* HAVE_PTHREAD_H */
 
@@ -158,7 +139,7 @@ static DWORD globalkey = TLS_OUT_OF_INDEXES;
 static DWORD mainthread;
 static struct {
     DWORD done;
-    DWORD control;
+    LONG control;
 } run_once = { 0, 0};
 static volatile LPCRITICAL_SECTION global_init_lock = NULL;
 
@@ -458,7 +439,8 @@ __xmlGlobalInitMutexLock(void)
 
         /* Swap it into the global_init_lock */
 #ifdef InterlockedCompareExchangePointer
-        InterlockedCompareExchangePointer(&global_init_lock, cs, NULL);
+        InterlockedCompareExchangePointer((void **) &global_init_lock,
+                                          cs, NULL);
 #else /* Use older void* version */
         InterlockedCompareExchange((void **) &global_init_lock,
                                    (void *) cs, NULL);
@@ -999,11 +981,23 @@ xmlOnceInit(void)
 #ifdef HAVE_PTHREAD_H
 #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
 #if defined(LIBXML_STATIC_FOR_DLL)
-BOOL XMLCALL
-xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+int XMLCALL
+xmlDllMain(ATTRIBUTE_UNUSED void *hinstDLL, unsigned long fdwReason,
+           ATTRIBUTE_UNUSED void *lpvReserved)
 #else
+/* declare to avoid "no previous prototype for 'DllMain'" warning */
+/* Note that we do NOT want to include this function declaration in
+   a public header because it's meant to be called by Windows itself,
+   not a program that uses this library.  This also has to be exported. */
+
+XMLPUBFUN BOOL WINAPI
+DllMain (HINSTANCE hinstDLL,
+         DWORD     fdwReason,
+         LPVOID    lpvReserved);
+
 BOOL WINAPI
-DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+DllMain(ATTRIBUTE_UNUSED HINSTANCE hinstDLL, DWORD fdwReason,
+        ATTRIBUTE_UNUSED LPVOID lpvReserved)
 #endif
 {
     switch (fdwReason) {
index 795f272..0c6346b 100644 (file)
 /*
- * taken from https://github.com/swenson/sort
- * Kept as is for the moment to be able to apply upstream patches for that
- * code, currently used only to speed up XPath node sorting, see xpath.c
+ * Taken from https://github.com/swenson/sort
+ * Revision: 05fd77bfec049ce8b7c408c4d3dd2d51ee061a15
+ * Removed all code unrelated to Timsort and made minor adjustments for
+ * cross-platform compatibility.
  */
 
 /*
- * All code in this header, unless otherwise specified, is hereby licensed under the MIT Public License:
-
-Copyright (c) 2010 Christopher Swenson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2010-2017 Christopher Swenson.
+ * Copyright (c) 2012 Vojtech Fried.
+ * Copyright (c) 2012 Google Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #ifdef HAVE_STDINT_H
 #include <stdint.h>
-#else
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif defined(WIN32)
-typedef __int64 int64_t;
+#elif defined(_WIN32)
 typedef unsigned __int64 uint64_t;
 #endif
+
+#ifndef SORT_NAME
+#error "Must declare SORT_NAME"
 #endif
 
-#ifndef MK_UINT64
-#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
-#define MK_UINT64(x) ((uint64_t)(x))
-#else
-#define MK_UINT64(x) x##ULL
+#ifndef SORT_TYPE
+#error "Must declare SORT_TYPE"
 #endif
+
+#ifndef SORT_CMP
+#define SORT_CMP(x, y)  ((x) < (y) ? -1 : ((x) == (y) ? 0 : 1))
 #endif
 
+#ifndef TIM_SORT_STACK_SIZE
+#define TIM_SORT_STACK_SIZE 128
+#endif
+
+#define SORT_SWAP(x,y) {SORT_TYPE __SORT_SWAP_t = (x); (x) = (y); (y) = __SORT_SWAP_t;}
+
+
+/* Common, type-agnosting functions and constants that we don't want to declare twice. */
+#ifndef SORT_COMMON_H
+#define SORT_COMMON_H
+
 #ifndef MAX
 #define MAX(x,y) (((x) > (y) ? (x) : (y)))
 #endif
+
 #ifndef MIN
 #define MIN(x,y) (((x) < (y) ? (x) : (y)))
 #endif
 
-int compute_minrun(uint64_t);
+static int compute_minrun(const uint64_t);
 
 #ifndef CLZ
-#if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ > 3))
+#ifdef __GNUC__
 #define CLZ __builtin_clzll
 #else
 
-int clzll(uint64_t);
+static int clzll(uint64_t);
 
 /* adapted from Hacker's Delight */
-int clzll(uint64_t x) /* {{{ */
-{
+static int clzll(uint64_t x) {
   int n;
 
-  if (x == 0) return(64);
+  if (x == 0) {
+    return 64;
+  }
+
   n = 0;
-  if (x <= MK_UINT64(0x00000000FFFFFFFF)) {n = n + 32; x = x << 32;}
-  if (x <= MK_UINT64(0x0000FFFFFFFFFFFF)) {n = n + 16; x = x << 16;}
-  if (x <= MK_UINT64(0x00FFFFFFFFFFFFFF)) {n = n + 8; x = x << 8;}
-  if (x <= MK_UINT64(0x0FFFFFFFFFFFFFFF)) {n = n + 4; x = x << 4;}
-  if (x <= MK_UINT64(0x3FFFFFFFFFFFFFFF)) {n = n + 2; x = x << 2;}
-  if (x <= MK_UINT64(0x7FFFFFFFFFFFFFFF)) {n = n + 1;}
+
+  if (x <= 0x00000000FFFFFFFFL) {
+    n = n + 32;
+    x = x << 32;
+  }
+
+  if (x <= 0x0000FFFFFFFFFFFFL) {
+    n = n + 16;
+    x = x << 16;
+  }
+
+  if (x <= 0x00FFFFFFFFFFFFFFL) {
+    n = n + 8;
+    x = x << 8;
+  }
+
+  if (x <= 0x0FFFFFFFFFFFFFFFL) {
+    n = n + 4;
+    x = x << 4;
+  }
+
+  if (x <= 0x3FFFFFFFFFFFFFFFL) {
+    n = n + 2;
+    x = x << 2;
+  }
+
+  if (x <= 0x7FFFFFFFFFFFFFFFL) {
+    n = n + 1;
+  }
+
   return n;
 }
-/* }}} */
 
 #define CLZ clzll
 #endif
 #endif
 
-int compute_minrun(uint64_t size) /* {{{ */
-{
+static __inline int compute_minrun(const uint64_t size) {
   const int top_bit = 64 - CLZ(size);
   const int shift = MAX(top_bit, 6) - 6;
   const int minrun = size >> shift;
-  const uint64_t mask = (MK_UINT64(1) << shift) - 1;
-  if (mask & size) return minrun + 1;
-  return minrun;
-}
-/* }}} */
-
-#ifndef SORT_NAME
-#error "Must declare SORT_NAME"
-#endif
+  const uint64_t mask = (1ULL << shift) - 1;
 
-#ifndef SORT_TYPE
-#error "Must declare SORT_TYPE"
-#endif
-
-#ifndef SORT_CMP
-#define SORT_CMP(x, y)  ((x) < (y) ? -1 : ((x) == (y) ? 0 : 1))
-#endif
+  if (mask & size) {
+    return minrun + 1;
+  }
 
+  return minrun;
+}
 
-#define SORT_SWAP(x,y) {SORT_TYPE __SORT_SWAP_t = (x); (x) = (y); (y) = __SORT_SWAP_t;}
+#endif /* SORT_COMMON_H */
 
 #define SORT_CONCAT(x, y) x ## _ ## y
 #define SORT_MAKE_STR1(x, y) SORT_CONCAT(x,y)
 #define SORT_MAKE_STR(x) SORT_MAKE_STR1(SORT_NAME,x)
 
-#define BINARY_INSERTION_FIND  SORT_MAKE_STR(binary_insertion_find)
-#define BINARY_INSERTION_SORT_START SORT_MAKE_STR(binary_insertion_sort_start)
-#define BINARY_INSERTION_SORT  SORT_MAKE_STR(binary_insertion_sort)
-#define REVERSE_ELEMENTS       SORT_MAKE_STR(reverse_elements)
-#define COUNT_RUN              SORT_MAKE_STR(count_run)
-#define CHECK_INVARIANT        SORT_MAKE_STR(check_invariant)
-#define TIM_SORT               SORT_MAKE_STR(tim_sort)
-#define TIM_SORT_RESIZE        SORT_MAKE_STR(tim_sort_resize)
-#define TIM_SORT_MERGE         SORT_MAKE_STR(tim_sort_merge)
-#define TIM_SORT_COLLAPSE      SORT_MAKE_STR(tim_sort_collapse)
+#define BINARY_INSERTION_FIND          SORT_MAKE_STR(binary_insertion_find)
+#define BINARY_INSERTION_SORT_START    SORT_MAKE_STR(binary_insertion_sort_start)
+#define BINARY_INSERTION_SORT          SORT_MAKE_STR(binary_insertion_sort)
+#define REVERSE_ELEMENTS               SORT_MAKE_STR(reverse_elements)
+#define COUNT_RUN                      SORT_MAKE_STR(count_run)
+#define CHECK_INVARIANT                SORT_MAKE_STR(check_invariant)
+#define TIM_SORT                       SORT_MAKE_STR(tim_sort)
+#define TIM_SORT_RESIZE                SORT_MAKE_STR(tim_sort_resize)
+#define TIM_SORT_MERGE                 SORT_MAKE_STR(tim_sort_merge)
+#define TIM_SORT_COLLAPSE              SORT_MAKE_STR(tim_sort_collapse)
 
-#define TIM_SORT_RUN_T         SORT_MAKE_STR(tim_sort_run_t)
-#define TEMP_STORAGE_T         SORT_MAKE_STR(temp_storage_t)
+#ifndef MAX
+#define MAX(x,y) (((x) > (y) ? (x) : (y)))
+#endif
+#ifndef MIN
+#define MIN(x,y) (((x) < (y) ? (x) : (y)))
+#endif
 
 typedef struct {
-  int64_t start;
-  int64_t length;
+  size_t start;
+  size_t length;
 } TIM_SORT_RUN_T;
 
+
 void BINARY_INSERTION_SORT(SORT_TYPE *dst, const size_t size);
 void TIM_SORT(SORT_TYPE *dst, const size_t size);
 
+
 /* Function used to do a binary search for binary insertion sort */
-static int64_t BINARY_INSERTION_FIND(SORT_TYPE *dst, const SORT_TYPE x, const size_t size)
-{
-  int64_t l, c, r;
-  SORT_TYPE lx;
+static __inline size_t BINARY_INSERTION_FIND(SORT_TYPE *dst, const SORT_TYPE x,
+    const size_t size) {
+  size_t l, c, r;
   SORT_TYPE cx;
   l = 0;
   r = size - 1;
   c = r >> 1;
-  lx = dst[l];
 
-  /* check for beginning conditions */
-  if (SORT_CMP(x, lx) < 0)
+  /* check for out of bounds at the beginning. */
+  if (SORT_CMP(x, dst[0]) < 0) {
     return 0;
-  else if (SORT_CMP(x, lx) == 0)
-  {
-    int64_t i = 1;
-    while (SORT_CMP(x, dst[i]) == 0) i++;
-    return i;
+  } else if (SORT_CMP(x, dst[r]) > 0) {
+    return r;
   }
 
   cx = dst[c];
-  while (1)
-  {
+
+  while (1) {
     const int val = SORT_CMP(x, cx);
-    if (val < 0)
-    {
-      if (c - l <= 1) return c;
+
+    if (val < 0) {
+      if (c - l <= 1) {
+        return c;
+      }
+
       r = c;
-    }
-    else if (val > 0)
-    {
-      if (r - c <= 1) return c + 1;
+    } else { /* allow = for stability. The binary search favors the right. */
+      if (r - c <= 1) {
+        return c + 1;
+      }
+
       l = c;
-      lx = cx;
-    }
-    else
-    {
-      do
-      {
-        cx = dst[++c];
-      } while (SORT_CMP(x, cx) == 0);
-      return c;
     }
+
     c = l + ((r - l) >> 1);
     cx = dst[c];
   }
 }
 
 /* Binary insertion sort, but knowing that the first "start" entries are sorted.  Used in timsort. */
-static void BINARY_INSERTION_SORT_START(SORT_TYPE *dst, const size_t start, const size_t size)
-{
-  int64_t i;
-  for (i = start; i < (int64_t) size; i++)
-  {
-    int64_t j;
+static void BINARY_INSERTION_SORT_START(SORT_TYPE *dst, const size_t start, const size_t size) {
+  size_t i;
+
+  for (i = start; i < size; i++) {
+    size_t j;
     SORT_TYPE x;
-    int64_t location;
+    size_t location;
+
     /* If this entry is already correct, just move along */
-    if (SORT_CMP(dst[i - 1], dst[i]) <= 0) continue;
+    if (SORT_CMP(dst[i - 1], dst[i]) <= 0) {
+      continue;
+    }
 
     /* Else we need to find the right place, shift everything over, and squeeze in */
     x = dst[i];
     location = BINARY_INSERTION_FIND(dst, x, i);
-    for (j = i - 1; j >= location; j--)
-    {
+
+    for (j = i - 1; j >= location; j--) {
       dst[j + 1] = dst[j];
+
+      if (j == 0) { /* check edge case because j is unsigned */
+        break;
+      }
     }
+
     dst[location] = x;
   }
 }
 
 /* Binary insertion sort */
-void BINARY_INSERTION_SORT(SORT_TYPE *dst, const size_t size)
-{
+void BINARY_INSERTION_SORT(SORT_TYPE *dst, const size_t size) {
+  /* don't bother sorting an array of size <= 1 */
+  if (size <= 1) {
+    return;
+  }
+
   BINARY_INSERTION_SORT_START(dst, 1, size);
 }
 
 /* timsort implementation, based on timsort.txt */
 
-static void REVERSE_ELEMENTS(SORT_TYPE *dst, int64_t start, int64_t end)
-{
-  while (1)
-  {
-    if (start >= end) return;
+static __inline void REVERSE_ELEMENTS(SORT_TYPE *dst, size_t start, size_t end) {
+  while (1) {
+    if (start >= end) {
+      return;
+    }
+
     SORT_SWAP(dst[start], dst[end]);
     start++;
     end--;
   }
 }
 
-static int64_t COUNT_RUN(SORT_TYPE *dst, const int64_t start, const size_t size)
-{
-  int64_t curr;
-  if (size - start == 1) return 1;
-  if (start >= (int64_t) size - 2)
-  {
-    if (SORT_CMP(dst[size - 2], dst[size - 1]) > 0)
+static size_t COUNT_RUN(SORT_TYPE *dst, const size_t start, const size_t size) {
+  size_t curr;
+
+  if (size - start == 1) {
+    return 1;
+  }
+
+  if (start >= size - 2) {
+    if (SORT_CMP(dst[size - 2], dst[size - 1]) > 0) {
       SORT_SWAP(dst[size - 2], dst[size - 1]);
+    }
+
     return 2;
   }
 
   curr = start + 2;
 
-  if (SORT_CMP(dst[start], dst[start + 1]) <= 0)
-  {
+  if (SORT_CMP(dst[start], dst[start + 1]) <= 0) {
     /* increasing run */
-    while (1)
-    {
-      if (curr == (int64_t) size - 1) break;
-      if (SORT_CMP(dst[curr - 1], dst[curr]) > 0) break;
+    while (1) {
+      if (curr == size - 1) {
+        break;
+      }
+
+      if (SORT_CMP(dst[curr - 1], dst[curr]) > 0) {
+        break;
+      }
+
       curr++;
     }
+
     return curr - start;
-  }
-  else
-  {
+  } else {
     /* decreasing run */
-    while (1)
-    {
-      if (curr == (int64_t) size - 1) break;
-      if (SORT_CMP(dst[curr - 1], dst[curr]) <= 0) break;
+    while (1) {
+      if (curr == size - 1) {
+        break;
+      }
+
+      if (SORT_CMP(dst[curr - 1], dst[curr]) <= 0) {
+        break;
+      }
+
       curr++;
     }
+
     /* reverse in-place */
     REVERSE_ELEMENTS(dst, start, curr - 1);
     return curr - start;
   }
 }
 
-#define PUSH_NEXT() do {\
-len = COUNT_RUN(dst, curr, size);\
-run = minrun;\
-if (run < minrun) run = minrun;\
-if (run > (int64_t) size - curr) run = size - curr;\
-if (run > len)\
-{\
-  BINARY_INSERTION_SORT_START(&dst[curr], len, run);\
-  len = run;\
-}\
-{\
-run_stack[stack_curr].start = curr;\
-run_stack[stack_curr].length = len;\
-stack_curr++;\
-}\
-curr += len;\
-if (curr == (int64_t) size)\
-{\
-  /* finish up */ \
-  while (stack_curr > 1) \
-  { \
-    TIM_SORT_MERGE(dst, run_stack, stack_curr, store); \
-    run_stack[stack_curr - 2].length += run_stack[stack_curr - 1].length; \
-    stack_curr--; \
-  } \
-  if (store->storage != NULL)\
-  {\
-    free(store->storage);\
-    store->storage = NULL;\
-  }\
-  return;\
-}\
-}\
-while (0)
-
-static int CHECK_INVARIANT(TIM_SORT_RUN_T *stack, const int stack_curr)
-{
-  int64_t A, B, C;
-  if (stack_curr < 2) return 1;
-  if (stack_curr == 2)
-  {
-    const int64_t A1 = stack[stack_curr - 2].length;
-    const int64_t B1 = stack[stack_curr - 1].length;
-    if (A1 <= B1) return 0;
+static int CHECK_INVARIANT(TIM_SORT_RUN_T *stack, const int stack_curr) {
+  size_t A, B, C;
+
+  if (stack_curr < 2) {
     return 1;
   }
+
+  if (stack_curr == 2) {
+    const size_t A1 = stack[stack_curr - 2].length;
+    const size_t B1 = stack[stack_curr - 1].length;
+
+    if (A1 <= B1) {
+      return 0;
+    }
+
+    return 1;
+  }
+
   A = stack[stack_curr - 3].length;
   B = stack[stack_curr - 2].length;
   C = stack[stack_curr - 1].length;
-  if ((A <= B + C) || (B <= C)) return 0;
+
+  if ((A <= B + C) || (B <= C)) {
+    return 0;
+  }
+
   return 1;
 }
 
@@ -315,86 +353,78 @@ typedef struct {
   SORT_TYPE *storage;
 } TEMP_STORAGE_T;
 
-
-static void TIM_SORT_RESIZE(TEMP_STORAGE_T *store, const size_t new_size)
-{
-  if (store->alloc < new_size)
-  {
+static void TIM_SORT_RESIZE(TEMP_STORAGE_T *store, const size_t new_size) {
+  if (store->alloc < new_size) {
     SORT_TYPE *tempstore = (SORT_TYPE *)realloc(store->storage, new_size * sizeof(SORT_TYPE));
-    if (tempstore == NULL)
-    {
-      fprintf(stderr, "Error allocating temporary storage for tim sort: need %lu bytes", sizeof(SORT_TYPE) * new_size);
+
+    if (tempstore == NULL) {
+      fprintf(stderr, "Error allocating temporary storage for tim sort: need %lu bytes",
+              (unsigned long)(sizeof(SORT_TYPE) * new_size));
       exit(1);
     }
+
     store->storage = tempstore;
     store->alloc = new_size;
   }
 }
 
-static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const int stack_curr, TEMP_STORAGE_T *store)
-{
-  const int64_t A = stack[stack_curr - 2].length;
-  const int64_t B = stack[stack_curr - 1].length;
-  const int64_t curr = stack[stack_curr - 2].start;
+static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const int stack_curr,
+                           TEMP_STORAGE_T *store) {
+  const size_t A = stack[stack_curr - 2].length;
+  const size_t B = stack[stack_curr - 1].length;
+  const size_t curr = stack[stack_curr - 2].start;
   SORT_TYPE *storage;
-  int64_t i, j, k;
-
+  size_t i, j, k;
   TIM_SORT_RESIZE(store, MIN(A, B));
   storage = store->storage;
 
   /* left merge */
-  if (A < B)
-  {
+  if (A < B) {
     memcpy(storage, &dst[curr], A * sizeof(SORT_TYPE));
     i = 0;
     j = curr + A;
 
-    for (k = curr; k < curr + A + B; k++)
-    {
-      if ((i < A) && (j < curr + A + B))
-      {
-        if (SORT_CMP(storage[i], dst[j]) <= 0)
+    for (k = curr; k < curr + A + B; k++) {
+      if ((i < A) && (j < curr + A + B)) {
+        if (SORT_CMP(storage[i], dst[j]) <= 0) {
           dst[k] = storage[i++];
-        else
+        } else {
           dst[k] = dst[j++];
-      }
-      else if (i < A)
-      {
+        }
+      } else if (i < A) {
         dst[k] = storage[i++];
+      } else {
+        break;
       }
-      else
-        dst[k] = dst[j++];
     }
-  }
-  /* right merge */
-  else
-  {
+  } else {
+    /* right merge */
     memcpy(storage, &dst[curr + A], B * sizeof(SORT_TYPE));
-    i = B - 1;
-    j = curr + A - 1;
-
-    for (k = curr + A + B - 1; k >= curr; k--)
-    {
-      if ((i >= 0) && (j >= curr))
-      {
-          if (SORT_CMP(dst[j], storage[i]) > 0)
-            dst[k] = dst[j--];
-          else
-            dst[k] = storage[i--];
+    i = B;
+    j = curr + A;
+    k = curr + A + B;
+
+    while (k-- > curr) {
+      if ((i > 0) && (j > curr)) {
+        if (SORT_CMP(dst[j - 1], storage[i - 1]) > 0) {
+          dst[k] = dst[--j];
+        } else {
+          dst[k] = storage[--i];
+        }
+      } else if (i > 0) {
+        dst[k] = storage[--i];
+      } else {
+        break;
       }
-      else if (i >= 0)
-        dst[k] = storage[i--];
-      else
-        dst[k] = dst[j--];
     }
   }
 }
 
-static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_curr, TEMP_STORAGE_T *store, const size_t size)
-{
+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, D;
-    int ABC, BCD, BD, CD;
+    size_t A, B, C, D;
+    int ABC, BCD, CD;
 
     /* if the stack only has one thing on it, we are done with the collapse */
     if (stack_curr <= 1) {
@@ -431,7 +461,6 @@ static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_cu
 
     BCD = (B <= C + D) || ABC;
     CD = (C <= D);
-    BD = (B < D);
 
     /* Both invariants are good */
     if (!BCD && !CD) {
@@ -455,41 +484,94 @@ static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_cu
   return stack_curr;
 }
 
-void TIM_SORT(SORT_TYPE *dst, const size_t size)
-{
-  int minrun;
+static __inline int PUSH_NEXT(SORT_TYPE *dst,
+                              const size_t size,
+                              TEMP_STORAGE_T *store,
+                              const size_t minrun,
+                              TIM_SORT_RUN_T *run_stack,
+                              size_t *stack_curr,
+                              size_t *curr) {
+  size_t len = COUNT_RUN(dst, *curr, size);
+  size_t run = minrun;
+
+  if (run > size - *curr) {
+    run = size - *curr;
+  }
+
+  if (run > len) {
+    BINARY_INSERTION_SORT_START(&dst[*curr], len, run);
+    len = run;
+  }
+
+  run_stack[*stack_curr].start = *curr;
+  run_stack[*stack_curr].length = len;
+  (*stack_curr)++;
+  *curr += len;
+
+  if (*curr == size) {
+    /* finish up */
+    while (*stack_curr > 1) {
+      TIM_SORT_MERGE(dst, run_stack, *stack_curr, store);
+      run_stack[*stack_curr - 2].length += run_stack[*stack_curr - 1].length;
+      (*stack_curr)--;
+    }
+
+    if (store->storage != NULL) {
+      free(store->storage);
+      store->storage = NULL;
+    }
+
+    return 0;
+  }
+
+  return 1;
+}
+
+void TIM_SORT(SORT_TYPE *dst, const size_t size) {
+  size_t minrun;
   TEMP_STORAGE_T _store, *store;
-  TIM_SORT_RUN_T run_stack[128];
-  int stack_curr = 0;
-  int64_t len, run;
-  int64_t curr = 0;
+  TIM_SORT_RUN_T run_stack[TIM_SORT_STACK_SIZE];
+  size_t stack_curr = 0;
+  size_t curr = 0;
 
-  if (size < 64)
-  {
+  /* don't bother sorting an array of size 1 */
+  if (size <= 1) {
+    return;
+  }
+
+  if (size < 64) {
     BINARY_INSERTION_SORT(dst, size);
     return;
   }
 
   /* compute the minimum run length */
   minrun = compute_minrun(size);
-
   /* temporary storage for merges */
   store = &_store;
   store->alloc = 0;
   store->storage = NULL;
 
-  PUSH_NEXT();
-  PUSH_NEXT();
-  PUSH_NEXT();
+  if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
+    return;
+  }
+
+  if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
+    return;
+  }
 
-  while (1)
-  {
-    if (!CHECK_INVARIANT(run_stack, stack_curr))
-    {
+  if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
+    return;
+  }
+
+  while (1) {
+    if (!CHECK_INVARIANT(run_stack, stack_curr)) {
       stack_curr = TIM_SORT_COLLAPSE(dst, run_stack, stack_curr, store, size);
       continue;
     }
-    PUSH_NEXT();
+
+    if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) {
+      return;
+    }
   }
 }
 
index 9d330b8..86a8da7 100644 (file)
  *
  */
 
+/* To avoid EBCDIC trouble when parsing on zOS */
+#if defined(__MVS__)
+#pragma convert("ISO8859-1")
+#endif
+
 #define IN_LIBXML
 #include "libxml.h"
 
 #include <string.h> /* for memset() only ! */
+#include <stddef.h>
 #include <limits.h>
 #ifdef HAVE_CTYPE_H
 #include <ctype.h>
@@ -254,10 +260,10 @@ xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix,
  *
  * [NS 7] LocalPart ::= NCName
  *
- * Returns NULL if not a QName, otherwise the local part, and prefix
- *   is updated to get the Prefix if any.
+ * Returns NULL if the name doesn't have a prefix. Otherwise, returns the
+ * local part, and prefix is updated to get the Prefix. Both the return value
+ * and the prefix must be freed by the caller.
  */
-
 xmlChar *
 xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
     int len = 0;
@@ -1401,6 +1407,8 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
                        else if ((ent != NULL) && (ent->children == NULL)) {
                            xmlNodePtr temp;
 
+                            /* Set to non-NULL value to avoid recursion. */
+                           ent->children = (xmlNodePtr) -1;
                            ent->children = xmlStringGetNodeList(doc,
                                    (const xmlChar*)node->content);
                            ent->owner = 1;
@@ -1593,6 +1601,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
                        else if ((ent != NULL) && (ent->children == NULL)) {
                            xmlNodePtr temp;
 
+                            /* Set to non-NULL value to avoid recursion. */
                            ent->children = (xmlNodePtr) -1;
                            ent->children = xmlStringGetNodeList(doc,
                                    (const xmlChar*)node->content);
@@ -1600,6 +1609,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
                            temp = ent->children;
                            while (temp) {
                                temp->parent = (xmlNodePtr)ent;
+                               ent->last = temp;
                                temp = temp->next;
                            }
                        }
@@ -4596,7 +4606,7 @@ xmlGetLineNoInternal(const xmlNode *node, int depth)
        (node->type == XML_PI_NODE)) {
        if (node->line == 65535) {
            if ((node->type == XML_TEXT_NODE) && (node->psvi != NULL))
-               result = (long) node->psvi;
+               result = (long) (ptrdiff_t) node->psvi;
            else if ((node->type == XML_ELEMENT_NODE) &&
                     (node->children != NULL))
                result = xmlGetLineNoInternal(node->children, depth + 1);
@@ -4755,8 +4765,8 @@ xmlGetNodePath(const xmlNode *node)
             if (occur == 0) {
                 tmp = cur->next;
                 while (tmp != NULL && occur == 0) {
-                 if (tmp->type == XML_COMMENT_NODE)
-                   occur++;
+                   if (tmp->type == XML_COMMENT_NODE)
+                       occur++;
                     tmp = tmp->next;
                 }
                 if (occur != 0)
@@ -8249,7 +8259,7 @@ xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc,
                        ns = ns->next;
                    } while (ns != NULL);
                }
-               /* No break on purpose. */
+                /* Falls through. */
            case XML_ATTRIBUTE_NODE:
                if (node->ns != NULL) {
                    /*
@@ -8840,7 +8850,7 @@ next_ns_decl:
                }
                if (! adoptns)
                    goto ns_end;
-               /* No break on purpose. */
+                /* Falls through. */
            case XML_ATTRIBUTE_NODE:
                /* No ns, no fun. */
                if (cur->ns == NULL)
@@ -9121,7 +9131,7 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
                            goto internal_error;
                    }
                }
-               /* No break on purpose. */
+                /* Falls through. */
            case XML_ATTRIBUTE_NODE:
                /* No namespace, no fun. */
                if (cur->ns == NULL)
index 71f1b1b..6fbabb5 100644 (file)
@@ -327,7 +327,7 @@ trio_nan(TRIO_NOARGS)
 
   if (result == 0.0) {
 
-#if defined(TRIO_COMPILER_SUPPORTS_C99) && !defined(__clang__)
+#if defined(TRIO_COMPILER_SUPPORTS_C99)
     result = nan("");
 
 #elif defined(NAN) && defined(__STDC_IEC_559__)
index 2bd5720..84e420a 100644 (file)
@@ -1961,8 +1961,9 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
            res->scheme = xmlMemStrdup(bas->scheme);
        if (bas->authority != NULL)
            res->authority = xmlMemStrdup(bas->authority);
-       else if (bas->server != NULL) {
-           res->server = xmlMemStrdup(bas->server);
+       else if ((bas->server != NULL) || (bas->port == -1)) {
+           if (bas->server != NULL)
+               res->server = xmlMemStrdup(bas->server);
            if (bas->user != NULL)
                res->user = xmlMemStrdup(bas->user);
            res->port = bas->port;
@@ -2024,8 +2025,9 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
     }
     if (bas->authority != NULL)
        res->authority = xmlMemStrdup(bas->authority);
-    else if (bas->server != NULL) {
-       res->server = xmlMemStrdup(bas->server);
+    else if ((bas->server != NULL) || (bas->port == -1)) {
+       if (bas->server != NULL)
+           res->server = xmlMemStrdup(bas->server);
        if (bas->user != NULL)
            res->user = xmlMemStrdup(bas->user);
        res->port = bas->port;
@@ -2163,7 +2165,6 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
     xmlChar *val = NULL;
     int ret;
     int ix;
-    int pos = 0;
     int nbslash = 0;
     int len;
     xmlURIPtr ref = NULL;
@@ -2254,19 +2255,22 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
        uptr = NULL;
        len = 1;        /* this is for a string terminator only */
     } else {
-    /*
-     * Next we compare the two strings and find where they first differ
-     */
-       if ((ref->path[pos] == '.') && (ref->path[pos+1] == '/'))
-            pos += 2;
+        xmlChar *rptr = (xmlChar *) ref->path;
+        int pos = 0;
+
+        /*
+         * Next we compare the two strings and find where they first differ
+         */
+       if ((*rptr == '.') && (rptr[1] == '/'))
+            rptr += 2;
        if ((*bptr == '.') && (bptr[1] == '/'))
             bptr += 2;
-       else if ((*bptr == '/') && (ref->path[pos] != '/'))
+       else if ((*bptr == '/') && (*rptr != '/'))
            bptr++;
-       while ((bptr[pos] == ref->path[pos]) && (bptr[pos] != 0))
+       while ((bptr[pos] == rptr[pos]) && (bptr[pos] != 0))
            pos++;
 
-       if (bptr[pos] == ref->path[pos]) {
+       if (bptr[pos] == rptr[pos]) {
            val = xmlStrdup(BAD_CAST "");
            goto done;          /* (I can't imagine why anyone would do this) */
        }
@@ -2276,25 +2280,25 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
         * beginning of the "unique" suffix of URI
         */
        ix = pos;
-       if ((ref->path[ix] == '/') && (ix > 0))
+       if ((rptr[ix] == '/') && (ix > 0))
            ix--;
-       else if ((ref->path[ix] == 0) && (ix > 1) && (ref->path[ix - 1] == '/'))
+       else if ((rptr[ix] == 0) && (ix > 1) && (rptr[ix - 1] == '/'))
            ix -= 2;
        for (; ix > 0; ix--) {
-           if (ref->path[ix] == '/')
+           if (rptr[ix] == '/')
                break;
        }
        if (ix == 0) {
-           uptr = (xmlChar *)ref->path;
+           uptr = (xmlChar *)rptr;
        } else {
            ix++;
-           uptr = (xmlChar *)&ref->path[ix];
+           uptr = (xmlChar *)&rptr[ix];
        }
 
        /*
         * In base, count the number of '/' from the differing point
         */
-       if (bptr[pos] != ref->path[pos]) {/* check for trivial URI == base */
+       if (bptr[pos] != rptr[pos]) {/* check for trivial URI == base */
            for (; bptr[ix] != 0; ix++) {
                if (bptr[ix] == '/')
                    nbslash++;
@@ -2390,8 +2394,7 @@ xmlCanonicPath(const xmlChar *path)
  */
 #if defined(_WIN32) && !defined(__CYGWIN__)
     int len = 0;
-    int i = 0;
-    xmlChar *p = NULL;
+    char *p = NULL;
 #endif
     xmlURIPtr uri;
     xmlChar *ret;
@@ -2455,6 +2458,7 @@ xmlCanonicPath(const xmlChar *path)
                xmlFreeURI(uri);
                return escURI;
            }
+            xmlFree(escURI);
        }
     }
 
@@ -2472,7 +2476,7 @@ path_processing:
     len = xmlStrlen(path);
     if ((len > 2) && IS_WINDOWS_PATH(path)) {
         /* make the scheme 'file' */
-       uri->scheme = xmlStrdup(BAD_CAST "file");
+       uri->scheme = (char *) xmlStrdup(BAD_CAST "file");
        /* allocate space for leading '/' + path + string terminator */
        uri->path = xmlMallocAtomic(len + 2);
        if (uri->path == NULL) {
@@ -2482,9 +2486,9 @@ path_processing:
        /* Put in leading '/' plus path */
        uri->path[0] = '/';
        p = uri->path + 1;
-       strncpy(p, path, len + 1);
+       strncpy(p, (char *) path, len + 1);
     } else {
-       uri->path = xmlStrdup(path);
+       uri->path = (char *) xmlStrdup(path);
        if (uri->path == NULL) {
            xmlFreeURI(uri);
            return(NULL);
index 19f84b8..a64b96b 100644 (file)
@@ -163,7 +163,7 @@ xmlErrValidNode(xmlValidCtxtPtr ctxt,
     __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,
                     XML_ERR_ERROR, NULL, 0,
                     (const char *) str1,
-                    (const char *) str1,
+                    (const char *) str2,
                     (const char *) str3, 0, 0, msg, str1, str2, str3);
 }
 #endif /* LIBXML_VALID_ENABLED or LIBXML_SCHEMAS_ENABLED */
@@ -247,7 +247,7 @@ xmlErrValidWarning(xmlValidCtxtPtr ctxt,
     __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,
                     XML_ERR_WARNING, NULL, 0,
                     (const char *) str1,
-                    (const char *) str1,
+                    (const char *) str2,
                     (const char *) str3, 0, 0, msg, str1, str2, str3);
 }
 
@@ -1172,29 +1172,33 @@ xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob)
            xmlBufferWriteCHAR(buf, content->name);
            break;
        case XML_ELEMENT_CONTENT_SEQ:
-           if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-               (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
+           if ((content->c1 != NULL) &&
+               ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
+                (content->c1->type == XML_ELEMENT_CONTENT_SEQ)))
                xmlDumpElementContent(buf, content->c1, 1);
            else
                xmlDumpElementContent(buf, content->c1, 0);
             xmlBufferWriteChar(buf, " , ");
-           if ((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
-               ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) &&
-                (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))
+           if ((content->c2 != NULL) &&
+               ((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
+                ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) &&
+                 (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))))
                xmlDumpElementContent(buf, content->c2, 1);
            else
                xmlDumpElementContent(buf, content->c2, 0);
            break;
        case XML_ELEMENT_CONTENT_OR:
-           if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-               (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
+           if ((content->c1 != NULL) &&
+               ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
+                (content->c1->type == XML_ELEMENT_CONTENT_SEQ)))
                xmlDumpElementContent(buf, content->c1, 1);
            else
                xmlDumpElementContent(buf, content->c1, 0);
             xmlBufferWriteChar(buf, " | ");
-           if ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
-               ((content->c2->type == XML_ELEMENT_CONTENT_OR) &&
-                (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))
+           if ((content->c2 != NULL) &&
+               ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
+                ((content->c2->type == XML_ELEMENT_CONTENT_OR) &&
+                 (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))))
                xmlDumpElementContent(buf, content->c2, 1);
            else
                xmlDumpElementContent(buf, content->c2, 0);
@@ -1262,22 +1266,23 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int
         case XML_ELEMENT_CONTENT_PCDATA:
             strcat(buf, "#PCDATA");
            break;
-       case XML_ELEMENT_CONTENT_ELEMENT:
+       case XML_ELEMENT_CONTENT_ELEMENT: {
+            int qnameLen = xmlStrlen(content->name);
+
+           if (content->prefix != NULL)
+                qnameLen += xmlStrlen(content->prefix) + 1;
+           if (size - len < qnameLen + 10) {
+               strcat(buf, " ...");
+               return;
+           }
            if (content->prefix != NULL) {
-               if (size - len < xmlStrlen(content->prefix) + 10) {
-                   strcat(buf, " ...");
-                   return;
-               }
                strcat(buf, (char *) content->prefix);
                strcat(buf, ":");
            }
-           if (size - len < xmlStrlen(content->name) + 10) {
-               strcat(buf, " ...");
-               return;
-           }
            if (content->name != NULL)
                strcat(buf, (char *) content->name);
            break;
+        }
        case XML_ELEMENT_CONTENT_SEQ:
            if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
                (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
@@ -1319,6 +1324,7 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int
                xmlSnprintfElementContent(buf, size, content->c2, 0);
            break;
     }
+    if (size - strlen(buf) <= 2) return;
     if (englob)
         strcat(buf, ")");
     switch (content->ocur) {
@@ -4621,6 +4627,12 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
        }
     }
 
+    /*
+     * Casting ns to xmlAttrPtr is wrong. We'd need separate functions
+     * xmlAddID and xmlAddRef for namespace declarations, but it makes
+     * no practical sense to use ID types anyway.
+     */
+#if 0
     /* Validity Constraint: ID uniqueness */
     if (attrDecl->atype == XML_ATTRIBUTE_ID) {
         if (xmlAddID(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
@@ -4632,6 +4644,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
         if (xmlAddRef(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
            ret = 0;
     }
+#endif
 
     /* Validity Constraint: Notation Attributes */
     if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
@@ -5177,6 +5190,7 @@ xmlSnprintfElements(char *buf, int size, xmlNodePtr node, int glob) {
             case XML_TEXT_NODE:
                if (xmlIsBlankNode(cur))
                    break;
+                /* Falls through. */
             case XML_CDATA_SECTION_NODE:
             case XML_ENTITY_REF_NODE:
                strcat(buf, "CDATA");
@@ -5725,7 +5739,7 @@ xmlValidatePushElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
        xmlElementPtr elemDecl;
 
        /*
-        * Check the new element agaisnt the content model of the new elem.
+        * Check the new element against the content model of the new elem.
         */
        if (state->elemDecl != NULL) {
            elemDecl = state->elemDecl;
@@ -5817,7 +5831,7 @@ xmlValidatePushCData(xmlValidCtxtPtr ctxt, const xmlChar *data, int len) {
        xmlElementPtr elemDecl;
 
        /*
-        * Check the new element agaisnt the content model of the new elem.
+        * Check the new element against the content model of the new elem.
         */
        if (state->elemDecl != NULL) {
            elemDecl = state->elemDecl;
@@ -5891,7 +5905,7 @@ xmlValidatePopElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc ATTRIBUTE_UNUSED,
        xmlElementPtr elemDecl;
 
        /*
-        * Check the new element agaisnt the content model of the new elem.
+        * Check the new element against the content model of the new elem.
         */
        if (state->elemDecl != NULL) {
            elemDecl = state->elemDecl;
index 309f48a..3ff958a 100644 (file)
@@ -12,6 +12,7 @@
 #include "libxml.h"
 
 #include <string.h>
+#include <stddef.h>
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -39,7 +40,8 @@
 #include <lzma.h>
 #endif
 
-#if defined(WIN32) || defined(_WIN32)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+//#define WIN32_LEAN_AND_MEAN
 //#include <windows.h>
 #include <winnls.h>
 #endif
 #include <winnls.h> /* for CP_UTF8 */
 #endif
 
-/* Figure a portable way to know if a file is a directory. */
-#ifndef HAVE_STAT
-#  ifdef HAVE__STAT
-     /* MS C library seems to define stat and _stat. The definition
-        is identical. Still, mapping them to each other causes a warning. */
-#    ifndef _MSC_VER
-#      define stat(x,y) _stat(x,y)
-#    endif
-#    define HAVE_STAT
-#  endif
-#else
-#  ifdef HAVE__STAT
-#    if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
-#      define stat _stat
-#    endif
-#  endif
-#endif
-#ifdef HAVE_STAT
-#  ifndef S_ISDIR
-#    ifdef _S_ISDIR
-#      define S_ISDIR(x) _S_ISDIR(x)
-#    else
-#      ifdef S_IFDIR
-#        ifndef S_IFMT
-#          ifdef _S_IFMT
-#            define S_IFMT _S_IFMT
-#          endif
-#        endif
-#        ifdef S_IFMT
-#          define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#        endif
-#      endif
+#ifndef S_ISDIR
+#  ifdef _S_ISDIR
+#    define S_ISDIR(x) _S_ISDIR(x)
+#  elif defined(S_IFDIR)
+#    ifdef S_IFMT
+#      define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#    elif defined(_S_IFMT)
+#      define S_ISDIR(m) (((m) & _S_IFMT) == S_IFDIR)
 #    endif
 #  endif
 #endif
@@ -657,99 +635,19 @@ xmlWrapGzOpenUtf8(const char *path, const char *mode)
  *
  */
 static int
-xmlWrapStatUtf8(const char *path,struct stat *info)
-{
-#ifdef HAVE_STAT
+xmlWrapStatUtf8(const char *path, struct _stat *info) {
     int retval = -1;
     wchar_t *wPath;
 
     wPath = __xmlIOWin32UTF8ToWChar(path);
-    if (wPath)
-    {
-       retval = _wstat(wPath,info);
+    if (wPath) {
+       retval = _wstat(wPath, info);
        xmlFree(wPath);
     }
     /* maybe path in native encoding */
     if(retval < 0)
-       retval = stat(path,info);
+       retval = _stat(path, info);
     return retval;
-#else
-    return -1;
-#endif
-}
-
-/**
- *  xmlWrapOpenNative:
- * @path:  the path
- * @mode:  type of access (0 - read, 1 - write)
- *
- * function opens the file specified by @path
- *
- */
-static FILE*
-xmlWrapOpenNative(const char *path,int mode)
-{
-    return fopen(path,mode ? "wb" : "rb");
-}
-
-/**
- *  xmlWrapStatNative:
- * @path:  the path
- * @info:  structure that stores results
- *
- * function obtains information about the file or directory
- *
- */
-static int
-xmlWrapStatNative(const char *path,struct stat *info)
-{
-#ifdef HAVE_STAT
-    return stat(path,info);
-#else
-    return -1;
-#endif
-}
-
-typedef int (* xmlWrapStatFunc) (const char *f, struct stat *s);
-static xmlWrapStatFunc xmlWrapStat = xmlWrapStatNative;
-typedef FILE* (* xmlWrapOpenFunc)(const char *f,int mode);
-static xmlWrapOpenFunc xmlWrapOpen = xmlWrapOpenNative;
-#ifdef HAVE_ZLIB_H
-typedef gzFile (* xmlWrapGzOpenFunc) (const char *f, const char *mode);
-static xmlWrapGzOpenFunc xmlWrapGzOpen = gzopen;
-#endif
-/**
- * xmlInitPlatformSpecificIo:
- *
- * Initialize platform specific features.
- */
-static void
-xmlInitPlatformSpecificIo(void)
-{
-    static int xmlPlatformIoInitialized = 0;
-    OSVERSIONINFO osvi;
-
-    if(xmlPlatformIoInitialized)
-      return;
-
-    osvi.dwOSVersionInfoSize = sizeof(osvi);
-
-    if(GetVersionEx(&osvi) && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
-      xmlWrapStat = xmlWrapStatUtf8;
-      xmlWrapOpen = xmlWrapOpenUtf8;
-#ifdef HAVE_ZLIB_H
-      xmlWrapGzOpen = xmlWrapGzOpenUtf8;
-#endif
-    } else {
-      xmlWrapStat = xmlWrapStatNative;
-      xmlWrapOpen = xmlWrapOpenNative;
-#ifdef HAVE_ZLIB_H
-      xmlWrapGzOpen = gzopen;
-#endif
-    }
-
-    xmlPlatformIoInitialized = 1;
-    return;
 }
 
 #endif
@@ -772,7 +670,11 @@ int
 xmlCheckFilename (const char *path)
 {
 #ifdef HAVE_STAT
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+    struct _stat stat_buffer;
+#else
     struct stat stat_buffer;
+#endif
 #endif
     if (path == NULL)
        return(0);
@@ -787,7 +689,7 @@ xmlCheckFilename (const char *path)
        (path[3] == '\\') )
            return 1;
 
-    if (xmlWrapStat(path, &stat_buffer) == -1)
+    if (xmlWrapStatUtf8(path, &stat_buffer) == -1)
         return 0;
 #else
     if (stat(path, &stat_buffer) == -1)
@@ -827,7 +729,7 @@ static int
 xmlFdRead (void * context, char * buffer, int len) {
     int ret;
 
-    ret = read((int) (long) context, &buffer[0], len);
+    ret = read((int) (ptrdiff_t) context, &buffer[0], len);
     if (ret < 0) xmlIOErr(0, "read()");
     return(ret);
 }
@@ -848,7 +750,7 @@ xmlFdWrite (void * context, const char * buffer, int len) {
     int ret = 0;
 
     if (len > 0) {
-       ret = write((int) (long) context, &buffer[0], len);
+       ret = write((int) (ptrdiff_t) context, &buffer[0], len);
        if (ret < 0) xmlIOErr(0, "write()");
     }
     return(ret);
@@ -866,7 +768,7 @@ xmlFdWrite (void * context, const char * buffer, int len) {
 static int
 xmlFdClose (void * context) {
     int ret;
-    ret = close((int) (long) context);
+    ret = close((int) (ptrdiff_t) context);
     if (ret < 0) xmlIOErr(0, "close()");
     return(ret);
 }
@@ -927,11 +829,14 @@ xmlFileOpen_real (const char *filename) {
 #endif
     }
 
+    /* Do not check DDNAME on zOS ! */
+#if !defined(__MVS__)
     if (!xmlCheckFilename(path))
         return(NULL);
+#endif
 
 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
-    fd = xmlWrapOpen(path, 0);
+    fd = xmlWrapOpenUtf8(path, 0);
 #else
     fd = fopen(path, "r");
 #endif /* WIN32 */
@@ -1004,12 +909,14 @@ xmlFileOpenW (const char *filename) {
        return(NULL);
 
 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
-    fd = xmlWrapOpen(path, 1);
+    fd = xmlWrapOpenUtf8(path, 1);
+#elif(__MVS__)
+    fd = fopen(path, "w");
 #else
-          fd = fopen(path, "wb");
+    fd = fopen(path, "wb");
 #endif /* WIN32 */
 
-        if (fd == NULL) xmlIOErr(0, path);
+    if (fd == NULL) xmlIOErr(0, path);
     return((void *) fd);
 }
 #endif /* LIBXML_OUTPUT_ENABLED */
@@ -1194,7 +1101,7 @@ xmlGzfileOpen_real (const char *filename) {
         return(NULL);
 
 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
-    fd = xmlWrapGzOpen(path, "rb");
+    fd = xmlWrapGzOpenUtf8(path, "rb");
 #else
     fd = gzopen(path, "rb");
 #endif
@@ -1271,7 +1178,7 @@ xmlGzfileOpenW (const char *filename, int compression) {
        return(NULL);
 
 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
-    fd = xmlWrapGzOpen(path, mode);
+    fd = xmlWrapGzOpenUtf8(path, mode);
 #else
     fd = gzopen(path, mode);
 #endif
@@ -1287,7 +1194,7 @@ xmlGzfileOpenW (const char *filename, int compression) {
  *
  * Read @len bytes to @buffer from the compressed I/O channel.
  *
- * Returns the number of bytes written
+ * Returns the number of bytes read.
  */
 static int
 xmlGzfileRead (void * context, char * buffer, int len) {
@@ -1675,7 +1582,7 @@ xmlZMemBuffExtend( xmlZMemBuffPtr buff, size_t ext_amt ) {
        xmlStrPrintf(msg, 500,
                    "xmlZMemBuffExtend:  %s %lu bytes.\n",
                    "Allocation failure extending output buffer to",
-                   new_size );
+                   (unsigned long) new_size );
        xmlIOErr(XML_IO_WRITE, (const char *) msg);
     }
 
@@ -1877,7 +1784,7 @@ xmlIOHTTPOpen (const char *filename) {
  */
 
 void *
-xmlIOHTTPOpenW(const char *post_uri, int compression)
+xmlIOHTTPOpenW(const char *post_uri, int compression ATTRIBUTE_UNUSED)
 {
 
     xmlIOHTTPWriteCtxtPtr ctxt = NULL;
@@ -2319,10 +2226,6 @@ xmlRegisterDefaultInputCallbacks(void) {
     if (xmlInputCallbackInitialized)
        return;
 
-#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
-    xmlInitPlatformSpecificIo();
-#endif
-
     xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen,
                              xmlFileRead, xmlFileClose);
 #ifdef HAVE_ZLIB_H
@@ -2357,10 +2260,6 @@ xmlRegisterDefaultOutputCallbacks (void) {
     if (xmlOutputCallbackInitialized)
        return;
 
-#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
-    xmlInitPlatformSpecificIo();
-#endif
-
     xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW,
                              xmlFileWrite, xmlFileClose);
 
@@ -3004,7 +2903,7 @@ xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
 
     ret = xmlAllocParserInputBuffer(enc);
     if (ret != NULL) {
-        ret->context = (void *) (long) fd;
+        ret->context = (void *) (ptrdiff_t) fd;
        ret->readcallback = xmlFdRead;
        ret->closecallback = xmlFdClose;
     }
@@ -3028,7 +2927,7 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
     xmlParserInputBufferPtr ret;
     int errcode;
 
-    if (size <= 0) return(NULL);
+    if (size < 0) return(NULL);
     if (mem == NULL) return(NULL);
 
     ret = xmlAllocParserInputBuffer(enc);
@@ -3064,7 +2963,7 @@ xmlParserInputBufferCreateStatic(const char *mem, int size,
                                  xmlCharEncoding enc) {
     xmlParserInputBufferPtr ret;
 
-    if (size <= 0) return(NULL);
+    if (size < 0) return(NULL);
     if (mem == NULL) return(NULL);
 
     ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer));
@@ -3110,7 +3009,7 @@ xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
 
     ret = xmlAllocOutputBufferInternal(encoder);
     if (ret != NULL) {
-        ret->context = (void *) (long) fd;
+        ret->context = (void *) (ptrdiff_t) fd;
        ret->writecallback = xmlFdWrite;
        ret->closecallback = NULL;
     }
@@ -3824,7 +3723,7 @@ xmlParserGetDirectory(const char *filename) {
 
     if (filename == NULL) return(NULL);
 
-#if defined(WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
 #   define IS_XMLPGD_SEP(ch) ((ch=='/')||(ch=='\\'))
 #else
 #   define IS_XMLPGD_SEP(ch) (ch=='/')
index 006f0cc..c02b97f 100644 (file)
@@ -312,7 +312,8 @@ static void usage(const char *name) {
     /* split into 2 printf's to avoid overly long string (gcc warning) */
     printf("\
 Usage : %s [options] catalogfile entities...\n\
-\tParse the catalog file and query it for the entities\n\
+\tParse the catalog file (void specification possibly expressed as \"\"\n\
+\tappoints the default system one) and query it for the entities\n\
 \t--sgml : handle SGML Super catalogs for --add and --del\n\
 \t--shell : run a shell allowing interactive queries\n\
 \t--create : create a new catalog\n\
@@ -408,11 +409,18 @@ int main(int argc, char **argv) {
            continue;
        } else if (argv[i][0] == '-')
            continue;
-       filename = argv[i];
+
+       if (filename == NULL && argv[i][0] == '\0') {
+           /* Interpret empty-string catalog specification as
+              a shortcut for a default system catalog. */
+           xmlInitializeCatalog();
+       } else {
+           filename = argv[i];
            ret = xmlLoadCatalog(argv[i]);
            if ((ret < 0) && (create)) {
                xmlCatalogAdd(BAD_CAST "catalog", BAD_CAST argv[i], NULL);
            }
+       }
        break;
     }
 
index 67f7adb..a691aa6 100644 (file)
 #include <stdarg.h>
 #include <assert.h>
 
-#if defined (_WIN32) && !defined(__CYGWIN__)
-#if defined (_MSC_VER) || defined(__BORLANDC__)
-#include <winsock2.h>
-#pragma comment(lib, "ws2_32.lib")
-#define gettimeofday(p1,p2)
-#endif /* _MSC_VER */
-#endif /* _WIN32 */
-
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
 #include <time.h>
 #endif
 
-#ifdef __MINGW32__
-#define _WINSOCKAPI_
-#include <wsockcompat.h>
-#include <winsock2.h>
-#undef XML_SOCKLEN_T
-#define XML_SOCKLEN_T unsigned int
-#endif
-
 #ifdef HAVE_SYS_TIMEB_H
 #include <sys/timeb.h>
 #endif
@@ -2991,124 +2975,124 @@ static void showVersion(const char *name) {
     fprintf(stderr, "\n");
 }
 
-static void usage(const char *name) {
-    printf("Usage : %s [options] XMLfiles ...\n", name);
+static void usage(FILE *f, const char *name) {
+    fprintf(f, "Usage : %s [options] XMLfiles ...\n", name);
 #ifdef LIBXML_OUTPUT_ENABLED
-    printf("\tParse the XML files and output the result of the parsing\n");
+    fprintf(f, "\tParse the XML files and output the result of the parsing\n");
 #else
-    printf("\tParse the XML files\n");
+    fprintf(f, "\tParse the XML files\n");
 #endif /* LIBXML_OUTPUT_ENABLED */
-    printf("\t--version : display the version of the XML library used\n");
+    fprintf(f, "\t--version : display the version of the XML library used\n");
 #ifdef LIBXML_DEBUG_ENABLED
-    printf("\t--debug : dump a debug tree of the in-memory document\n");
-    printf("\t--shell : run a navigating shell\n");
-    printf("\t--debugent : debug the entities defined in the document\n");
+    fprintf(f, "\t--debug : dump a debug tree of the in-memory document\n");
+    fprintf(f, "\t--shell : run a navigating shell\n");
+    fprintf(f, "\t--debugent : debug the entities defined in the document\n");
 #else
 #ifdef LIBXML_READER_ENABLED
-    printf("\t--debug : dump the nodes content when using --stream\n");
+    fprintf(f, "\t--debug : dump the nodes content when using --stream\n");
 #endif /* LIBXML_READER_ENABLED */
 #endif
 #ifdef LIBXML_TREE_ENABLED
-    printf("\t--copy : used to test the internal copy implementation\n");
+    fprintf(f, "\t--copy : used to test the internal copy implementation\n");
 #endif /* LIBXML_TREE_ENABLED */
-    printf("\t--recover : output what was parsable on broken XML documents\n");
-    printf("\t--huge : remove any internal arbitrary parser limits\n");
-    printf("\t--noent : substitute entity references by their value\n");
-    printf("\t--noenc : ignore any encoding specified inside the document\n");
-    printf("\t--noout : don't output the result tree\n");
-    printf("\t--path 'paths': provide a set of paths for resources\n");
-    printf("\t--load-trace : print trace of all external entities loaded\n");
-    printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
-    printf("\t--nocompact : do not generate compact text nodes\n");
-    printf("\t--htmlout : output results as HTML\n");
-    printf("\t--nowrap : do not put HTML doc wrapper\n");
+    fprintf(f, "\t--recover : output what was parsable on broken XML documents\n");
+    fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n");
+    fprintf(f, "\t--noent : substitute entity references by their value\n");
+    fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n");
+    fprintf(f, "\t--noout : don't output the result tree\n");
+    fprintf(f, "\t--path 'paths': provide a set of paths for resources\n");
+    fprintf(f, "\t--load-trace : print trace of all external entities loaded\n");
+    fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n");
+    fprintf(f, "\t--nocompact : do not generate compact text nodes\n");
+    fprintf(f, "\t--htmlout : output results as HTML\n");
+    fprintf(f, "\t--nowrap : do not put HTML doc wrapper\n");
 #ifdef LIBXML_VALID_ENABLED
-    printf("\t--valid : validate the document in addition to std well-formed check\n");
-    printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
-    printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
-    printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
+    fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n");
+    fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
+    fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
+    fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
 #endif /* LIBXML_VALID_ENABLED */
-    printf("\t--timing : print some timings\n");
-    printf("\t--output file or -o file: save to a given file\n");
-    printf("\t--repeat : repeat 100 times, for timing or profiling\n");
-    printf("\t--insert : ad-hoc test for valid insertions\n");
+    fprintf(f, "\t--timing : print some timings\n");
+    fprintf(f, "\t--output file or -o file: save to a given file\n");
+    fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
+    fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
 #ifdef LIBXML_OUTPUT_ENABLED
 #ifdef HAVE_ZLIB_H
-    printf("\t--compress : turn on gzip compression of output\n");
+    fprintf(f, "\t--compress : turn on gzip compression of output\n");
 #endif
 #endif /* LIBXML_OUTPUT_ENABLED */
 #ifdef LIBXML_HTML_ENABLED
-    printf("\t--html : use the HTML parser\n");
-    printf("\t--xmlout : force to use the XML serializer when using --html\n");
-    printf("\t--nodefdtd : do not default HTML doctype\n");
+    fprintf(f, "\t--html : use the HTML parser\n");
+    fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
+    fprintf(f, "\t--nodefdtd : do not default HTML doctype\n");
 #endif
 #ifdef LIBXML_PUSH_ENABLED
-    printf("\t--push : use the push mode of the parser\n");
-    printf("\t--pushsmall : use the push mode of the parser using tiny increments\n");
+    fprintf(f, "\t--push : use the push mode of the parser\n");
+    fprintf(f, "\t--pushsmall : use the push mode of the parser using tiny increments\n");
 #endif /* LIBXML_PUSH_ENABLED */
 #ifdef HAVE_MMAP
-    printf("\t--memory : parse from memory\n");
+    fprintf(f, "\t--memory : parse from memory\n");
 #endif
-    printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
-    printf("\t--nowarning : do not emit warnings from parser/validator\n");
-    printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
-    printf("\t--nocdata : replace cdata section with text nodes\n");
+    fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
+    fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n");
+    fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
+    fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
 #ifdef LIBXML_OUTPUT_ENABLED
-    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");
-    printf("\t                 0 Do not pretty print\n");
-    printf("\t                 1 Format the XML content, as --format\n");
-    printf("\t                 2 Add whitespace inside tags, preserving content\n");
+    fprintf(f, "\t--format : reformat/reindent the output\n");
+    fprintf(f, "\t--encode encoding : output in the given encoding\n");
+    fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
+    fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
+    fprintf(f, "\t                 0 Do not pretty print\n");
+    fprintf(f, "\t                 1 Format the XML content, as --format\n");
+    fprintf(f, "\t                 2 Add whitespace inside tags, preserving content\n");
 #endif /* LIBXML_OUTPUT_ENABLED */
-    printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
-    printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
-    printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
+    fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
+    fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
+    fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
 #ifdef LIBXML_C14N_ENABLED
 #endif /* LIBXML_C14N_ENABLED */
-    printf("\t--nsclean : remove redundant namespace declarations\n");
-    printf("\t--testIO : test user I/O support\n");
+    fprintf(f, "\t--nsclean : remove redundant namespace declarations\n");
+    fprintf(f, "\t--testIO : test user I/O support\n");
 #ifdef LIBXML_CATALOG_ENABLED
-    printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
-    printf("\t             otherwise XML Catalogs starting from \n");
-    printf("\t         %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
-    printf("\t--nocatalogs: deactivate all catalogs\n");
+    fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
+    fprintf(f, "\t             otherwise XML Catalogs starting from \n");
+    fprintf(f, "\t         %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
+    fprintf(f, "\t--nocatalogs: deactivate all catalogs\n");
 #endif
-    printf("\t--auto : generate a small doc on the fly\n");
+    fprintf(f, "\t--auto : generate a small doc on the fly\n");
 #ifdef LIBXML_XINCLUDE_ENABLED
-    printf("\t--xinclude : do XInclude processing\n");
-    printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
-    printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
+    fprintf(f, "\t--xinclude : do XInclude processing\n");
+    fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n");
+    fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n");
 #endif
-    printf("\t--loaddtd : fetch external DTD\n");
-    printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
+    fprintf(f, "\t--loaddtd : fetch external DTD\n");
+    fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
 #ifdef LIBXML_READER_ENABLED
-    printf("\t--stream : use the streaming interface to process very large files\n");
-    printf("\t--walker : create a reader and walk though the resulting doc\n");
+    fprintf(f, "\t--stream : use the streaming interface to process very large files\n");
+    fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n");
 #endif /* LIBXML_READER_ENABLED */
 #ifdef LIBXML_PATTERN_ENABLED
-    printf("\t--pattern pattern_value : test the pattern support\n");
+    fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
 #endif
-    printf("\t--chkregister : verify the node registration code\n");
+    fprintf(f, "\t--chkregister : verify the node registration code\n");
 #ifdef LIBXML_SCHEMAS_ENABLED
-    printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
-    printf("\t--schema schema : do validation against the WXS schema\n");
+    fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
+    fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
 #endif
 #ifdef LIBXML_SCHEMATRON_ENABLED
-    printf("\t--schematron schema : do validation against a schematron\n");
+    fprintf(f, "\t--schematron schema : do validation against a schematron\n");
 #endif
 #ifdef LIBXML_SAX1_ENABLED
-    printf("\t--sax1: use the old SAX1 interfaces for processing\n");
+    fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n");
 #endif
-    printf("\t--sax: do not build a tree but work just at the SAX level\n");
-    printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
+    fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n");
+    fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
 #ifdef LIBXML_XPATH_ENABLED
-    printf("\t--xpath expr: evaluate the XPath expression, imply --noout\n");
+    fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n");
 #endif
 
-    printf("\nLibxml project home page: http://xmlsoft.org/\n");
-    printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
+    fprintf(f, "\nLibxml project home page: http://xmlsoft.org/\n");
+    fprintf(f, "To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
 }
 
 static void registerNode(xmlNodePtr node)
@@ -3138,7 +3122,7 @@ main(int argc, char **argv) {
     const char* indent;
 
     if (argc <= 1) {
-       usage(argv[0]);
+       usage(stderr, argv[0]);
        return(1);
     }
     LIBXML_TEST_VERSION
@@ -3490,7 +3474,7 @@ main(int argc, char **argv) {
            options |= XML_PARSE_OLD10;
        } else {
            fprintf(stderr, "Unknown option %s\n", argv[i]);
-           usage(argv[0]);
+           usage(stderr, argv[0]);
            return(1);
        }
     }
@@ -3784,7 +3768,7 @@ main(int argc, char **argv) {
        xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
     }
     if ((files == 0) && (!generate) && (version == 0)) {
-       usage(argv[0]);
+       usage(stderr, argv[0]);
     }
 #ifdef LIBXML_SCHEMATRON_ENABLED
     if (wxschematron != NULL)
index f08c8c3..6f16c4b 100644 (file)
@@ -111,7 +111,7 @@ typedef struct memnod {
 
 #define MAX_SIZE_T ((size_t)-1)
 
-#define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))
+#define CLIENT_2_HDR(a) ((void *) (((char *) (a)) - RESERVE_SIZE))
 #define HDR_2_CLIENT(a)    ((void *) (((char *) (a)) + RESERVE_SIZE))
 
 
@@ -172,6 +172,13 @@ xmlMallocLoc(size_t size, const char * file, int line)
 
     TEST_POINT
 
+    if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
+       xmlGenericError(xmlGenericErrorContext,
+               "xmlMallocLoc : Unsigned overflow\n");
+       xmlMemoryDump();
+       return(NULL);
+    }
+
     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
 
     if (!p) {
@@ -243,7 +250,7 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
 
     if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
        xmlGenericError(xmlGenericErrorContext,
-               "xmlMallocAtomicLoc : Unsigned overflow prevented\n");
+               "xmlMallocAtomicLoc : Unsigned overflow\n");
        xmlMemoryDump();
        return(NULL);
     }
@@ -352,6 +359,13 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
 #endif
     xmlMutexUnlock(xmlMemMutex);
 
+    if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
+       xmlGenericError(xmlGenericErrorContext,
+               "xmlReallocLoc : Unsigned overflow\n");
+       xmlMemoryDump();
+       return(NULL);
+    }
+
     tmp = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
     if (!tmp) {
         free(p);
@@ -473,7 +487,7 @@ xmlMemFree(void *ptr)
 
 error:
     xmlGenericError(xmlGenericErrorContext,
-           "xmlMemFree(%lX) error\n", (unsigned long) ptr);
+           "xmlMemFree(%p) error\n", ptr);
     xmlMallocBreakpoint();
     return;
 }
@@ -499,6 +513,13 @@ xmlMemStrdupLoc(const char *str, const char *file, int line)
     if (!xmlMemInitialized) xmlInitMemory();
     TEST_POINT
 
+    if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
+       xmlGenericError(xmlGenericErrorContext,
+               "xmlMemStrdupLoc : Unsigned overflow\n");
+       xmlMemoryDump();
+       return(NULL);
+    }
+
     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
     if (!p) {
       goto error;
index 1499f1d..e3a8bd6 100644 (file)
@@ -8,6 +8,11 @@
  * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
  */
 
+/* In order RTLD_GLOBAL and RTLD_NOW to be defined on zOS */
+#if defined(__MVS__)
+#define _UNIX03_SOURCE
+#endif
+
 #define IN_LIBXML
 #include "libxml.h"
 
@@ -296,9 +301,10 @@ xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
 #endif /* HAVE_SHLLOAD */
 #endif /* ! HAVE_DLOPEN */
 
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
 
-//#include <windows.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
 
 /*
  * xmlModulePlatformOpen:
index f285790..34c4c6b 100644 (file)
@@ -3982,7 +3982,7 @@ xmlTextReaderPreserve(xmlTextReaderPtr reader) {
  * pattern. The caller must also use xmlTextReaderCurrentDoc() to
  * keep an handle on the resulting document once parsing has finished
  *
- * Returns a positive number in case of success and -1 in case of error
+ * Returns a non-negative number in case of success and -1 in case of error
  */
 int
 xmlTextReaderPreservePattern(xmlTextReaderPtr reader, const xmlChar *pattern,
index ca3b4f4..d255fbf 100644 (file)
@@ -2810,18 +2810,21 @@ xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg,
            break;
         case XML_REGEXP_NOTSPACE:
            neg = !neg;
+            /* Falls through. */
         case XML_REGEXP_ANYSPACE:
            ret = ((codepoint == '\n') || (codepoint == '\r') ||
                   (codepoint == '\t') || (codepoint == ' '));
            break;
         case XML_REGEXP_NOTINITNAME:
            neg = !neg;
+            /* Falls through. */
         case XML_REGEXP_INITNAME:
            ret = (IS_LETTER(codepoint) ||
                   (codepoint == '_') || (codepoint == ':'));
            break;
         case XML_REGEXP_NOTNAMECHAR:
            neg = !neg;
+            /* Falls through. */
         case XML_REGEXP_NAMECHAR:
            ret = (IS_LETTER(codepoint) || IS_DIGIT(codepoint) ||
                   (codepoint == '.') || (codepoint == '-') ||
@@ -2830,11 +2833,13 @@ xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg,
            break;
         case XML_REGEXP_NOTDECIMAL:
            neg = !neg;
+            /* Falls through. */
         case XML_REGEXP_DECIMAL:
            ret = xmlUCSIsCatNd(codepoint);
            break;
         case XML_REGEXP_REALCHAR:
            neg = !neg;
+            /* Falls through. */
         case XML_REGEXP_NOTREALCHAR:
            ret = xmlUCSIsCatP(codepoint);
            if (ret == 0)
@@ -4089,8 +4094,9 @@ rollback:
                    xmlFree(exec->errString);
                exec->errString = xmlStrdup(value);
                exec->errState = exec->state;
-               memcpy(exec->errCounts, exec->counts,
-                      exec->comp->nbCounters * sizeof(int));
+                if (exec->comp->nbCounters)
+                    memcpy(exec->errCounts, exec->counts,
+                           exec->comp->nbCounters * sizeof(int));
            }
 
            /*
@@ -4880,7 +4886,8 @@ xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) {
        }
        NEXT;
        xmlFAParseCharProp(ctxt);
-       ctxt->atom->neg = 1;
+        if (ctxt->atom != NULL)
+           ctxt->atom->neg = 1;
        if (CUR != '}') {
            ERROR("Expecting '}'");
            return;
@@ -5051,7 +5058,7 @@ xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) {
                return;
        }
         len = 1;
-    } else if ((cur != 0x5B) && (cur != 0x5D)) {
+    } else if ((cur != '\0') && (cur != 0x5B) && (cur != 0x5D)) {
         end = CUR_SCHAR(ctxt->cur, len);
     } else {
        ERROR("Expecting the end of a char range");
index 4a8e3f3..fea135f 100644 (file)
@@ -2109,8 +2109,6 @@ xmlBufAttrSerializeTxtContent(xmlBufPtr buf, xmlDocPtr doc,
                 xmlBufAdd(buf, base, cur - base);
             if (*cur < 0xC0) {
                 xmlSaveErr(XML_SAVE_NOT_UTF8, (xmlNodePtr) attr, NULL);
-                if (doc != NULL)
-                    doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
                xmlSerializeHexCharRef(tmp, *cur);
                 xmlBufAdd(buf, (xmlChar *) tmp, -1);
                 cur++;
@@ -2140,9 +2138,6 @@ xmlBufAttrSerializeTxtContent(xmlBufPtr buf, xmlDocPtr doc,
             }
             if ((l == 1) || (!IS_CHAR(val))) {
                 xmlSaveErr(XML_SAVE_CHAR_INVALID, (xmlNodePtr) attr, NULL);
-                if (doc != NULL)
-                    doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
-
                xmlSerializeHexCharRef(tmp, *cur);
                 xmlBufAdd(buf, (xmlChar *) tmp, -1);
                 cur++;
index 7afe2eb..05a12e0 100644 (file)
  *     but is done here due to performance. Move it to an other layer
  *     is schema construction via an API is implemented.
  */
+
+/* To avoid EBCDIC trouble when parsing on zOS */
+#if defined(__MVS__)
+#pragma convert("ISO8859-1")
+#endif
+
 #define IN_LIBXML
 #include "libxml.h"
 
@@ -166,7 +172,7 @@ static const xmlChar *xmlNamespaceNs = (const xmlChar *)
 /*
 * Macros for attribute uses.
 */
-#define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
+#define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
 
 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
 
@@ -363,6 +369,7 @@ typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
 struct _xmlSchemaAbstractCtxt {
     int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
+    void *dummy; /* Fix alignment issues */
 };
 
 typedef struct _xmlSchemaBucket xmlSchemaBucket;
@@ -473,6 +480,7 @@ typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
 struct _xmlSchemaBasicItem {
     xmlSchemaTypeType type;
+    void *dummy; /* Fix alignment issues */
 };
 
 /**
@@ -1734,6 +1742,7 @@ xmlSchemaFormatItemForReport(xmlChar **buf,
                *buf = xmlStrcat(*buf, BAD_CAST "'");
                FREE_AND_NULL(str);
            }
+            /* Falls through. */
        default:
            named = 0;
        }
@@ -15890,7 +15899,7 @@ xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
  * STATUS: (seems) complete
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
@@ -16137,7 +16146,7 @@ xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  *     (1.4.3.2.2.2) "Particle Valid (Extension)"
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
@@ -16394,7 +16403,7 @@ xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
  * Validation Rule: Checking complex type subsumption
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
@@ -16584,7 +16593,7 @@ xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
  * (3.4.6) Constraints on Complex Type Definition Schema Components
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
@@ -16614,7 +16623,7 @@ xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
  * Complex Type Definition Representation OK (src-ct)
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
@@ -16783,7 +16792,7 @@ xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
  * STATUS: complete
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
@@ -16813,7 +16822,7 @@ xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
  *   CLARIFY: (3.2.2)
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
@@ -16918,7 +16927,7 @@ xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
  * STATUS: complete
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
@@ -16962,7 +16971,7 @@ xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
  * STATUS: TODO
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
@@ -16988,7 +16997,7 @@ xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
  * STATUS: complete
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
@@ -17038,7 +17047,7 @@ xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
  * STATUS: TODO
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
@@ -17079,7 +17088,7 @@ xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
  * STATUS: TODO: subst-groups
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
@@ -17134,7 +17143,7 @@ xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
  * TODO: subst-groups
  *
  * Returns 0 if the constraints are satisfied, a positive
- * error code if not and -1 if an internal error occured.
+ * error code if not and -1 if an internal error occurred.
  */
 static int
 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
@@ -17764,7 +17773,7 @@ xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
     return (0);
 internal_error:
     PERROR_INT("xmlSchemaDeriveAndValidateFacets",
-       "an error occured");
+       "an error occurred");
     return (-1);
 }
 
@@ -21413,7 +21422,7 @@ exit_failure:
        ctxt->ownsConstructor = 0;
     }
     PERROR_INT2("xmlSchemaParse",
-       "An internal error occured");
+       "An internal error occurred");
     ctxt->schema = NULL;
     return(NULL);
 }
@@ -22029,7 +22038,7 @@ xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
  * Creates an augmented IDC definition for the imported schema.
  */
 static void
-xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
+xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt, xmlChar *name ATTRIBUTE_UNUSED) {
     if (imported->schema->idcDef != NULL) {
            xmlHashScan(imported->schema->idcDef ,
            (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
@@ -26094,7 +26103,7 @@ xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
 
            /*
            * Get hold of the still expected content, since a further
-           * call to xmlRegExecPushString() will loose this information.
+           * call to xmlRegExecPushString() will lose this information.
            */
            xmlRegExecNextValues(inode->regexCtxt,
                &nbval, &nbneg, &values[0], &terminal);
@@ -27150,7 +27159,7 @@ root_found:
                    }
                    if (ret < 0) {
                        /*
-                       * VAL TODO: A reader error occured; what to do here?
+                       * VAL TODO: A reader error occurred; what to do here?
                        */
                        ret = 1;
                        goto exit;
@@ -27391,6 +27400,7 @@ xmlSchemaSAXHandleStartElementNs(void *ctx,
     * attributes yet.
     */
     if (nb_attributes != 0) {
+       int valueLen, k, l;
        xmlChar *value;
 
         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
@@ -27400,12 +27410,31 @@ xmlSchemaSAXHandleStartElementNs(void *ctx,
            * libxml2 differs from normal SAX here in that it escapes all ampersands
            * as &#38; instead of delivering the raw converted string. Changing the
            * behavior at this point would break applications that use this API, so
-           * we are forced to work around it. There is no danger of accidentally
-           * decoding some entity other than &#38; in this step because without
-           * unescaped ampersands there can be no other entities in the string.
+           * we are forced to work around it.
            */
-           value = xmlStringLenDecodeEntities(vctxt->parserCtxt, attributes[j+3],
-               attributes[j+4] - attributes[j+3], XML_SUBSTITUTE_REF, 0, 0, 0);
+           valueLen = attributes[j+4] - attributes[j+3];
+           value = xmlMallocAtomic(valueLen + 1);
+           if (value == NULL) {
+               xmlSchemaVErrMemory(vctxt,
+                   "allocating string for decoded attribute",
+                   NULL);
+               goto internal_error;
+           }
+           for (k = 0, l = 0; k < valueLen; l++) {
+               if (k < valueLen - 4 &&
+                   attributes[j+3][k+0] == '&' &&
+                   attributes[j+3][k+1] == '#' &&
+                   attributes[j+3][k+2] == '3' &&
+                   attributes[j+3][k+3] == '8' &&
+                   attributes[j+3][k+4] == ';') {
+                   value[l] = '&';
+                   k += 5;
+               } else {
+                   value[l] = attributes[j+3][k];
+                   k++;
+               }
+           }
+           value[l] = '\0';
            /*
            * TODO: Set the node line.
            */
index 5f38599..c6c9365 100644 (file)
@@ -7,6 +7,11 @@
  * Daniel Veillard <veillard@redhat.com>
  */
 
+/* To avoid EBCDIC trouble when parsing on zOS */
+#if defined(__MVS__)
+#pragma convert("ISO8859-1")
+#endif
+
 #define IN_LIBXML
 #include "libxml.h"
 
@@ -5398,7 +5403,7 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
            if ((valType == XML_SCHEMAS_QNAME) ||
                (valType == XML_SCHEMAS_NOTATION))
                return (0);
-           /* No break on purpose. */
+            /* Falls through. */
        case XML_SCHEMA_FACET_MAXLENGTH:
        case XML_SCHEMA_FACET_MINLENGTH: {
            unsigned int len = 0;
index cc85777..8d2e06f 100644 (file)
@@ -440,8 +440,8 @@ xmlStrlen(const xmlChar *str) {
  * first bytes of @add. Note that if @len < 0 then this is an API error
  * and NULL will be returned.
  *
- * Returns a new xmlChar *, the original @cur is reallocated if needed
- * and should not be freed
+ * Returns a new xmlChar *, the original @cur is reallocated and should
+ * not be freed.
  */
 
 xmlChar *
@@ -519,7 +519,8 @@ xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len) {
  * encoded in UTF-8 or an encoding with 8bit based chars, we assume
  * a termination mark of '0'.
  *
- * Returns a new xmlChar * containing the concatenated string.
+ * Returns a new xmlChar * containing the concatenated string. The original
+ * @cur is reallocated and should not be freed.
  */
 xmlChar *
 xmlStrcat(xmlChar *cur, const xmlChar *add) {
@@ -822,7 +823,7 @@ xmlCheckUTF8(const unsigned char *utf)
  * @len:  the number of characters in the array
  *
  * storage size of an UTF8 string
- * the behaviour is not garanteed if the input string is not UTF-8
+ * the behaviour is not guaranteed if the input string is not UTF-8
  *
  * Returns the storage size of
  * the first 'len' characters of ARRAY
index ce6e9a4..6d0a96a 100644 (file)
@@ -29,14 +29,14 @@ typedef struct {
 } xmlUnicodeRange;
 
 typedef struct {
-    xmlUnicodeRange *table;
+    const xmlUnicodeRange *table;
     int                    numentries;
 } xmlUnicodeNameTable;
 
 
 static xmlIntFunc *xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname);
 
-static xmlUnicodeRange xmlUnicodeBlocks[] = {
+static const xmlUnicodeRange xmlUnicodeBlocks[] = {
   {"AegeanNumbers", xmlUCSIsAegeanNumbers},
   {"AlphabeticPresentationForms", xmlUCSIsAlphabeticPresentationForms},
   {"Arabic", xmlUCSIsArabic},
@@ -945,7 +945,7 @@ static xmlUnicodeNameTable xmlUnicodeCatTbl = {xmlUnicodeCats, 36};
 static xmlIntFunc
 *xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname) {
     int low, high, mid, cmp;
-    xmlUnicodeRange *sptr;
+    const xmlUnicodeRange *sptr;
 
     if ((tptr == NULL) || (tname == NULL)) return(NULL);
 
index 69541b8..eb94e6e 100644 (file)
@@ -3754,6 +3754,7 @@ xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
             if (count < 0)
                 return -1;
             sum += count;
+            /* Falls through. */
         case XML_TEXTWRITER_DTD_ENTY:
         case XML_TEXTWRITER_DTD_PENT:
             count = xmlOutputBufferWriteString(writer->out, ">");
index 113bce6..3527473 100644 (file)
  *
  */
 
+/* To avoid EBCDIC trouble when parsing on zOS */
+#if defined(__MVS__)
+#pragma convert("ISO8859-1")
+#endif
+
 #define IN_LIBXML
 #include "libxml.h"
 
+#include <limits.h>
 #include <string.h>
+#include <stddef.h>
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -153,7 +160,7 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
     int misc = 0, precedence1 = 0, precedence2 = 0;
     xmlNodePtr miscNode1 = NULL, miscNode2 = NULL;
     xmlNodePtr cur, root;
-    long l1, l2;
+    ptrdiff_t l1, l2;
 
     if ((node1 == NULL) || (node2 == NULL))
        return(-2);
@@ -167,12 +174,12 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
     switch (node1->type) {
        case XML_ELEMENT_NODE:
            if (node2->type == XML_ELEMENT_NODE) {
-               if ((0 > (long) node1->content) && /* TODO: Would a != 0 suffice here? */
-                   (0 > (long) node2->content) &&
+               if ((0 > (ptrdiff_t) node1->content) &&
+                   (0 > (ptrdiff_t) node2->content) &&
                    (node1->doc == node2->doc))
                {
-                   l1 = -((long) node1->content);
-                   l2 = -((long) node2->content);
+                   l1 = -((ptrdiff_t) node1->content);
+                   l2 = -((ptrdiff_t) node2->content);
                    if (l1 < l2)
                        return(1);
                    if (l1 > l2)
@@ -217,7 +224,7 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
                node1 = node1->parent;
            }
            if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE) ||
-               (0 <= (long) node1->content)) {
+               (0 <= (ptrdiff_t) node1->content)) {
                /*
                * Fallback for whatever case.
                */
@@ -267,7 +274,7 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
                node2 = node2->parent;
            }
            if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) ||
-               (0 <= (long) node2->content))
+               (0 <= (ptrdiff_t) node2->content))
            {
                node2 = miscNode2;
                precedence2 = 0;
@@ -340,12 +347,12 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
      */
     if ((node1->type == XML_ELEMENT_NODE) &&
        (node2->type == XML_ELEMENT_NODE) &&
-       (0 > (long) node1->content) &&
-       (0 > (long) node2->content) &&
+       (0 > (ptrdiff_t) node1->content) &&
+       (0 > (ptrdiff_t) node2->content) &&
        (node1->doc == node2->doc)) {
 
-       l1 = -((long) node1->content);
-       l2 = -((long) node2->content);
+       l1 = -((ptrdiff_t) node1->content);
+       l2 = -((ptrdiff_t) node2->content);
        if (l1 < l2)
            return(1);
        if (l1 > l2)
@@ -408,12 +415,12 @@ turtle_comparison:
      */
     if ((node1->type == XML_ELEMENT_NODE) &&
        (node2->type&n