diff --git a/SOURCES/expat-2.1.0-Add-missing-validation-of-encoding.patch b/SOURCES/expat-2.1.0-Add-missing-validation-of-encoding.patch
new file mode 100644
index 0000000..69f775a
--- /dev/null
+++ b/SOURCES/expat-2.1.0-Add-missing-validation-of-encoding.patch
@@ -0,0 +1,101 @@
+commit c8abeb6dbc14761866da2d3cf359d795f126b6d8
+Author: Tomas Korbar <tkorbar@redhat.com>
+Date:   Mon Mar 21 12:48:53 2022 +0100
+
+    Add missing validation of encoding
+
+diff --git a/lib/xmltok.c b/lib/xmltok.c
+index cb98ce1..a080f59 100644
+--- a/lib/xmltok.c
++++ b/lib/xmltok.c
+@@ -71,13 +71,6 @@
+                       + ((((byte)[2]) >> 5) & 1)] \
+          & (1 << (((byte)[2]) & 0x1F)))
+ 
+-#define UTF8_GET_NAMING(pages, p, n) \
+-  ((n) == 2 \
+-  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
+-  : ((n) == 3 \
+-     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
+-     : 0))
+-
+ /* Detection of invalid UTF-8 sequences is based on Table 3.1B
+    of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
+    with the additional restriction of not allowing the Unicode
+diff --git a/lib/xmltok_impl.c b/lib/xmltok_impl.c
+index c93e2ac..a135514 100644
+--- a/lib/xmltok_impl.c
++++ b/lib/xmltok_impl.c
+@@ -34,7 +34,7 @@
+    case BT_LEAD ## n: \
+      if (end - ptr < n) \
+        return XML_TOK_PARTIAL_CHAR; \
+-     if (!IS_NAME_CHAR(enc, ptr, n)) { \
++     if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NAME_CHAR(enc, ptr, n)) { \
+        *nextTokPtr = ptr; \
+        return XML_TOK_INVALID; \
+      } \
+@@ -62,7 +62,7 @@
+    case BT_LEAD ## n: \
+      if (end - ptr < n) \
+        return XML_TOK_PARTIAL_CHAR; \
+-     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
++     if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NMSTRT_CHAR(enc, ptr, n)) { \
+        *nextTokPtr = ptr; \
+        return XML_TOK_INVALID; \
+      } \
+@@ -1097,6 +1097,10 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
+   case BT_LEAD ## n: \
+     if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
++    if (IS_INVALID_CHAR(enc, ptr, n)) {                                        \
++      *nextTokPtr = ptr;                                                       \
++      return XML_TOK_INVALID;                                                  \
++    }                                                                          \
+     if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
+       ptr += n; \
+       tok = XML_TOK_NAME; \
+diff --git a/tests/runtests.c b/tests/runtests.c
+index 86f8b18..c01f096 100644
+--- a/tests/runtests.c
++++ b/tests/runtests.c
+@@ -14,6 +14,7 @@
+ #include <string.h>
+ #include <stdint.h>
+ #include <limits.h>
++#include <stdbool.h>
+ 
+ #include "expat.h"
+ #include "chardata.h"
+@@ -82,7 +83,7 @@ _xml_failure(XML_Parser parser, const char *file, int line)
+ 
+ static void
+ _expect_failure(char *text, enum XML_Error errorCode, char *errorMessage,
+-                char *file, int lineno)
++                const char *file, int lineno)
+ {
+     if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK)
+         /* Hackish use of _fail_unless() macro, but let's us report
+@@ -1541,6 +1542,13 @@ START_TEST(test_ns_separator_in_uri) {
+ }
+ END_TEST
+ 
++START_TEST(test_bad_doctype_utf8) {
++  char *text = "<!DOCTYPE \xDB\x25"
++                     "doc><doc/>"; // [1101 1011] [<0>010 0101]
++  expect_failure(text, XML_ERROR_INVALID_TOKEN,
++                 "Invalid UTF-8 in DOCTYPE not faulted");
++}
++END_TEST
+ 
+ START_TEST(test_utf8_in_start_tags) {
+   struct test_case {
+@@ -1695,6 +1703,8 @@ make_suite(void)
+     tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces);
+     tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls);
+     tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls);
++    tcase_add_test(tc_basic, test_utf8_in_start_tags);
++    tcase_add_test(tc_basic, test_bad_doctype_utf8);
+ 
+     suite_add_tcase(s, tc_namespace);
+     tcase_add_checked_fixture(tc_namespace,
diff --git a/SOURCES/expat-2.1.0-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch b/SOURCES/expat-2.1.0-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch
new file mode 100644
index 0000000..3cddd51
--- /dev/null
+++ b/SOURCES/expat-2.1.0-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch
@@ -0,0 +1,243 @@
+commit 513535dbf339c5c5dd38b77809c6a88969c05109
+Author: Tomas Korbar <tkorbar@redhat.com>
+Date:   Mon Feb 21 13:42:02 2022 +0100
+
+    CVE-2022-23852
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index 2ebd80f..d4f30b7 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -75,6 +75,9 @@ typedef char ICHAR;
+ /* Round up n to be a multiple of sz, where sz is a power of 2. */
+ #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+ 
++/* Do safe (NULL-aware) pointer arithmetic */
++#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
++
+ /* Handle the case where memmove() doesn't exist. */
+ #ifndef HAVE_MEMMOVE
+ #ifdef HAVE_BCOPY
+@@ -1678,50 +1681,70 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+ void * XMLCALL
+ XML_GetBuffer(XML_Parser parser, int len)
+ {
++  if (parser == NULL)
++    return NULL;
+   if (len < 0) {
+-    errorCode = XML_ERROR_NO_MEMORY;
++    parser->m_errorCode = XML_ERROR_NO_MEMORY;
+     return NULL;
+   }
+-  switch (ps_parsing) {
++  switch (parser->m_parsingStatus.parsing) {
+   case XML_SUSPENDED:
+-    errorCode = XML_ERROR_SUSPENDED;
++    parser->m_errorCode = XML_ERROR_SUSPENDED;
+     return NULL;
+   case XML_FINISHED:
+-    errorCode = XML_ERROR_FINISHED;
++    parser->m_errorCode = XML_ERROR_FINISHED;
+     return NULL;
+   default: ;
+   }
+ 
+-  if (len > bufferLim - bufferEnd) {
+-    int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));
++  if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
++    int keep;
++    /* Do not invoke signed arithmetic overflow: */
++    int neededSize = (int)((unsigned)len
++                           + (unsigned)EXPAT_SAFE_PTR_DIFF(
++                               parser->m_bufferEnd, parser->m_bufferPtr));
+     if (neededSize < 0) {
+-      errorCode = XML_ERROR_NO_MEMORY;
++      parser->m_errorCode = XML_ERROR_NO_MEMORY;
+       return NULL;
+     }
+-#ifdef XML_CONTEXT_BYTES
+-    int keep = (int)(bufferPtr - buffer);
+ 
++    keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
+     if (keep > XML_CONTEXT_BYTES)
+       keep = XML_CONTEXT_BYTES;
++    /* Detect and prevent integer overflow */
++    if (keep > INT_MAX - neededSize) {
++      parser->m_errorCode = XML_ERROR_NO_MEMORY;
++      return NULL;
++    }
+     neededSize += keep;
+-#endif  /* defined XML_CONTEXT_BYTES */
+-    if (neededSize  <= bufferLim - buffer) {
++    if (neededSize
++        <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
+ #ifdef XML_CONTEXT_BYTES
+-      if (keep < bufferPtr - buffer) {
+-        int offset = (int)(bufferPtr - buffer) - keep;
+-        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
+-        bufferEnd -= offset;
+-        bufferPtr -= offset;
++      if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
++        int offset
++            = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
++              - keep;
++        /* The buffer pointers cannot be NULL here; we have at least some bytes
++         * in the buffer */
++        memmove(parser->m_buffer, &parser->m_buffer[offset],
++                parser->m_bufferEnd - parser->m_bufferPtr + keep);
++        parser->m_bufferEnd -= offset;
++        parser->m_bufferPtr -= offset;
+       }
+ #else
+-      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
+-      bufferEnd = buffer + (bufferEnd - bufferPtr);
+-      bufferPtr = buffer;
+-#endif  /* not defined XML_CONTEXT_BYTES */
+-    }
+-    else {
++      if (parser->m_buffer && parser->m_bufferPtr) {
++        memmove(parser->m_buffer, parser->m_bufferPtr,
++                EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
++        parser->m_bufferEnd
++            = parser->m_buffer
++              + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
++        parser->m_bufferPtr = parser->m_buffer;
++      }
++#endif /* not defined XML_CONTEXT_BYTES */
++    } else {
+       char *newBuf;
+-      int bufferSize = (int)(bufferLim - bufferPtr);
++      int bufferSize
++          = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
+       if (bufferSize == 0)
+         bufferSize = INIT_BUFFER_SIZE;
+       do {
+@@ -1729,43 +1752,51 @@ XML_GetBuffer(XML_Parser parser, int len)
+         bufferSize = (int) (2U * (unsigned) bufferSize);
+       } while (bufferSize < neededSize && bufferSize > 0);
+       if (bufferSize <= 0) {
+-        errorCode = XML_ERROR_NO_MEMORY;
++        parser->m_errorCode = XML_ERROR_NO_MEMORY;
+         return NULL;
+       }
+       newBuf = (char *)MALLOC(bufferSize);
+       if (newBuf == 0) {
+-        errorCode = XML_ERROR_NO_MEMORY;
++        parser->m_errorCode = XML_ERROR_NO_MEMORY;
+         return NULL;
+       }
+-      bufferLim = newBuf + bufferSize;
++      parser->m_bufferLim = newBuf + bufferSize;
+ #ifdef XML_CONTEXT_BYTES
+-      if (bufferPtr) {
+-        int keep = (int)(bufferPtr - buffer);
+-        if (keep > XML_CONTEXT_BYTES)
+-          keep = XML_CONTEXT_BYTES;
+-        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
+-        FREE(buffer);
+-        buffer = newBuf;
+-        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
+-        bufferPtr = buffer + keep;
+-      }
+-      else {
+-        bufferEnd = newBuf + (bufferEnd - bufferPtr);
+-        bufferPtr = buffer = newBuf;
++      if (parser->m_bufferPtr) {
++        memcpy(newBuf, &parser->m_bufferPtr[-keep],
++               EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
++                   + keep);
++        FREE(parser->m_buffer);
++        parser->m_buffer = newBuf;
++        parser->m_bufferEnd
++            = parser->m_buffer
++              + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
++              + keep;
++        parser->m_bufferPtr = parser->m_buffer + keep;
++      } else {
++        /* This must be a brand new buffer with no data in it yet */
++        parser->m_bufferEnd = newBuf;
++        parser->m_bufferPtr = parser->m_buffer = newBuf;
+       }
+ #else
+-      if (bufferPtr) {
+-        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+-        FREE(buffer);
++      if (parser->m_bufferPtr) {
++        memcpy(newBuf, parser->m_bufferPtr,
++               EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
++        FREE(parser->m_buffer);
++        parser->m_bufferEnd
++            = newBuf
++              + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
++      } else {
++        /* This must be a brand new buffer with no data in it yet */
++        parser->m_bufferEnd = newBuf;
+       }
+-      bufferEnd = newBuf + (bufferEnd - bufferPtr);
+-      bufferPtr = buffer = newBuf;
++      parser->m_bufferPtr = parser->m_buffer = newBuf;
+ #endif  /* not defined XML_CONTEXT_BYTES */
+     }
+-    eventPtr = eventEndPtr = NULL;
+-    positionPtr = NULL;
++    parser->m_eventPtr = parser->m_eventEndPtr = NULL;
++    parser->m_positionPtr = NULL;
+   }
+-  return bufferEnd;
++  return parser->m_bufferEnd;
+ }
+ 
+ enum XML_Status XMLCALL
+diff --git a/tests/runtests.c b/tests/runtests.c
+index 233956e..b99e375 100644
+--- a/tests/runtests.c
++++ b/tests/runtests.c
+@@ -13,6 +13,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdint.h>
++#include <limits.h>
+ 
+ #include "expat.h"
+ #include "chardata.h"
+@@ -149,6 +150,30 @@ dummy_start_element(void *userData,
+ {}
+ 
+ 
++/* Test for signed integer overflow CVE-2022-23852 */
++#if defined(XML_CONTEXT_BYTES)
++START_TEST(test_get_buffer_3_overflow) {
++  XML_Parser parser = XML_ParserCreate(NULL);
++  assert(parser != NULL);
++
++  const char *const text = "\n";
++  const int expectedKeepValue = (int)strlen(text);
++
++  // After this call, variable "keep" in XML_GetBuffer will
++  // have value expectedKeepValue
++  if (XML_Parse(parser, text, (int)strlen(text), XML_FALSE /* isFinal */)
++      == XML_STATUS_ERROR)
++    xml_failure(parser);
++
++  assert(expectedKeepValue > 0);
++  if (XML_GetBuffer(parser, INT_MAX - expectedKeepValue + 1) != NULL)
++    fail("enlarging buffer not failed");
++
++  XML_ParserFree(parser);
++}
++END_TEST
++#endif // defined(XML_CONTEXT_BYTES)
++
+ /*
+  * Character & encoding tests.
+  */
+@@ -1483,6 +1508,9 @@ make_suite(void)
+ 
+     suite_add_tcase(s, tc_basic);
+     tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
++#if defined(XML_CONTEXT_BYTES)
++    tcase_add_test(tc_basic, test_get_buffer_3_overflow);
++#endif
+     tcase_add_test(tc_basic, test_nul_byte);
+     tcase_add_test(tc_basic, test_u0000_char);
+     tcase_add_test(tc_basic, test_bom_utf8);
diff --git a/SOURCES/expat-2.1.0-Detect-and-prevent-troublesome-left-shifts.patch b/SOURCES/expat-2.1.0-Detect-and-prevent-troublesome-left-shifts.patch
new file mode 100644
index 0000000..3439786
--- /dev/null
+++ b/SOURCES/expat-2.1.0-Detect-and-prevent-troublesome-left-shifts.patch
@@ -0,0 +1,62 @@
+commit 25f4e86a2b3e8d1e12c4fcd6ba0ef182e2d0a387
+Author: Tomas Korbar <tkorbar@redhat.com>
+Date:   Mon Feb 21 16:55:36 2022 +0100
+
+    CVE-2021-45960
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index d4f30b7..e743f78 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -2922,7 +2922,13 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
+   if (nPrefixes) {
+     int j;  /* hash table index */
+     unsigned long version = nsAttsVersion;
+-    int nsAttsSize = (int)1 << nsAttsPower;
++    /* Detect and prevent invalid shift */
++    if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) {
++      return XML_ERROR_NO_MEMORY;
++    }
++
++    unsigned int nsAttsSize = 1u << parser->m_nsAttsPower;
++    unsigned char oldNsAttsPower = parser->m_nsAttsPower;
+     /* size of hash table must be at least 2 * (# of prefixed attributes) */
+     if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
+       NS_ATT *temp;
+@@ -2930,10 +2936,34 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
+       while (nPrefixes >> nsAttsPower++);
+       if (nsAttsPower < 3)
+         nsAttsPower = 3;
+-      nsAttsSize = (int)1 << nsAttsPower;
++
++      /* Detect and prevent invalid shift */
++      if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) {
++        /* Restore actual size of memory in m_nsAtts */
++        parser->m_nsAttsPower = oldNsAttsPower;
++        return XML_ERROR_NO_MEMORY;
++      }
++
++      nsAttsSize = 1u << parser->m_nsAttsPower;
++
++      /* 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 (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) {
++        /* Restore actual size of memory in m_nsAtts */
++        parser->m_nsAttsPower = oldNsAttsPower;
++        return XML_ERROR_NO_MEMORY;
++      }
++#endif
++
+       temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
+-      if (!temp)
++      if (!temp) {
++        /* Restore actual size of memory in m_nsAtts */
++        parser->m_nsAttsPower = oldNsAttsPower;
+         return XML_ERROR_NO_MEMORY;
++      }
+       nsAtts = temp;
+       version = 0;  /* force re-initialization of nsAtts hash table */
+     }
diff --git a/SOURCES/expat-2.1.0-Prevent-integer-overflow-in-storeRawNames.patch b/SOURCES/expat-2.1.0-Prevent-integer-overflow-in-storeRawNames.patch
new file mode 100644
index 0000000..f337792
--- /dev/null
+++ b/SOURCES/expat-2.1.0-Prevent-integer-overflow-in-storeRawNames.patch
@@ -0,0 +1,31 @@
+commit 1b57efe37fd4ef80058b05415a2a0e6b8eaab565
+Author: Tomas Korbar <tkorbar@redhat.com>
+Date:   Mon Mar 21 12:51:17 2022 +0100
+
+    Prevent integer overflow in storeRawNames
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index 4bfb860..989ab8c 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -2099,6 +2099,7 @@ storeRawNames(XML_Parser parser)
+   while (tag) {
+     int bufSize;
+     int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
++    size_t rawNameLen;
+     char *rawNameBuf = tag->buf + nameLen;
+     /* Stop if already stored.  Since tagStack is a stack, we can stop
+        at the first entry that has already been copied; everything
+@@ -2110,7 +2111,11 @@ storeRawNames(XML_Parser parser)
+     /* For re-use purposes we need to ensure that the
+        size of tag->buf is a multiple of sizeof(XML_Char).
+     */
+-    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
++    rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
++    /* Detect and prevent integer overflow. */
++    if (rawNameLen > (size_t)INT_MAX - nameLen)
++      return XML_FALSE;
++    bufSize = nameLen + (int)rawNameLen;
+     if (bufSize > tag->bufEnd - tag->buf) {
+       char *temp = (char *)REALLOC(tag->buf, bufSize);
+       if (temp == NULL)
diff --git a/SOURCES/expat-2.1.0-Prevent-integer-overflow-on-m_groupSize-in-function.patch b/SOURCES/expat-2.1.0-Prevent-integer-overflow-on-m_groupSize-in-function.patch
new file mode 100644
index 0000000..79c2358
--- /dev/null
+++ b/SOURCES/expat-2.1.0-Prevent-integer-overflow-on-m_groupSize-in-function.patch
@@ -0,0 +1,36 @@
+commit 9939d60f01ff598134628ea64b9b65d4b84209ce
+Author: Tomas Korbar <tkorbar@redhat.com>
+Date:   Mon Feb 21 17:09:17 2022 +0100
+
+    CVE-2021-46143
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index e743f78..1371f61 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -4501,11 +4501,25 @@ doProlog(XML_Parser parser,
+     case XML_ROLE_GROUP_OPEN:
+       if (prologState.level >= groupSize) {
+         if (groupSize) {
++          /* Detect and prevent integer overflow */
++          if (parser->m_groupSize > (unsigned int)(-1) / 2u) {
++            return XML_ERROR_NO_MEMORY;
++          }
++
+           char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
+           if (temp == NULL)
+             return XML_ERROR_NO_MEMORY;
+           groupConnector = temp;
+           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 *temp = (int *)REALLOC(dtd->scaffIndex,
+                           groupSize * sizeof(int));
+             if (temp == NULL)
diff --git a/SOURCES/expat-2.1.0-Prevent-more-integer-overflows.patch b/SOURCES/expat-2.1.0-Prevent-more-integer-overflows.patch
new file mode 100644
index 0000000..6a04665
--- /dev/null
+++ b/SOURCES/expat-2.1.0-Prevent-more-integer-overflows.patch
@@ -0,0 +1,237 @@
+commit c98f9d35bdd6e4536e8b82898d241a9c99c543f8
+Author: Tomas Korbar <tkorbar@redhat.com>
+Date:   Mon Feb 21 17:27:38 2022 +0100
+
+    CVE-2022-22822 to CVE-2022-22827
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index 1371f61..87d1a98 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -2772,18 +2772,54 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
+ 
+   /* get the attributes from the tokenizer */
+   n = XmlGetAttributes(enc, attStr, attsSize, atts);
++
++  /* Detect and prevent integer overflow */
++  if (n > INT_MAX - nDefaultAtts) {
++    return XML_ERROR_NO_MEMORY;
++  }
++
+   if (n + nDefaultAtts > attsSize) {
+     int oldAttsSize = attsSize;
+     ATTRIBUTE *temp;
+ #ifdef XML_ATTR_INFO
+     XML_AttrInfo *temp2;
+ #endif
++
++    /* Detect and prevent integer overflow */
++    if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
++        || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
++      return XML_ERROR_NO_MEMORY;
++    }
++
+     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
++
++    /* 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 ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
++      parser->m_attsSize = oldAttsSize;
++      return XML_ERROR_NO_MEMORY;
++    }
++#endif
++
+     temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
+     if (temp == NULL)
+       return XML_ERROR_NO_MEMORY;
+     atts = temp;
+ #ifdef XML_ATTR_INFO
++    /* 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 ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) {
++      parser->m_attsSize = oldAttsSize;
++      return XML_ERROR_NO_MEMORY;
++    }
++#  endif
++
+     temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
+     if (temp2 == NULL)
+       return XML_ERROR_NO_MEMORY;
+@@ -3089,9 +3125,30 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
+   tagNamePtr->prefixLen = prefixLen;
+   for (i = 0; localPart[i++];)
+     ;  /* i includes null terminator */
++
++  /* Detect and prevent integer overflow */
++  if (binding->uriLen > INT_MAX - prefixLen
++      || i > INT_MAX - (binding->uriLen + prefixLen)) {
++    return XML_ERROR_NO_MEMORY;
++  }
++
+   n = i + binding->uriLen + prefixLen;
+   if (n > binding->uriAlloc) {
+     TAG *p;
++    /* Detect and prevent integer overflow */
++    if (n > INT_MAX - EXPAND_SPARE) {
++      return XML_ERROR_NO_MEMORY;
++    }
++    /* 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 ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
++      return XML_ERROR_NO_MEMORY;
++    }
++#endif
++
+     uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
+     if (!uri)
+       return XML_ERROR_NO_MEMORY;
+@@ -3192,6 +3249,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+   if (freeBindingList) {
+     b = freeBindingList;
+     if (len > b->uriAlloc) {
++      /* Detect and prevent integer overflow */
++      if (len > INT_MAX - EXPAND_SPARE) {
++        return XML_ERROR_NO_MEMORY;
++      }
++
++      /* 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 ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
++        return XML_ERROR_NO_MEMORY;
++      }
++#endif
++
+       XML_Char *temp = (XML_Char *)REALLOC(b->uri,
+                           sizeof(XML_Char) * (len + EXPAND_SPARE));
+       if (temp == NULL)
+@@ -3205,6 +3277,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+     b = (BINDING *)MALLOC(sizeof(BINDING));
+     if (!b)
+       return XML_ERROR_NO_MEMORY;
++
++    /* Detect and prevent integer overflow */
++    if (len > INT_MAX - EXPAND_SPARE) {
++      return XML_ERROR_NO_MEMORY;
++    }
++    /* 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 ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
++      return XML_ERROR_NO_MEMORY;
++    }
++#endif
++
+     b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
+     if (!b->uri) {
+       FREE(b);
+@@ -5471,7 +5558,24 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
+     }
+     else {
+       DEFAULT_ATTRIBUTE *temp;
++
++      /* Detect and prevent integer overflow */
++      if (type->allocDefaultAtts > INT_MAX / 2) {
++        return 0;
++      }
++
+       int count = type->allocDefaultAtts * 2;
++
++      /* 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 ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) {
++        return 0;
++      }
++#endif
++
+       temp = (DEFAULT_ATTRIBUTE *)
+         REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
+       if (temp == NULL)
+@@ -6098,8 +6202,20 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
+     /* check for overflow (table is half full) */
+     if (table->used >> (table->power - 1)) {
+       unsigned char newPower = table->power + 1;
++
++      /* Detect and prevent invalid shift */
++      if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) {
++        return NULL;
++      }
++
+       size_t newSize = (size_t)1 << newPower;
+       unsigned long newMask = (unsigned long)newSize - 1;
++
++      /* Detect and prevent integer overflow */
++      if (newSize > (size_t)(-1) / sizeof(NAMED *)) {
++        return NULL;
++      }
++
+       size_t tsize = newSize * sizeof(NAMED *);
+       NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
+       if (!newV)
+@@ -6390,6 +6506,20 @@ nextScaffoldPart(XML_Parser parser)
+   if (dtd->scaffCount >= dtd->scaffSize) {
+     CONTENT_SCAFFOLD *temp;
+     if (dtd->scaffold) {
++      /* Detect and prevent integer overflow */
++      if (dtd->scaffSize > UINT_MAX / 2u) {
++        return -1;
++      }
++      /* 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 (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) {
++        return -1;
++      }
++#endif
++
+       temp = (CONTENT_SCAFFOLD *)
+         REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
+       if (temp == NULL)
+@@ -6466,9 +6596,27 @@ build_model (XML_Parser parser)
+   XML_Content *ret;
+   XML_Content *cpos;
+   XML_Char * str;
+-  int allocsize = (dtd->scaffCount * sizeof(XML_Content)
+-                   + (dtd->contentStringLen * sizeof(XML_Char)));
+ 
++  /* 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 (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) {
++    return NULL;
++  }
++  if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) {
++    return NULL;
++  }
++#endif
++  if (dtd->scaffCount * sizeof(XML_Content)
++      > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) {
++    return NULL;
++  }
++
++  const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content)
++                            + (dtd->contentStringLen * sizeof(XML_Char)));
++ 
+   ret = (XML_Content *)MALLOC(allocsize);
+   if (!ret)
+     return NULL;
diff --git a/SOURCES/expat-2.1.0-Protect-against-malicious-namespace-declarations.patch b/SOURCES/expat-2.1.0-Protect-against-malicious-namespace-declarations.patch
new file mode 100644
index 0000000..1a989e5
--- /dev/null
+++ b/SOURCES/expat-2.1.0-Protect-against-malicious-namespace-declarations.patch
@@ -0,0 +1,354 @@
+commit f9ba0addb8e60cb72f8a8524fb4379d741cd4e7d
+Author: Tomas Korbar <tkorbar@redhat.com>
+Date:   Mon Mar 21 12:42:50 2022 +0100
+
+    Protect against malicious namespace declarations
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index 87d1a98..4bfb860 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -679,8 +679,7 @@ XML_ParserCreate(const XML_Char *encodingName)
+ XML_Parser XMLCALL
+ XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+ {
+-  XML_Char tmp[2];
+-  *tmp = nsSep;
++  XML_Char tmp[2] = {nsSep, 0};
+   return XML_ParserCreate_MM(encodingName, NULL, tmp);
+ }
+ 
+@@ -1044,8 +1043,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser,
+      would be otherwise.
+   */
+   if (ns) {
+-    XML_Char tmp[2];
+-    *tmp = namespaceSeparator;
++    XML_Char tmp[2] = {parser->m_namespaceSeparator, 0};
+     parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
+   }
+   else {
+@@ -3173,6 +3171,117 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
+   return XML_ERROR_NONE;
+ }
+ 
++static XML_Bool
++is_rfc3986_uri_char(XML_Char candidate) {
++  // For the RFC 3986 ANBF grammar see
++  // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A
++
++  switch (candidate) {
++  // From rule "ALPHA" (uppercase half)
++  case 'A':
++  case 'B':
++  case 'C':
++  case 'D':
++  case 'E':
++  case 'F':
++  case 'G':
++  case 'H':
++  case 'I':
++  case 'J':
++  case 'K':
++  case 'L':
++  case 'M':
++  case 'N':
++  case 'O':
++  case 'P':
++  case 'Q':
++  case 'R':
++  case 'S':
++  case 'T':
++  case 'U':
++  case 'V':
++  case 'W':
++  case 'X':
++  case 'Y':
++  case 'Z':
++
++  // From rule "ALPHA" (lowercase half)
++  case 'a':
++  case 'b':
++  case 'c':
++  case 'd':
++  case 'e':
++  case 'f':
++  case 'g':
++  case 'h':
++  case 'i':
++  case 'j':
++  case 'k':
++  case 'l':
++  case 'm':
++  case 'n':
++  case 'o':
++  case 'p':
++  case 'q':
++  case 'r':
++  case 's':
++  case 't':
++  case 'u':
++  case 'v':
++  case 'w':
++  case 'x':
++  case 'y':
++  case 'z':
++
++  // From rule "DIGIT"
++  case '0':
++  case '1':
++  case '2':
++  case '3':
++  case '4':
++  case '5':
++  case '6':
++  case '7':
++  case '8':
++  case '9':
++
++  // From rule "pct-encoded"
++  case '%':
++
++  // From rule "unreserved"
++  case '-':
++  case '.':
++  case '_':
++  case '~':
++
++  // From rule "gen-delims"
++  case ':':
++  case '/':
++  case '?':
++  case '#':
++  case '[':
++  case ']':
++  case '@':
++
++  // From rule "sub-delims"
++  case '!':
++  case '$':
++  case '&':
++  case '\'':
++  case '(':
++  case ')':
++  case '*':
++  case '+':
++  case ',':
++  case ';':
++  case '=':
++    return XML_TRUE;
++
++  default:
++    return XML_FALSE;
++  }
++}
++
+ /* addBinding() overwrites the value of prefix->binding without checking.
+    Therefore one must keep track of the old value outside of addBinding().
+ */
+@@ -3233,6 +3342,29 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+     if (!mustBeXML && isXMLNS
+         && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
+       isXMLNS = XML_FALSE;
++
++    // NOTE: While Expat does not validate namespace URIs against RFC 3986
++    //       today (and is not REQUIRED to do so with regard to the XML 1.0
++    //       namespaces specification) we have to at least make sure, that
++    //       the application on top of Expat (that is likely splitting expanded
++    //       element names ("qualified names") of form
++    //       "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces
++    //       in its element handler code) cannot be confused by an attacker
++    //       putting additional namespace separator characters into namespace
++    //       declarations.  That would be ambiguous and not to be expected.
++    //
++    //       While the HTML API docs of function XML_ParserCreateNS have been
++    //       advising against use of a namespace separator character that can
++    //       appear in a URI for >20 years now, some widespread applications
++    //       are using URI characters (':' (colon) in particular) for a
++    //       namespace separator, in practice.  To keep these applications
++    //       functional, we only reject namespaces URIs containing the
++    //       application-chosen namespace separator if the chosen separator
++    //       is a non-URI character with regard to RFC 3986.
++    if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)
++        && ! is_rfc3986_uri_char(uri[len])) {
++      return XML_ERROR_SYNTAX;
++    }
+   }
+   isXML = isXML && len == xmlLen;
+   isXMLNS = isXMLNS && len == xmlnsLen;
+diff --git a/tests/runtests.c b/tests/runtests.c
+index b99e375..86f8b18 100644
+--- a/tests/runtests.c
++++ b/tests/runtests.c
+@@ -31,6 +31,13 @@
+ 
+ static XML_Parser parser;
+ 
++#ifndef UNUSED_P
++# ifdef __GNUC__
++#  define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
++# else
++#  define UNUSED_P(p) UNUSED_ ## p
++# endif
++#endif
+ 
+ static void
+ basic_setup(void)
+@@ -40,6 +47,10 @@ basic_setup(void)
+         fail("Parser not created.");
+ }
+ 
++static void
++dummy_end_element(void *UNUSED_P(userData), const XML_Char *UNUSED_P(name))
++{}
++
+ static void
+ basic_teardown(void)
+ {
+@@ -1499,6 +1510,138 @@ START_TEST(test_ns_unbound_prefix_on_element)
+ }
+ END_TEST
+ 
++START_TEST(test_ns_separator_in_uri) {
++  struct test_case {
++    enum XML_Status expectedStatus;
++    const char *doc;
++    XML_Char namesep;
++  };
++  struct test_case cases[] = {
++      {XML_STATUS_OK, "<doc xmlns='one_two' />", '\n'},
++      {XML_STATUS_ERROR, "<doc xmlns='one&#x0A;two' />", '\n'},
++      {XML_STATUS_OK, "<doc xmlns='one:two' />", ':'},
++  };
++
++  size_t i = 0;
++  size_t failCount = 0;
++  for (; i < sizeof(cases) / sizeof(cases[0]); i++) {
++    XML_Parser parser = XML_ParserCreateNS(NULL, cases[i].namesep);
++    XML_SetElementHandler(parser, dummy_start_element, dummy_end_element);
++    if (XML_Parse(parser, cases[i].doc, (int)strlen(cases[i].doc),
++                  /*isFinal*/ XML_TRUE)
++        != cases[i].expectedStatus) {
++      failCount++;
++    }
++    XML_ParserFree(parser);
++  }
++
++  if (failCount) {
++    fail("Namespace separator handling is broken");
++  }
++}
++END_TEST
++
++
++START_TEST(test_utf8_in_start_tags) {
++  struct test_case {
++    bool goodName;
++    bool goodNameStart;
++    const char *tagName;
++  };
++
++  // The idea with the tests below is this:
++  // We want to cover 1-, 2- and 3-byte sequences, 4-byte sequences
++  // go to isNever and are hence not a concern.
++  //
++  // We start with a character that is a valid name character
++  // (or even name-start character, see XML 1.0r4 spec) and then we flip
++  // single bits at places where (1) the result leaves the UTF-8 encoding space
++  // and (2) we stay in the same n-byte sequence family.
++  //
++  // The flipped bits are highlighted in angle brackets in comments,
++  // e.g. "[<1>011 1001]" means we had [0011 1001] but we now flipped
++  // the most significant bit to 1 to leave UTF-8 encoding space.
++  struct test_case cases[] = {
++      // 1-byte UTF-8: [0xxx xxxx]
++      {true, true, "\x3A"},   // [0011 1010] = ASCII colon ':'
++      {false, false, "\xBA"}, // [<1>011 1010]
++      {true, false, "\x39"},  // [0011 1001] = ASCII nine '9'
++      {false, false, "\xB9"}, // [<1>011 1001]
++
++      // 2-byte UTF-8: [110x xxxx] [10xx xxxx]
++      {true, true, "\xDB\xA5"},   // [1101 1011] [1010 0101] =
++                                  // Arabic small waw U+06E5
++      {false, false, "\x9B\xA5"}, // [1<0>01 1011] [1010 0101]
++      {false, false, "\xDB\x25"}, // [1101 1011] [<0>010 0101]
++      {false, false, "\xDB\xE5"}, // [1101 1011] [1<1>10 0101]
++      {true, false, "\xCC\x81"},  // [1100 1100] [1000 0001] =
++                                  // combining char U+0301
++      {false, false, "\x8C\x81"}, // [1<0>00 1100] [1000 0001]
++      {false, false, "\xCC\x01"}, // [1100 1100] [<0>000 0001]
++      {false, false, "\xCC\xC1"}, // [1100 1100] [1<1>00 0001]
++
++      // 3-byte UTF-8: [1110 xxxx] [10xx xxxx] [10xxxxxx]
++      {true, true, "\xE0\xA4\x85"},   // [1110 0000] [1010 0100] [1000 0101] =
++                                      // Devanagari Letter A U+0905
++      {false, false, "\xA0\xA4\x85"}, // [1<0>10 0000] [1010 0100] [1000 0101]
++      {false, false, "\xE0\x24\x85"}, // [1110 0000] [<0>010 0100] [1000 0101]
++      {false, false, "\xE0\xE4\x85"}, // [1110 0000] [1<1>10 0100] [1000 0101]
++      {false, false, "\xE0\xA4\x05"}, // [1110 0000] [1010 0100] [<0>000 0101]
++      {false, false, "\xE0\xA4\xC5"}, // [1110 0000] [1010 0100] [1<1>00 0101]
++      {true, false, "\xE0\xA4\x81"},  // [1110 0000] [1010 0100] [1000 0001] =
++                                      // combining char U+0901
++      {false, false, "\xA0\xA4\x81"}, // [1<0>10 0000] [1010 0100] [1000 0001]
++      {false, false, "\xE0\x24\x81"}, // [1110 0000] [<0>010 0100] [1000 0001]
++      {false, false, "\xE0\xE4\x81"}, // [1110 0000] [1<1>10 0100] [1000 0001]
++      {false, false, "\xE0\xA4\x01"}, // [1110 0000] [1010 0100] [<0>000 0001]
++      {false, false, "\xE0\xA4\xC1"}, // [1110 0000] [1010 0100] [1<1>00 0001]
++  };
++  const bool atNameStart[] = {true, false};
++
++  size_t i = 0;
++  char doc[1024];
++  size_t failCount = 0;
++
++  for (; i < sizeof(cases) / sizeof(cases[0]); i++) {
++    size_t j = 0;
++    for (; j < sizeof(atNameStart) / sizeof(atNameStart[0]); j++) {
++      const bool expectedSuccess
++          = atNameStart[j] ? cases[i].goodNameStart : cases[i].goodName;
++      sprintf(doc, "<%s%s><!--", atNameStart[j] ? "" : "a", cases[i].tagName);
++      XML_Parser parser = XML_ParserCreate(NULL);
++
++      const enum XML_Status status
++          = XML_Parse(parser, doc, (int)strlen(doc), /*isFinal=*/XML_FALSE);
++
++      bool success = true;
++      if ((status == XML_STATUS_OK) != expectedSuccess) {
++        success = false;
++      }
++      if ((status == XML_STATUS_ERROR)
++          && (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)) {
++        success = false;
++      }
++
++      if (! success) {
++        fprintf(
++            stderr,
++            "FAIL case %2u (%sat name start, %u-byte sequence, error code %d)\n",
++            (unsigned)i + 1u, atNameStart[j] ? "    " : "not ",
++            (unsigned)strlen(cases[i].tagName), XML_GetErrorCode(parser));
++        failCount++;
++      }
++
++      XML_ParserFree(parser);
++    
++  }
++
++  if (failCount > 0) {
++    fail("UTF-8 regression detected");
++  }
++}
++}
++END_TEST
++
+ static Suite *
+ make_suite(void)
+ {
+@@ -1569,6 +1712,7 @@ make_suite(void)
+     tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
+     tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
+     tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
++    tcase_add_test(tc_namespace, test_ns_separator_in_uri);
+ 
+ #ifdef XML_DTD
+     tcase_add_test(tc_basic,
diff --git a/SPECS/expat.spec b/SPECS/expat.spec
index fa09adc..f2f860e 100644
--- a/SPECS/expat.spec
+++ b/SPECS/expat.spec
@@ -1,7 +1,7 @@
 Summary: An XML parser library
 Name: expat
 Version: 2.1.0
-Release: 12%{?dist}
+Release: 14%{?dist}
 Group: System Environment/Libraries
 Source: http://downloads.sourceforge.net/expat/expat-%{version}.tar.gz
 Patch0: expat-2.1.0-xmlwfargs.patch
@@ -9,6 +9,14 @@ Patch1: expat-2.1.0-CVE-2016-0718.patch
 Patch2: expat-2.1.0-CVE-2015-2716.patch
 Patch3: expat-2.1.0-CVE-2018-20843.patch
 Patch4: expat-2.1.0-CVE-2019-15903.patch
+Patch5:	expat-2.1.0-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch
+Patch6:	expat-2.1.0-Detect-and-prevent-troublesome-left-shifts.patch
+Patch7:	expat-2.1.0-Prevent-integer-overflow-on-m_groupSize-in-function.patch
+Patch8:	expat-2.1.0-Prevent-more-integer-overflows.patch
+Patch9: expat-2.1.0-Protect-against-malicious-namespace-declarations.patch
+Patch10: expat-2.1.0-Add-missing-validation-of-encoding.patch
+Patch11: expat-2.1.0-Prevent-integer-overflow-in-storeRawNames.patch
+
 URL: http://www.libexpat.org/
 License: MIT
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -47,6 +55,13 @@ Install it if you need to link statically with expat.
 %patch2 -p1 -b .cve2716
 %patch3 -p1 -b .cve20843
 %patch4 -p1 -b .cve15903
+%patch5 -p1 -b .CVE-2022-23852
+%patch6 -p1 -b .CVE-2021-45960
+%patch7 -p1 -b .CVE-2021-46143
+%patch8 -p1 -b .CVE-2022-22822-CVE-2022-22827
+%patch9 -p1 -b .CVE-2022-25236
+%patch10 -p1 -b .CVE-2022-25235
+%patch11 -p1 -b .CVE-2022-25315
 
 %build
 rm -rf autom4te*.cache
@@ -93,6 +108,36 @@ rm -rf ${RPM_BUILD_ROOT}
 %{_libdir}/lib*.a
 
 %changelog
+* Mon Mar 21 2022 Tomas Korbar <tkorbar@redhat.com> - 2.1.0-14
+- Fix multiple CVEs
+- CVE-2022-25236 expat: namespace-separator characters in "xmlns[:prefix]" attribute values can lead to arbitrary code execution
+- CVE-2022-25235 expat: malformed 2- and 3-byte UTF-8 sequences can lead to arbitrary code execution
+- CVE-2022-25315 expat: integer overflow in storeRawNames()
+- Resolves: CVE-2022-25236
+- Resolves: CVE-2022-25235
+- Resolves: CVE-2022-25315
+
+* Mon Feb 21 2022 Tomas Korbar <tkorbar@redhat.com> - 2.1.0-13
+- Fix multiple CVEs
+- CVE-2022-23852 expat: integer overflow in function XML_GetBuffer
+- CVE-2021-45960 expat: Large number of prefixed XML attributes on a single tag can crash libexpat
+- CVE-2021-46143 expat: Integer overflow in doProlog in xmlparse.c
+- CVE-2022-22827 Integer overflow in storeAtts in xmlparse.c
+- CVE-2022-22826 Integer overflow in nextScaffoldPart in xmlparse.c
+- CVE-2022-22825 Integer overflow in lookup in xmlparse.c
+- CVE-2022-22824 Integer overflow in defineAttribute in xmlparse.c
+- CVE-2022-22823 Integer overflow in build_model in xmlparse.c
+- CVE-2022-22822 Integer overflow in addBinding in xmlparse.c
+- Resolves: CVE-2022-23852
+- Resolves: CVE-2021-45960
+- Resolves: CVE-2021-46143
+- Resolves: CVE-2022-22827
+- Resolves: CVE-2022-22826
+- Resolves: CVE-2022-22825
+- Resolves: CVE-2022-22824
+- Resolves: CVE-2022-22823
+- Resolves: CVE-2022-22822 
+
 * Thu Apr  2 2020 Joe Orton <jorton@redhat.com> - 2.1.0-12
 - add security fixes for CVE-2018-20843, CVE-2019-15903