Module Name:    src
Committed By:   christos
Date:           Sat Jun 17 22:05:21 UTC 2017

Modified Files:
        src/external/mit/expat/dist/lib: xmlparse.c xmltok.c
        src/external/mit/expat/dist/tests: xmltest.sh
Removed Files:
        src/external/mit/expat/dist: configure.in expat.dsw
        src/external/mit/expat/dist/amiga: Makefile README.txt expat.xml
            expat_68k.c expat_68k.h expat_68k_handler_stubs.c expat_base.h
            expat_lib.c expat_vectors.c launch.c
        src/external/mit/expat/dist/amiga/include/inline4: expat.h
        src/external/mit/expat/dist/amiga/include/interfaces: expat.h
        src/external/mit/expat/dist/amiga/include/libraries: expat.h
        src/external/mit/expat/dist/amiga/include/proto: expat.h
        src/external/mit/expat/dist/bcb5: README.txt all_projects.bpg
            elements.bpf elements.bpr elements.mak expat.bpf expat.bpr
            expat.mak expat_static.bpf expat_static.bpr expat_static.mak
            expatw.bpf expatw.bpr expatw.mak expatw_static.bpf
            expatw_static.bpr expatw_static.mak libexpat_mtd.def
            libexpatw_mtd.def makefile.mak outline.bpf outline.bpr outline.mak
            setup.bat xmlwf.bpf xmlwf.bpr xmlwf.mak
        src/external/mit/expat/dist/examples: elements.dsp outline.dsp
        src/external/mit/expat/dist/lib: Makefile.MPW amigaconfig.h expat.dsp
            expat_static.dsp expatw.dsp expatw_static.dsp macconfig.h
        src/external/mit/expat/dist/tests/benchmark: benchmark.dsp
            benchmark.dsw
        src/external/mit/expat/dist/vms: README.vms descrip.mms expat_config.h
        src/external/mit/expat/dist/xmlwf: xmlwf.dsp

Log Message:
merge conflicts


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.2 -r0 src/external/mit/expat/dist/configure.in
cvs rdiff -u -r1.1.1.1 -r0 src/external/mit/expat/dist/expat.dsw
cvs rdiff -u -r1.1.1.2 -r0 src/external/mit/expat/dist/amiga/Makefile \
    src/external/mit/expat/dist/amiga/README.txt \
    src/external/mit/expat/dist/amiga/expat_lib.c \
    src/external/mit/expat/dist/amiga/expat_vectors.c \
    src/external/mit/expat/dist/amiga/launch.c
cvs rdiff -u -r1.1.1.1 -r0 src/external/mit/expat/dist/amiga/expat.xml \
    src/external/mit/expat/dist/amiga/expat_68k.c \
    src/external/mit/expat/dist/amiga/expat_68k.h \
    src/external/mit/expat/dist/amiga/expat_68k_handler_stubs.c \
    src/external/mit/expat/dist/amiga/expat_base.h
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/mit/expat/dist/amiga/include/inline4/expat.h
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/mit/expat/dist/amiga/include/interfaces/expat.h
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/mit/expat/dist/amiga/include/libraries/expat.h
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/mit/expat/dist/amiga/include/proto/expat.h
cvs rdiff -u -r1.1.1.1 -r0 src/external/mit/expat/dist/bcb5/README.txt \
    src/external/mit/expat/dist/bcb5/all_projects.bpg \
    src/external/mit/expat/dist/bcb5/elements.bpf \
    src/external/mit/expat/dist/bcb5/elements.mak \
    src/external/mit/expat/dist/bcb5/expat.bpf \
    src/external/mit/expat/dist/bcb5/expat_static.bpf \
    src/external/mit/expat/dist/bcb5/expatw.bpf \
    src/external/mit/expat/dist/bcb5/expatw_static.bpf \
    src/external/mit/expat/dist/bcb5/libexpat_mtd.def \
    src/external/mit/expat/dist/bcb5/libexpatw_mtd.def \
    src/external/mit/expat/dist/bcb5/makefile.mak \
    src/external/mit/expat/dist/bcb5/outline.bpf \
    src/external/mit/expat/dist/bcb5/outline.mak \
    src/external/mit/expat/dist/bcb5/setup.bat \
    src/external/mit/expat/dist/bcb5/xmlwf.bpf
cvs rdiff -u -r1.1.1.2 -r0 src/external/mit/expat/dist/bcb5/elements.bpr \
    src/external/mit/expat/dist/bcb5/expat.mak \
    src/external/mit/expat/dist/bcb5/expat_static.mak \
    src/external/mit/expat/dist/bcb5/expatw.mak \
    src/external/mit/expat/dist/bcb5/expatw_static.mak \
    src/external/mit/expat/dist/bcb5/outline.bpr \
    src/external/mit/expat/dist/bcb5/xmlwf.mak
cvs rdiff -u -r1.1.1.3 -r0 src/external/mit/expat/dist/bcb5/expat.bpr \
    src/external/mit/expat/dist/bcb5/expat_static.bpr \
    src/external/mit/expat/dist/bcb5/expatw.bpr \
    src/external/mit/expat/dist/bcb5/expatw_static.bpr \
    src/external/mit/expat/dist/bcb5/xmlwf.bpr
cvs rdiff -u -r1.1.1.2 -r0 src/external/mit/expat/dist/examples/elements.dsp \
    src/external/mit/expat/dist/examples/outline.dsp
cvs rdiff -u -r1.1.1.1 -r0 src/external/mit/expat/dist/lib/Makefile.MPW \
    src/external/mit/expat/dist/lib/macconfig.h
cvs rdiff -u -r1.1.1.2 -r0 src/external/mit/expat/dist/lib/amigaconfig.h \
    src/external/mit/expat/dist/lib/expatw_static.dsp
cvs rdiff -u -r1.1.1.3 -r0 src/external/mit/expat/dist/lib/expat.dsp \
    src/external/mit/expat/dist/lib/expat_static.dsp \
    src/external/mit/expat/dist/lib/expatw.dsp
cvs rdiff -u -r1.6 -r1.7 src/external/mit/expat/dist/lib/xmlparse.c
cvs rdiff -u -r1.3 -r1.4 src/external/mit/expat/dist/lib/xmltok.c
cvs rdiff -u -r1.2 -r1.3 src/external/mit/expat/dist/tests/xmltest.sh
cvs rdiff -u -r1.1.1.2 -r0 \
    src/external/mit/expat/dist/tests/benchmark/benchmark.dsp
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/mit/expat/dist/tests/benchmark/benchmark.dsw
cvs rdiff -u -r1.1.1.1 -r0 src/external/mit/expat/dist/vms/README.vms \
    src/external/mit/expat/dist/vms/descrip.mms \
    src/external/mit/expat/dist/vms/expat_config.h
