summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2017-06-20 12:17:48 (GMT)
committerTobias Markmann <tm@ayena.de>2017-06-20 14:43:05 (GMT)
commita507a88a189bb603c9f2d686c9c8dafca49c053d (patch)
treeac32d8281fdefb83f3a0d9ef79c3983d98bed24d /3rdParty/Expat/src/xmlparse.c
parentb807e3fa975cf25e5e901b59643419a5a73a12fe (diff)
downloadswift-a507a88a189bb603c9f2d686c9c8dafca49c053d.zip
swift-a507a88a189bb603c9f2d686c9c8dafca49c053d.tar.bz2
Update 3rdParty/Expat to version 2.2.1
Test-Information: Build successfully on macOS 10.12.5 with clang trunk and ./scons test=all try_libxml=no try_expat=no . Change-Id: I0cc0680086ea40f92bbfa7296d10beb08cc657e3
Diffstat (limited to '3rdParty/Expat/src/xmlparse.c')
-rw-r--r--3rdParty/Expat/src/xmlparse.c734
1 files changed, 579 insertions, 155 deletions
diff --git a/3rdParty/Expat/src/xmlparse.c b/3rdParty/Expat/src/xmlparse.c
index 9b8bd69..76f078e 100644
--- a/3rdParty/Expat/src/xmlparse.c
+++ b/3rdParty/Expat/src/xmlparse.c
@@ -2,4 +2,8 @@
See the file COPYING for copying permission.
+
+ 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+)
*/
+#define _GNU_SOURCE /* syscall prototype */
+
#include <stddef.h>
@@ -8,3 +12,12 @@
#include <limits.h> /* UINT_MAX */
-#include <time.h> /* time() */
+#include <stdio.h> /* fprintf */
+#include <stdlib.h> /* getenv */
+
+#ifdef _WIN32
+#define getpid GetCurrentProcessId
+#else
+#include <sys/time.h> /* gettimeofday() */
+#include <sys/types.h> /* getpid() */
+#include <unistd.h> /* getpid() */
+#endif
@@ -12,13 +25,7 @@
-#ifdef COMPILED_FROM_DSP
+#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 COMPILED_FROM_DSP */
+#endif /* ndef _WIN32 */
@@ -26,2 +33,3 @@
#include "expat.h"
+#include "siphash.h"
@@ -104,13 +112,7 @@ typedef struct {
-/* 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);
@@ -350,2 +352,4 @@ doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+static void
+freeBindings(XML_Parser parser, BINDING *bindings);
static enum XML_Error
@@ -434,3 +438,3 @@ getElementType(XML_Parser parser, const ENCODING *enc,
-static unsigned long generate_hash_secret_salt(void);
+static unsigned long generate_hash_secret_salt(XML_Parser parser);
static XML_Bool startParsing(XML_Parser parser);
@@ -692,8 +696,151 @@ static const XML_Char implicitContext[] = {
+
+#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
-generate_hash_secret_salt(void)
+gather_time_entropy(void)
{
- unsigned int seed = time(NULL) % UINT_MAX;
- srand(seed);
- return rand();
+#ifdef _WIN32
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft); /* never fails */
+ return ft.dwHighDateTime ^ ft.dwLowDateTime;
+#else
+ struct timeval tv;
+ int gettimeofday_res;
+
+ gettimeofday_res = gettimeofday(&tv, NULL);
+ assert (gettimeofday_res == 0);
+
+ /* Microseconds time is <20 bits entropy */
+ return tv.tv_usec;
+#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)
+{
+ 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_DEBUG("fallback(4)", entropy * 2147483647);
+ } else {
+ 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;
}
@@ -705,3 +852,3 @@ startParsing(XML_Parser parser)
if (hash_secret_salt == 0)
- hash_secret_salt = generate_hash_secret_salt();
+ hash_secret_salt = generate_hash_secret_salt(parser);
if (ns) {
@@ -928,2 +1075,6 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
OPEN_INTERNAL_ENTITY *openEntityList;
+
+ if (parser == NULL)
+ return XML_FALSE;
+
if (parentParser)
@@ -962,2 +1113,4 @@ 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.
@@ -985,42 +1138,34 @@ XML_ExternalEntityParserCreate(XML_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
@@ -1030,3 +1175,47 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser,
*/
- 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;
@@ -1196,3 +1385,4 @@ XML_UseParserAsHandlerArg(XML_Parser parser)
{
- handlerArg = parser;
+ if (parser != NULL)
+ handlerArg = parser;
}
@@ -1202,2 +1392,4 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
{
+ if (parser == NULL)
+ return XML_ERROR_INVALID_ARGUMENT;
#ifdef XML_DTD
@@ -1216,2 +1408,4 @@ XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
{
+ if (parser == NULL)
+ return;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
@@ -1225,2 +1419,4 @@ XML_SetUserData(XML_Parser parser, void *p)
{
+ if (parser == NULL)
+ return;
if (handlerArg == userData)
@@ -1234,2 +1430,4 @@ XML_SetBase(XML_Parser parser, const XML_Char *p)
{
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
if (p) {
@@ -1248,2 +1446,4 @@ XML_GetBase(XML_Parser parser)
{
+ if (parser == NULL)
+ return NULL;
return curBase;
@@ -1254,2 +1454,4 @@ XML_GetSpecifiedAttributeCount(XML_Parser parser)
{
+ if (parser == NULL)
+ return -1;
return nSpecifiedAtts;
@@ -1260,2 +1462,4 @@ XML_GetIdAttributeIndex(XML_Parser parser)
{
+ if (parser == NULL)
+ return -1;
return idAttIndex;
@@ -1267,2 +1471,4 @@ XML_GetAttributeInfo(XML_Parser parser)
{
+ if (parser == NULL)
+ return NULL;
return attInfo;
@@ -1276,2 +1482,4 @@ XML_SetElementHandler(XML_Parser parser,
{
+ if (parser == NULL)
+ return;
startElementHandler = start;
@@ -1283,3 +1491,4 @@ XML_SetStartElementHandler(XML_Parser parser,
XML_StartElementHandler start) {
- startElementHandler = start;
+ if (parser != NULL)
+ startElementHandler = start;
}
@@ -1289,3 +1498,4 @@ XML_SetEndElementHandler(XML_Parser parser,
XML_EndElementHandler end) {
- endElementHandler = end;
+ if (parser != NULL)
+ endElementHandler = end;
}
@@ -1296,3 +1506,4 @@ XML_SetCharacterDataHandler(XML_Parser parser,
{
- characterDataHandler = handler;
+ if (parser != NULL)
+ characterDataHandler = handler;
}
@@ -1303,3 +1514,4 @@ XML_SetProcessingInstructionHandler(XML_Parser parser,
{
- processingInstructionHandler = handler;
+ if (parser != NULL)
+ processingInstructionHandler = handler;
}
@@ -1310,3 +1522,4 @@ XML_SetCommentHandler(XML_Parser parser,
{
- commentHandler = handler;
+ if (parser != NULL)
+ commentHandler = handler;
}
@@ -1318,2 +1531,4 @@ XML_SetCdataSectionHandler(XML_Parser parser,
{
+ if (parser == NULL)
+ return;
startCdataSectionHandler = start;
@@ -1325,3 +1540,4 @@ XML_SetStartCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start) {
- startCdataSectionHandler = start;
+ if (parser != NULL)
+ startCdataSectionHandler = start;
}
@@ -1331,3 +1547,4 @@ XML_SetEndCdataSectionHandler(XML_Parser parser,
XML_EndCdataSectionHandler end) {
- endCdataSectionHandler = end;
+ if (parser != NULL)
+ endCdataSectionHandler = end;
}
@@ -1338,2 +1555,4 @@ XML_SetDefaultHandler(XML_Parser parser,
{
+ if (parser == NULL)
+ return;
defaultHandler = handler;
@@ -1346,2 +1565,4 @@ XML_SetDefaultHandlerExpand(XML_Parser parser,
{
+ if (parser == NULL)
+ return;
defaultHandler = handler;
@@ -1355,2 +1576,4 @@ XML_SetDoctypeDeclHandler(XML_Parser parser,
{
+ if (parser == NULL)
+ return;
startDoctypeDeclHandler = start;
@@ -1362,3 +1585,4 @@ XML_SetStartDoctypeDeclHandler(XML_Parser parser,
XML_StartDoctypeDeclHandler start) {
- startDoctypeDeclHandler = start;
+ if (parser != NULL)
+ startDoctypeDeclHandler = start;
}
@@ -1368,3 +1592,4 @@ XML_SetEndDoctypeDeclHandler(XML_Parser parser,
XML_EndDoctypeDeclHandler end) {
- endDoctypeDeclHandler = end;
+ if (parser != NULL)
+ endDoctypeDeclHandler = end;
}
@@ -1375,3 +1600,4 @@ XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
{
- unparsedEntityDeclHandler = handler;
+ if (parser != NULL)
+ unparsedEntityDeclHandler = handler;
}
@@ -1382,3 +1608,4 @@ XML_SetNotationDeclHandler(XML_Parser parser,
{
- notationDeclHandler = handler;
+ if (parser != NULL)
+ notationDeclHandler = handler;
}
@@ -1390,2 +1617,4 @@ XML_SetNamespaceDeclHandler(XML_Parser parser,
{
+ if (parser == NULL)
+ return;
startNamespaceDeclHandler = start;
@@ -1397,3 +1626,4 @@ XML_SetStartNamespaceDeclHandler(XML_Parser parser,
XML_StartNamespaceDeclHandler start) {
- startNamespaceDeclHandler = start;
+ if (parser != NULL)
+ startNamespaceDeclHandler = start;
}
@@ -1403,3 +1633,4 @@ XML_SetEndNamespaceDeclHandler(XML_Parser parser,
XML_EndNamespaceDeclHandler end) {
- endNamespaceDeclHandler = end;
+ if (parser != NULL)
+ endNamespaceDeclHandler = end;
}
@@ -1410,3 +1641,4 @@ XML_SetNotStandaloneHandler(XML_Parser parser,
{
- notStandaloneHandler = handler;
+ if (parser != NULL)
+ notStandaloneHandler = handler;
}
@@ -1417,3 +1649,4 @@ XML_SetExternalEntityRefHandler(XML_Parser parser,
{
- externalEntityRefHandler = handler;
+ if (parser != NULL)
+ externalEntityRefHandler = handler;
}
@@ -1423,2 +1656,4 @@ XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
{
+ if (parser == NULL)
+ return;
if (arg)
@@ -1433,3 +1668,4 @@ XML_SetSkippedEntityHandler(XML_Parser parser,
{
- skippedEntityHandler = handler;
+ if (parser != NULL)
+ skippedEntityHandler = handler;
}
@@ -1441,2 +1677,4 @@ XML_SetUnknownEncodingHandler(XML_Parser parser,
{
+ if (parser == NULL)
+ return;
unknownEncodingHandler = handler;
@@ -1449,3 +1687,4 @@ XML_SetElementDeclHandler(XML_Parser parser,
{
- elementDeclHandler = eldecl;
+ if (parser != NULL)
+ elementDeclHandler = eldecl;
}
@@ -1456,3 +1695,4 @@ XML_SetAttlistDeclHandler(XML_Parser parser,
{
- attlistDeclHandler = attdecl;
+ if (parser != NULL)
+ attlistDeclHandler = attdecl;
}
@@ -1463,3 +1703,4 @@ XML_SetEntityDeclHandler(XML_Parser parser,
{
- entityDeclHandler = handler;
+ if (parser != NULL)
+ entityDeclHandler = handler;
}
@@ -1469,3 +1710,4 @@ XML_SetXmlDeclHandler(XML_Parser parser,
XML_XmlDeclHandler handler) {
- xmlDeclHandler = handler;
+ if (parser != NULL)
+ xmlDeclHandler = handler;
}
@@ -1476,2 +1718,4 @@ XML_SetParamEntityParsing(XML_Parser parser,
{
+ if (parser == NULL)
+ return 0;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
@@ -1491,2 +1735,6 @@ XML_SetHashSalt(XML_Parser parser,
{
+ 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 */
@@ -1501,2 +1749,6 @@ 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) {
@@ -1552,3 +1804,10 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
int nLeftOver;
- enum XML_Error result;
+ 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;
@@ -1585,7 +1844,10 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
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) {
@@ -1597,3 +1859,3 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
buffer = temp;
- bufferLim = buffer + len * 2;
+ bufferLim = buffer + bytesToAllocate;
}
@@ -1627,2 +1889,4 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
switch (ps_parsing) {
@@ -1680,2 +1944,8 @@ XML_GetBuffer(XML_Parser parser, int len)
{
+ if (parser == NULL)
+ return NULL;
+ if (len < 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
switch (ps_parsing) {
@@ -1691,7 +1961,13 @@ XML_GetBuffer(XML_Parser parser, int len)
if (len > bufferLim - bufferEnd) {
- /* FIXME avoid integer overflow */
- int neededSize = len + (int)(bufferEnd - bufferPtr);
#ifdef XML_CONTEXT_BYTES
- int keep = (int)(bufferPtr - buffer);
-
+ int keep;
+#endif /* defined XML_CONTEXT_BYTES */
+ /* Do not invoke signed arithmetic overflow: */
+ int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));
+ if (neededSize < 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
+#ifdef XML_CONTEXT_BYTES
+ keep = (int)(bufferPtr - buffer);
if (keep > XML_CONTEXT_BYTES)
@@ -1720,4 +1996,9 @@ XML_GetBuffer(XML_Parser parser, int len)
do {
- bufferSize *= 2;
- } while (bufferSize < neededSize);
+ /* Do not invoke signed arithmetic overflow: */
+ bufferSize = (int) (2U * (unsigned) bufferSize);
+ } while (bufferSize < neededSize && bufferSize > 0);
+ if (bufferSize <= 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
newBuf = (char *)MALLOC(bufferSize);
@@ -1761,2 +2042,4 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable)
{
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
switch (ps_parsing) {
@@ -1793,2 +2076,4 @@ XML_ResumeParser(XML_Parser parser)
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
if (ps_parsing != XML_SUSPENDED) {
@@ -1829,2 +2114,4 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
{
+ if (parser == NULL)
+ return;
assert(status != NULL);
@@ -1836,2 +2123,4 @@ XML_GetErrorCode(XML_Parser parser)
{
+ if (parser == NULL)
+ return XML_ERROR_INVALID_ARGUMENT;
return errorCode;
@@ -1842,4 +2131,6 @@ XML_GetCurrentByteIndex(XML_Parser parser)
{
+ if (parser == NULL)
+ return -1;
if (eventPtr)
- return parseEndByteIndex - (parseEndPtr - eventPtr);
+ return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
return -1;
@@ -1850,2 +2141,4 @@ XML_GetCurrentByteCount(XML_Parser parser)
{
+ if (parser == NULL)
+ return 0;
if (eventEndPtr && eventPtr)
@@ -1859,7 +2152,15 @@ 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 */
@@ -1871,2 +2172,4 @@ XML_GetCurrentLineNumber(XML_Parser parser)
{
+ if (parser == NULL)
+ return 0;
if (eventPtr && eventPtr >= positionPtr) {
@@ -1881,2 +2184,4 @@ XML_GetCurrentColumnNumber(XML_Parser parser)
{
+ if (parser == NULL)
+ return 0;
if (eventPtr && eventPtr >= positionPtr) {
@@ -1891,3 +2196,4 @@ XML_FreeContentModel(XML_Parser parser, XML_Content *model)
{
- FREE(model);
+ if (parser != NULL)
+ FREE(model);
}
@@ -1897,2 +2203,4 @@ XML_MemMalloc(XML_Parser parser, size_t size)
{
+ if (parser == NULL)
+ return NULL;
return MALLOC(size);
@@ -1903,2 +2211,4 @@ XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
{
+ if (parser == NULL)
+ return NULL;
return REALLOC(ptr, size);
@@ -1909,3 +2219,4 @@ XML_MemFree(XML_Parser parser, void *ptr)
{
- FREE(ptr);
+ if (parser != NULL)
+ FREE(ptr);
}
@@ -1915,2 +2226,4 @@ XML_DefaultCurrent(XML_Parser parser)
{
+ if (parser == NULL)
+ return;
if (defaultHandler) {
@@ -2417,3 +2730,3 @@ doContent(XML_Parser parser,
int convLen;
- XmlConvert(enc,
+ const enum XML_Convert_Result convert_res = XmlConvert(enc,
&fromPtr, rawNameEnd,
@@ -2421,3 +2734,3 @@ doContent(XML_Parser parser,
convLen = (int)(toPtr - (XML_Char *)tag->buf);
- if (fromPtr == rawNameEnd) {
+ if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
tag->name.strLen = convLen;
@@ -2464,4 +2777,6 @@ doContent(XML_Parser parser,
result = storeAtts(parser, enc, s, &name, &bindings);
- if (result)
+ if (result != XML_ERROR_NONE) {
+ freeBindings(parser, bindings);
return result;
+ }
poolFinish(&tempPool);
@@ -2480,11 +2795,3 @@ doContent(XML_Parser parser,
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);
}
@@ -2642,3 +2949,3 @@ doContent(XML_Parser parser,
ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = s;
@@ -2646,3 +2953,3 @@ doContent(XML_Parser parser,
(int)(dataPtr - (ICHAR *)dataBuf));
- if (s == next)
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
@@ -2686,2 +2993,25 @@ doContent(XML_Parser parser,
+/* 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;
@@ -2910,12 +3240,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
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)
+ return XML_ERROR_NO_MEMORY;
b = id->prefix->binding;
- if (!b) {
- //return XML_ERROR_UNBOUND_PREFIX;
- continue;
- }
+ 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++) {
@@ -2924,13 +3259,18 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
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).
@@ -2995,3 +3335,3 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
/* expand the element type name */
- if (elementType->prefix && elementType->prefix->binding) {
+ if (elementType->prefix) {
binding = elementType->prefix->binding;
@@ -3091,6 +3431,6 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
/* Not allowed to bind xmlns */
- /*if (prefix->name[3] == XML_T(ASCII_n)
+ if (prefix->name[3] == XML_T(ASCII_n)
&& prefix->name[4] == XML_T(ASCII_s)
&& prefix->name[5] == XML_T('\0'))
- return XML_ERROR_RESERVED_PREFIX_XMLNS;*/
+ return XML_ERROR_RESERVED_PREFIX_XMLNS;
@@ -3111,8 +3451,8 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
- /*if (mustBeXML != isXML)
+ if (mustBeXML != isXML)
return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
- : XML_ERROR_RESERVED_NAMESPACE_URI;*/
+ : XML_ERROR_RESERVED_NAMESPACE_URI;
- /*if (isXMLNS)
- return XML_ERROR_RESERVED_NAMESPACE_URI;*/
+ if (isXMLNS)
+ return XML_ERROR_RESERVED_NAMESPACE_URI;
@@ -3252,3 +3592,3 @@ doCdataSection(XML_Parser parser,
ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = next;
@@ -3256,3 +3596,3 @@ doCdataSection(XML_Parser parser,
(int)(dataPtr - (ICHAR *)dataBuf));
- if (s == next)
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
@@ -3648,2 +3988,10 @@ entityValueInitProcessor(XML_Parser parser,
}
+ /* 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;
@@ -4824,2 +5172,4 @@ processInternalEntity(XML_Parser parser, ENTITY *entity,
textEnd = (char *)(entity->textPtr + entity->textLen);
+ /* Set a safe default value in case 'next' does not get set */
+ next = textStart;
@@ -4869,2 +5219,4 @@ internalEntityProcessor(XML_Parser parser,
textEnd = (char *)(entity->textPtr + entity->textLen);
+ /* Set a safe default value in case 'next' does not get set */
+ next = textStart;
@@ -4915,5 +5267,5 @@ static enum XML_Error PTRCALL
errorProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
+ const char *UNUSED_P(s),
+ const char *UNUSED_P(end),
+ const char **UNUSED_P(nextPtr))
{
@@ -5333,2 +5685,3 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
if (MUST_CONVERT(enc, s)) {
+ enum XML_Convert_Result convert_res;
const char **eventPP;
@@ -5345,3 +5698,3 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = s;
@@ -5349,3 +5702,3 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
*eventPP = s;
- } while (s != end);
+ } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
}
@@ -5479,2 +5832,4 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
sizeof(PREFIX));
+ if (!id->prefix)
+ return NULL;
if (id->prefix->name == poolStart(&dtd->pool))
@@ -5826,3 +6181,2 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
if (!newE->defaultAtts) {
- ms->free_fcn(newE);
return 0;
@@ -5961,2 +6315,17 @@ keyeq(KEY s1, KEY s2)
+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
@@ -5964,6 +6333,10 @@ 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);
}
@@ -6152,4 +6525,4 @@ poolAppend(STRING_POOL *pool, const ENCODING *enc,
for (;;) {
- XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
- if (ptr == end)
+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
@@ -6210,2 +6583,31 @@ poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+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
@@ -6237,7 +6639,15 @@ poolGrow(STRING_POOL *pool)
if (pool->blocks && pool->start == pool->blocks->s) {
- int blockSize = (int)(pool->end - pool->start)*2;
- BLOCK *temp = (BLOCK *)
- pool->mem->realloc_fcn(pool->blocks,
- (offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char)));
+ 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, (unsigned)bytesToAllocate);
if (temp == NULL)
@@ -6253,8 +6663,22 @@ poolGrow(STRING_POOL *pool)
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)