Index: third_party/expat/files/lib/xmlparse.c.original |
diff --git a/third_party/expat/files/lib/xmlparse.c.original b/third_party/expat/files/lib/xmlparse.c.original |
index f35aa36ba8a7fce3bae90f31b20354435b15d2f2..b308e67e2d390d244df194ac0eaca949b91c0462 100644 |
--- a/third_party/expat/files/lib/xmlparse.c.original |
+++ b/third_party/expat/files/lib/xmlparse.c.original |
@@ -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,38 @@ 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); |
+ |
+ /* Microseconds time is <20 bits entropy */ |
+ return tv.tv_usec; |
+#endif |
+} |
+ |
+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; |
+ |
+ /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ |
+ if (sizeof(unsigned long) == 4) { |
+ return entropy * 2147483647; |
+ } else { |
+ return entropy * (unsigned long)2305843009213693951; |
+ } |
} |
static XML_Bool /* only valid for root parser */ |
@@ -703,7 +737,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 +1584,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,6 +1712,10 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) |
void * XMLCALL |
XML_GetBuffer(XML_Parser parser, int len) |
{ |
+ if (len < 0) { |
+ errorCode = XML_ERROR_NO_MEMORY; |
+ return NULL; |
+ } |
switch (ps_parsing) { |
case XML_SUSPENDED: |
errorCode = XML_ERROR_SUSPENDED; |
@@ -1689,11 +1727,17 @@ 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) |
keep = XML_CONTEXT_BYTES; |
neededSize += keep; |
@@ -1718,8 +1762,13 @@ XML_GetBuffer(XML_Parser parser, int len) |
if (bufferSize == 0) |
bufferSize = INIT_BUFFER_SIZE; |
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); |
if (newBuf == 0) { |
errorCode = XML_ERROR_NO_MEMORY; |
@@ -1841,7 +1890,7 @@ XML_Index XMLCALL |
XML_GetCurrentByteIndex(XML_Parser parser) |
{ |
if (eventPtr) |
- return parseEndByteIndex - (parseEndPtr - eventPtr); |
+ return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr)); |
return -1; |
} |
@@ -2415,11 +2464,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 ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { |
tag->name.strLen = convLen; |
break; |
} |
@@ -2640,11 +2689,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; |
} |
@@ -2911,6 +2960,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; |
@@ -3248,11 +3299,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; |
} |
@@ -4911,9 +4962,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; |
} |
@@ -5329,6 +5380,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) { |
@@ -5341,11 +5393,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)); |
@@ -5475,6 +5527,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 |
@@ -6148,8 +6202,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; |
@@ -6233,8 +6287,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))); |
@@ -6249,6 +6308,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 |