cvs rdiff -u -r1.1.1.3 -r0 src/external/mit/expat/dist/xmlwf/xmlwf.dsp

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/mit/expat/dist/lib/xmlparse.c
diff -u src/external/mit/expat/dist/lib/xmlparse.c:1.6 src/external/mit/expat/dist/lib/xmlparse.c:1.7
--- src/external/mit/expat/dist/lib/xmlparse.c:1.6	Sat Feb  4 05:56:10 2017
+++ src/external/mit/expat/dist/lib/xmlparse.c	Sat Jun 17 18:05:20 2017
@@ -1,13 +1,19 @@
 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
    See the file COPYING for copying permission.
+
+   77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+)
 */
 
+#define _GNU_SOURCE                     /* syscall prototype */
+
 #include <stddef.h>
 #include <string.h>                     /* memset(), memcpy() */
 #include <assert.h>
 #include <limits.h>                     /* UINT_MAX */
+#include <stdio.h>                      /* fprintf */
+#include <stdlib.h>                     /* getenv */
 
-#ifdef WIN32
+#ifdef _WIN32
 #define getpid GetCurrentProcessId
 #else
 #include <sys/time.h>                   /* gettimeofday() */
@@ -17,20 +23,15 @@
 
 #define XML_BUILDING_EXPAT 1
 
-#ifdef WIN32
+#ifdef _WIN32
 #include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
 #elif defined(HAVE_EXPAT_CONFIG_H)
 #include <expat_config.h>
-#endif /* ndef WIN32 */
+#endif /* ndef _WIN32 */
 
 #include "ascii.h"
 #include "expat.h"
+#include "siphash.h"
 
 #ifdef XML_UNICODE
 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
@@ -109,17 +110,11 @@ typedef struct {
   const XML_Memory_Handling_Suite *mem;
 } HASH_TABLE;
 
-/* Basic character hash algorithm, taken from Python's string hash:
-   h = h * 1000003 ^ character, the constant being a prime number.
+static size_t
+keylen(KEY s);
 
-*/
-#ifdef XML_UNICODE
-#define CHAR_HASH(h, c) \
-  (((h) * 0xF4243) ^ (unsigned short)(c))
-#else
-#define CHAR_HASH(h, c) \
-  (((h) * 0xF4243) ^ (unsigned char)(c))
-#endif
+static void
+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);
 
 /* For probing (after a collision) we need a step size relative prime
    to the hash table size, which is a power of 2. We use double-hashing,
@@ -355,6 +350,8 @@ doIgnoreSection(XML_Parser parser, const
                 const char *end, const char **nextPtr, XML_Bool haveMore);
 #endif /* XML_DTD */
 
+static void
+freeBindings(XML_Parser parser, BINDING *bindings);
 static enum XML_Error
 storeAtts(XML_Parser parser, const ENCODING *, const char *s,
           TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
@@ -697,10 +694,84 @@ static const XML_Char implicitContext[] 
   ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
 };
 
+
+#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+# include <errno.h>
+
+# if defined(HAVE_GETRANDOM)
+#  include <sys/random.h>    /* getrandom */
+# else
+#  include <unistd.h>        /* syscall */
+#  include <sys/syscall.h>   /* SYS_getrandom */
+# endif
+
+/* Obtain entropy on Linux 3.17+ */
+static int
+writeRandomBytes_getrandom(void * target, size_t count) {
+  int success = 0;  /* full count bytes written? */
+  size_t bytesWrittenTotal = 0;
+  const unsigned int getrandomFlags = 0;
+
+  do {
+    void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
+    const size_t bytesToWrite = count - bytesWrittenTotal;
+
+    const int bytesWrittenMore =
+#if defined(HAVE_GETRANDOM)
+        getrandom(currentTarget, bytesToWrite, getrandomFlags);
+#else
+        syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
+#endif
+
+    if (bytesWrittenMore > 0) {
+      bytesWrittenTotal += bytesWrittenMore;
+      if (bytesWrittenTotal >= count)
+        success = 1;
+    }
+  } while (! success && (errno == EINTR || errno == EAGAIN));
+
+  return success;
+}
+
+#endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
+
+
+#ifdef _WIN32
+
+typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
+
+/* Obtain entropy on Windows XP / Windows Server 2003 and later.
+ * Hint on RtlGenRandom and the following article from libsodioum.
+ *
+ * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
+ * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
+ */
+static int
+writeRandomBytes_RtlGenRandom(void * target, size_t count) {
+  int success = 0;  /* full count bytes written? */
+  const HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL");
+
+  if (advapi32) {
+    const RTLGENRANDOM_FUNC RtlGenRandom
+        = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036");
+    if (RtlGenRandom) {
+      if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) {
+        success = 1;
+      }
+    }
+    FreeLibrary(advapi32);
+  }
+
+  return success;
+}
+
+#endif /* _WIN32 */
+
+
 static unsigned long
 gather_time_entropy(void)
 {
-#ifdef WIN32
+#ifdef _WIN32
   FILETIME ft;
   GetSystemTimeAsFileTime(&ft); /* never fails */
   return ft.dwHighDateTime ^ ft.dwLowDateTime;
@@ -716,20 +787,62 @@ gather_time_entropy(void)
 #endif
 }
 
+#if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD)
+# include <bsd/stdlib.h>
+#endif
+
+static unsigned long
+ENTROPY_DEBUG(const char * label, unsigned long entropy) {
+  const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
+  if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
+    fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n",
+        label,
+        (int)sizeof(entropy) * 2, entropy,
+        (unsigned long)sizeof(entropy));
+  }
+  return entropy;
+}
+
 static unsigned long
 generate_hash_secret_salt(XML_Parser parser)
 {
-  /* Process ID is 0 bits entropy if attacker has local access
-   * XML_Parser address is few bits of entropy if attacker has local access */
-  const unsigned long entropy =
-      gather_time_entropy() ^ getpid() ^ (unsigned long)parser;
+  unsigned long entropy;
+  (void)parser;
+#if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__)
+  (void)gather_time_entropy;
+  arc4random_buf(&entropy, sizeof(entropy));
+  return ENTROPY_DEBUG("arc4random_buf", entropy);
+#else
+  /* Try high quality providers first .. */
+#ifdef _WIN32
+  if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) {
+    return ENTROPY_DEBUG("RtlGenRandom", entropy);
+  }
+#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+  if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) {
+    return ENTROPY_DEBUG("getrandom", entropy);
+  }
+#endif
+  /* .. and self-made low quality for backup: */
+
+  /* Process ID is 0 bits entropy if attacker has local access */
+  entropy = gather_time_entropy() ^ getpid();
 
   /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
   if (sizeof(unsigned long) == 4) {
-    return entropy * 2147483647;
+    return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
   } else {
-    return entropy * (unsigned long)2305843009213693951;
+    return ENTROPY_DEBUG("fallback(8)",
+        entropy * (unsigned long)2305843009213693951);
   }
