| Index: third_party/expat/files/lib/xmlparse.c
|
| diff --git a/third_party/expat/files/lib/xmlparse.c b/third_party/expat/files/lib/xmlparse.c
|
| index ede7b5bb6673eed3fecbe83056da3a906cdafe41..72b39fced490333df0d0213d51918d31654bbec0 100644
|
| --- a/third_party/expat/files/lib/xmlparse.c
|
| +++ b/third_party/expat/files/lib/xmlparse.c
|
| @@ -6,11 +6,18 @@
|
| #include <string.h> /* memset(), memcpy() */
|
| #include <assert.h>
|
| #include <limits.h> /* UINT_MAX */
|
| -#include <time.h> /* time() */
|
| +
|
| +#ifdef WIN32
|
| +#define getpid GetCurrentProcessId
|
| +#else
|
| +#include <sys/time.h> /* gettimeofday() */
|
| +#include <sys/types.h> /* getpid() */
|
| +#include <unistd.h> /* getpid() */
|
| +#endif
|
|
|
| #define XML_BUILDING_EXPAT 1
|
|
|
| -#ifdef COMPILED_FROM_DSP
|
| +#ifdef WIN32
|
| #include "winconfig.h"
|
| #elif defined(MACOS_CLASSIC)
|
| #include "macconfig.h"
|
| @@ -20,7 +27,7 @@
|
| #include "watcomconfig.h"
|
| #elif defined(HAVE_EXPAT_CONFIG_H)
|
| #include <expat_config.h>
|
| -#endif /* ndef COMPILED_FROM_DSP */
|
| +#endif /* ndef WIN32 */
|
|
|
| #include "ascii.h"
|
| #include "expat.h"
|
| @@ -432,7 +439,7 @@ static ELEMENT_TYPE *
|
| getElementType(XML_Parser parser, const ENCODING *enc,
|
| const char *ptr, const char *end);
|
|
|
| -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);
|
|
|
| static XML_Parser
|
| @@ -691,11 +698,50 @@ static const XML_Char implicitContext[] = {
|
| };
|
|
|
| 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);
|
| + (void)gettimeofday_res;
|
| +
|
| + /* Microseconds time is <20 bits entropy */
|
| + return tv.tv_usec;
|
| +#endif
|
| +}
|
| +
|
| +static unsigned long
|
| +generate_hash_secret_salt(XML_Parser parser)
|
| +{
|
| +#if defined(__UINTPTR_TYPE__)
|
| +# define PARSER_CAST(p) (__UINTPTR_TYPE__)(p)
|
| +#elif defined(_WIN64) && defined(_MSC_VER)
|
| +# define PARSER_CAST(p) (unsigned __int64)(p)
|
| +#else
|
| +# define PARSER_CAST(p) (p)
|
| +#endif
|
| +
|
| + /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
|
| + unsigned long small_factory = 2147483647ul;
|
| + unsigned long long big_factory = 2305843009213693951ull;
|
| +
|
| + /* 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_CAST(parser);
|
| +
|
| + if (sizeof(unsigned long) == 4) {
|
| + return entropy * small_factory;
|
| + } else {
|
| + return entropy * (unsigned long)big_factory;
|
| + }
|
| }
|
|
|
| static XML_Bool /* only valid for root parser */
|
| @@ -703,7 +749,7 @@ startParsing(XML_Parser parser)
|
| {
|
| /* hash functions must be initialized before setContext() is called */
|
| if (hash_secret_salt == 0)
|
| - hash_secret_salt = generate_hash_secret_salt();
|
| + hash_secret_salt = generate_hash_secret_salt(parser);
|
| if (ns) {
|
| /* implicit context only set for root parser, since child
|
| parsers (i.e. external entity parsers) will inherit it
|
| @@ -1550,7 +1596,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
|
| else if (bufferPtr == bufferEnd) {
|
| const char *end;
|
| int nLeftOver;
|
| - enum XML_Error result;
|
| + enum XML_Status result;
|
| parseEndByteIndex += len;
|
| positionPtr = s;
|
| ps_finalBuffer = (XML_Bool)isFinal;
|
| @@ -1678,12 +1724,10 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
|
| void * XMLCALL
|
| XML_GetBuffer(XML_Parser parser, int len)
|
| {
|
| -/* BEGIN MOZILLA CHANGE (sanity check len) */
|
| if (len < 0) {
|
| errorCode = XML_ERROR_NO_MEMORY;
|
| return NULL;
|
| }
|
| -/* END MOZILLA CHANGE */
|
| switch (ps_parsing) {
|
| case XML_SUSPENDED:
|
| errorCode = XML_ERROR_SUSPENDED;
|
| @@ -1695,16 +1739,17 @@ XML_GetBuffer(XML_Parser parser, int len)
|
| }
|
|
|
| if (len > bufferLim - bufferEnd) {
|
| - int neededSize = len + (int)(bufferEnd - bufferPtr);
|
| -/* BEGIN MOZILLA CHANGE (sanity check neededSize) */
|
| +#ifdef XML_CONTEXT_BYTES
|
| + 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;
|
| }
|
| -/* END MOZILLA CHANGE */
|
| #ifdef XML_CONTEXT_BYTES
|
| - int keep = (int)(bufferPtr - buffer);
|
| -
|
| + keep = (int)(bufferPtr - buffer);
|
| if (keep > XML_CONTEXT_BYTES)
|
| keep = XML_CONTEXT_BYTES;
|
| neededSize += keep;
|
| @@ -1729,16 +1774,13 @@ XML_GetBuffer(XML_Parser parser, int len)
|
| if (bufferSize == 0)
|
| bufferSize = INIT_BUFFER_SIZE;
|
| do {
|
| - bufferSize *= 2;
|
| -/* BEGIN MOZILLA CHANGE (prevent infinite loop on overflow) */
|
| + /* Do not invoke signed arithmetic overflow: */
|
| + bufferSize = (int) (2U * (unsigned) bufferSize);
|
| } while (bufferSize < neededSize && bufferSize > 0);
|
| -/* END MOZILLA CHANGE */
|
| -/* BEGIN MOZILLA CHANGE (sanity check bufferSize) */
|
| if (bufferSize <= 0) {
|
| errorCode = XML_ERROR_NO_MEMORY;
|
| return NULL;
|
| }
|
| -/* END MOZILLA CHANGE */
|
| newBuf = (char *)MALLOC(bufferSize);
|
| if (newBuf == 0) {
|
| errorCode = XML_ERROR_NO_MEMORY;
|
| @@ -1860,7 +1902,7 @@ XML_Index XMLCALL
|
| XML_GetCurrentByteIndex(XML_Parser parser)
|
| {
|
| if (eventPtr)
|
| - return parseEndByteIndex - (parseEndPtr - eventPtr);
|
| + return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
|
| return -1;
|
| }
|
|
|
| @@ -2434,11 +2476,11 @@ doContent(XML_Parser parser,
|
| for (;;) {
|
| int bufSize;
|
| int convLen;
|
| - XmlConvert(enc,
|
| + const enum XML_Convert_Result convert_res = XmlConvert(enc,
|
| &fromPtr, rawNameEnd,
|
| (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
|
| convLen = (int)(toPtr - (XML_Char *)tag->buf);
|
| - if (fromPtr == rawNameEnd) {
|
| + if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
|
| tag->name.strLen = convLen;
|
| break;
|
| }
|
| @@ -2659,11 +2701,11 @@ doContent(XML_Parser parser,
|
| if (MUST_CONVERT(enc, s)) {
|
| for (;;) {
|
| 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;
|
| charDataHandler(handlerArg, dataBuf,
|
| (int)(dataPtr - (ICHAR *)dataBuf));
|
| - if (s == next)
|
| + if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
|
| break;
|
| *eventPP = s;
|
| }
|
| @@ -2930,6 +2972,8 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
|
| unsigned long uriHash = hash_secret_salt;
|
| ((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;
|
| @@ -3267,11 +3311,11 @@ doCdataSection(XML_Parser parser,
|
| if (MUST_CONVERT(enc, s)) {
|
| for (;;) {
|
| 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;
|
| charDataHandler(handlerArg, dataBuf,
|
| (int)(dataPtr - (ICHAR *)dataBuf));
|
| - if (s == next)
|
| + if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
|
| break;
|
| *eventPP = s;
|
| }
|
| @@ -4930,9 +4974,9 @@ internalEntityProcessor(XML_Parser parser,
|
|
|
| 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))
|
| {
|
| return errorCode;
|
| }
|
| @@ -5348,6 +5392,7 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
|
| const char *s, const char *end)
|
| {
|
| if (MUST_CONVERT(enc, s)) {
|
| + enum XML_Convert_Result convert_res;
|
| const char **eventPP;
|
| const char **eventEndPP;
|
| if (enc == encoding) {
|
| @@ -5360,11 +5405,11 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
|
| }
|
| do {
|
| ICHAR *dataPtr = (ICHAR *)dataBuf;
|
| - XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
|
| + convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
|
| *eventEndPP = s;
|
| defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
|
| *eventPP = s;
|
| - } while (s != end);
|
| + } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
|
| }
|
| else
|
| defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
|
| @@ -5494,6 +5539,8 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
|
| return NULL;
|
| id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
|
| sizeof(PREFIX));
|
| + if (!id->prefix)
|
| + return NULL;
|
| if (id->prefix->name == poolStart(&dtd->pool))
|
| poolFinish(&dtd->pool);
|
| else
|
| @@ -5841,7 +5888,6 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
|
| newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
|
| ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
|
| if (!newE->defaultAtts) {
|
| - ms->free_fcn(newE);
|
| return 0;
|
| }
|
| }
|
| @@ -6167,8 +6213,8 @@ poolAppend(STRING_POOL *pool, const ENCODING *enc,
|
| if (!pool->ptr && !poolGrow(pool))
|
| return NULL;
|
| 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;
|
| if (!poolGrow(pool))
|
| return NULL;
|
| @@ -6252,8 +6298,13 @@ poolGrow(STRING_POOL *pool)
|
| }
|
| }
|
| if (pool->blocks && pool->start == pool->blocks->s) {
|
| - int blockSize = (int)(pool->end - pool->start)*2;
|
| - BLOCK *temp = (BLOCK *)
|
| + BLOCK *temp;
|
| + int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
|
| +
|
| + if (blockSize < 0)
|
| + return XML_FALSE;
|
| +
|
| + temp = (BLOCK *)
|
| pool->mem->realloc_fcn(pool->blocks,
|
| (offsetof(BLOCK, s)
|
| + blockSize * sizeof(XML_Char)));
|
| @@ -6268,6 +6319,10 @@ poolGrow(STRING_POOL *pool)
|
| else {
|
| BLOCK *tem;
|
| int blockSize = (int)(pool->end - pool->start);
|
| +
|
| + if (blockSize < 0)
|
| + return XML_FALSE;
|
| +
|
| if (blockSize < INIT_BLOCK_SIZE)
|
| blockSize = INIT_BLOCK_SIZE;
|
| else
|
|
|