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 |