+#endif
+}
+
+static unsigned long
+get_hash_secret_salt(XML_Parser parser) {
+  if (parser->m_parentParser != NULL)
+    return get_hash_secret_salt(parser->m_parentParser);
+  return parser->m_hash_secret_salt;
 }
 
 static XML_Bool  /* only valid for root parser */
@@ -960,6 +1073,10 @@ XML_ParserReset(XML_Parser parser, const
 {
   TAG *tStk;
   OPEN_INTERNAL_ENTITY *openEntityList;
+
+  if (parser == NULL)
+      return XML_FALSE;
+
   if (parentParser)
     return XML_FALSE;
   /* move tagStack to freeTagList */
@@ -994,6 +1111,8 @@ XML_ParserReset(XML_Parser parser, const
 enum XML_Status XMLCALL
 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
 {
+  if (parser == NULL)
+      return XML_STATUS_ERROR;
   /* Block after XML_Parse()/XML_ParseBuffer() has been called.
      XXX There's no way for the caller to determine which of the
      XXX possible error cases caused the XML_STATUS_ERROR return.
@@ -1017,52 +1136,88 @@ XML_ExternalEntityParserCreate(XML_Parse
 {
   XML_Parser parser = oldParser;
   DTD *newDtd = NULL;
-  DTD *oldDtd = _dtd;
-  XML_StartElementHandler oldStartElementHandler = startElementHandler;
-  XML_EndElementHandler oldEndElementHandler = endElementHandler;
-  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
-  XML_ProcessingInstructionHandler oldProcessingInstructionHandler
-      = processingInstructionHandler;
-  XML_CommentHandler oldCommentHandler = commentHandler;
-  XML_StartCdataSectionHandler oldStartCdataSectionHandler
-      = startCdataSectionHandler;
-  XML_EndCdataSectionHandler oldEndCdataSectionHandler
-      = endCdataSectionHandler;
-  XML_DefaultHandler oldDefaultHandler = defaultHandler;
-  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
-      = unparsedEntityDeclHandler;
-  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
-  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
-      = startNamespaceDeclHandler;
-  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
-      = endNamespaceDeclHandler;
-  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
-  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
-      = externalEntityRefHandler;
-  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
-  XML_UnknownEncodingHandler oldUnknownEncodingHandler
-      = unknownEncodingHandler;
-  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
-  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
-  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
-  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
-  ELEMENT_TYPE * oldDeclElementType = declElementType;
-
-  void *oldUserData = userData;
-  void *oldHandlerArg = handlerArg;
-  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
-  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+  DTD *oldDtd;
+  XML_StartElementHandler oldStartElementHandler;
+  XML_EndElementHandler oldEndElementHandler;
+  XML_CharacterDataHandler oldCharacterDataHandler;
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
+  XML_CommentHandler oldCommentHandler;
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler;
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler;
+  XML_DefaultHandler oldDefaultHandler;
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
+  XML_NotationDeclHandler oldNotationDeclHandler;
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
+  XML_NotStandaloneHandler oldNotStandaloneHandler;
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
+  XML_SkippedEntityHandler oldSkippedEntityHandler;
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler;
+  XML_ElementDeclHandler oldElementDeclHandler;
+  XML_AttlistDeclHandler oldAttlistDeclHandler;
+  XML_EntityDeclHandler oldEntityDeclHandler;
+  XML_XmlDeclHandler oldXmlDeclHandler;
+  ELEMENT_TYPE * oldDeclElementType;
+
+  void *oldUserData;
+  void *oldHandlerArg;
+  XML_Bool oldDefaultExpandInternalEntities;
+  XML_Parser oldExternalEntityRefHandlerArg;
 #ifdef XML_DTD
-  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
-  int oldInEntityValue = prologState.inEntityValue;
+  enum XML_ParamEntityParsing oldParamEntityParsing;
+  int oldInEntityValue;
 #endif
-  XML_Bool oldns_triplets = ns_triplets;
+  XML_Bool oldns_triplets;
   /* Note that the new parser shares the same hash secret as the old
      parser, so that dtdCopy and copyEntityTable can lookup values
      from hash tables associated with either parser without us having
      to worry which hash secrets each table has.
   */
-  unsigned long oldhash_secret_salt = hash_secret_salt;
+  unsigned long oldhash_secret_salt;
+
+  /* Validate the oldParser parameter before we pull everything out of it */
+  if (oldParser == NULL)
+    return NULL;
+
+  /* Stash the original parser contents on the stack */
+  oldDtd = _dtd;
+  oldStartElementHandler = startElementHandler;
+  oldEndElementHandler = endElementHandler;
+  oldCharacterDataHandler = characterDataHandler;
+  oldProcessingInstructionHandler = processingInstructionHandler;
+  oldCommentHandler = commentHandler;
+  oldStartCdataSectionHandler = startCdataSectionHandler;
+  oldEndCdataSectionHandler = endCdataSectionHandler;
+  oldDefaultHandler = defaultHandler;
+  oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+  oldNotationDeclHandler = notationDeclHandler;
+  oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
+  oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+  oldNotStandaloneHandler = notStandaloneHandler;
+  oldExternalEntityRefHandler = externalEntityRefHandler;
+  oldSkippedEntityHandler = skippedEntityHandler;
+  oldUnknownEncodingHandler = unknownEncodingHandler;
+  oldElementDeclHandler = elementDeclHandler;
+  oldAttlistDeclHandler = attlistDeclHandler;
+  oldEntityDeclHandler = entityDeclHandler;
+  oldXmlDeclHandler = xmlDeclHandler;
+  oldDeclElementType = declElementType;
+
+  oldUserData = userData;
+  oldHandlerArg = handlerArg;
+  oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+  oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+  oldParamEntityParsing = paramEntityParsing;
+  oldInEntityValue = prologState.inEntityValue;
+#endif
+  oldns_triplets = ns_triplets;
+  /* Note that the new parser shares the same hash secret as the old
+     parser, so that dtdCopy and copyEntityTable can lookup values
+     from hash tables associated with either parser without us having
+     to worry which hash secrets each table has.
+  */
+  oldhash_secret_salt = hash_secret_salt;
 
 #ifdef XML_DTD
   if (!context)
@@ -1228,12 +1383,15 @@ XML_ParserFree(XML_Parser parser)
 void XMLCALL
 XML_UseParserAsHandlerArg(XML_Parser parser)
 {
-  handlerArg = parser;
+  if (parser != NULL)
+    handlerArg = parser;
 }
 
 enum XML_Error XMLCALL
 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
 {
+  if (parser == NULL)
+    return XML_ERROR_INVALID_ARGUMENT;
 #ifdef XML_DTD
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
@@ -1248,6 +1406,8 @@ XML_UseForeignDTD(XML_Parser parser, XML
 void XMLCALL
 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
 {
+  if (parser == NULL)
+    return;
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
     return;
@@ -1257,6 +1417,8 @@ XML_SetReturnNSTriplet(XML_Parser parser
 void XMLCALL
 XML_SetUserData(XML_Parser parser, void *p)
 {
+  if (parser == NULL)
+    return;
   if (handlerArg == userData)
     handlerArg = userData = p;
   else
@@ -1266,6 +1428,8 @@ XML_SetUserData(XML_Parser parser, void 
 enum XML_Status XMLCALL
 XML_SetBase(XML_Parser parser, const XML_Char *p)
 {
+  if (parser == NULL)
+    return XML_STATUS_ERROR;
   if (p) {
     p = poolCopyString(&_dtd->pool, p);
     if (!p)
@@ -1280,18 +1444,24 @@ XML_SetBase(XML_Parser parser, const XML
 const XML_Char * XMLCALL
 XML_GetBase(XML_Parser parser)
 {
+  if (parser == NULL)
+    return NULL;
   return curBase;
 }
 
 int XMLCALL
 XML_GetSpecifiedAttributeCount(XML_Parser parser)
 {
+  if (parser == NULL)
+    return -1;
   return nSpecifiedAtts;
 }
 
 int XMLCALL
 XML_GetIdAttributeIndex(XML_Parser parser)
 {
+  if (parser == NULL)
+    return -1;
   return idAttIndex;
 }
 
@@ -1299,6 +1469,8 @@ XML_GetIdAttributeIndex(XML_Parser parse
 const XML_AttrInfo * XMLCALL
 XML_GetAttributeInfo(XML_Parser parser)
 {
+  if (parser == NULL)
+    return NULL;
   return attInfo;
 }
 #endif
@@ -1308,6 +1480,8 @@ XML_SetElementHandler(XML_Parser parser,
                       XML_StartElementHandler start,
                       XML_EndElementHandler end)
 {
+  if (parser == NULL)
+    return;
   startElementHandler = start;
   endElementHandler = end;
 }
@@ -1315,34 +1489,39 @@ XML_SetElementHandler(XML_Parser parser,
 void XMLCALL
 XML_SetStartElementHandler(XML_Parser parser,
                            XML_StartElementHandler start) {
-  startElementHandler = start;
+  if (parser != NULL)
+    startElementHandler = start;
 }
 
 void XMLCALL
 XML_SetEndElementHandler(XML_Parser parser,
                          XML_EndElementHandler end) {
-  endElementHandler = end;
+  if (parser != NULL)
+    endElementHandler = end;
 }
 
 void XMLCALL
 XML_SetCharacterDataHandler(XML_Parser parser,
                             XML_CharacterDataHandler handler)
 {
-  characterDataHandler = handler;
+  if (parser != NULL)
+    characterDataHandler = handler;
 }
 
 void XMLCALL
 XML_SetProcessingInstructionHandler(XML_Parser parser,
                                     XML_ProcessingInstructionHandler handler)
 {
-  processingInstructionHandler = handler;
+  if (parser != NULL)
+    processingInstructionHandler = handler;
 }
 
 void XMLCALL
 XML_SetCommentHandler(XML_Parser parser,
                       XML_CommentHandler handler)
 {
-  commentHandler = handler;
+  if (parser != NULL)
+    commentHandler = handler;
 }
 
 void XMLCALL
@@ -1350,6 +1529,8 @@ XML_SetCdataSectionHandler(XML_Parser pa
                            XML_StartCdataSectionHandler start,
                            XML_EndCdataSectionHandler end)
 {
+  if (parser == NULL)
+    return;
   startCdataSectionHandler = start;
   endCdataSectionHandler = end;
 }
@@ -1357,19 +1538,23 @@ XML_SetCdataSectionHandler(XML_Parser pa
 void XMLCALL
 XML_SetStartCdataSectionHandler(XML_Parser parser,
                                 XML_StartCdataSectionHandler start) {
-  startCdataSectionHandler = start;
+  if (parser != NULL)
+    startCdataSectionHandler = start;
 }
 
 void XMLCALL
 XML_SetEndCdataSectionHandler(XML_Parser parser,
                               XML_EndCdataSectionHandler end) {
-  endCdataSectionHandler = end;
+  if (parser != NULL)
+    endCdataSectionHandler = end;
 }
 
 void XMLCALL
 XML_SetDefaultHandler(XML_Parser parser,
                       XML_DefaultHandler handler)
 {
+  if (parser == NULL)
+    return;
   defaultHandler = handler;
   defaultExpandInternalEntities = XML_FALSE;
 }
@@ -1378,6 +1563,8 @@ void XMLCALL
 XML_SetDefaultHandlerExpand(XML_Parser parser,
                             XML_DefaultHandler handler)
 {
+  if (parser == NULL)
+    return;
   defaultHandler = handler;
   defaultExpandInternalEntities = XML_TRUE;
 }
@@ -1387,6 +1574,8 @@ XML_SetDoctypeDeclHandler(XML_Parser par
                           XML_StartDoctypeDeclHandler start,
                           XML_EndDoctypeDeclHandler end)
 {
+  if (parser == NULL)
+    return;
   startDoctypeDeclHandler = start;
   endDoctypeDeclHandler = end;
 }
@@ -1394,27 +1583,31 @@ XML_SetDoctypeDeclHandler(XML_Parser par
 void XMLCALL
 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
                                XML_StartDoctypeDeclHandler start) {
-  startDoctypeDeclHandler = start;
+  if (parser != NULL)
+    startDoctypeDeclHandler = start;
 }
 
 void XMLCALL
 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
                              XML_EndDoctypeDeclHandler end) {
-  endDoctypeDeclHandler = end;
+  if (parser != NULL)
+    endDoctypeDeclHandler = end;
 }
 
 void XMLCALL
 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
                                  XML_UnparsedEntityDeclHandler handler)
 {
-  unparsedEntityDeclHandler = handler;
+  if (parser != NULL)
+    unparsedEntityDeclHandler = handler;
 }
 
 void XMLCALL
 XML_SetNotationDeclHandler(XML_Parser parser,
                            XML_NotationDeclHandler handler)
 {
-  notationDeclHandler = handler;
+  if (parser != NULL)
+    notationDeclHandler = handler;
 }
 
 void XMLCALL
@@ -1422,6 +1615,8 @@ XML_SetNamespaceDeclHandler(XML_Parser p
                             XML_StartNamespaceDeclHandler start,
                             XML_EndNamespaceDeclHandler end)
 {
+  if (parser == NULL)
+    return;
   startNamespaceDeclHandler = start;
   endNamespaceDeclHandler = end;
 }
@@ -1429,32 +1624,38 @@ XML_SetNamespaceDeclHandler(XML_Parser p
 void XMLCALL
 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
                                  XML_StartNamespaceDeclHandler start) {
-  startNamespaceDeclHandler = start;
+  if (parser != NULL)
+    startNamespaceDeclHandler = start;
 }
 
 void XMLCALL
 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
                                XML_EndNamespaceDeclHandler end) {
-  endNamespaceDeclHandler = end;
+  if (parser != NULL)
+    endNamespaceDeclHandler = end;
 }
 
 void XMLCALL
 XML_SetNotStandaloneHandler(XML_Parser parser,
                             XML_NotStandaloneHandler handler)
 {
-  notStandaloneHandler = handler;
+  if (parser != NULL)
+    notStandaloneHandler = handler;
 }
 
 void XMLCALL
 XML_SetExternalEntityRefHandler(XML_Parser parser,
                                 XML_ExternalEntityRefHandler handler)
 {
-  externalEntityRefHandler = handler;
+  if (parser != NULL)
+    externalEntityRefHandler = handler;
 }
 
 void XMLCALL
 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
 {
+  if (parser == NULL)
+    return;
   if (arg)
     externalEntityRefHandlerArg = (XML_Parser)arg;
   else
@@ -1465,7 +1666,8 @@ void XMLCALL
 XML_SetSkippedEntityHandler(XML_Parser parser,
                             XML_SkippedEntityHandler handler)
 {
-  skippedEntityHandler = handler;
+  if (parser != NULL)
+    skippedEntityHandler = handler;
 }
 
 void XMLCALL
@@ -1473,6 +1675,8 @@ XML_SetUnknownEncodingHandler(XML_Parser
                               XML_UnknownEncodingHandler handler,
                               void *data)
 {
+  if (parser == NULL)
+    return;
   unknownEncodingHandler = handler;
   unknownEncodingHandlerData = data;
 }
@@ -1481,33 +1685,39 @@ void XMLCALL
 XML_SetElementDeclHandler(XML_Parser parser,
                           XML_ElementDeclHandler eldecl)
 {
-  elementDeclHandler = eldecl;
+  if (parser != NULL)
+    elementDeclHandler = eldecl;
 }
 
 void XMLCALL
 XML_SetAttlistDeclHandler(XML_Parser parser,
                           XML_AttlistDeclHandler attdecl)
 {
-  attlistDeclHandler = attdecl;
+  if (parser != NULL)
+    attlistDeclHandler = attdecl;
 }
 
 void XMLCALL
 XML_SetEntityDeclHandler(XML_Parser parser,
                          XML_EntityDeclHandler handler)
 {
-  entityDeclHandler = handler;
+  if (parser != NULL)
+    entityDeclHandler = handler;
 }
 
 void XMLCALL
 XML_SetXmlDeclHandler(XML_Parser parser,
                       XML_XmlDeclHandler handler) {
-  xmlDeclHandler = handler;
+  if (parser != NULL)
+    xmlDeclHandler = handler;
 }
 
 int XMLCALL
 XML_SetParamEntityParsing(XML_Parser parser,
                           enum XML_ParamEntityParsing peParsing)
 {
+  if (parser == NULL)
+    return 0;
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
     return 0;
@@ -1523,6 +1733,10 @@ int XMLCALL
 XML_SetHashSalt(XML_Parser parser,
                 unsigned long hash_salt)
 {
+  if (parser == NULL)
+    return 0;
+  if (parser->m_parentParser)
+    return XML_SetHashSalt(parser->m_parentParser, hash_salt);
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
     return 0;
@@ -1533,6 +1747,10 @@ XML_SetHashSalt(XML_Parser parser,
 enum XML_Status XMLCALL
 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
 {
+  if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
+    errorCode = XML_ERROR_INVALID_ARGUMENT;
+    return XML_STATUS_ERROR;
+  }
   switch (ps_parsing) {
   case XML_SUSPENDED:
     errorCode = XML_ERROR_SUSPENDED;
@@ -1585,6 +1803,13 @@ XML_Parse(XML_Parser parser, const char 
     const char *end;
     int nLeftOver;
     enum XML_Status result;
+    /* Detect overflow (a+b > MAX <==> b > MAX-a) */
+    if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) {
+       errorCode = XML_ERROR_NO_MEMORY;
+       eventPtr = eventEndPtr = NULL;
+       processor = errorProcessor;
+       return XML_STATUS_ERROR;
+    }
     parseEndByteIndex += len;
     positionPtr = s;
     ps_finalBuffer = (XML_Bool)isFinal;
@@ -1617,11 +1842,14 @@ XML_Parse(XML_Parser parser, const char 
     nLeftOver = s + len - end;
     if (nLeftOver) {
       if (buffer == NULL || nLeftOver > bufferLim - buffer) {
-        /* FIXME avoid integer overflow */
-        char *temp;
-        temp = (buffer == NULL
-                ? (char *)MALLOC(len * 2)
-                : (char *)REALLOC(buffer, len * 2));
+        /* avoid _signed_ integer overflow */
+        char *temp = NULL;
+        const int bytesToAllocate = (int)((unsigned)len * 2U);
+        if (bytesToAllocate > 0) {
+          temp = (buffer == NULL
+                ? (char *)MALLOC(bytesToAllocate)
+                : (char *)REALLOC(buffer, bytesToAllocate));
+        }
         if (temp == NULL) {
           errorCode = XML_ERROR_NO_MEMORY;
           eventPtr = eventEndPtr = NULL;
@@ -1629,7 +1857,7 @@ XML_Parse(XML_Parser parser, const char 
           return XML_STATUS_ERROR;
         }
         buffer = temp;
-        bufferLim = buffer + len * 2;
+        bufferLim = buffer + bytesToAllocate;
       }
       memcpy(buffer, end, nLeftOver);
     }
@@ -1659,6 +1887,8 @@ XML_ParseBuffer(XML_Parser parser, int l
   const char *start;
   enum XML_Status result = XML_STATUS_OK;
 
+  if (parser == NULL)
+    return XML_STATUS_ERROR;
   switch (ps_parsing) {
   case XML_SUSPENDED:
     errorCode = XML_ERROR_SUSPENDED;
@@ -1712,6 +1942,8 @@ XML_ParseBuffer(XML_Parser parser, int l
 void * XMLCALL
 XML_GetBuffer(XML_Parser parser, int len)
 {
+  if (parser == NULL)
+    return NULL;
   if (len < 0) {
     errorCode = XML_ERROR_NO_MEMORY;
     return NULL;
@@ -1808,6 +2040,8 @@ XML_GetBuffer(XML_Parser parser, int len
 enum XML_Status XMLCALL
 XML_StopParser(XML_Parser parser, XML_Bool resumable)
 {
+  if (parser == NULL)
+    return XML_STATUS_ERROR;
   switch (ps_parsing) {
   case XML_SUSPENDED:
     if (resumable) {
@@ -1840,6 +2074,8 @@ XML_ResumeParser(XML_Parser parser)
 {
   enum XML_Status result = XML_STATUS_OK;
 
+  if (parser == NULL)
+    return XML_STATUS_ERROR;
   if (ps_parsing != XML_SUSPENDED) {
     errorCode = XML_ERROR_NOT_SUSPENDED;
     return XML_STATUS_ERROR;
@@ -1876,6 +2112,8 @@ XML_ResumeParser(XML_Parser parser)
 void XMLCALL
 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
 {
+  if (parser == NULL)
+    return;
   assert(status != NULL);
   *status = parser->m_parsingStatus;
 }
@@ -1883,12 +2121,16 @@ XML_GetParsingStatus(XML_Parser parser, 
 enum XML_Error XMLCALL
 XML_GetErrorCode(XML_Parser parser)
 {
+  if (parser == NULL)
+    return XML_ERROR_INVALID_ARGUMENT;
   return errorCode;
 }
 
 XML_Index XMLCALL
 XML_GetCurrentByteIndex(XML_Parser parser)
 {
+  if (parser == NULL)
+    return -1;
   if (eventPtr)
     return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
   return -1;
@@ -1897,6 +2139,8 @@ XML_GetCurrentByteIndex(XML_Parser parse
 int XMLCALL
 XML_GetCurrentByteCount(XML_Parser parser)
 {
+  if (parser == NULL)
+    return 0;
   if (eventEndPtr && eventPtr)
     return (int)(eventEndPtr - eventPtr);
   return 0;
@@ -1906,11 +2150,19 @@ const char * XMLCALL
 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
 {
 #ifdef XML_CONTEXT_BYTES
+  if (parser == NULL)
+    return NULL;
   if (eventPtr && buffer) {
-    *offset = (int)(eventPtr - buffer);
-    *size   = (int)(bufferEnd - buffer);
+    if (offset != NULL)
+      *offset = (int)(eventPtr - buffer);
+    if (size != NULL)
+      *size   = (int)(bufferEnd - buffer);
     return buffer;
   }
+#else
+  (void)parser;
+  (void)offset;
+  (void)size;
 #endif /* defined XML_CONTEXT_BYTES */
   return (char *) 0;
 }
@@ -1918,6 +2170,8 @@ XML_GetInputContext(XML_Parser parser, i
 XML_Size XMLCALL
 XML_GetCurrentLineNumber(XML_Parser parser)
 {
+  if (parser == NULL)
+    return 0;
   if (eventPtr && eventPtr >= positionPtr) {
     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
     positionPtr = eventPtr;
@@ -1928,6 +2182,8 @@ XML_GetCurrentLineNumber(XML_Parser pars
 XML_Size XMLCALL
 XML_GetCurrentColumnNumber(XML_Parser parser)
 {
+  if (parser == NULL)
+    return 0;
   if (eventPtr && eventPtr >= positionPtr) {
     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
     positionPtr = eventPtr;
@@ -1938,30 +2194,38 @@ XML_GetCurrentColumnNumber(XML_Parser pa
 void XMLCALL
 XML_FreeContentModel(XML_Parser parser, XML_Content *model)
 {
-  FREE(model);
+  if (parser != NULL)
+    FREE(model);
 }
 
 void * XMLCALL
 XML_MemMalloc(XML_Parser parser, size_t size)
 {
+  if (parser == NULL)
+    return NULL;
   return MALLOC(size);
 }
 
 void * XMLCALL
 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
 {
+  if (parser == NULL)
+    return NULL;
   return REALLOC(ptr, size);
 }
 
 void XMLCALL
 XML_MemFree(XML_Parser parser, void *ptr)
 {
-  FREE(ptr);
+  if (parser != NULL)
+    FREE(ptr);
 }
 
 void XMLCALL
 XML_DefaultCurrent(XML_Parser parser)
 {
+  if (parser == NULL)
+    return;
   if (defaultHandler) {
     if (openInternalEntities)
       reportDefault(parser,
@@ -2468,7 +2732,7 @@ doContent(XML_Parser parser,
                        &fromPtr, rawNameEnd,
                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
             convLen = (int)(toPtr - (XML_Char *)tag->buf);
-            if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
+            if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
               tag->name.strLen = convLen;
               break;
             }
@@ -2511,8 +2775,10 @@ doContent(XML_Parser parser,
           return XML_ERROR_NO_MEMORY;
         poolFinish(&tempPool);
         result = storeAtts(parser, enc, s, &name, &bindings);
-        if (result)
+        if (result != XML_ERROR_NONE) {
+          freeBindings(parser, bindings);
           return result;
+        }
         poolFinish(&tempPool);
         if (startElementHandler) {
           startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
@@ -2527,15 +2793,7 @@ doContent(XML_Parser parser,
         if (noElmHandlers && defaultHandler)
           reportDefault(parser, enc, s, next);
         poolClear(&tempPool);
-        while (bindings) {
-          BINDING *b = bindings;
-          if (endNamespaceDeclHandler)
-            endNamespaceDeclHandler(handlerArg, b->prefix->name);
-          bindings = bindings->nextTagBinding;
-          b->nextTagBinding = freeBindingList;
-          freeBindingList = b;
-          b->prefix->binding = b->prevPrefixBinding;
-        }
+        freeBindings(parser, bindings);
       }
       if (tagLevel == 0)
         return epilogProcessor(parser, next, end, nextPtr);
@@ -2733,6 +2991,29 @@ doContent(XML_Parser parser,
   /* not reached */
 }
 
+/* This function does not call free() on the allocated memory, merely
+ * moving it to the parser's freeBindingList where it can be freed or
+ * reused as appropriate.
+ */
+static void
+freeBindings(XML_Parser parser, BINDING *bindings)
+{
+  while (bindings) {
+    BINDING *b = bindings;
+
+    /* startNamespaceDeclHandler will have been called for this
+     * binding in addBindings(), so call the end handler now.
+     */
+    if (endNamespaceDeclHandler)
+        endNamespaceDeclHandler(handlerArg, b->prefix->name);
+
+    bindings = bindings->nextTagBinding;
+    b->nextTagBinding = freeBindingList;
+    freeBindingList = b;
+    b->prefix->binding = b->prevPrefixBinding;
+  }
+}
+
 /* Precondition: all arguments must be non-NULL;
    Purpose:
    - normalize attributes
@@ -2957,7 +3238,13 @@ storeAtts(XML_Parser parser, const ENCOD
       if (s[-1] == 2) {  /* prefixed */
         ATTRIBUTE_ID *id;
         const BINDING *b;
-        unsigned long uriHash = hash_secret_salt;
+        unsigned long uriHash;
+        struct siphash sip_state;
+        struct sipkey sip_key;
+
+        copy_salt_to_sipkey(parser, &sip_key);
+        sip24_init(&sip_state, &sip_key);
+
         ((XML_Char *)s)[-1] = 0;  /* clear flag */
         id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
         if (!id || !id->prefix)
@@ -2966,22 +3253,26 @@ storeAtts(XML_Parser parser, const ENCOD
         if (!b)
           return XML_ERROR_UNBOUND_PREFIX;
 
-        /* as we expand the name we also calculate its hash value */
         for (j = 0; j < b->uriLen; j++) {
           const XML_Char c = b->uri[j];
           if (!poolAppendChar(&tempPool, c))
             return XML_ERROR_NO_MEMORY;
-          uriHash = CHAR_HASH(uriHash, c);
         }
+
+        sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
+
         while (*s++ != XML_T(ASCII_COLON))
           ;
+
+        sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
+
         do {  /* copies null terminator */
-          const XML_Char c = *s;
           if (!poolAppendChar(&tempPool, *s))
             return XML_ERROR_NO_MEMORY;
-          uriHash = CHAR_HASH(uriHash, c);
         } while (*s++);
 
+        uriHash = (unsigned long)sip24_final(&sip_state);
+
         { /* Check hash table for duplicate of expanded name (uriName).
              Derived from code in lookup(parser, HASH_TABLE *table, ...).
           */
@@ -3695,6 +3986,14 @@ entityValueInitProcessor(XML_Parser pars
       *nextPtr = next;
       return XML_ERROR_NONE;
     }
+    /* If we get this token, we have the start of what might be a
+       normal tag, but not a declaration (i.e. it doesn't begin with
+       "<!").  In a DTD context, that isn't legal.
+    */
+    else if (tok == XML_TOK_INSTANCE_START) {
+      *nextPtr = next;
+      return XML_ERROR_SYNTAX;
+    }
     start = next;
     eventPtr = start;
   }
@@ -4871,6 +5170,8 @@ processInternalEntity(XML_Parser parser,
   openEntity->internalEventEndPtr = NULL;
   textStart = (char *)entity->textPtr;
   textEnd = (char *)(entity->textPtr + entity->textLen);
+  /* Set a safe default value in case 'next' does not get set */
+  next = textStart;
 
 #ifdef XML_DTD
   if (entity->is_param) {
@@ -4916,6 +5217,8 @@ internalEntityProcessor(XML_Parser parse
   entity = openEntity->entity;
   textStart = ((char *)entity->textPtr) + entity->processed;
   textEnd = (char *)(entity->textPtr + entity->textLen);
+  /* Set a safe default value in case 'next' does not get set */
+  next = textStart;
 
 #ifdef XML_DTD
   if (entity->is_param) {
@@ -5876,7 +6179,6 @@ dtdCopy(XML_Parser oldParser, DTD *newDt
       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
           ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
       if (!newE->defaultAtts) {
-        ms->free_fcn(newE);
         return 0;
       }
     }
@@ -6011,13 +6313,32 @@ keyeq(KEY s1, KEY s2)
   return XML_FALSE;
 }
 
+static size_t
+keylen(KEY s)
+{
+  size_t len = 0;
+  for (; *s; s++, len++);
+  return len;
+}
+
+static void
+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)
+{
+  key->k[0] = 0;
+  key->k[1] = get_hash_secret_salt(parser);
+}
+
 static unsigned long FASTCALL
 hash(XML_Parser parser, KEY s)
 {
-  unsigned long h = hash_secret_salt;
-  while (*s)
-    h = CHAR_HASH(h, *s++);
-  return h;
+  struct siphash state;
+  struct sipkey key;
+  (void)sip_tobin;
+  (void)sip24_valid;
+  copy_salt_to_sipkey(parser, &key);
+  sip24_init(&state, &key);
+  sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
+  return (unsigned long)sip24_final(&state);
 }
 
 static NAMED *
@@ -6260,6 +6581,35 @@ poolStoreString(STRING_POOL *pool, const
   return pool->start;
 }
 
+static size_t
+poolBytesToAllocateFor(int blockSize)
+{
+  /* Unprotected math would be:
+  ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
+  **
+  ** Detect overflow, avoiding _signed_ overflow undefined behavior
+  ** For a + b * c we check b * c in isolation first, so that addition of a
+  ** on top has no chance of making us accept a small non-negative number
+  */
+  const size_t stretch = sizeof(XML_Char);  /* can be 4 bytes */
+
+  if (blockSize <= 0)
+    return 0;
+
+  if (blockSize > (int)(INT_MAX / stretch))
+    return 0;
+
+  {
+    const int stretchedBlockSize = blockSize * (int)stretch;
+    const int bytesToAllocate = (int)(
+        offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
+    if (bytesToAllocate < 0)
+      return 0;
+
+    return (size_t)bytesToAllocate;
+  }
+}
+
 static XML_Bool FASTCALL
 poolGrow(STRING_POOL *pool)
 {
@@ -6289,14 +6639,17 @@ poolGrow(STRING_POOL *pool)
   if (pool->blocks && pool->start == pool->blocks->s) {
     BLOCK *temp;
     int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
+    size_t bytesToAllocate;
 
     if (blockSize < 0)
       return XML_FALSE;
 
+    bytesToAllocate = poolBytesToAllocateFor(blockSize);
+    if (bytesToAllocate == 0)
+      return XML_FALSE;
+
     temp = (BLOCK *)
-      pool->mem->realloc_fcn(pool->blocks,
-                             (offsetof(BLOCK, s)
-                              + blockSize * sizeof(XML_Char)));
+      pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);
     if (temp == NULL)
       return XML_FALSE;
     pool->blocks = temp;
@@ -6308,16 +6661,26 @@ poolGrow(STRING_POOL *pool)
   else {
     BLOCK *tem;
     int blockSize = (int)(pool->end - pool->start);
+    size_t bytesToAllocate;
 
     if (blockSize < 0)
       return XML_FALSE;
 
     if (blockSize < INIT_BLOCK_SIZE)
       blockSize = INIT_BLOCK_SIZE;
-    else
+    else {
+      /* Detect overflow, avoiding _signed_ overflow undefined behavior */
+      if ((int)((unsigned)blockSize * 2U) < 0) {
+        return XML_FALSE;
+      }
       blockSize *= 2;
-    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
-                                        + blockSize * sizeof(XML_Char));
+    }
+
+    bytesToAllocate = poolBytesToAllocateFor(blockSize);
+    if (bytesToAllocate == 0)
+      return XML_FALSE;
+
+    tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
     if (!tem)
       return XML_FALSE;
     tem->size = blockSize;

Index: src/external/mit/expat/dist/lib/xmltok.c
diff -u src/external/mit/expat/dist/lib/xmltok.c:1.3 src/external/mit/expat/dist/lib/xmltok.c:1.4
--- src/external/mit/expat/dist/lib/xmltok.c:1.3	Sat Feb  4 05:56:10 2017
+++ src/external/mit/expat/dist/lib/xmltok.c	Sat Jun 17 18:05:20 2017
@@ -4,19 +4,13 @@
 
 #include <stddef.h>
 
-#ifdef WIN32
+#ifdef _WIN32
 #include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
 #else
 #ifdef HAVE_EXPAT_CONFIG_H
 #include <expat_config.h>
 #endif
-#endif /* ndef WIN32 */
+#endif /* ndef _WIN32 */
 
 #include "expat_external.h"
 #include "internal.h"
@@ -369,24 +363,24 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc
             const char **fromP, const char *fromLim,
             char **toP, const char *toLim)
 {
-  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
   char *to;
   const char *from;
-  if (fromLim - *fromP > toLim - *toP) {
-    /* Avoid copying partial characters. */
-    res = XML_CONVERT_OUTPUT_EXHAUSTED;
-    fromLim = *fromP + (toLim - *toP);
-    align_limit_to_full_utf8_characters(*fromP, &fromLim);
-  }
+  const char *fromLimInitial = fromLim;
+
+  /* Avoid copying partial characters. */
+  align_limit_to_full_utf8_characters(*fromP, &fromLim);
+
   for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++)
     *to = *from;
   *fromP = from;
   *toP = to;
 
-  if ((to == toLim) && (from < fromLim))
+  if (fromLim < fromLimInitial)
+    return XML_CONVERT_INPUT_INCOMPLETE;
+  else if ((to == toLim) && (from < fromLim))
     return XML_CONVERT_OUTPUT_EXHAUSTED;
   else
-    return res;
+    return XML_CONVERT_COMPLETED;
 }
 
 static enum XML_Convert_Result PTRCALL
@@ -402,7 +396,7 @@ utf8_toUtf16(const ENCODING *enc,
     case BT_LEAD2:
       if (fromLim - from < 2) {
         res = XML_CONVERT_INPUT_INCOMPLETE;
-        break;
+        goto after;
       }
       *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
       from += 2;
@@ -410,7 +404,7 @@ utf8_toUtf16(const ENCODING *enc,
     case BT_LEAD3:
       if (fromLim - from < 3) {
         res = XML_CONVERT_INPUT_INCOMPLETE;
-        break;
+        goto after;
       }
       *to++ = (unsigned short)(((from[0] & 0xf) << 12)
                                | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
@@ -441,6 +435,8 @@ utf8_toUtf16(const ENCODING *enc,
       break;
     }
   }
+  if (from < fromLim)
+    res = XML_CONVERT_OUTPUT_EXHAUSTED;
 after:
   *fromP = from;
   *toP = to;

Index: src/external/mit/expat/dist/tests/xmltest.sh
diff -u src/external/mit/expat/dist/tests/xmltest.sh:1.2 src/external/mit/expat/dist/tests/xmltest.sh:1.3
--- src/external/mit/expat/dist/tests/xmltest.sh:1.2	Sat Feb  4 05:56:10 2017
+++ src/external/mit/expat/dist/tests/xmltest.sh	Sat Jun 17 18:05:20 2017
@@ -25,9 +25,9 @@ shopt -s nullglob
 MYDIR="`dirname \"$0\"`"
 cd "$MYDIR"
 MYDIR="`pwd`"
-# XMLWF="`dirname \"$MYDIR\"`/xmlwf/xmlwf"
+#XMLWF="${1:-`dirname \"$MYDIR\"`/xmlwf/xmlwf}"
 XMLWF=/usr/bin/xmlwf
-TS="$MYDIR/XML-Test-Suite"
+TS="$MYDIR"
 # OUTPUT must terminate with the directory separator.
 OUTPUT="$TS/out/"
 # OUTPUT=/home/tmp/xml-testsuite-out/
@@ -98,7 +98,8 @@ for xmldir in ibm/valid/P* \
               sun/invalid ; do
   cd "$TS/xmlconf/$xmldir"
   mkdir -p "$OUTPUT$xmldir"
-  for xmlfile in *.xml ; do
+  for xmlfile in $(ls -1 *.xml | sort -d) ; do
+      [[ -f "$xmlfile" ]] || continue
       RunXmlwfWF "$xmlfile" "$xmldir/"
       UpdateStatus $?
   done

Reply via email to