bpo-29591: Upgrade Modules/expat to libexpat 2.2 (#2164)
* bpo-29591: Upgrade Modules/expat to libexpat 2.2
* bpo-29591: Restore Python changes on expat
* bpo-29591: Remove expat config of unsupported platforms
Remove the configuration (Modules/expat/*config.h) of unsupported
platforms:
* Amiga
* MacOS Classic on PPC32
* Open Watcom
* bpo-29591: Remove useless XML_HAS_SET_HASH_SALT
The XML_HAS_SET_HASH_SALT define of Modules/expat/expat.h became
useless since our local expat copy was upgrade to expat 2.1 (it's now
expat 2.2.0).
diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c
index 4128387..b308e67 100644
--- a/Modules/expat/xmlparse.c
+++ b/Modules/expat/xmlparse.c
@@ -2,9 +2,22 @@
See the file COPYING for copying permission.
*/
+#include <stddef.h>
+#include <string.h> /* memset(), memcpy() */
+#include <assert.h>
+#include <limits.h> /* UINT_MAX */
+
+#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"
@@ -14,13 +27,7 @@
#include "watcomconfig.h"
#elif defined(HAVE_EXPAT_CONFIG_H)
#include <expat_config.h>
-#endif /* ndef COMPILED_FROM_DSP */
-
-#include <stddef.h>
-#include <string.h> /* memset(), memcpy() */
-#include <assert.h>
-#include <limits.h> /* UINT_MAX */
-#include <time.h> /* time() */
+#endif /* ndef WIN32 */
#include "ascii.h"
#include "expat.h"
@@ -432,7 +439,7 @@
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 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 @@
{
/* 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
@@ -1695,15 +1729,15 @@
if (len > bufferLim - bufferEnd) {
#ifdef XML_CONTEXT_BYTES
int keep;
-#endif
- int neededSize = len + (int)(bufferEnd - bufferPtr);
+#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;
@@ -1728,7 +1762,8 @@
if (bufferSize == 0)
bufferSize = INIT_BUFFER_SIZE;
do {
- bufferSize *= 2;
+ /* Do not invoke signed arithmetic overflow: */
+ bufferSize = (int) (2U * (unsigned) bufferSize);
} while (bufferSize < neededSize && bufferSize > 0);
if (bufferSize <= 0) {
errorCode = XML_ERROR_NO_MEMORY;
@@ -1855,7 +1890,7 @@
XML_GetCurrentByteIndex(XML_Parser parser)
{
if (eventPtr)
- return parseEndByteIndex - (parseEndPtr - eventPtr);
+ return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
return -1;
}
@@ -2429,11 +2464,11 @@
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;
}
@@ -2654,11 +2689,11 @@
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;
}
@@ -3264,11 +3299,11 @@
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;
}
@@ -4927,9 +4962,9 @@
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;
}
@@ -5345,6 +5380,7 @@
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) {
@@ -5357,11 +5393,11 @@
}
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));
@@ -6166,8 +6202,8 @@
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;
@@ -6251,8 +6287,13 @@
}
}
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)));
@@ -6267,6 +6308,10 @@
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