Merge pull request #538 from libexpat/issue-532-integer-overflow

[CVE-2021-46143] lib: Prevent integer overflow on m_groupSize in function doProlog (fixes #532)
diff --git a/expat/Changes b/expat/Changes
index 4d4de0b..98d4f53 100644
--- a/expat/Changes
+++ b/expat/Changes
@@ -16,6 +16,10 @@
                     where XML_ParserCreateNS is used to create the parser
                     (which needs argument "-n" when running xmlwf).
                     Impact is denial of service, or more.
+       #532 #538  CVE-2021-46143 (ZDI-CAN-16157) -- Fix integer overflow
+                    on variable m_groupSize in function doProlog leading
+                    to realloc acting as free.
+                    Impact is denial of service or more.
 
         Other changes:
             #535  CMake: Make call to file(GENERATE [..]) work for CMake <3.19
@@ -27,11 +31,13 @@
             #536  CI: Check for realistic minimum CMake version
 
         Special thanks to:
+            An anonymous whitehat
             Christopher Degawa
             J. Peter Mugaas
             Tyson Smith
                  and
             GCC Farm Project
+            Trend Micro Zero Day Initiative
 
 Release 2.4.2 Sun December 19 2021
         Other changes:
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
index b47c31b..8f24312 100644
--- a/expat/lib/xmlparse.c
+++ b/expat/lib/xmlparse.c
@@ -5046,6 +5046,11 @@
       if (parser->m_prologState.level >= parser->m_groupSize) {
         if (parser->m_groupSize) {
           {
+            /* Detect and prevent integer overflow */
+            if (parser->m_groupSize > (unsigned int)(-1) / 2u) {
+              return XML_ERROR_NO_MEMORY;
+            }
+
             char *const new_connector = (char *)REALLOC(
                 parser, parser->m_groupConnector, parser->m_groupSize *= 2);
             if (new_connector == NULL) {
@@ -5056,6 +5061,16 @@
           }
 
           if (dtd->scaffIndex) {
+            /* Detect and prevent integer overflow.
+             * The preprocessor guard addresses the "always false" warning
+             * from -Wtype-limits on platforms where
+             * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+            if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) {
+              return XML_ERROR_NO_MEMORY;
+            }
+#endif
+
             int *const new_scaff_index = (int *)REALLOC(
                 parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
             if (new_scaff_index == NULL)