From 2651e43deb827007f3c671d9e2a057947b2bb2ea Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 14 May 2025 19:02:40 +0000 Subject: [PATCH] import UBI expat-2.7.1-1.el10_0 --- .expat.metadata | 1 - .gitignore | 2 +- 3176EF7DB2367F1FCA4F306B1F9B0E909AF37285 | 233 +++ ...5-Add-missing-validation-of-encoding.patch | 200 --- SOURCES/expat-2.2.5-CVE-2018-20843.patch | 15 - SOURCES/expat-2.2.5-CVE-2019-15903.patch | 171 -- SOURCES/expat-2.2.5-CVE-2022-43680.patch | 89 - SOURCES/expat-2.2.5-CVE-2023-52425.patch | 1440 --------------- SOURCES/expat-2.2.5-CVE-2024-45490.patch | 129 -- SOURCES/expat-2.2.5-CVE-2024-45491.patch | 29 - SOURCES/expat-2.2.5-CVE-2024-45492.patch | 28 - SOURCES/expat-2.2.5-CVE-2024-50602.patch | 108 -- SOURCES/expat-2.2.5-CVE-2024-8176.patch | 1595 ----------------- ...nt-integer-overflow-in-XML_GetBuffer.patch | 183 -- ...-and-prevent-troublesome-left-shifts.patch | 54 - ...re-safe-exiting-internalEntityParser.patch | 118 -- ...event-integer-overflow-in-copyString.patch | 19 - ...nt-integer-overflow-in-storeRawNames.patch | 31 - ...-overflow-on-m_groupSize-in-function.patch | 38 - ...2.2.5-Prevent-more-integer-overflows.patch | 238 --- ...vent-stack-exhaustion-in-build_model.patch | 228 --- ...nst-malicious-namespace-declarations.patch | 229 --- SOURCES/expat-2.2.5-doc2man.patch | 26 - SPECS/expat.spec | 430 ----- expat-2.7.1.tar.gz.asc | 16 + expat.spec | 485 +++++ sources | 1 + 27 files changed, 736 insertions(+), 5400 deletions(-) delete mode 100644 .expat.metadata create mode 100644 3176EF7DB2367F1FCA4F306B1F9B0E909AF37285 delete mode 100644 SOURCES/expat-2.2.5-Add-missing-validation-of-encoding.patch delete mode 100644 SOURCES/expat-2.2.5-CVE-2018-20843.patch delete mode 100644 SOURCES/expat-2.2.5-CVE-2019-15903.patch delete mode 100644 SOURCES/expat-2.2.5-CVE-2022-43680.patch delete mode 100644 SOURCES/expat-2.2.5-CVE-2023-52425.patch delete mode 100644 SOURCES/expat-2.2.5-CVE-2024-45490.patch delete mode 100644 SOURCES/expat-2.2.5-CVE-2024-45491.patch delete mode 100644 SOURCES/expat-2.2.5-CVE-2024-45492.patch delete mode 100644 SOURCES/expat-2.2.5-CVE-2024-50602.patch delete mode 100644 SOURCES/expat-2.2.5-CVE-2024-8176.patch delete mode 100644 SOURCES/expat-2.2.5-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch delete mode 100644 SOURCES/expat-2.2.5-Detect-and-prevent-troublesome-left-shifts.patch delete mode 100644 SOURCES/expat-2.2.5-Ensure-raw-tagnames-are-safe-exiting-internalEntityParser.patch delete mode 100644 SOURCES/expat-2.2.5-Prevent-integer-overflow-in-copyString.patch delete mode 100644 SOURCES/expat-2.2.5-Prevent-integer-overflow-in-storeRawNames.patch delete mode 100644 SOURCES/expat-2.2.5-Prevent-integer-overflow-on-m_groupSize-in-function.patch delete mode 100644 SOURCES/expat-2.2.5-Prevent-more-integer-overflows.patch delete mode 100644 SOURCES/expat-2.2.5-Prevent-stack-exhaustion-in-build_model.patch delete mode 100644 SOURCES/expat-2.2.5-Protect-against-malicious-namespace-declarations.patch delete mode 100644 SOURCES/expat-2.2.5-doc2man.patch delete mode 100644 SPECS/expat.spec create mode 100644 expat-2.7.1.tar.gz.asc create mode 100644 expat.spec create mode 100644 sources diff --git a/.expat.metadata b/.expat.metadata deleted file mode 100644 index e69ad7b..0000000 --- a/.expat.metadata +++ /dev/null @@ -1 +0,0 @@ -fa46ccce6770ccae767c28f6ac55e2428089d4a0 SOURCES/expat-2.2.5.tar.gz diff --git a/.gitignore b/.gitignore index 2d47f87..3270d6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/expat-2.2.5.tar.gz +expat-2.7.1.tar.gz diff --git a/3176EF7DB2367F1FCA4F306B1F9B0E909AF37285 b/3176EF7DB2367F1FCA4F306B1F9B0E909AF37285 new file mode 100644 index 0000000..0328cdb --- /dev/null +++ b/3176EF7DB2367F1FCA4F306B1F9B0E909AF37285 @@ -0,0 +1,233 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: 3176 EF7D B236 7F1F CA4F 306B 1F9B 0E90 9AF3 7285 +Comment: Sebastian Pipping + +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 +=gYkV +-----END PGP PUBLIC KEY BLOCK----- diff --git a/SOURCES/expat-2.2.5-Add-missing-validation-of-encoding.patch b/SOURCES/expat-2.2.5-Add-missing-validation-of-encoding.patch deleted file mode 100644 index 8876367..0000000 --- a/SOURCES/expat-2.2.5-Add-missing-validation-of-encoding.patch +++ /dev/null @@ -1,200 +0,0 @@ -commit e8f285b522a907603501329e5b4212755f525fdf -Author: Tomas Korbar -Date: Thu Mar 3 12:04:09 2022 +0100 - - CVE-2022-25235 - -diff --git a/lib/xmltok.c b/lib/xmltok.c -index 6b415d8..b55732a 100644 ---- a/lib/xmltok.c -+++ b/lib/xmltok.c -@@ -103,13 +103,6 @@ - + ((((byte)[2]) >> 5) & 1)] \ - & (1u << (((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 0403dd3..56d7a40 100644 ---- a/lib/xmltok_impl.c -+++ b/lib/xmltok_impl.c -@@ -61,7 +61,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; \ - } \ -@@ -89,7 +89,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; \ - } \ -@@ -1117,6 +1117,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 278bfa1..0f3afde 100644 ---- a/tests/runtests.c -+++ b/tests/runtests.c -@@ -6540,6 +6540,106 @@ START_TEST(test_utf8_in_cdata_section_2) - } - 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>"}, // long comment, used to be O(N²) -+ {"<", "/>"}, // big elem name, used to be O(N²) -+ }; -+ const int num_cases = sizeof(text) / sizeof(text[0]); -+ // For the test we need a value that is: -+ // (1) big enough that the test passes reliably (avoiding flaky tests), and -+ // (2) small enough that the test actually catches regressions. -+ const int max_slowdown = 15; -+ char aaaaaa[4096]; -+ const int fillsize = (int)sizeof(aaaaaa); -+ const int fillcount = 100; -+ -+ memset(aaaaaa, 'a', fillsize); -+ -+ if (! g_reparseDeferralEnabledDefault) { -+ return; // heuristic is disabled; we would get O(n^2) and fail. -+ } -+#if defined(_WIN32) -+ if (CLOCKS_PER_SEC < 100000) { -+ // Skip this test if clock() doesn't have reasonably good resolution. -+ // This workaround is only applied to Windows targets, since XSI requires -+ // the value to be 1 000 000 (10x the condition here), and we want to be -+ // very sure that at least one platform in CI can catch regressions. -+ return; -+ } -+#endif -+ -+ clock_t baseline = 0; -+ for (int i = 0; i < num_cases; ++i) { -+ XML_Parser parser = XML_ParserCreate(NULL); -+ assert_true(parser != NULL); -+ enum XML_Status status; -+ const clock_t start = clock(); -+ -+ // parse the start text -+ status = _XML_Parse_SINGLE_BYTES(parser, text[i].pre, -+ (int)strlen(text[i].pre), XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ // parse lots of 'a', failing the test early if it takes too long -+ for (int f = 0; f < fillcount; ++f) { -+ status = _XML_Parse_SINGLE_BYTES(parser, aaaaaa, fillsize, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ // i == 0 means we're still calculating the baseline value -+ if (i > 0) { -+ const clock_t now = clock(); -+ const clock_t clocks_so_far = now - start; -+ const int slowdown = clocks_so_far / baseline; -+ if (slowdown >= max_slowdown) { -+ fprintf( -+ stderr, -+ "fill#%d: clocks_so_far=%d baseline=%d slowdown=%d max_slowdown=%d\n", -+ f, (int)clocks_so_far, (int)baseline, slowdown, max_slowdown); -+ fail(too_slow_failure_message); -+ } -+ } -+ } -+ // parse the end text -+ status = _XML_Parse_SINGLE_BYTES(parser, text[i].post, -+ (int)strlen(text[i].post), XML_TRUE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ -+ // how long did it take in total? -+ const clock_t end = clock(); -+ const clock_t taken = end - start; -+ if (i == 0) { -+ assert_true(taken > 0); // just to make sure we don't div-by-0 later -+ baseline = taken; -+ } -+ const int slowdown = taken / baseline; -+ if (slowdown >= max_slowdown) { -+ fprintf(stderr, "taken=%d baseline=%d slowdown=%d max_slowdown=%d\n", -+ (int)taken, (int)baseline, slowdown, max_slowdown); -+ fail(too_slow_failure_message); -+ } -+ -+ XML_ParserFree(parser); -+ } -+} -+END_TEST -+ -+START_TEST(test_set_reparse_deferral) { -+ const char *const pre = ""; -+ const char *const start = ""; -+ char eeeeee[100]; -+ const int fillsize = (int)sizeof(eeeeee); -+ memset(eeeeee, 'e', fillsize); -+ -+ for (int enabled = 0; enabled <= 1; enabled += 1) { -+ -+ XML_Parser parser = XML_ParserCreate(NULL); -+ assert_true(parser != NULL); -+ assert_true(XML_SetReparseDeferralEnabled(parser, enabled)); -+ // pre-grow the buffer to avoid reparsing due to almost-fullness -+ assert_true(XML_GetBuffer(parser, fillsize * 10103) != NULL); -+ -+ CharData storage; -+ CharData_Init(&storage); -+ XML_SetUserData(parser, &storage); -+ XML_SetStartElementHandler(parser, start_element_event_handler); -+ -+ enum XML_Status status; -+ // parse the start text -+ status = XML_Parse(parser, pre, (int)strlen(pre), XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ CharData_CheckXMLChars(&storage, XCS("d")); // first element should be done -+ -+ // ..and the start of the token -+ status = XML_Parse(parser, start, (int)strlen(start), XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ CharData_CheckXMLChars(&storage, XCS("d")); // still just the first one -+ -+ // try to parse lots of 'e', but the token isn't finished -+ for (int c = 0; c < 100; ++c) { -+ status = XML_Parse(parser, eeeeee, fillsize, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ } -+ CharData_CheckXMLChars(&storage, XCS("d")); // *still* just the first one -+ -+ // end the token. -+ status = XML_Parse(parser, end, (int)strlen(end), XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ -+ if (enabled) { -+ // In general, we may need to push more data to trigger a reparse attempt, -+ // but in this test, the data is constructed to always require it. -+ CharData_CheckXMLChars(&storage, XCS("d")); // or the test is incorrect -+ // 2x the token length should suffice; the +1 covers the start and end. -+ for (int c = 0; c < 101; ++c) { -+ status = XML_Parse(parser, eeeeee, fillsize, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ } -+ } -+ CharData_CheckXMLChars(&storage, XCS("dx")); // the should be done -+ -+ XML_ParserFree(parser); -+ } -+} -+END_TEST -+ -+struct element_decl_data { -+ XML_Parser parser; -+ int count; -+}; -+ -+static void -+element_decl_counter(void *userData, const XML_Char *UNUSED_P(name), XML_Content *model) { -+ struct element_decl_data *testdata = (struct element_decl_data *)userData; -+ testdata->count += 1; -+ XML_FreeContentModel(testdata->parser, model); -+} -+ -+static int -+external_inherited_parser(XML_Parser p, const XML_Char *context, -+ const XML_Char *UNUSED_P(base), const XML_Char *UNUSED_P(systemId), -+ const XML_Char *UNUSED_P(publicId)) { -+ const char *const pre = "\n"; -+ const char *const start = "\n"; -+ const char *const post = "\n"; -+ const int enabled = *(int *)XML_GetUserData(p); -+ char eeeeee[100]; -+ char spaces[100]; -+ const int fillsize = (int)sizeof(eeeeee); -+ assert_true(fillsize == (int)sizeof(spaces)); -+ memset(eeeeee, 'e', fillsize); -+ memset(spaces, ' ', fillsize); -+ -+ XML_Parser parser = XML_ExternalEntityParserCreate(p, context, NULL); -+ assert_true(parser != NULL); -+ // pre-grow the buffer to avoid reparsing due to almost-fullness -+ assert_true(XML_GetBuffer(parser, fillsize * 10103) != NULL); -+ -+ struct element_decl_data testdata; -+ testdata.parser = parser; -+ testdata.count = 0; -+ XML_SetUserData(parser, &testdata); -+ XML_SetElementDeclHandler(parser, element_decl_counter); -+ -+ enum XML_Status status; -+ // parse the initial text -+ status = XML_Parse(parser, pre, (int)strlen(pre), XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ assert_true(testdata.count == 1); // first element should be done -+ -+ // ..and the start of the big token -+ status = XML_Parse(parser, start, (int)strlen(start), XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ assert_true(testdata.count == 1); // still just the first one -+ -+ // try to parse lots of 'e', but the token isn't finished -+ for (int c = 0; c < 100; ++c) { -+ status = XML_Parse(parser, eeeeee, fillsize, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ } -+ assert_true(testdata.count == 1); // *still* just the first one -+ -+ // end the big token. -+ status = XML_Parse(parser, end, (int)strlen(end), XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ -+ if (enabled) { -+ // In general, we may need to push more data to trigger a reparse attempt, -+ // but in this test, the data is constructed to always require it. -+ assert_true(testdata.count == 1); // or the test is incorrect -+ // 2x the token length should suffice; the +1 covers the start and end. -+ for (int c = 0; c < 101; ++c) { -+ status = XML_Parse(parser, spaces, fillsize, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ } -+ } -+ assert_true(testdata.count == 2); // the big token should be done -+ -+ // parse the final text -+ status = XML_Parse(parser, post, (int)strlen(post), XML_TRUE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ assert_true(testdata.count == 3); // after isFinal=XML_TRUE, all must be done -+ -+ XML_ParserFree(parser); -+ return XML_STATUS_OK; -+} -+ -+START_TEST(test_reparse_deferral_is_inherited) { -+ const char *const text -+ = ""; -+ for (int enabled = 0; enabled <= 1; ++enabled) { -+ -+ XML_Parser parser = XML_ParserCreate(NULL); -+ assert_true(parser != NULL); -+ XML_SetUserData(parser, (void *)&enabled); -+ XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS); -+ // this handler creates a sub-parser and checks that its deferral behavior -+ // is what we expected, based on the value of `enabled` (in userdata). -+ XML_SetExternalEntityRefHandler(parser, external_inherited_parser); -+ assert_true(XML_SetReparseDeferralEnabled(parser, enabled)); -+ if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_OK) -+ xml_failure(parser); -+ -+ XML_ParserFree(parser); -+ } -+} -+END_TEST -+ -+START_TEST(test_set_reparse_deferral_on_null_parser) { -+ assert_true(XML_SetReparseDeferralEnabled(NULL, 0) == XML_FALSE); -+ assert_true(XML_SetReparseDeferralEnabled(NULL, 1) == XML_FALSE); -+ assert_true(XML_SetReparseDeferralEnabled(NULL, 10) == XML_FALSE); -+ assert_true(XML_SetReparseDeferralEnabled(NULL, 100) == XML_FALSE); -+ assert_true(XML_SetReparseDeferralEnabled(NULL, (XML_Bool)INT_MIN) -+ == XML_FALSE); -+ assert_true(XML_SetReparseDeferralEnabled(NULL, (XML_Bool)INT_MAX) -+ == XML_FALSE); -+} -+END_TEST -+ -+START_TEST(test_set_reparse_deferral_on_the_fly) { -+ const char *const pre = ""; -+ char iiiiii[100]; -+ const int fillsize = (int)sizeof(iiiiii); -+ memset(iiiiii, 'i', fillsize); -+ -+ XML_Parser parser = XML_ParserCreate(NULL); -+ assert_true(parser != NULL); -+ assert_true(XML_SetReparseDeferralEnabled(parser, XML_TRUE)); -+ -+ CharData storage; -+ CharData_Init(&storage); -+ XML_SetUserData(parser, &storage); -+ XML_SetStartElementHandler(parser, start_element_event_handler); -+ -+ enum XML_Status status; -+ // parse the start text -+ status = XML_Parse(parser, pre, (int)strlen(pre), XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ CharData_CheckXMLChars(&storage, XCS("d")); // first element should be done -+ -+ // try to parse some 'i', but the token isn't finished -+ status = XML_Parse(parser, iiiiii, fillsize, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ CharData_CheckXMLChars(&storage, XCS("d")); // *still* just the first one -+ -+ // end the token. -+ status = XML_Parse(parser, end, (int)strlen(end), XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ CharData_CheckXMLChars(&storage, XCS("d")); // not yet. -+ -+ // now change the heuristic setting and add *no* data -+ assert_true(XML_SetReparseDeferralEnabled(parser, XML_FALSE)); -+ // we avoid isFinal=XML_TRUE, because that would force-bypass the heuristic. -+ status = XML_Parse(parser, "", 0, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ CharData_CheckXMLChars(&storage, XCS("dx")); -+ -+ XML_ParserFree(parser); -+} -+END_TEST -+ -+START_TEST(test_set_bad_reparse_option) { -+ XML_Parser parser = XML_ParserCreate(NULL); -+ assert_true(XML_FALSE == XML_SetReparseDeferralEnabled(parser, 2)); -+ assert_true(XML_FALSE == XML_SetReparseDeferralEnabled(parser, 3)); -+ assert_true(XML_FALSE == XML_SetReparseDeferralEnabled(parser, 99)); -+ assert_true(XML_FALSE == XML_SetReparseDeferralEnabled(parser, 127)); -+ assert_true(XML_FALSE == XML_SetReparseDeferralEnabled(parser, 128)); -+ assert_true(XML_FALSE == XML_SetReparseDeferralEnabled(parser, 129)); -+ assert_true(XML_FALSE == XML_SetReparseDeferralEnabled(parser, 255)); -+ assert_true(XML_TRUE == XML_SetReparseDeferralEnabled(parser, 0)); -+ assert_true(XML_TRUE == XML_SetReparseDeferralEnabled(parser, 1)); -+ XML_ParserFree(parser); -+} -+END_TEST -+ -+static size_t g_totalAlloc = 0; -+static size_t g_biggestAlloc = 0; -+ -+static void * -+counting_realloc(void *ptr, size_t size) { -+ g_totalAlloc += size; -+ if (size > g_biggestAlloc) { -+ g_biggestAlloc = size; -+ } -+ return realloc(ptr, size); -+} -+ -+static void * -+counting_malloc(size_t size) { -+ return counting_realloc(NULL, size); -+} -+ -+START_TEST(test_bypass_heuristic_when_close_to_bufsize) { -+ if (! g_reparseDeferralEnabledDefault) { -+ return; // this test is irrelevant when the deferral heuristic is disabled. -+ } -+ -+ const int document_length = 65536; -+ char *const document = (char *)malloc(document_length); -+ -+ const XML_Memory_Handling_Suite memfuncs = { -+ counting_malloc, -+ counting_realloc, -+ free, -+ }; -+ -+ const int leading_list[] = {0, 3, 61, 96, 400, 401, 4000, 4010, 4099, -1}; -+ const int bigtoken_list[] = {3000, 4000, 4001, 4096, 4099, 5000, 20000, -1}; -+ const int fillsize_list[] = {131, 256, 399, 400, 401, 1025, 4099, 4321, -1}; -+ -+ for (const int *leading = leading_list; *leading >= 0; leading++) { -+ for (const int *bigtoken = bigtoken_list; *bigtoken >= 0; bigtoken++) { -+ for (const int *fillsize = fillsize_list; *fillsize >= 0; fillsize++) { -+ // start by checking that the test looks reasonably valid -+ assert_true(*leading + *bigtoken <= document_length); -+ -+ // put 'x' everywhere; some will be overwritten by elements. -+ memset(document, 'x', document_length); -+ // maybe add an initial tag -+ if (*leading) { -+ assert_true(*leading >= 3); // or the test case is invalid -+ memcpy(document, "", 3); -+ } -+ // add the large token -+ document[*leading + 0] = '<'; -+ document[*leading + 1] = 'b'; -+ memset(&document[*leading + 2], ' ', *bigtoken - 2); // a spacy token -+ document[*leading + *bigtoken - 1] = '>'; -+ -+ // 1 for 'b', plus 1 or 0 depending on the presence of 'a' -+ const int expected_elem_total = 1 + (*leading ? 1 : 0); -+ -+ XML_Parser parser = XML_ParserCreate_MM(NULL, &memfuncs, NULL); -+ assert_true(parser != NULL); -+ -+ CharData storage; -+ CharData_Init(&storage); -+ XML_SetUserData(parser, &storage); -+ XML_SetStartElementHandler(parser, start_element_event_handler); -+ -+ g_biggestAlloc = 0; -+ g_totalAlloc = 0; -+ int offset = 0; -+ // fill data until the big token is covered (but not necessarily parsed) -+ while (offset < *leading + *bigtoken) { -+ assert_true(offset + *fillsize <= document_length); -+ const enum XML_Status status -+ = XML_Parse(parser, &document[offset], *fillsize, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ offset += *fillsize; -+ } -+ // Now, check that we've had a buffer allocation that could fit the -+ // context bytes and our big token. In order to detect a special case, -+ // we need to know how many bytes of our big token were included in the -+ // first push that contained _any_ bytes of the big token: -+ const int bigtok_first_chunk_bytes = *fillsize - (*leading % *fillsize); -+ if (bigtok_first_chunk_bytes >= *bigtoken && XML_CONTEXT_BYTES == 0) { -+ // Special case: we aren't saving any context, and the whole big token -+ // was covered by a single fill, so Expat may have parsed directly -+ // from our input pointer, without allocating an internal buffer. -+ } else if (*leading < XML_CONTEXT_BYTES) { -+ assert_true(g_biggestAlloc >= *leading + (size_t)*bigtoken); -+ } else { -+ assert_true(g_biggestAlloc >= XML_CONTEXT_BYTES + (size_t)*bigtoken); -+ } -+ // fill data until the big token is actually parsed -+ while (storage.count < expected_elem_total) { -+ const size_t alloc_before = g_totalAlloc; -+ assert_true(offset + *fillsize <= document_length); -+ const enum XML_Status status -+ = XML_Parse(parser, &document[offset], *fillsize, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ offset += *fillsize; -+ // since all the bytes of the big token are already in the buffer, -+ // the bufsize ceiling should make us finish its parsing without any -+ // further buffer allocations. We assume that there will be no other -+ // large allocations in this test. -+ assert_true(g_totalAlloc - alloc_before < 4096); -+ } -+ // test-the-test: was our alloc even called? -+ assert_true(g_totalAlloc > 0); -+ // test-the-test: there shouldn't be any extra start elements -+ assert_true(storage.count == expected_elem_total); -+ -+ XML_ParserFree(parser); -+ } -+ } -+ } -+ free(document); -+} -+END_TEST -+ -+START_TEST(test_varying_buffer_fills) { -+ const int KiB = 1024; -+ const int MiB = 1024 * KiB; -+ const int document_length = 16 * MiB; -+ const int big = 7654321; // arbitrarily chosen between 4 and 8 MiB -+ -+ char *const document = (char *)malloc(document_length); -+ assert_true(document != NULL); -+ memset(document, 'x', document_length); -+ document[0] = '<'; -+ document[1] = 't'; -+ memset(&document[2], ' ', big - 2); // a very spacy token -+ document[big - 1] = '>'; -+ -+ // Each testcase is a list of buffer fill sizes, terminated by a value < 0. -+ // When reparse deferral is enabled, the final (negated) value is the expected -+ // maximum number of bytes scanned in parse attempts. -+ const int testcases[][30] = { -+ {8 * MiB, -8 * MiB}, -+ {4 * MiB, 4 * MiB, -12 * MiB}, // try at 4MB, then 8MB = 12 MB total -+ // zero-size fills shouldn't trigger the bypass -+ {4 * MiB, 0, 4 * MiB, -12 * MiB}, -+ {4 * MiB, 0, 0, 4 * MiB, -12 * MiB}, -+ {4 * MiB, 0, 1 * MiB, 0, 3 * MiB, -12 * MiB}, -+ // try to hit the buffer ceiling only once (at the end) -+ {4 * MiB, 2 * MiB, 1 * MiB, 512 * KiB, 256 * KiB, 256 * KiB, -12 * MiB}, -+ // try to hit the same buffer ceiling multiple times -+ {4 * MiB + 1, 2 * MiB, 1 * MiB, 512 * KiB, -25 * MiB}, -+ -+ // try to hit every ceiling, by always landing 1K shy of the buffer size -+ {1 * KiB, 2 * KiB, 4 * KiB, 8 * KiB, 16 * KiB, 32 * KiB, 64 * KiB, -+ 128 * KiB, 256 * KiB, 512 * KiB, 1 * MiB, 2 * MiB, 4 * MiB, -16 * MiB}, -+ -+ // try to avoid every ceiling, by always landing 1B past the buffer size -+ // the normal 2x heuristic threshold still forces parse attempts. -+ {2 * KiB + 1, // will attempt 2KiB + 1 ==> total 2KiB + 1 -+ 2 * KiB, 4 * KiB, // will attempt 8KiB + 1 ==> total 10KiB + 2 -+ 8 * KiB, 16 * KiB, // will attempt 32KiB + 1 ==> total 42KiB + 3 -+ 32 * KiB, 64 * KiB, // will attempt 128KiB + 1 ==> total 170KiB + 4 -+ 128 * KiB, 256 * KiB, // will attempt 512KiB + 1 ==> total 682KiB + 5 -+ 512 * KiB, 1 * MiB, // will attempt 2MiB + 1 ==> total 2M + 682K + 6 -+ 2 * MiB, 4 * MiB, // will attempt 8MiB + 1 ==> total 10M + 682K + 7 -+ -(10 * MiB + 682 * KiB + 7)}, -+ // try to avoid every ceiling again, except on our last fill. -+ {2 * KiB + 1, // will attempt 2KiB + 1 ==> total 2KiB + 1 -+ 2 * KiB, 4 * KiB, // will attempt 8KiB + 1 ==> total 10KiB + 2 -+ 8 * KiB, 16 * KiB, // will attempt 32KiB + 1 ==> total 42KiB + 3 -+ 32 * KiB, 64 * KiB, // will attempt 128KiB + 1 ==> total 170KiB + 4 -+ 128 * KiB, 256 * KiB, // will attempt 512KiB + 1 ==> total 682KiB + 5 -+ 512 * KiB, 1 * MiB, // will attempt 2MiB + 1 ==> total 2M + 682K + 6 -+ 2 * MiB, 4 * MiB - 1, // will attempt 8MiB ==> total 10M + 682K + 6 -+ -(10 * MiB + 682 * KiB + 6)}, -+ -+ // try to hit ceilings on the way multiple times -+ {512 * KiB + 1, 256 * KiB, 128 * KiB, 128 * KiB - 1, // 1 MiB buffer -+ 512 * KiB + 1, 256 * KiB, 128 * KiB, 128 * KiB - 1, // 2 MiB buffer -+ 1 * MiB + 1, 512 * KiB, 256 * KiB, 256 * KiB - 1, // 4 MiB buffer -+ 2 * MiB + 1, 1 * MiB, 512 * KiB, // 8 MiB buffer -+ // we'll make a parse attempt at every parse call -+ -(45 * MiB + 12)}, -+ }; -+ const int testcount = sizeof(testcases) / sizeof(testcases[0]); -+ for (int test_i = 0; test_i < testcount; test_i++) { -+ const int *fillsize = testcases[test_i]; -+ XML_Parser parser = XML_ParserCreate(NULL); -+ assert_true(parser != NULL); -+ g_parseAttempts = 0; -+ -+ CharData storage; -+ CharData_Init(&storage); -+ XML_SetUserData(parser, &storage); -+ XML_SetStartElementHandler(parser, start_element_event_handler); -+ -+ int worstcase_bytes = 0; // sum of (buffered bytes at each XML_Parse call) -+ int scanned_bytes = 0; // sum of (buffered bytes at each actual parse) -+ int offset = 0; -+ while (*fillsize >= 0) { -+ assert_true(offset + *fillsize <= document_length); // or test is invalid -+ const unsigned attempts_before = g_parseAttempts; -+ const enum XML_Status status -+ = XML_Parse(parser, &document[offset], *fillsize, XML_FALSE); -+ if (status != XML_STATUS_OK) { -+ xml_failure(parser); -+ } -+ offset += *fillsize; -+ fillsize++; -+ assert_true(offset <= INT_MAX - worstcase_bytes); // avoid overflow -+ worstcase_bytes += offset; // we might've tried to parse all pending bytes -+ if (g_parseAttempts != attempts_before) { -+ assert_true(g_parseAttempts == attempts_before + 1); // max 1/XML_Parse -+ assert_true(offset <= INT_MAX - scanned_bytes); // avoid overflow -+ scanned_bytes += offset; // we *did* try to parse all pending bytes -+ } -+ } -+ assert_true(storage.count == 1); // the big token should've been parsed -+ assert_true(scanned_bytes > 0); // test-the-test: does our counter work? -+ if (g_reparseDeferralEnabledDefault) { -+ // heuristic is enabled; some XML_Parse calls may have deferred reparsing -+ const int max_bytes_scanned = -*fillsize; -+ if (scanned_bytes > max_bytes_scanned) { -+ fprintf(stderr, -+ "bytes scanned in parse attempts: actual=%d limit=%d \n", -+ scanned_bytes, max_bytes_scanned); -+ fail("too many bytes scanned in parse attempts"); -+ } -+ assert_true(scanned_bytes <= worstcase_bytes); -+ } else { -+ // heuristic is disabled; every XML_Parse() will have reparsed -+ assert_true(scanned_bytes == worstcase_bytes); -+ } -+ -+ XML_ParserFree(parser); -+ } -+ free(document); -+} -+END_TEST -+ -+ - /* - * Namespaces tests. - */ -@@ -7435,13 +8058,13 @@ START_TEST(test_return_ns_triplet) - if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), - XML_FALSE) == XML_STATUS_ERROR) - xml_failure(parser); -- if (!triplet_start_flag) -- fail("triplet_start_checker not invoked"); - /* Check that unsetting "return triplets" fails while still parsing */ - XML_SetReturnNSTriplet(parser, XML_FALSE); - if (_XML_Parse_SINGLE_BYTES(parser, epilog, strlen(epilog), - XML_TRUE) == XML_STATUS_ERROR) - xml_failure(parser); -+ if (!triplet_start_flag) -+ fail("triplet_start_checker not invoked"); - if (!triplet_end_flag) - fail("triplet_end_checker not invoked"); - if (dummy_handler_flags != (DUMMY_START_NS_DECL_HANDLER_FLAG | -@@ -12476,6 +13099,7 @@ make_suite(void) - #if defined(XML_CONTEXT_BYTES) - tcase_add_test(tc_basic, test_get_buffer_3_overflow); - #endif -+ tcase_add_test(tc_basic, test_getbuffer_allocates_on_zero_len); - tcase_add_test(tc_basic, test_byte_info_at_end); - tcase_add_test(tc_basic, test_byte_info_at_error); - tcase_add_test(tc_basic, test_byte_info_at_cdata); -@@ -12588,6 +13212,14 @@ make_suite(void) - tcase_add_test(tc_basic, test_bad_notation); - tcase_add_test(tc_basic, test_default_doctype_handler); - tcase_add_test(tc_basic, test_empty_element_abort); -+ tcase_add_test(tc_basic, test_big_tokens_take_linear_time); -+ tcase_add_test(tc_basic, test_set_reparse_deferral); -+ tcase_add_test(tc_basic, test_reparse_deferral_is_inherited); -+ tcase_add_test(tc_basic, test_set_reparse_deferral_on_null_parser); -+ tcase_add_test(tc_basic, test_set_reparse_deferral_on_the_fly); -+ tcase_add_test(tc_basic, test_set_bad_reparse_option); -+ tcase_add_test(tc_basic, test_bypass_heuristic_when_close_to_bufsize); -+ tcase_add_test(tc_basic, test_varying_buffer_fills); - - suite_add_tcase(s, tc_namespace); - tcase_add_checked_fixture(tc_namespace, -diff --git a/expat/xmlwf/xmlwf.c b/expat/xmlwf/xmlwf.c -index 82d028e..cd26919 100644 ---- a/expat/xmlwf/xmlwf.c -+++ b/expat/xmlwf/xmlwf.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - - #include "expat.h" - #include "codepage.h" -@@ -892,7 +893,7 @@ static void - usage(const XML_Char *prog, int rc) - { - ftprintf(stderr, -- T("usage: %s [-s] [-n] [-p] [-x] [-e encoding] [-w] [-d output-dir] [-c] [-m] [-r] [-t] [-N] [file ...]\n"), prog); -+ T("usage: %s [-s] [-n] [-p] [-x] [-e encoding] [-w] [-d output-dir] [-c] [-m] [-r] [-t] [-N] [-q] [file ...]\n"), prog); - exit(rc); - } - -@@ -917,6 +918,8 @@ tmain(int argc, XML_Char **argv) - XML_PARAM_ENTITY_PARSING_NEVER; - int useStdin = 0; - XmlwfUserData userData = { NULL, NULL, NULL }; -+ XML_Bool disableDeferral = XML_FALSE; -+ - - #ifdef _MSC_VER - _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF); -@@ -1003,6 +1006,11 @@ tmain(int argc, XML_Char **argv) - case T('v'): - showVersion(argv[0]); - return 0; -+ case T('q'): { -+ disableDeferral = XML_TRUE; -+ j++; -+ break; -+ } - case T('\0'): - if (j > 1) { - i++; -@@ -1033,6 +1041,16 @@ tmain(int argc, XML_Char **argv) - exit(1); - } - -+ if (disableDeferral) { -+ const XML_Bool success = XML_SetReparseDeferralEnabled(parser, XML_FALSE); -+ if (! success) { -+ // This prevents tperror(..) from reporting misleading "[..]: Success" -+ errno = EINVAL; -+ tperror(T("Failed to disable reparse deferral")); -+ exit(1); -+ } -+ } -+ - if (requireStandalone) - XML_SetNotStandaloneHandler(parser, notStandalone); - XML_SetParamEntityParsing(parser, paramEntityParsing); -diff --git a/testdata/largefiles/aaaaaa_attr.xml b/testdata/largefiles/aaaaaa_attr.xml -new file mode 100644 -index 0000000..66e3d25 ---- /dev/null -+++ b/testdata/largefiles/aaaaaa_attr.xml -@@ -0,0 +1 @@ -+ -\ No newline at end of file -diff --git a/testdata/largefiles/aaaaaa_cdata.xml b/testdata/largefiles/aaaaaa_cdata.xml -new file mode 100644 -index 0000000..66f64bd ---- /dev/null -+++ b/testdata/largefiles/aaaaaa_cdata.xml -@@ -0,0 +1 @@ -+ -\ No newline at end of file -diff --git a/testdata/largefiles/aaaaaa_comment.xml b/testdata/largefiles/aaaaaa_comment.xml -new file mode 100644 -index 0000000..bb9af13 ---- /dev/null -+++ b/testdata/largefiles/aaaaaa_comment.xml -@@ -0,0 +1 @@ -+ -\ No newline at end of file -diff --git a/testdata/largefiles/aaaaaa_tag.xml b/testdata/largefiles/aaaaaa_tag.xml -new file mode 100644 -index 0000000..946f701 ---- /dev/null -+++ b/testdata/largefiles/aaaaaa_tag.xml -@@ -0,0 +1 @@ -+ -\ No newline at end of file -diff --git a/testdata/largefiles/aaaaaa_text.xml b/testdata/largefiles/aaaaaa_text.xml -new file mode 100644 -index 0000000..e266acb ---- /dev/null -+++ b/testdata/largefiles/aaaaaa_text.xml -@@ -0,0 +1 @@ -+ACHARS -\ No newline at end of file diff --git a/SOURCES/expat-2.2.5-CVE-2024-45490.patch b/SOURCES/expat-2.2.5-CVE-2024-45490.patch deleted file mode 100644 index 384797b..0000000 --- a/SOURCES/expat-2.2.5-CVE-2024-45490.patch +++ /dev/null @@ -1,129 +0,0 @@ -commit 3c1a64705b5662c5b78f4aa5a5acc7a59c477094 -Author: Tomas Korbar -Date: Wed Sep 11 15:03:05 2024 +0200 - - Fix CVE-2024-45490 - - https://github.com/libexpat/libexpat/pull/890 - -diff --git a/expat/doc/reference.html b/expat/doc/reference.html -index 95c33c7..08cf9b0 100644 ---- a/expat/doc/reference.html -+++ b/expat/doc/reference.html -@@ -1039,7 +1039,9 @@ containing part (or perhaps all) of the document. The number of bytes of s - that are part of the document is indicated by len. This means - that s doesn't have to be null terminated. It also means that - if len is larger than the number of bytes in the block of --memory that s points at, then a memory fault is likely. The -+memory that s points at, then a memory fault is likely. -+Negative values for len are rejected since Expat 2.2.1. -+The - isFinal parameter informs the parser that this is the last - piece of the document. Frequently, the last piece is empty (i.e. - len is zero.) -@@ -1054,11 +1056,17 @@ XML_ParseBuffer(XML_Parser p, - int isFinal); - -
-+

- This is just like XML_Parse, - except in this case Expat provides the buffer. By obtaining the - buffer from Expat with the XML_GetBuffer function, the application can avoid double - copying of the input. -+

-+ -+

-+Negative values for len are rejected since Expat 2.6.3. -+

-
- -
-diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
-index 488f63f..c3c1af9 100644
---- a/expat/lib/xmlparse.c
-+++ b/expat/lib/xmlparse.c
-@@ -1981,6 +1981,12 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
- 
-   if (parser == NULL)
-     return XML_STATUS_ERROR;
-+
-+  if (len < 0) {
-+    parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
-+    return XML_STATUS_ERROR;
-+  }
-+
-   switch (parser->m_parsingStatus.parsing) {
-   case XML_SUSPENDED:
-     parser->m_errorCode = XML_ERROR_SUSPENDED;
-diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
-index 486073f..6a3e09a 100644
---- a/expat/tests/runtests.c
-+++ b/expat/tests/runtests.c
-@@ -4083,6 +4083,57 @@ START_TEST(test_empty_parse)
- }
- END_TEST
- 
-+/* Test XML_Parse for len < 0 */
-+START_TEST(test_negative_len_parse) {
-+  const char *const doc = "";
-+  for (int isFinal = 0; isFinal < 2; isFinal++) {
-+    XML_Parser parser = XML_ParserCreate(NULL);
-+
-+    if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
-+      fail("There was not supposed to be any initial parse error.");
-+
-+    const enum XML_Status status = XML_Parse(parser, doc, -1, isFinal);
-+
-+    if (status != XML_STATUS_ERROR)
-+      fail("Negative len was expected to fail the parse but did not.");
-+
-+    if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
-+      fail("Parse error does not match XML_ERROR_INVALID_ARGUMENT.");
-+
-+    XML_ParserFree(parser);
-+  }
-+}
-+END_TEST
-+
-+/* Test XML_ParseBuffer for len < 0 */
-+START_TEST(test_negative_len_parse_buffer) {
-+  const char *const doc = "";
-+  for (int isFinal = 0; isFinal < 2; isFinal++) {
-+    XML_Parser parser = XML_ParserCreate(NULL);
-+
-+    if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
-+      fail("There was not supposed to be any initial parse error.");
-+
-+    void *const buffer = XML_GetBuffer(parser, (int)strlen(doc));
-+
-+    if (buffer == NULL)
-+      fail("XML_GetBuffer failed.");
-+
-+    memcpy(buffer, doc, strlen(doc));
-+
-+    const enum XML_Status status = XML_ParseBuffer(parser, -1, isFinal);
-+
-+    if (status != XML_STATUS_ERROR)
-+      fail("Negative len was expected to fail the parse but did not.");
-+
-+    if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
-+      fail("Parse error does not match XML_ERROR_INVALID_ARGUMENT.");
-+
-+    XML_ParserFree(parser);
-+  }
-+}
-+END_TEST
-+
- /* Test odd corners of the XML_GetBuffer interface */
- static enum XML_Status
- get_feature(enum XML_FeatureEnum feature_id, long *presult)
-@@ -13094,6 +13145,8 @@ make_suite(void)
-     tcase_add_test(tc_basic, test_user_parameters);
-     tcase_add_test(tc_basic, test_ext_entity_ref_parameter);
-     tcase_add_test(tc_basic, test_empty_parse);
-+    tcase_add_test(tc_basic, test_negative_len_parse);
-+    tcase_add_test(tc_basic, test_negative_len_parse_buffer);
-     tcase_add_test(tc_basic, test_get_buffer_1);
-     tcase_add_test(tc_basic, test_get_buffer_2);
- #if defined(XML_CONTEXT_BYTES)
diff --git a/SOURCES/expat-2.2.5-CVE-2024-45491.patch b/SOURCES/expat-2.2.5-CVE-2024-45491.patch
deleted file mode 100644
index 621d052..0000000
--- a/SOURCES/expat-2.2.5-CVE-2024-45491.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-commit 75bb51c072a0a505037bea18d18103473000b339
-Author: Tomas Korbar 
-Date:   Wed Sep 11 15:07:26 2024 +0200
-
-    Fix CVE-2024-45491
-    
-    https://github.com/libexpat/libexpat/pull/891
-
-diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
-index c3c1af9..6818c4e 100644
---- a/expat/lib/xmlparse.c
-+++ b/expat/lib/xmlparse.c
-@@ -6843,6 +6843,16 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
-     if (!newE)
-       return 0;
-     if (oldE->nDefaultAtts) {
-+      /* Detect and prevent integer overflow.
-+       * The preprocessor guard addresses the "always false" warning
-+       * from -Wtype-limits on platforms where
-+       * sizeof(int) < sizeof(size_t), e.g. on x86_64. */
-+#if UINT_MAX >= SIZE_MAX
-+      if ((size_t)oldE->nDefaultAtts
-+          > ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) {
-+        return 0;
-+      }
-+#endif
-       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
-           ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
-       if (!newE->defaultAtts) {
diff --git a/SOURCES/expat-2.2.5-CVE-2024-45492.patch b/SOURCES/expat-2.2.5-CVE-2024-45492.patch
deleted file mode 100644
index 137911f..0000000
--- a/SOURCES/expat-2.2.5-CVE-2024-45492.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-commit 6fd04be3c2f7a2730c85b0eaf061549953161da3
-Author: Tomas Korbar 
-Date:   Wed Sep 11 15:12:38 2024 +0200
-
-    Fix CVE-2024-45492
-    
-    https://github.com/libexpat/libexpat/pull/892
-
-diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
-index 6818c4e..698e907 100644
---- a/expat/lib/xmlparse.c
-+++ b/expat/lib/xmlparse.c
-@@ -7426,6 +7426,15 @@ nextScaffoldPart(XML_Parser parser)
-   int next;
- 
-   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 -1;
-+    }
-+#endif
-     dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
-     if (!dtd->scaffIndex)
-       return -1;
diff --git a/SOURCES/expat-2.2.5-CVE-2024-50602.patch b/SOURCES/expat-2.2.5-CVE-2024-50602.patch
deleted file mode 100644
index 3886c7d..0000000
--- a/SOURCES/expat-2.2.5-CVE-2024-50602.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-commit c84ad1507fa42c25937af06e349c8f2f9bc34c11
-Author: Tomas Korbar 
-Date:   Fri Nov 8 11:18:42 2024 +0100
-
-    Fix CVE-2024-50602
-    
-    See https://github.com/libexpat/libexpat/pull/915
-
-diff --git a/expat/lib/expat.h b/expat/lib/expat.h
-index afe12c5..157953c 100644
---- a/expat/lib/expat.h
-+++ b/expat/lib/expat.h
-@@ -124,7 +124,9 @@ enum XML_Error {
-   XML_ERROR_RESERVED_PREFIX_XMLNS,
-   XML_ERROR_RESERVED_NAMESPACE_URI,
-   /* Added in 2.2.1. */
--  XML_ERROR_INVALID_ARGUMENT
-+  XML_ERROR_INVALID_ARGUMENT,
-+  /* Added in 2.6.4. */
-+  XML_ERROR_NOT_STARTED
- };
- 
- enum XML_Content_Type {
-diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
-index 698e907..ed079a5 100644
---- a/expat/lib/xmlparse.c
-+++ b/expat/lib/xmlparse.c
-@@ -2170,6 +2170,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable)
-   if (parser == NULL)
-     return XML_STATUS_ERROR;
-   switch (parser->m_parsingStatus.parsing) {
-+  case XML_INITIALIZED:
-+    parser->m_errorCode = XML_ERROR_NOT_STARTED;
-+    return XML_STATUS_ERROR;
-   case XML_SUSPENDED:
-     if (resumable) {
-       parser->m_errorCode = XML_ERROR_SUSPENDED;
-@@ -2180,7 +2183,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable)
-   case XML_FINISHED:
-     parser->m_errorCode = XML_ERROR_FINISHED;
-     return XML_STATUS_ERROR;
--  default:
-+  case XML_PARSING:
-     if (resumable) {
- #ifdef XML_DTD
-       if (parser->m_isParamEntity) {
-@@ -2192,6 +2195,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable)
-     }
-     else
-       parser->m_parsingStatus.parsing = XML_FINISHED;
-+    break;
-+  default:
-+    assert(0);
-   }
-   return XML_STATUS_OK;
- }
-@@ -2456,6 +2462,9 @@ XML_ErrorString(enum XML_Error code)
-   /* Added in 2.2.5. */
-   case XML_ERROR_INVALID_ARGUMENT:  /* Constant added in 2.2.1, already */
-     return XML_L("invalid argument");
-+  /* Added in 2.6.4. */
-+  case XML_ERROR_NOT_STARTED:
-+    return XML_L("parser not started");
-   }
-   return NULL;
- }
-diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
-index 6a3e09a..7b6d9fb 100644
---- a/expat/tests/runtests.c
-+++ b/expat/tests/runtests.c
-@@ -9162,6 +9162,28 @@ START_TEST(test_misc_utf16le)
- END_TEST
- 
- 
-+START_TEST(test_misc_resumeparser_not_crashing) {
-+  XML_Parser parser = XML_ParserCreate(NULL);
-+  XML_GetBuffer(parser, 1);
-+  XML_StopParser(parser, /*resumable=*/XML_TRUE);
-+  XML_ResumeParser(parser); // could crash here, previously
-+  XML_ParserFree(parser);
-+}
-+END_TEST
-+
-+START_TEST(test_misc_stopparser_rejects_unstarted_parser) {
-+  const XML_Bool cases[] = {XML_TRUE, XML_FALSE};
-+  for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
-+    const XML_Bool resumable = cases[i];
-+    XML_Parser parser = XML_ParserCreate(NULL);
-+    assert_true(XML_GetErrorCode(parser) == XML_ERROR_NONE);
-+    assert_true(XML_StopParser(parser, resumable) == XML_STATUS_ERROR);
-+    assert_true(XML_GetErrorCode(parser) == XML_ERROR_NOT_STARTED);
-+    XML_ParserFree(parser);
-+  }
-+}
-+END_TEST
-+
- static void
- alloc_setup(void)
- {
-@@ -13325,6 +13347,8 @@ make_suite(void)
-     tcase_add_test(tc_misc,
-                    test_misc_deny_internal_entity_closing_doctype_issue_317);
- #endif
-+    tcase_add_test(tc_misc, test_misc_resumeparser_not_crashing);
-+    tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser);
- 
-     suite_add_tcase(s, tc_alloc);
-     tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
diff --git a/SOURCES/expat-2.2.5-CVE-2024-8176.patch b/SOURCES/expat-2.2.5-CVE-2024-8176.patch
deleted file mode 100644
index 44e1af8..0000000
--- a/SOURCES/expat-2.2.5-CVE-2024-8176.patch
+++ /dev/null
@@ -1,1595 +0,0 @@
-commit 9f90e0bc7b061a12dbe8b5d1c6ef389cf61e0614
-Author: Tomas Korbar 
-Date:   Fri Apr 4 10:19:58 2025 +0200
-
-    Fix CVE-2024-8176
-    
-    Backport of upstream commit e113a4667258fd2328659f35ed9c29b64731edab
-    Pull Request #298
-
-diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
-index ed079a5..d00d23a 100644
---- a/expat/lib/xmlparse.c
-+++ b/expat/lib/xmlparse.c
-@@ -284,6 +284,10 @@ typedef struct {
-   const XML_Char *publicId;
-   const XML_Char *notation;
-   XML_Bool open;
-+  XML_Bool hasMore; /* true if entity has not been completely processed */
-+  /* An entity can be open while being already completely processed (hasMore ==
-+    XML_FALSE). The reason is the delayed closing of entities until their inner
-+    entities are processed and closed */
-   XML_Bool is_param;
-   XML_Bool is_internal; /* true if declared in internal subset outside PE */
- } ENTITY;
-@@ -374,6 +378,12 @@ typedef struct {
-   int *scaffIndex;
- } DTD;
- 
-+enum EntityType {
-+  ENTITY_INTERNAL,
-+  ENTITY_ATTRIBUTE,
-+  ENTITY_VALUE,
-+};
-+
- typedef struct open_internal_entity {
-   const char *internalEventPtr;
-   const char *internalEventEndPtr;
-@@ -381,6 +391,7 @@ typedef struct open_internal_entity {
-   ENTITY *entity;
-   int startTagLevel;
-   XML_Bool betweenDecl; /* WFC: PE Between Declarations */
-+  enum EntityType type;
- } OPEN_INTERNAL_ENTITY;
- 
- typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
-@@ -418,9 +429,8 @@ static enum XML_Error
- doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
-          const char *end, int tok, const char *next, const char **nextPtr,
-                                XML_Bool haveMore, XML_Bool allowClosingDoctype);
--static enum XML_Error
--processInternalEntity(XML_Parser parser, ENTITY *entity,
--                      XML_Bool betweenDecl);
-+static enum XML_Error processEntity(XML_Parser parser, ENTITY *entity,
-+                                    XML_Bool betweenDecl, enum EntityType type);
- static enum XML_Error
- doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
-           const char *start, const char *end, const char **endPtr,
-@@ -449,8 +459,9 @@ static enum XML_Error
- storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
-                     const char *, const char *, STRING_POOL *);
- static enum XML_Error
--appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
--                     const char *, const char *, STRING_POOL *);
-+appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
-+                     const char *ptr, const char *end, STRING_POOL *pool,
-+                     const char **nextPtr);
- static ATTRIBUTE_ID *
- getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
-                const char *end);
-@@ -458,7 +469,10 @@ static int
- setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
- static enum XML_Error
- storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
--                 const char *end);
-+                 const char *end, const char **nextPtr);
-+static enum XML_Error callStoreEntityValue(XML_Parser parser,
-+                                          const ENCODING *enc,
-+                                          const char *start, const char *end);
- static int
- reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
-                             const char *start, const char *end);
-@@ -611,6 +625,10 @@ struct XML_ParserStruct {
-   const char *m_positionPtr;
-   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
-   OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
-+  OPEN_INTERNAL_ENTITY *m_openAttributeEntities;
-+  OPEN_INTERNAL_ENTITY *m_freeAttributeEntities;
-+  OPEN_INTERNAL_ENTITY *m_openValueEntities;
-+  OPEN_INTERNAL_ENTITY *m_freeValueEntities;
-   XML_Bool m_defaultExpandInternalEntities;
-   int m_tagLevel;
-   ENTITY *m_declEntity;
-@@ -654,6 +672,7 @@ struct XML_ParserStruct {
-   enum XML_ParamEntityParsing m_paramEntityParsing;
- #endif
-   unsigned long m_hash_secret_salt;
-+  XML_Bool m_reenter;
- };
- 
- #define MALLOC(parser, s)      (parser->m_mem.malloc_fcn((s)))
-@@ -930,7 +949,29 @@ callProcessor(XML_Parser parser, const char *start, const char *end,
-     }
-   }
-   g_parseAttempts += 1;
--  const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr);
-+  // Run in a loop to eliminate dangerous recursion depths
-+  enum XML_Error ret;
-+  *endPtr = start;
-+  while (1) {
-+    // Use endPtr as the new start in each iteration, since it will
-+    // be set to the next start point by m_processor.
-+    ret = parser->m_processor(parser, *endPtr, end, endPtr);
-+
-+    // Make parsing status (and in particular XML_SUSPENDED) take
-+    // precedence over re-enter flag when they disagree
-+    if (parser->m_parsingStatus.parsing != XML_PARSING) {
-+      parser->m_reenter = XML_FALSE;
-+    }
-+
-+    if (! parser->m_reenter) {
-+      break;
-+    }
-+
-+    parser->m_reenter = XML_FALSE;
-+    if (ret != XML_ERROR_NONE)
-+      return ret;
-+  }
-+
-   if (ret == XML_ERROR_NONE) {
-     // if we consumed nothing, remember what we had on this parse attempt.
-     if (*endPtr == start) {
-@@ -1045,6 +1086,8 @@ parserCreate(const XML_Char *encodingName,
-   parser->m_freeBindingList = NULL;
-   parser->m_freeTagList = NULL;
-   parser->m_freeInternalEntities = NULL;
-+  parser->m_freeAttributeEntities = NULL;
-+  parser->m_freeValueEntities = NULL;
- 
-   parser->m_groupSize = 0;
-   parser->m_groupConnector = NULL;
-@@ -1149,6 +1192,8 @@ parserInit(XML_Parser parser, const XML_Char *encodingName)
-   parser->m_eventEndPtr = NULL;
-   parser->m_positionPtr = NULL;
-   parser->m_openInternalEntities = NULL;
-+  parser->m_openAttributeEntities = NULL;
-+  parser->m_openValueEntities = NULL;
-   parser->m_defaultExpandInternalEntities = XML_TRUE;
-   parser->m_tagLevel = 0;
-   parser->m_tagStack = NULL;
-@@ -1159,6 +1204,8 @@ parserInit(XML_Parser parser, const XML_Char *encodingName)
-   parser->m_unknownEncodingData = NULL;
-   parser->m_parentParser = NULL;
-   parser->m_parsingStatus.parsing = XML_INITIALIZED;
-+  // Reentry can only be triggered inside m_processor calls
-+  parser->m_reenter = XML_FALSE;
- #ifdef XML_DTD
-   parser->m_isParamEntity = XML_FALSE;
-   parser->m_useForeignDTD = XML_FALSE;
-@@ -1208,6 +1255,24 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
-     openEntity->next = parser->m_freeInternalEntities;
-     parser->m_freeInternalEntities = openEntity;
-   }
-+  /* move m_openAttributeEntities to m_freeAttributeEntities (i.e. same task but
-+   * for attributes) */
-+  openEntityList = parser->m_openAttributeEntities;
-+  while (openEntityList) {
-+    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
-+    openEntityList = openEntity->next;
-+    openEntity->next = parser->m_freeAttributeEntities;
-+    parser->m_freeAttributeEntities = openEntity;
-+  }
-+  /* move m_openValueEntities to m_freeValueEntities (i.e. same task but
-+   * for value entities) */
-+  openEntityList = parser->m_openValueEntities;
-+  while (openEntityList) {
-+    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
-+    openEntityList = openEntity->next;
-+    openEntity->next = parser->m_freeValueEntities;
-+    parser->m_freeValueEntities = openEntity;
-+  }
-   moveToFreeBindingList(parser, parser->m_inheritedBindings);
-   FREE(parser, parser->m_unknownEncodingMem);
-   if (parser->m_unknownEncodingRelease)
-@@ -1221,6 +1286,19 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
-   return XML_TRUE;
- }
- 
-+static XML_Bool
-+parserBusy(XML_Parser parser) {
-+  switch (parser->m_parsingStatus.parsing) {
-+  case XML_PARSING:
-+  case XML_SUSPENDED:
-+    return XML_TRUE;
-+  case XML_INITIALIZED:
-+  case XML_FINISHED:
-+  default:
-+    return XML_FALSE;
-+  }
-+}
-+
- enum XML_Status XMLCALL
- XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
- {
-@@ -1230,7 +1308,7 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
-      XXX There's no way for the caller to determine which of the
-      XXX possible error cases caused the XML_STATUS_ERROR return.
-   */
--  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
-+  if (parserBusy(parser))
-     return XML_STATUS_ERROR;
- 
-   /* Get rid of any previous encoding name */
-@@ -1473,7 +1551,34 @@ XML_ParserFree(XML_Parser parser)
-     entityList = entityList->next;
-     FREE(parser, openEntity);
-   }
--
-+  /* free m_openAttributeEntities and m_freeAttributeEntities */
-+  entityList = parser->m_openAttributeEntities;
-+  for (;;) {
-+    OPEN_INTERNAL_ENTITY *openEntity;
-+    if (entityList == NULL) {
-+      if (parser->m_freeAttributeEntities == NULL)
-+        break;
-+      entityList = parser->m_freeAttributeEntities;
-+      parser->m_freeAttributeEntities = NULL;
-+    }
-+    openEntity = entityList;
-+    entityList = entityList->next;
-+    FREE(parser, openEntity);
-+  }
-+  /* free m_openValueEntities and m_freeValueEntities */
-+  entityList = parser->m_openValueEntities;
-+  for (;;) {
-+    OPEN_INTERNAL_ENTITY *openEntity;
-+    if (entityList == NULL) {
-+      if (parser->m_freeValueEntities == NULL)
-+        break;
-+      entityList = parser->m_freeValueEntities;
-+      parser->m_freeValueEntities = NULL;
-+    }
-+    openEntity = entityList;
-+    entityList = entityList->next;
-+    FREE(parser, openEntity);
-+  }
-   destroyBindings(parser->m_freeBindingList, parser);
-   destroyBindings(parser->m_inheritedBindings, parser);
-   poolDestroy(&parser->m_tempPool);
-@@ -1516,7 +1621,7 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
-     return XML_ERROR_INVALID_ARGUMENT;
- #ifdef XML_DTD
-   /* block after XML_Parse()/XML_ParseBuffer() has been called */
--  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
-+  if (parserBusy(parser))
-     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
-   parser->m_useForeignDTD = useDTD;
-   return XML_ERROR_NONE;
-@@ -1531,7 +1636,7 @@ XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
-   if (parser == NULL)
-     return;
-   /* block after XML_Parse()/XML_ParseBuffer() has been called */
--  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
-+  if (parserBusy(parser))
-     return;
-   parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
- }
-@@ -1841,7 +1946,7 @@ XML_SetParamEntityParsing(XML_Parser parser,
-   if (parser == NULL)
-     return 0;
-   /* block after XML_Parse()/XML_ParseBuffer() has been called */
--  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
-+  if (parserBusy(parser))
-     return 0;
- #ifdef XML_DTD
-   parser->m_paramEntityParsing = peParsing;
-@@ -1860,7 +1965,7 @@ XML_SetHashSalt(XML_Parser parser,
-   if (parser->m_parentParser)
-     return XML_SetHashSalt(parser->m_parentParser, hash_salt);
-   /* block after XML_Parse()/XML_ParseBuffer() has been called */
--  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
-+  if (parserBusy(parser))
-     return 0;
-   parser->m_hash_secret_salt = hash_salt;
-   return 1;
-@@ -2164,6 +2269,11 @@ XML_GetBuffer(XML_Parser parser, int len)
-   return parser->m_bufferEnd;
- }
- 
-+static void
-+triggerReenter(XML_Parser parser) {
-+  parser->m_reenter = XML_TRUE;
-+}
-+
- enum XML_Status XMLCALL
- XML_StopParser(XML_Parser parser, XML_Bool resumable)
- {
-@@ -2610,8 +2720,8 @@ contentProcessor(XML_Parser parser,
-                  const char *end,
-                  const char **endPtr)
- {
--  enum XML_Error result = doContent(parser, 0, parser->m_encoding, start, end,
--                                    endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
-+  enum XML_Error result = doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, start, end,
-+                                    endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer);
-   if (result == XML_ERROR_NONE) {
-     if (!storeRawNames(parser))
-       return XML_ERROR_NO_MEMORY;
-@@ -2697,6 +2807,11 @@ externalEntityInitProcessor3(XML_Parser parser,
-         return XML_ERROR_NONE;
-       case XML_FINISHED:
-         return XML_ERROR_ABORTED;
-+      case XML_PARSING:
-+        if (parser->m_reenter) {
-+          return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE
-+        }
-+        /* Fall through */
-       default:
-         start = next;
-       }
-@@ -2863,7 +2978,7 @@ doContent(XML_Parser parser,
-               reportDefault(parser, enc, s, next);
-             break;
-           }
--          result = processInternalEntity(parser, entity, XML_FALSE);
-+          result = processEntity(parser, entity, XML_FALSE, ENTITY_INTERNAL);
-           if (result != XML_ERROR_NONE)
-             return result;
-         }
-@@ -2990,9 +3105,13 @@ doContent(XML_Parser parser,
-         poolClear(&parser->m_tempPool);
-         freeBindings(parser, bindings);
-       }
--      if ((parser->m_tagLevel == 0) &&
--          !((parser->m_parsingStatus.parsing == XML_FINISHED) || (parser->m_parsingStatus.parsing == XML_SUSPENDED))) {
--        return epilogProcessor(parser, next, end, nextPtr);
-+      if ((parser->m_tagLevel == 0) && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
-+          if (parser->m_parsingStatus.parsing == XML_SUSPENDED
-+              || (parser->m_parsingStatus.parsing == XML_PARSING
-+                  && parser->m_reenter))
-+          parser->m_processor = epilogProcessor;
-+        else
-+          return epilogProcessor(parser, next, end, nextPtr);
-       }
-       break;
-     case XML_TOK_END_TAG:
-@@ -3046,8 +3165,15 @@ doContent(XML_Parser parser,
-           parser->m_freeBindingList = b;
-           b->prefix->binding = b->prevPrefixBinding;
-         }
--        if (parser->m_tagLevel == 0)
--          return epilogProcessor(parser, next, end, nextPtr);
-+        if ((parser->m_tagLevel == 0)
-+            && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
-+            if (parser->m_parsingStatus.parsing == XML_SUSPENDED
-+                || (parser->m_parsingStatus.parsing == XML_PARSING
-+                    && parser->m_reenter))
-+            parser->m_processor = epilogProcessor;
-+          else
-+            return epilogProcessor(parser, next, end, nextPtr);
-+        }
-       }
-       break;
-     case XML_TOK_CHAR_REF:
-@@ -3183,14 +3309,22 @@ doContent(XML_Parser parser,
-       break;
-       /* LCOV_EXCL_STOP */
-     }
--    *eventPP = s = next;
-     switch (parser->m_parsingStatus.parsing) {
-     case XML_SUSPENDED:
-+      *eventPP = next;
-       *nextPtr = next;
-       return XML_ERROR_NONE;
-     case XML_FINISHED:
-+      *eventPP = next;
-       return XML_ERROR_ABORTED;
-+    case XML_PARSING:
-+      if (parser->m_reenter) {
-+        *nextPtr = next;
-+        return XML_ERROR_NONE;
-+      }
-+      /* Fall through */
-     default: ;
-+      *eventPP = s = next;
-     }
-   }
-   /* not reached */
-@@ -4112,14 +4246,21 @@ doCdataSection(XML_Parser parser,
-       /* LCOV_EXCL_STOP */
-     }
- 
--    *eventPP = s = next;
-     switch (parser->m_parsingStatus.parsing) {
-     case XML_SUSPENDED:
-+      *eventPP = next;
-       *nextPtr = next;
-       return XML_ERROR_NONE;
-     case XML_FINISHED:
-+      *eventPP = next;
-       return XML_ERROR_ABORTED;
-+    case XML_PARSING:
-+      if (parser->m_reenter) {
-+        return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE
-+      }
-+      /* Fall through */
-     default: ;
-+      *eventPP = s = next;
-     }
-   }
-   /* not reached */
-@@ -4466,7 +4607,7 @@ entityValueInitProcessor(XML_Parser parser,
-         break;
-       }
-       /* found end of entity value - can store it now */
--      return storeEntityValue(parser, parser->m_encoding, s, end);
-+      return storeEntityValue(parser, parser->m_encoding, s, end, NULL);
-     }
-     else if (tok == XML_TOK_XML_DECL) {
-       enum XML_Error result;
-@@ -4581,7 +4722,7 @@ entityValueProcessor(XML_Parser parser,
-         break;
-       }
-       /* found end of entity value - can store it now */
--      return storeEntityValue(parser, enc, s, end);
-+      return storeEntityValue(parser, enc, s, end, NULL);
-     }
-     start = next;
-   }
-@@ -5012,9 +5153,8 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
-       break;
-     case XML_ROLE_ENTITY_VALUE:
-       if (dtd->keepProcessing) {
--        enum XML_Error result = storeEntityValue(parser, enc,
--                                            s + enc->minBytesPerChar,
--                                            next - enc->minBytesPerChar);
-+        enum XML_Error result = callStoreEntityValue(
-+          parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
-         if (parser->m_declEntity) {
-           parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
-           parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
-@@ -5429,7 +5569,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
-           enum XML_Error result;
-           XML_Bool betweenDecl =
-             (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
--          result = processInternalEntity(parser, entity, betweenDecl);
-+          result = processEntity(parser, entity, betweenDecl, ENTITY_INTERNAL);
-           if (result != XML_ERROR_NONE)
-             return result;
-           handleDefault = XML_FALSE;
-@@ -5627,6 +5767,12 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
-       return XML_ERROR_NONE;
-     case XML_FINISHED:
-       return XML_ERROR_ABORTED;
-+    case XML_PARSING:
-+      if (parser->m_reenter) {
-+        *nextPtr = next;
-+        return XML_ERROR_NONE;
-+      }
-+    /* Fall through */
-     default:
-       s = next;
-       tok = XmlPrologTok(enc, s, end, &next);
-@@ -5690,75 +5836,80 @@ epilogProcessor(XML_Parser parser,
-     default:
-       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
-     }
--    parser->m_eventPtr = s = next;
-     switch (parser->m_parsingStatus.parsing) {
-     case XML_SUSPENDED:
-+      parser->m_eventPtr = next;
-       *nextPtr = next;
-       return XML_ERROR_NONE;
-     case XML_FINISHED:
-+      parser->m_eventPtr = next;
-       return XML_ERROR_ABORTED;
-+    case XML_PARSING:
-+      if (parser->m_reenter) {
-+        return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE
-+      }
-+    /* Fall through */
-     default: ;
-+      parser->m_eventPtr = s = next;
-     }
-   }
- }
- 
- static enum XML_Error
--processInternalEntity(XML_Parser parser, ENTITY *entity,
--                      XML_Bool betweenDecl)
--{
--  const char *textStart, *textEnd;
--  const char *next;
--  enum XML_Error result;
--  OPEN_INTERNAL_ENTITY *openEntity;
--
--  if (parser->m_freeInternalEntities) {
--    openEntity = parser->m_freeInternalEntities;
--    parser->m_freeInternalEntities = openEntity->next;
-+processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl,
-+                enum EntityType type) {
-+    OPEN_INTERNAL_ENTITY *openEntity, **openEntityList, **freeEntityList;
-+    switch (type) {
-+    case ENTITY_INTERNAL:
-+      parser->m_processor = internalEntityProcessor;
-+      openEntityList = &parser->m_openInternalEntities;
-+      freeEntityList = &parser->m_freeInternalEntities;
-+      break;
-+    case ENTITY_ATTRIBUTE:
-+      openEntityList = &parser->m_openAttributeEntities;
-+      freeEntityList = &parser->m_freeAttributeEntities;
-+      break;
-+    case ENTITY_VALUE:
-+      openEntityList = &parser->m_openValueEntities;
-+      freeEntityList = &parser->m_freeValueEntities;
-+      break;
-+      /* default case serves merely as a safety net in case of a
-+       * wrong entityType. Therefore we exclude the following lines
-+       * from the test coverage.
-+       *
-+       * LCOV_EXCL_START
-+       */
-+    default:
-+      // Should not reach here
-+      assert(0);
-+      /* LCOV_EXCL_STOP */
-   }
--  else {
-+
-+  if (*freeEntityList) {
-+      openEntity = *freeEntityList;
-+      *freeEntityList = openEntity->next;
-+  } else {
-     openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
-     if (!openEntity)
-       return XML_ERROR_NO_MEMORY;
-   }
-   entity->open = XML_TRUE;
-+  entity->hasMore = XML_TRUE;
-   entity->processed = 0;
--  openEntity->next = parser->m_openInternalEntities;
--  parser->m_openInternalEntities = openEntity;
-+  openEntity->next = *openEntityList;
-+  *openEntityList = openEntity;
-   openEntity->entity = entity;
-+  openEntity->type = type;
-   openEntity->startTagLevel = parser->m_tagLevel;
-   openEntity->betweenDecl = betweenDecl;
-   openEntity->internalEventPtr = NULL;
-   openEntity->internalEventEndPtr = NULL;
--  textStart = (char *)entity->textPtr;
--  textEnd = (char *)(entity->textPtr + entity->textLen);
--  /* Set a safe default value in case 'next' does not get set */
--  next = textStart;
--
--#ifdef XML_DTD
--  if (entity->is_param) {
--    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
--    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
--                      next, &next, XML_FALSE, XML_FALSE);
--  }
--  else
--#endif /* XML_DTD */
--    result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, textStart,
--                       textEnd, &next, XML_FALSE);
--
--  if (result == XML_ERROR_NONE) {
--    if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
--      entity->processed = (int)(next - textStart);
--      parser->m_processor = internalEntityProcessor;
--    }
--    else {
--      entity->open = XML_FALSE;
--      parser->m_openInternalEntities = openEntity->next;
--      /* put openEntity back in list of free instances */
--      openEntity->next = parser->m_freeInternalEntities;
--      parser->m_freeInternalEntities = openEntity;
--    }
-+  // Only internal entities make use of the reenter flag
-+  // therefore no need to set it for other entity types
-+  if (type == ENTITY_INTERNAL) {
-+    triggerReenter(parser);
-   }
--  return result;
-+  return XML_ERROR_NONE;
- }
- 
- static enum XML_Error PTRCALL
-@@ -5776,58 +5927,59 @@ internalEntityProcessor(XML_Parser parser,
-     return XML_ERROR_UNEXPECTED_STATE;
- 
-   entity = openEntity->entity;
--  textStart = ((char *)entity->textPtr) + entity->processed;
--  textEnd = (char *)(entity->textPtr + entity->textLen);
--  /* Set a safe default value in case 'next' does not get set */
--  next = textStart;
--
--#ifdef XML_DTD
--  if (entity->is_param) {
--    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
--    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
--                      next, &next, XML_FALSE, XML_TRUE);
--  }
--  else
--#endif /* XML_DTD */
--    result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding,
--                       textStart, textEnd, &next, XML_FALSE);
--
--  if (result != XML_ERROR_NONE)
--    return result;
--  else if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
--    entity->processed = (int)(next - (char *)entity->textPtr);
--    return result;
--  }
--  else {
--    entity->open = XML_FALSE;
--    parser->m_openInternalEntities = openEntity->next;
--    /* put openEntity back in list of free instances */
--    openEntity->next = parser->m_freeInternalEntities;
--    parser->m_freeInternalEntities = openEntity;
--  }
-+  // This will return early
-+  if (entity->hasMore) {
-+    textStart = ((const char *)entity->textPtr) + entity->processed;
-+    textEnd = (const char *)(entity->textPtr + entity->textLen);
-+    /* Set a safe default value in case 'next' does not get set */
-+    next = textStart;
-+
-+    if (entity->is_param) {
-+      int tok
-+          = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
-+      result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
-+                        tok, next, &next, XML_FALSE, XML_FALSE);
-+    } else {
-+      result = doContent(parser, openEntity->startTagLevel,
-+                          parser->m_internalEncoding, textStart, textEnd, &next,
-+                          XML_FALSE);
-+    }
- 
--#ifdef XML_DTD
--  if (entity->is_param) {
--    int tok;
--    parser->m_processor = prologProcessor;
--    tok = XmlPrologTok(parser->m_encoding, s, end, &next);
--    return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
--                    (XML_Bool)!parser->m_parsingStatus.finalBuffer, XML_TRUE);
--  }
--  else
--#endif /* XML_DTD */
--  {
--    parser->m_processor = contentProcessor;
--    /* see externalEntityContentProcessor vs contentProcessor */
--    result = doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
--                      s, end, nextPtr,
--                      (XML_Bool)! parser->m_parsingStatus.finalBuffer);
--    if (result == XML_ERROR_NONE) {
--      if (! storeRawNames(parser))
--        return XML_ERROR_NO_MEMORY;
-+    if (result != XML_ERROR_NONE)
-+      return result;
-+    // Check if entity is complete, if not, mark down how much of it is
-+    // processed
-+    if (textEnd != next
-+        && (parser->m_parsingStatus.parsing == XML_SUSPENDED
-+            || (parser->m_parsingStatus.parsing == XML_PARSING
-+                && parser->m_reenter))) {
-+      entity->processed = (int)(next - (const char *)entity->textPtr);
-+      return result;
-     }
-+    // Entity is complete. We cannot close it here since we need to first
-+    // process its possible inner entities (which are added to the
-+    // m_openInternalEntities during doProlog or doContent calls above)
-+    entity->hasMore = XML_FALSE;
-+    triggerReenter(parser);  
-     return result;
--  }
-+  } // End of entity processing, "if" block will return here
-+  // Remove fully processed openEntity from open entity list.
-+
-+  // openEntity is m_openInternalEntities' head, as we set it at the start of
-+  // this function and we skipped doProlog and doContent calls with hasMore set
-+  // to false. This means we can directly remove the head of
-+  // m_openInternalEntities
-+  assert(parser->m_openInternalEntities == openEntity);
-+  entity->open = XML_FALSE;
-+  parser->m_openInternalEntities = parser->m_openInternalEntities->next;
-+  /* put openEntity back in list of free instances */
-+  openEntity->next = parser->m_freeInternalEntities;
-+  parser->m_freeInternalEntities = openEntity;
-+  if (parser->m_openInternalEntities == NULL) {
-+    parser->m_processor = entity->is_param ? prologProcessor : contentProcessor;
-+  }
-+  triggerReenter(parser);
-+  return XML_ERROR_NONE;
- }
- 
- static enum XML_Error PTRCALL
-@@ -5844,8 +5996,66 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
-                     const char *ptr, const char *end,
-                     STRING_POOL *pool)
- {
--  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
--                                               end, pool);
-+  const char *next = ptr;
-+  enum XML_Error result = XML_ERROR_NONE;
-+
-+  while (1) {
-+    if (! parser->m_openAttributeEntities) {
-+      result = appendAttributeValue(parser, enc, isCdata, next, end, pool,
-+                                    &next);
-+    } else {
-+      OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openAttributeEntities;
-+      if (! openEntity)
-+        return XML_ERROR_UNEXPECTED_STATE;
-+
-+      ENTITY *const entity = openEntity->entity;
-+      const char *const textStart
-+          = ((const char *)entity->textPtr) + entity->processed;
-+      const char *const textEnd
-+          = (const char *)(entity->textPtr + entity->textLen);
-+      /* Set a safe default value in case 'next' does not get set */
-+      const char *nextInEntity = textStart;
-+      if (entity->hasMore) {
-+        result = appendAttributeValue(
-+            parser, parser->m_internalEncoding, isCdata, textStart, textEnd,
-+            pool, &nextInEntity);
-+        if (result != XML_ERROR_NONE)
-+          break;
-+        // Check if entity is complete, if not, mark down how much of it is
-+        // processed. A XML_SUSPENDED check here is not required as
-+        // appendAttributeValue will never suspend the parser.
-+        if (textEnd != nextInEntity) {
-+          entity->processed
-+              = (int)(nextInEntity - (const char *)entity->textPtr);
-+          continue;
-+        }
-+
-+        // Entity is complete. We cannot close it here since we need to first
-+        // process its possible inner entities (which are added to the
-+        // m_openAttributeEntities during appendAttributeValue)
-+        entity->hasMore = XML_FALSE;
-+        continue;
-+      } // End of entity processing, "if" block skips the rest
-+
-+      // openEntity is m_openAttributeEntities' head, since we set it at the
-+      // start of this function and because we skipped appendAttributeValue call
-+      // with hasMore set to false. This means we can directly remove the head
-+      // of m_openAttributeEntities
-+      assert(parser->m_openAttributeEntities == openEntity);
-+      entity->open = XML_FALSE;
-+      parser->m_openAttributeEntities = parser->m_openAttributeEntities->next;
-+
-+      /* put openEntity back in list of free instances */
-+      openEntity->next = parser->m_freeAttributeEntities;
-+      parser->m_freeAttributeEntities = openEntity;
-+    }
-+
-+    // Break if an error occurred or there is nothing left to process
-+    if (result || (parser->m_openAttributeEntities == NULL && end == next)) {
-+      break;
-+    }
-+  }
-+    
-   if (result)
-     return result;
-   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
-@@ -5858,14 +6068,17 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- static enum XML_Error
- appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
-                      const char *ptr, const char *end,
--                     STRING_POOL *pool)
-+                     STRING_POOL *pool, const char **nextPtr)
- {
-   DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
-   for (;;) {
--    const char *next;
-+    const char *next = ptr; /* XmlAttributeValueTok doesn't always set the last arg */
-     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
-     switch (tok) {
-     case XML_TOK_NONE:
-+      if (nextPtr) {
-+        *nextPtr = next;
-+      }
-       return XML_ERROR_NONE;
-     case XML_TOK_INVALID:
-       if (enc == parser->m_encoding)
-@@ -6006,14 +6219,11 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
-         }
-         else {
-           enum XML_Error result;
--          const XML_Char *textEnd = entity->textPtr + entity->textLen;
--          entity->open = XML_TRUE;
--          result = appendAttributeValue(parser, parser->m_internalEncoding, isCdata,
--                                        (char *)entity->textPtr,
--                                        (char *)textEnd, pool);
--          entity->open = XML_FALSE;
--          if (result)
--            return result;
-+          result = processEntity(parser, entity, XML_FALSE, ENTITY_ATTRIBUTE);
-+          if ((result == XML_ERROR_NONE) && (nextPtr != NULL)) {
-+            *nextPtr = next;
-+          }
-+          return result;
-         }
-       }
-       break;
-@@ -6043,7 +6253,8 @@ static enum XML_Error
- storeEntityValue(XML_Parser parser,
-                  const ENCODING *enc,
-                  const char *entityTextPtr,
--                 const char *entityTextEnd)
-+                 const char *entityTextEnd,
-+                 const char **nextPtr)
- {
-   DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
-   STRING_POOL *pool = &(dtd->entityValuePool);
-@@ -6060,8 +6271,9 @@ storeEntityValue(XML_Parser parser,
-       return XML_ERROR_NO_MEMORY;
-   }
- 
-+  const char *next;
-   for (;;) {
--    const char *next;
-+    next = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
-     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
-     switch (tok) {
-     case XML_TOK_PARAM_ENTITY_REF:
-@@ -6115,15 +6327,8 @@ storeEntityValue(XML_Parser parser,
-             dtd->keepProcessing = dtd->standalone;
-         }
-         else {
--          entity->open = XML_TRUE;
--          result = storeEntityValue(parser,
--                                    parser->m_internalEncoding,
--                                    (char *)entity->textPtr,
--                                    (char *)(entity->textPtr
--                                             + entity->textLen));
--          entity->open = XML_FALSE;
--          if (result)
--            goto endEntityValue;
-+          result = processEntity(parser, entity, XML_FALSE, ENTITY_VALUE);
-+          goto endEntityValue;
-         }
-         break;
-       }
-@@ -6213,9 +6418,79 @@ endEntityValue:
- #ifdef XML_DTD
-   parser->m_prologState.inEntityValue = oldInEntityValue;
- #endif /* XML_DTD */
-+  // If 'nextPtr' is given, it should be updated during the processing
-+  if (nextPtr != NULL) {
-+    *nextPtr = next;
-+  }
-   return result;
- }
- 
-+static enum XML_Error
-+callStoreEntityValue(XML_Parser parser, const ENCODING *enc,
-+                     const char *entityTextPtr, const char *entityTextEnd) {
-+  const char *next = entityTextPtr;
-+  enum XML_Error result = XML_ERROR_NONE;
-+  while (1) {
-+    if (! parser->m_openValueEntities) {
-+      result
-+          = storeEntityValue(parser, enc, next, entityTextEnd, &next);
-+    } else {
-+      OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openValueEntities;
-+      if (! openEntity)
-+        return XML_ERROR_UNEXPECTED_STATE;
-+
-+      ENTITY *const entity = openEntity->entity;
-+      const char *const textStart
-+          = ((const char *)entity->textPtr) + entity->processed;
-+      const char *const textEnd
-+          = (const char *)(entity->textPtr + entity->textLen);
-+      /* Set a safe default value in case 'next' does not get set */
-+      const char *nextInEntity = textStart;
-+      if (entity->hasMore) {
-+        result = storeEntityValue(parser, parser->m_internalEncoding, textStart,
-+                                  textEnd, &nextInEntity);
-+        if (result != XML_ERROR_NONE)
-+          break;
-+        // Check if entity is complete, if not, mark down how much of it is
-+        // processed. A XML_SUSPENDED check here is not required as
-+        // appendAttributeValue will never suspend the parser.
-+        if (textEnd != nextInEntity) {
-+          entity->processed
-+              = (int)(nextInEntity - (const char *)entity->textPtr);
-+          continue;
-+        }
-+
-+        // Entity is complete. We cannot close it here since we need to first
-+        // process its possible inner entities (which are added to the
-+        // m_openValueEntities during storeEntityValue)
-+        entity->hasMore = XML_FALSE;
-+        continue;
-+      } // End of entity processing, "if" block skips the rest
-+
-+      // openEntity is m_openValueEntities' head, since we set it at the
-+      // start of this function and because we skipped storeEntityValue call
-+      // with hasMore set to false. This means we can directly remove the head
-+      // of m_openValueEntities
-+      assert(parser->m_openValueEntities == openEntity);
-+      entity->open = XML_FALSE;
-+      parser->m_openValueEntities = parser->m_openValueEntities->next;
-+
-+      /* put openEntity back in list of free instances */
-+      openEntity->next = parser->m_freeValueEntities;
-+      parser->m_freeValueEntities = openEntity;
-+    }
-+
-+    // Break if an error occurred or there is nothing left to process
-+    if (result
-+        || (parser->m_openValueEntities == NULL && entityTextEnd == next)) {
-+      break;
-+    }
-+  }
-+
-+   return result;
-+}
-+
-+
- static void FASTCALL
- normalizeLines(XML_Char *s)
- {
-diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
-index 7b6d9fb..0b5bcf1 100644
---- a/expat/tests/runtests.c
-+++ b/expat/tests/runtests.c
-@@ -39,6 +39,8 @@
- #endif
- 
- #include 
-+#include 
-+#include  // for SIZE_MAX
- #include 
- #include 
- #include 
-@@ -1915,6 +1917,87 @@ START_TEST(test_wfc_no_recursive_entity_refs)
- }
- END_TEST
- 
-+START_TEST(test_no_indirectly_recursive_entity_refs) {
-+  struct TestCase {
-+    const char *doc;
-+    bool usesParameterEntities;
-+  };
-+
-+  const struct TestCase cases[] = {
-+      // general entity + character data
-+      {"\n"
-+       "  \n"
-+       "]>&e2;\n",
-+       false},
-+
-+      // general entity + attribute value
-+      {"\n"
-+       "  \n"
-+       "]>\n",
-+       false},
-+
-+      // parameter entity
-+      {"\n"
-+       "  \n"
-+       "  \">\n"
-+       "  %define_g;\n"
-+       "]>\n"
-+       "\n",
-+       true},
-+  };
-+  const XML_Bool reset_or_not[] = {XML_TRUE, XML_FALSE};
-+
-+  for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
-+    for (size_t j = 0; j < sizeof(reset_or_not) / sizeof(reset_or_not[0]);
-+         j++) {
-+      const XML_Bool reset_wanted = reset_or_not[j];
-+      const char *const doc = cases[i].doc;
-+      const bool usesParameterEntities = cases[i].usesParameterEntities;
-+
-+#ifdef XML_DTD // both GE and DTD
-+      const bool rejection_expected = true;
-+#else             // neither DTD nor GE
-+      const bool rejection_expected = false;
-+#endif
-+
-+      XML_Parser parser = XML_ParserCreate(NULL);
-+
-+#ifdef XML_DTD
-+      if (usesParameterEntities) {
-+        assert_true(
-+            XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS)
-+            == 1);
-+      }
-+#endif // XML_DTD
-+
-+      const enum XML_Status status
-+          = _XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc),
-+                                    /*isFinal*/ XML_TRUE);
-+
-+      if (rejection_expected) {
-+        assert_true(status == XML_STATUS_ERROR);
-+        assert_true(XML_GetErrorCode(parser) == XML_ERROR_RECURSIVE_ENTITY_REF);
-+      } else {
-+        assert_true(status == XML_STATUS_OK);
-+      }
-+
-+      if (reset_wanted) {
-+        // This covers free'ing of (eventually) all three open entity lists by
-+        // XML_ParserReset.
-+        XML_ParserReset(parser, NULL);
-+      }
-+
-+      // This covers free'ing of (eventually) all three open entity lists by
-+      // XML_ParserFree (unless XML_ParserReset has already done that above).
-+      XML_ParserFree(parser);
-+    }
-+  }
-+}
-+END_TEST
-+
- /* Test incomplete external entities are faulted */
- START_TEST(test_ext_entity_invalid_parse)
- {
-@@ -5352,6 +5435,34 @@ START_TEST(test_suspend_epilog)
- }
- END_TEST
- 
-+static void XMLCALL
-+suspending_end_handler(void *userData,
-+                       const XML_Char *UNUSED_P(s))
-+{
-+    XML_StopParser((XML_Parser)userData, 1);
-+}
-+
-+START_TEST(test_suspend_in_sole_empty_tag)
-+{
-+    const char *text = "";
-+    enum XML_Status rc;
-+
-+    XML_SetEndElementHandler(parser, suspending_end_handler);
-+    XML_SetUserData(parser, parser);
-+    rc = _XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
-+                                 XML_TRUE);
-+    if (rc == XML_STATUS_ERROR)
-+        xml_failure(parser);
-+    else if (rc != XML_STATUS_SUSPENDED)
-+        fail("Suspend not triggered");
-+    rc = XML_ResumeParser(parser);
-+    if (rc == XML_STATUS_ERROR)
-+        xml_failure(parser);
-+    else if (rc != XML_STATUS_OK)
-+        fail("Resume failed");
-+}
-+END_TEST
-+
- START_TEST(test_unfinished_epilog)
- {
-     const char *text = "<";
-@@ -5671,6 +5782,7 @@ END_TEST
- typedef struct ext_hdlr_data {
-     const char *parse_text;
-     XML_ExternalEntityRefHandler handler;
-+    CharData *storage;
- } ExtHdlrData;
- 
- static int XMLCALL
-@@ -5708,7 +5820,8 @@ START_TEST(test_skipped_null_loaded_ext_entity)
-         "\n"
-         "\n"
-         "%pe2;\n",
--        external_entity_null_loader
-+        external_entity_null_loader,
-+        NULL
-     };
- 
-     XML_SetUserData(parser, &test_data);
-@@ -5729,6 +5842,7 @@ START_TEST(test_skipped_unloaded_ext_entity)
-         "\n"
-         "\n"
-         "%pe2;\n",
-+        NULL,
-         NULL
-     };
- 
-@@ -6957,6 +7071,24 @@ accumulate_entity_decl(void *userData,
-     CharData_AppendXMLChars(storage, XCS("\n"), 1);
- }
- 
-+typedef struct {
-+  XML_Parser parser;
-+  CharData *storage;
-+} ParserPlusStorage;
-+
-+static void XMLCALL
-+accumulate_char_data_and_suspend(void *userData, const XML_Char *s, int len) {
-+  ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData;
-+
-+  CharData_AppendXMLChars(parserPlusStorage->storage, s, len);
-+
-+  for (int i = 0; i < len; i++) {
-+    if (s[i] == 'Z') {
-+      XML_StopParser(parserPlusStorage->parser, /*resumable=*/XML_TRUE);
-+      break;
-+    }
-+  }
-+}
- 
- START_TEST(test_utf16_pe)
- {
-@@ -7423,6 +7555,176 @@ START_TEST(test_empty_element_abort)
- }
- END_TEST
- 
-+/* Test a possible early return location in internalEntityProcessor */
-+START_TEST(test_entity_ref_no_elements) {
-+  const char *const text = "\n"
-+                           "]> &e1;"; // intentionally missing newline
-+
-+  XML_Parser parser = XML_ParserCreate(NULL);
-+  assert_true(_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
-+              == XML_STATUS_ERROR);
-+  assert_true(XML_GetErrorCode(parser) == XML_ERROR_NO_ELEMENTS);
-+  XML_ParserFree(parser);
-+}
-+END_TEST
-+
-+/* Tests if chained entity references lead to unbounded recursion */
-+START_TEST(test_deep_nested_entity) {
-+  const size_t N_LINES = 60000;
-+  const size_t SIZE_PER_LINE = 50;
-+
-+  char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
-+  if (text == NULL) {
-+    fail("malloc failed");
-+  }
-+
-+  char *textPtr = text;
-+
-+  // Create the XML
-+  textPtr += snprintf(textPtr, SIZE_PER_LINE,
-+                      "\n");
-+
-+  for (size_t i = 1; i < N_LINES; ++i) {
-+    textPtr += snprintf(textPtr, SIZE_PER_LINE, "  \n",
-+                        (long unsigned)i, (long unsigned)(i - 1));
-+  }
-+
-+  snprintf(textPtr, SIZE_PER_LINE, "]> &s%lu;\n",
-+           (long unsigned)(N_LINES - 1));
-+
-+  const XML_Char *const expected = XCS("deepText");
-+
-+  CharData storage;
-+  CharData_Init(&storage);
-+
-+  XML_Parser parser = XML_ParserCreate(NULL);
-+
-+  XML_SetCharacterDataHandler(parser, accumulate_characters);
-+  XML_SetUserData(parser, &storage);
-+
-+  if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
-+      == XML_STATUS_ERROR)
-+    xml_failure(parser);
-+
-+  CharData_CheckXMLChars(&storage, expected);
-+  XML_ParserFree(parser);
-+  free(text);
-+}
-+END_TEST
-+
-+/* Tests if chained entity references in attributes
-+lead to unbounded recursion */
-+START_TEST(test_deep_nested_attribute_entity) {
-+  const size_t N_LINES = 60000;
-+  const size_t SIZE_PER_LINE = 100;
-+
-+  char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
-+  if (text == NULL) {
-+    fail("malloc failed");
-+  }
-+
-+  char *textPtr = text;
-+
-+  // Create the XML
-+  textPtr += snprintf(textPtr, SIZE_PER_LINE,
-+                      "\n");
-+
-+  for (size_t i = 1; i < N_LINES; ++i) {
-+    textPtr += snprintf(textPtr, SIZE_PER_LINE, "  \n",
-+                        (long unsigned)i, (long unsigned)(i - 1));
-+  }
-+
-+  snprintf(textPtr, SIZE_PER_LINE, "]> mainText\n",
-+           (long unsigned)(N_LINES - 1));
-+
-+  AttrInfo doc_info[] = {{XCS("name"), XCS("deepText")}, {NULL, NULL}};
-+  ElementInfo info[] = {{XCS("foo"), 1, NULL, NULL}, {NULL, 0, NULL, NULL}};
-+  info[0].attributes = doc_info;
-+
-+  XML_SetStartElementHandler(parser, counting_start_element_handler);
-+  XML_SetUserData(parser, &info);
-+
-+  if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
-+      == XML_STATUS_ERROR)
-+    xml_failure(parser);
-+
-+  free(text);
-+}
-+END_TEST
-+
-+START_TEST(test_deep_nested_entity_delayed_interpretation) {
-+  const size_t N_LINES = 70000;
-+  const size_t SIZE_PER_LINE = 100;
-+
-+  char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
-+  if (text == NULL) {
-+    fail("malloc failed");
-+  }
-+
-+  char *textPtr = text;
-+
-+  // Create the XML
-+  textPtr += snprintf(textPtr, SIZE_PER_LINE,
-+                      "\n");
-+
-+  for (size_t i = 1; i < N_LINES; ++i) {
-+    textPtr += snprintf(textPtr, SIZE_PER_LINE,
-+                        "  \n", (long unsigned)i,
-+                        (long unsigned)(i - 1));
-+  }
-+
-+  snprintf(textPtr, SIZE_PER_LINE,
-+           "  \">\n"
-+           "  %%define_g;\n"
-+           "]>\n"
-+           "\n",
-+           (long unsigned)(N_LINES - 1));
-+
-+  XML_Parser parser = XML_ParserCreate(NULL);
-+
-+  XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
-+  if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
-+      == XML_STATUS_ERROR)
-+    xml_failure(parser);
-+
-+  XML_ParserFree(parser);
-+  free(text);
-+}
-+END_TEST
-+
-+START_TEST(test_nested_entity_suspend_2) {
-+  const char *const text = "\n"
-+                           "  \n"
-+                           "  \n"
-+                           "]>\n"
-+                           "&ge3;";
-+  const XML_Char *const expected = XCS("head3") XCS("head2") XCS("head1")
-+      XCS("Z") XCS("tail1") XCS("tail2") XCS("tail3");
-+  CharData storage;
-+  CharData_Init(&storage);
-+  XML_Parser parser = XML_ParserCreate(NULL);
-+  ParserPlusStorage parserPlusStorage = {parser, &storage};
-+
-+  XML_SetCharacterDataHandler(parser, accumulate_char_data_and_suspend);
-+  XML_SetUserData(parser, &parserPlusStorage);
-+
-+  enum XML_Status status = XML_Parse(parser, text, (int)strlen(text), XML_TRUE);
-+  while (status == XML_STATUS_SUSPENDED) {
-+    status = XML_ResumeParser(parser);
-+  }
-+  if (status != XML_STATUS_OK)
-+    xml_failure(parser);
-+
-+  CharData_CheckXMLChars(&storage, expected);
-+  XML_ParserFree(parser);
-+}
-+END_TEST
-+
- /* Regression test for quadratic parsing on large tokens */
- START_TEST(test_big_tokens_take_linear_time) {
-   const char *const too_slow_failure_message
-@@ -7599,6 +7901,69 @@ struct element_decl_data {
-   int count;
- };
- 
-+typedef struct {
-+  XML_Parser parser;
-+  int deep;
-+} DataIssue240;
-+
-+static void
-+start_element_issue_240(void *userData, const XML_Char *UNUSED_P(name),
-+                        const XML_Char **UNUSED_P(atts)) {
-+  DataIssue240 *mydata = (DataIssue240 *)userData;
-+  mydata->deep++;
-+}
-+
-+static void
-+end_element_issue_240(void *userData, const XML_Char *UNUSED_P(name)) {
-+  DataIssue240 *mydata = (DataIssue240 *)userData;
-+  mydata->deep--;
-+  if (mydata->deep == 0) {
-+    XML_StopParser(mydata->parser, 0);
-+  }
-+}
-+
-+START_TEST(test_misc_stop_during_end_handler_issue_240_1) {
-+  XML_Parser parser;
-+  DataIssue240 *mydata;
-+  enum XML_Status result;
-+  const char *const doc1 = "";
-+
-+  parser = XML_ParserCreate(NULL);
-+  XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
-+  mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
-+  mydata->parser = parser;
-+  mydata->deep = 0;
-+  XML_SetUserData(parser, mydata);
-+
-+  result = XML_Parse(parser, doc1, (int)strlen(doc1), 1);
-+  XML_ParserFree(parser);
-+  free(mydata);
-+  if (result != XML_STATUS_ERROR)
-+    fail("Stopping the parser did not work as expected");
-+}
-+END_TEST
-+
-+START_TEST(test_misc_stop_during_end_handler_issue_240_2) {
-+  XML_Parser parser;
-+  DataIssue240 *mydata;
-+  enum XML_Status result;
-+  const char *const doc2 = "";
-+
-+  parser = XML_ParserCreate(NULL);
-+  XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
-+  mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
-+  mydata->parser = parser;
-+  mydata->deep = 0;
-+  XML_SetUserData(parser, mydata);
-+
-+  result = XML_Parse(parser, doc2, (int)strlen(doc2), 1);
-+  XML_ParserFree(parser);
-+  free(mydata);
-+  if (result != XML_STATUS_ERROR)
-+    fail("Stopping the parser did not work as expected");
-+}
-+END_TEST
-+
- static void
- element_decl_counter(void *userData, const XML_Char *UNUSED_P(name), XML_Content *model) {
-   struct element_decl_data *testdata = (struct element_decl_data *)userData;
-@@ -8939,6 +9304,29 @@ static void *duff_reallocator(void *ptr, size_t size)
-     return realloc(ptr, size);
- }
- 
-+// Portable remake of strndup(3) for C99; does not care about space efficiency
-+static char *
-+portable_strndup(const char *s, size_t n) {
-+  if ((s == NULL) || (n == SIZE_MAX)) {
-+    errno = EINVAL;
-+    return NULL;
-+  }
-+
-+  char *const buffer = (char *)malloc(n + 1);
-+  if (buffer == NULL) {
-+    errno = ENOMEM;
-+    return NULL;
-+  }
-+
-+  errno = 0;
-+
-+  memcpy(buffer, s, n);
-+
-+  buffer[n] = '\0';
-+
-+  return buffer;
-+}
-+
- /* Test that a failure to allocate the parser structure fails gracefully */
- START_TEST(test_misc_alloc_create_parser)
- {
-@@ -9174,7 +9562,7 @@ END_TEST
- START_TEST(test_misc_stopparser_rejects_unstarted_parser) {
-   const XML_Bool cases[] = {XML_TRUE, XML_FALSE};
-   for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
--    const XML_Bool resumable = cases[i];
-+    resumable = cases[i];
-     XML_Parser parser = XML_ParserCreate(NULL);
-     assert_true(XML_GetErrorCode(parser) == XML_ERROR_NONE);
-     assert_true(XML_StopParser(parser, resumable) == XML_STATUS_ERROR);
-@@ -9184,6 +9572,105 @@ START_TEST(test_misc_stopparser_rejects_unstarted_parser) {
- }
- END_TEST
- 
-+/* Adaptation of accumulate_characters that takes ExtHdlrData input to work with
-+ * test_renter_loop_finite_content below */
-+static void XMLCALL
-+accumulate_characters_ext_handler(void *userData, const XML_Char *s, int len) {
-+  ExtHdlrData *const test_data = (ExtHdlrData *)userData;
-+  CharData_AppendXMLChars(test_data->storage, s, len);
-+}
-+
-+/* Test that internalEntityProcessor does not re-enter forever;
-+ * based on files tests/xmlconf/xmltest/valid/ext-sa/012.{xml,ent} */
-+START_TEST(test_renter_loop_finite_content) {
-+  CharData storage;
-+  CharData_Init(&storage);
-+  const char *const text = "\n"
-+                           "\n"
-+                           "\n"
-+                           "\n"
-+                           "\n"
-+                           "\n"
-+                           "]>\n"
-+                           "&e1;\n";
-+  ExtHdlrData test_data = {"&e4;\n", external_entity_null_loader, &storage};
-+  const XML_Char *const expected = XCS("(e5)\n");
-+
-+  XML_Parser parser = XML_ParserCreate(NULL);
-+  assert_true(parser != NULL);
-+  XML_SetUserData(parser, &test_data);
-+  XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader);
-+  XML_SetCharacterDataHandler(parser, accumulate_characters_ext_handler);
-+  if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
-+      == XML_STATUS_ERROR)
-+    xml_failure(parser);
-+
-+  CharData_CheckXMLChars(&storage, expected);
-+  XML_ParserFree(parser);
-+}
-+END_TEST
-+
-+// Inspired by function XML_OriginalString of Perl's XML::Parser
-+static char *
-+dup_original_string(XML_Parser parser) {
-+  const int byte_count = XML_GetCurrentByteCount(parser);
-+
-+  assert_true(byte_count >= 0);
-+
-+  int offset = -1;
-+  int size = -1;
-+
-+  const char *const context = XML_GetInputContext(parser, &offset, &size);
-+
-+#if XML_CONTEXT_BYTES > 0
-+  assert_true(context != NULL);
-+  assert_true(offset >= 0);
-+  assert_true(size >= 0);
-+  return portable_strndup(context + offset, byte_count);
-+#else
-+  assert_true(context == NULL);
-+  return NULL;
-+#endif
-+}
-+
-+static void
-+on_characters_issue_980(void *userData, const XML_Char *s, int len) {
-+  (void)s;
-+  (void)len;
-+  XML_Parser parser = (XML_Parser)userData;
-+
-+  char *const original_string = dup_original_string(parser);
-+
-+#if XML_CONTEXT_BYTES > 0
-+  assert_true(original_string != NULL);
-+  assert_true(strcmp(original_string, "&draft.day;") == 0);
-+  free(original_string);
-+#else
-+  assert_true(original_string == NULL);
-+#endif
-+}
-+
-+START_TEST(test_misc_expected_event_ptr_issue_980) {
-+  // NOTE: This is a tiny subset of sample "REC-xml-19980210.xml"
-+  //       from Perl's XML::Parser
-+  const char *const doc = "\n"
-+                          "]>\n"
-+                          "&draft.day;\n";
-+
-+  XML_Parser parser = XML_ParserCreate(NULL);
-+  XML_SetUserData(parser, parser);
-+  XML_SetCharacterDataHandler(parser, on_characters_issue_980);
-+
-+  assert_true(_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc),
-+                                      /*isFinal=*/XML_TRUE)
-+              == XML_STATUS_OK);
-+
-+  XML_ParserFree(parser);
-+}
-+END_TEST
-+
- static void
- alloc_setup(void)
- {
-@@ -9809,6 +10296,31 @@ START_TEST(test_alloc_internal_entity)
- END_TEST
- 
- 
-+START_TEST(test_alloc_parameter_entity) {
-+  const char *text = "\">"
-+                     "%param1;"
-+                     "]> &internal;content";
-+  int i;
-+  const int alloc_test_max_repeats = 30;
-+
-+  for (i = 0; i < alloc_test_max_repeats; i++) {
-+    allocation_count = i;
-+    XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
-+    if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
-+        != XML_STATUS_ERROR)
-+      break;
-+    alloc_teardown();
-+    alloc_setup();
-+  }
-+  allocation_count = -1;
-+  if (i == 0)
-+    fail("Parameter entity processed despite duff allocator");
-+  if (i == alloc_test_max_repeats)
-+    fail("Parameter entity not processed at max allocation count");
-+}
-+END_TEST
-+
- /* Test the robustness against allocation failure of element handling
-  * Based on test_dtd_default_handling().
-  */
-@@ -13114,6 +13626,7 @@ make_suite(void)
-     tcase_add_test(tc_basic,
-                    test_entity_with_external_subset_unless_standalone);
-     tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs);
-+    tcase_add_test(tc_basic, test_no_indirectly_recursive_entity_refs);
-     tcase_add_test(tc_basic, test_ext_entity_set_encoding);
-     tcase_add_test(tc_basic, test_ext_entity_no_handler);
-     tcase_add_test(tc_basic, test_ext_entity_set_bom);
-@@ -13203,6 +13716,7 @@ make_suite(void)
-     tcase_add_test(tc_basic, test_abort_epilog);
-     tcase_add_test(tc_basic, test_abort_epilog_2);
-     tcase_add_test(tc_basic, test_suspend_epilog);
-+    tcase_add_test(tc_basic, test_suspend_in_sole_empty_tag);
-     tcase_add_test(tc_basic, test_unfinished_epilog);
-     tcase_add_test(tc_basic, test_partial_char_in_epilog);
-     tcase_add_test(tc_basic, test_hash_collision);
-@@ -13287,6 +13801,14 @@ make_suite(void)
-     tcase_add_test(tc_basic, test_bad_notation);
-     tcase_add_test(tc_basic, test_default_doctype_handler);
-     tcase_add_test(tc_basic, test_empty_element_abort);
-+#ifdef XML_DTD
-+    tcase_add_test(tc_basic, test_entity_ref_no_elements);
-+    tcase_add_test(tc_basic, test_deep_nested_entity);
-+    tcase_add_test(tc_basic, test_deep_nested_attribute_entity);
-+    tcase_add_test(tc_basic,
-+                test_deep_nested_entity_delayed_interpretation);
-+    tcase_add_test(tc_basic, test_nested_entity_suspend_2);
-+#endif
-     tcase_add_test(tc_basic, test_big_tokens_take_linear_time);
-     tcase_add_test(tc_basic, test_set_reparse_deferral);
-     tcase_add_test(tc_basic, test_reparse_deferral_is_inherited);
-@@ -13343,12 +13865,18 @@ make_suite(void)
-     tcase_add_test(tc_misc, test_misc_features);
-     tcase_add_test(tc_misc, test_misc_attribute_leak);
-     tcase_add_test(tc_misc, test_misc_utf16le);
-+    tcase_add_test(tc_misc, test_misc_stop_during_end_handler_issue_240_1);
-+    tcase_add_test(tc_misc, test_misc_stop_during_end_handler_issue_240_2);
- #ifdef XML_DTD
-     tcase_add_test(tc_misc,
-                    test_misc_deny_internal_entity_closing_doctype_issue_317);
- #endif
-     tcase_add_test(tc_misc, test_misc_resumeparser_not_crashing);
-     tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser);
-+#ifdef XML_DTD
-+    tcase_add_test(tc_misc, test_renter_loop_finite_content);
-+#endif
-+    tcase_add_test(tc_misc, test_misc_expected_event_ptr_issue_980);
- 
-     suite_add_tcase(s, tc_alloc);
-     tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
-@@ -13365,6 +13893,9 @@ make_suite(void)
-     tcase_add_test(tc_alloc, test_alloc_external_entity);
-     tcase_add_test(tc_alloc, test_alloc_ext_entity_set_encoding);
-     tcase_add_test(tc_alloc, test_alloc_internal_entity);
-+#ifdef XML_DTD
-+    tcase_add_test(tc_alloc, test_alloc_parameter_entity);
-+#endif
-     tcase_add_test(tc_alloc, test_alloc_dtd_default_handling);
-     tcase_add_test(tc_alloc, test_alloc_explicit_encoding);
-     tcase_add_test(tc_alloc, test_alloc_set_base);
diff --git a/SOURCES/expat-2.2.5-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch b/SOURCES/expat-2.2.5-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch
deleted file mode 100644
index 4ea8add..0000000
--- a/SOURCES/expat-2.2.5-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-commit 22fe2da8e2bc0625d3c492f42d6b716adb36d5c2
-Author: Tomas Korbar 
-Date:   Mon Feb 14 12:09:42 2022 +0100
-
-    CVE-2022-23852
-
-diff --git a/lib/xmlparse.c b/lib/xmlparse.c
-index 85ee0a8..4552680 100644
---- a/lib/xmlparse.c
-+++ b/lib/xmlparse.c
-@@ -161,6 +161,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
-@@ -2026,39 +2029,54 @@ XML_GetBuffer(XML_Parser parser, int len)
-   default: ;
-   }
- 
--  if (len > parser->m_bufferLim - parser->m_bufferEnd) {
--#ifdef XML_CONTEXT_BYTES
-+  if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
-     int keep;
--#endif  /* defined XML_CONTEXT_BYTES */
-     /* Do not invoke signed arithmetic overflow: */
--    int neededSize = (int) ((unsigned)len + (unsigned)(parser->m_bufferEnd - parser->m_bufferPtr));
-+    int neededSize = (int)((unsigned)len
-+                           + (unsigned)EXPAT_SAFE_PTR_DIFF(
-+                               parser->m_bufferEnd, parser->m_bufferPtr));
-     if (neededSize < 0) {
-       parser->m_errorCode = XML_ERROR_NO_MEMORY;
-       return NULL;
-     }
--#ifdef XML_CONTEXT_BYTES
--    keep = (int)(parser->m_bufferPtr - parser->m_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  <= parser->m_bufferLim - parser->m_buffer) {
-+    if (neededSize
-+        <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
- #ifdef XML_CONTEXT_BYTES
--      if (keep < parser->m_bufferPtr - parser->m_buffer) {
--        int offset = (int)(parser->m_bufferPtr - parser->m_buffer) - keep;
--        memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep);
-+      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(parser->m_buffer, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr);
--      parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr);
--      parser->m_bufferPtr = parser->m_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)(parser->m_bufferLim - parser->m_bufferPtr);
-+      int bufferSize
-+          = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
-       if (bufferSize == 0)
-         bufferSize = INIT_BUFFER_SIZE;
-       do {
-@@ -2077,25 +2095,33 @@ XML_GetBuffer(XML_Parser parser, int len)
-       parser->m_bufferLim = newBuf + bufferSize;
- #ifdef XML_CONTEXT_BYTES
-       if (parser->m_bufferPtr) {
--        int keep = (int)(parser->m_bufferPtr - parser->m_buffer);
--        if (keep > XML_CONTEXT_BYTES)
--          keep = XML_CONTEXT_BYTES;
--        memcpy(newBuf, &parser->m_bufferPtr[-keep], parser->m_bufferEnd - parser->m_bufferPtr + keep);
-+        memcpy(newBuf, &parser->m_bufferPtr[-keep],
-+               EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
-+                   + keep);
-         FREE(parser, parser->m_buffer);
-         parser->m_buffer = newBuf;
--        parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr) + keep;
-+        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 {
--        parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr);
-+      } 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 (parser->m_bufferPtr) {
--        memcpy(newBuf, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr);
-+        memcpy(newBuf, parser->m_bufferPtr,
-+               EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
-         FREE(parser, 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;
-       }
--      parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr);
-       parser->m_bufferPtr = parser->m_buffer = newBuf;
- #endif  /* not defined XML_CONTEXT_BYTES */
-     }
-diff --git a/tests/runtests.c b/tests/runtests.c
-index e1f1ad1..ecc6f47 100644
---- a/tests/runtests.c
-+++ b/tests/runtests.c
-@@ -4116,6 +4116,31 @@ START_TEST(test_get_buffer_2)
- }
- END_TEST
- 
-+/* 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)
-+
-+
- /* Test position information macros */
- START_TEST(test_byte_info_at_end)
- {
-@@ -12117,6 +12142,9 @@ make_suite(void)
-     tcase_add_test(tc_basic, test_empty_parse);
-     tcase_add_test(tc_basic, test_get_buffer_1);
-     tcase_add_test(tc_basic, test_get_buffer_2);
-+#if defined(XML_CONTEXT_BYTES)
-+    tcase_add_test(tc_basic, test_get_buffer_3_overflow);
-+#endif
-     tcase_add_test(tc_basic, test_byte_info_at_end);
-     tcase_add_test(tc_basic, test_byte_info_at_error);
-     tcase_add_test(tc_basic, test_byte_info_at_cdata);
diff --git a/SOURCES/expat-2.2.5-Detect-and-prevent-troublesome-left-shifts.patch b/SOURCES/expat-2.2.5-Detect-and-prevent-troublesome-left-shifts.patch
deleted file mode 100644
index cfb28fb..0000000
--- a/SOURCES/expat-2.2.5-Detect-and-prevent-troublesome-left-shifts.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-commit dbac77ddbccb23d507758c591fad622e2b6e6324
-Author: Tomas Korbar 
-Date:   Mon Feb 14 12:20:25 2022 +0100
-
-    CVE-2021-45960
-
-diff --git a/lib/xmlparse.c b/lib/xmlparse.c
-index 2821c6f..c45be0c 100644
---- a/lib/xmlparse.c
-+++ b/lib/xmlparse.c
-@@ -3341,7 +3341,12 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
-   if (nPrefixes) {
-     int j;  /* hash table index */
-     unsigned long version = parser->m_nsAttsVersion;
--    int nsAttsSize = (int)1 << parser->m_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) >> parser->m_nsAttsPower) {  /* true for m_nsAttsPower = 0 */
-@@ -3350,7 +3355,28 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
-       while (nPrefixes >> parser->m_nsAttsPower++);
-       if (parser->m_nsAttsPower < 3)
-         parser->m_nsAttsPower = 3;
--      nsAttsSize = (int)1 << parser->m_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(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT));
-       if (!temp) {
-         /* Restore actual size of memory in m_nsAtts */
diff --git a/SOURCES/expat-2.2.5-Ensure-raw-tagnames-are-safe-exiting-internalEntityParser.patch b/SOURCES/expat-2.2.5-Ensure-raw-tagnames-are-safe-exiting-internalEntityParser.patch
deleted file mode 100644
index 76e6a7c..0000000
--- a/SOURCES/expat-2.2.5-Ensure-raw-tagnames-are-safe-exiting-internalEntityParser.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-commit bfecc1f11ab5f0cc2aa3dc5cb87d3236a87ce61d
-Author: Tomas Korbar 
-Date:   Fri Sep 30 10:52:04 2022 +0200
-
-    Fix CVE-2022-40674
-
-diff --git a/lib/xmlparse.c b/lib/xmlparse.c
-index d47e42c..0cc24f6 100644
---- a/lib/xmlparse.c
-+++ b/lib/xmlparse.c
-@@ -5765,8 +5765,14 @@ internalEntityProcessor(XML_Parser parser,
-   {
-     parser->m_processor = contentProcessor;
-     /* see externalEntityContentProcessor vs contentProcessor */
--    return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, s, end,
--                     nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
-+    result = doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
-+                      s, end, nextPtr,
-+                      (XML_Bool)! parser->m_parsingStatus.finalBuffer);
-+    if (result == XML_ERROR_NONE) {
-+      if (! storeRawNames(parser))
-+        return XML_ERROR_NO_MEMORY;
-+    }
-+    return result;
-   }
- }
- 
-diff --git a/tests/runtests.c b/tests/runtests.c
-index 569ad8c..f3ebbd7 100644
---- a/tests/runtests.c
-+++ b/tests/runtests.c
-@@ -5401,6 +5401,78 @@ START_TEST(test_resume_entity_with_syntax_error)
- }
- END_TEST
- 
-+void
-+suspending_comment_handler(void *userData, const XML_Char *UNUSED_P(data)) {
-+  XML_Parser parser = (XML_Parser)userData;
-+  XML_StopParser(parser, XML_TRUE);
-+}
-+
-+START_TEST(test_suspend_resume_internal_entity_issue_629) {
-+  const char *const text
-+      = "a'>]>&e;\n"
-+        "<"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+        "/>"
-+        "";
-+  const size_t firstChunkSizeBytes = 54;
-+
-+  XML_Parser parser = XML_ParserCreate(NULL);
-+  XML_SetUserData(parser, parser);
-+  XML_SetCommentHandler(parser, suspending_comment_handler);
-+
-+  if (XML_Parse(parser, text, (int)firstChunkSizeBytes, XML_FALSE)
-+      != XML_STATUS_SUSPENDED)
-+    xml_failure(parser);
-+  if (XML_ResumeParser(parser) != XML_STATUS_OK)
-+    xml_failure(parser);
-+  if (XML_Parse(parser, text + firstChunkSizeBytes,
-+                (int)(strlen(text) - firstChunkSizeBytes), XML_TRUE)
-+      != XML_STATUS_OK)
-+    xml_failure(parser);
-+  XML_ParserFree(parser);
-+}
-+END_TEST
-+
-+
- /* Test suspending and resuming in a parameter entity substitution */
- static void XMLCALL
- element_decl_suspender(void *UNUSED_P(userData),
-@@ -12395,6 +12467,7 @@ make_suite(void)
-     tcase_add_test(tc_basic, test_hash_collision);
-     tcase_add_test(tc_basic, test_suspend_resume_internal_entity);
-     tcase_add_test(tc_basic, test_resume_entity_with_syntax_error);
-+    tcase_add_test(tc_basic, test_suspend_resume_internal_entity_issue_629);
-     tcase_add_test(tc_basic, test_suspend_resume_parameter_entity);
-     tcase_add_test(tc_basic, test_restart_on_error);
-     tcase_add_test(tc_basic, test_reject_lt_in_attribute_value);
diff --git a/SOURCES/expat-2.2.5-Prevent-integer-overflow-in-copyString.patch b/SOURCES/expat-2.2.5-Prevent-integer-overflow-in-copyString.patch
deleted file mode 100644
index f67a898..0000000
--- a/SOURCES/expat-2.2.5-Prevent-integer-overflow-in-copyString.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-commit e5b609876e5a266725fba1c377b0ac95c737e6ed
-Author: Tomas Korbar 
-Date:   Mon May 2 12:44:06 2022 +0200
-
-    Fix CVE-2022-25314
-
-diff --git a/lib/xmlparse.c b/lib/xmlparse.c
-index 1f1413f..ceeec26 100644
---- a/lib/xmlparse.c
-+++ b/lib/xmlparse.c
-@@ -7525,7 +7525,7 @@ static XML_Char *
- copyString(const XML_Char *s,
-            const XML_Memory_Handling_Suite *memsuite)
- {
--    int charsRequired = 0;
-+    size_t charsRequired = 0;
-     XML_Char *result;
- 
-     /* First determine how long the string is */
diff --git a/SOURCES/expat-2.2.5-Prevent-integer-overflow-in-storeRawNames.patch b/SOURCES/expat-2.2.5-Prevent-integer-overflow-in-storeRawNames.patch
deleted file mode 100644
index be5927b..0000000
--- a/SOURCES/expat-2.2.5-Prevent-integer-overflow-in-storeRawNames.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-commit 3a4141add108097fa548b196f5950c6663e1578e
-Author: Tomas Korbar 
-Date:   Thu Mar 3 13:50:20 2022 +0100
-
-    CVE-2022-25315
-
-diff --git a/lib/xmlparse.c b/lib/xmlparse.c
-index f0061c8..45fda00 100644
---- a/lib/xmlparse.c
-+++ b/lib/xmlparse.c
-@@ -2508,6 +2508,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 m_tagStack is a stack, we can stop
-        at the first entry that has already been copied; everything
-@@ -2519,7 +2520,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(parser, tag->buf, bufSize);
-       if (temp == NULL)
diff --git a/SOURCES/expat-2.2.5-Prevent-integer-overflow-on-m_groupSize-in-function.patch b/SOURCES/expat-2.2.5-Prevent-integer-overflow-on-m_groupSize-in-function.patch
deleted file mode 100644
index f7e76e6..0000000
--- a/SOURCES/expat-2.2.5-Prevent-integer-overflow-on-m_groupSize-in-function.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-commit 835df27bc1a1eae1ec51b14122ea40c974dd7409
-Author: Tomas Korbar 
-Date:   Mon Feb 14 12:29:20 2022 +0100
-
-    CVE-2021-46143
-
-diff --git a/lib/xmlparse.c b/lib/xmlparse.c
-index c45be0c..22d0a75 100644
---- a/lib/xmlparse.c
-+++ b/lib/xmlparse.c
-@@ -4995,6 +4995,11 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
-     case XML_ROLE_GROUP_OPEN:
-       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 *temp = (char *)REALLOC(parser, parser->m_groupConnector, parser->m_groupSize *= 2);
-           if (temp == NULL) {
-             parser->m_groupSize /= 2;
-@@ -5002,6 +5007,15 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
-           }
-           parser->m_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(parser, dtd->scaffIndex,
-                           parser->m_groupSize * sizeof(int));
-             if (temp == NULL)
diff --git a/SOURCES/expat-2.2.5-Prevent-more-integer-overflows.patch b/SOURCES/expat-2.2.5-Prevent-more-integer-overflows.patch
deleted file mode 100644
index 45e3f8d..0000000
--- a/SOURCES/expat-2.2.5-Prevent-more-integer-overflows.patch
+++ /dev/null
@@ -1,238 +0,0 @@
-commit 0f920007dc157e052fed2fc66a83c6c23ccec0aa
-Author: Tomas Korbar 
-Date:   Mon Feb 14 12:41:56 2022 +0100
-
-    CVE-2022-22822 to CVE-2022-22827
-
-diff --git a/lib/xmlparse.c b/lib/xmlparse.c
-index 22d0a75..6a880af 100644
---- a/lib/xmlparse.c
-+++ b/lib/xmlparse.c
-@@ -3187,13 +3187,38 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
- 
-   /* get the attributes from the tokenizer */
-   n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
-+
-+  /* Detect and prevent integer overflow */
-+  if (n > INT_MAX - nDefaultAtts) {
-+    return XML_ERROR_NO_MEMORY;
-+  }
-+
-   if (n + nDefaultAtts > parser->m_attsSize) {
-     int oldAttsSize = parser->m_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;
-+    }
-+
-     parser->m_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(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE));
-     if (temp == NULL) {
-       parser->m_attsSize = oldAttsSize;
-@@ -3201,6 +3226,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
-     }
-     parser->m_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(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo));
-     if (temp2 == NULL) {
-       parser->m_attsSize = oldAttsSize;
-@@ -3535,9 +3571,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(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
-     if (!uri)
-       return XML_ERROR_NO_MEMORY;
-@@ -3638,6 +3695,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
-   if (parser->m_freeBindingList) {
-     b = parser->m_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(parser, b->uri,
-                           sizeof(XML_Char) * (len + EXPAND_SPARE));
-       if (temp == NULL)
-@@ -3651,6 +3723,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
-     b = (BINDING *)MALLOC(parser, 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(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
-     if (!b->uri) {
-       FREE(parser, b);
-@@ -6058,7 +6145,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(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
-       if (temp == NULL)
-@@ -6733,8 +6837,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)
-@@ -7100,6 +7216,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(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
-       if (temp == NULL)
-@@ -7176,8 +7306,26 @@ 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(parser, allocsize);
-   if (!ret)
diff --git a/SOURCES/expat-2.2.5-Prevent-stack-exhaustion-in-build_model.patch b/SOURCES/expat-2.2.5-Prevent-stack-exhaustion-in-build_model.patch
deleted file mode 100644
index 52af442..0000000
--- a/SOURCES/expat-2.2.5-Prevent-stack-exhaustion-in-build_model.patch
+++ /dev/null
@@ -1,228 +0,0 @@
-commit f1b61e6fbaedbb2bbea736269a015d97d4df46ce
-Author: Tomas Korbar 
-Date:   Tue May 3 13:42:54 2022 +0200
-
-    Fix CVE-2022-25313
-
-diff --git a/lib/xmlparse.c b/lib/xmlparse.c
-index ceeec26..d47e42c 100644
---- a/lib/xmlparse.c
-+++ b/lib/xmlparse.c
-@@ -7458,12 +7458,14 @@ build_node(XML_Parser parser,
- }
- 
- static XML_Content *
--build_model (XML_Parser parser)
--{
--  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
-+build_model(XML_Parser parser) {
-+  /* Function build_model transforms the existing parser->m_dtd->scaffold
-+   * array of CONTENT_SCAFFOLD tree nodes into a new array of
-+   * XML_Content tree nodes followed by a gapless list of zero-terminated
-+   * strings. */
-+  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
-   XML_Content *ret;
--  XML_Content *cpos;
--  XML_Char * str;
-+  XML_Char *str; /* the current string writing location */
- 
-   /* Detect and prevent integer overflow.
-    * The preprocessor guard addresses the "always false" warning
-@@ -7486,13 +7488,99 @@ build_model (XML_Parser parser)
-                             + (dtd->contentStringLen * sizeof(XML_Char)));
- 
-   ret = (XML_Content *)MALLOC(parser, allocsize);
--  if (!ret)
-+  if (! ret)
-     return NULL;
- 
--  str =  (XML_Char *) (&ret[dtd->scaffCount]);
--  cpos = &ret[1];
-+  /* What follows is an iterative implementation (of what was previously done
-+   * recursively in a dedicated function called "build_node".  The old recursive
-+   * build_node could be forced into stack exhaustion from input as small as a
-+   * few megabyte, and so that was a security issue.  Hence, a function call
-+   * stack is avoided now by resolving recursion.)
-+   *
-+   * The iterative approach works as follows:
-+   *
-+   * - We have two writing pointers, both walking up the result array; one does
-+   *   the work, the other creates "jobs" for its colleague to do, and leads
-+   *   the way:
-+   *
-+   *   - The faster one, pointer jobDest, always leads and writes "what job
-+   *     to do" by the other, once they reach that place in the
-+   *     array: leader "jobDest" stores the source node array index (relative
-+   *     to array dtd->scaffold) in field "numchildren".
-+   *
-+   *   - The slower one, pointer dest, looks at the value stored in the
-+   *     "numchildren" field (which actually holds a source node array index
-+   *     at that time) and puts the real data from dtd->scaffold in.
-+   *
-+   * - Before the loop starts, jobDest writes source array index 0
-+   *   (where the root node is located) so that dest will have something to do
-+   *   when it starts operation.
-+   *
-+   * - Whenever nodes with children are encountered, jobDest appends
-+   *   them as new jobs, in order.  As a result, tree node siblings are
-+   *   adjacent in the resulting array, for example:
-+   *
-+   *     [0] root, has two children
-+   *       [1] first child of 0, has three children
-+   *         [3] first child of 1, does not have children
-+   *         [4] second child of 1, does not have children
-+   *         [5] third child of 1, does not have children
-+   *       [2] second child of 0, does not have children
-+   *
-+   *   Or (the same data) presented in flat array view:
-+   *
-+   *     [0] root, has two children
-+   *
-+   *     [1] first child of 0, has three children
-+   *     [2] second child of 0, does not have children
-+   *
-+   *     [3] first child of 1, does not have children
-+   *     [4] second child of 1, does not have children
-+   *     [5] third child of 1, does not have children
-+   *
-+   * - The algorithm repeats until all target array indices have been processed.
-+   */
-+  XML_Content *dest = ret; /* tree node writing location, moves upwards */
-+  XML_Content *const destLimit = &ret[dtd->scaffCount];
-+  XML_Content *jobDest = ret; /* next free writing location in target array */
-+  str = (XML_Char *)&ret[dtd->scaffCount];
-+
-+  /* Add the starting job, the root node (index 0) of the source tree  */
-+  (jobDest++)->numchildren = 0;
-+
-+  for (; dest < destLimit; dest++) {
-+    /* Retrieve source tree array index from job storage */
-+    const int src_node = (int)dest->numchildren;
-+
-+    /* Convert item */
-+    dest->type = dtd->scaffold[src_node].type;
-+    dest->quant = dtd->scaffold[src_node].quant;
-+    if (dest->type == XML_CTYPE_NAME) {
-+      const XML_Char *src;
-+      dest->name = str;
-+      src = dtd->scaffold[src_node].name;
-+      for (;;) {
-+        *str++ = *src;
-+        if (! *src)
-+          break;
-+        src++;
-+      }
-+      dest->numchildren = 0;
-+      dest->children = NULL;
-+    } else {
-+      unsigned int i;
-+      int cn;
-+      dest->name = NULL;
-+      dest->numchildren = dtd->scaffold[src_node].childcnt;
-+      dest->children = jobDest;
-+
-+      /* Append scaffold indices of children to array */
-+      for (i = 0, cn = dtd->scaffold[src_node].firstchild;
-+           i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib)
-+        (jobDest++)->numchildren = (unsigned int)cn;
-+    }
-+  }
- 
--  build_node(parser, 0, ret, &cpos, &str);
-   return ret;
- }
- 
-diff --git a/tests/runtests.c b/tests/runtests.c
-index eacd163..569ad8c 100644
---- a/tests/runtests.c
-+++ b/tests/runtests.c
-@@ -2848,6 +2848,81 @@ START_TEST(test_dtd_elements)
- }
- END_TEST
- 
-+static void XMLCALL
-+element_decl_check_model(void *UNUSED_P(userData), const XML_Char *name,
-+                         XML_Content *model) {
-+  uint32_t errorFlags = 0;
-+
-+  /* Expected model array structure is this:
-+   * [0] (type 6, quant 0)
-+   *   [1] (type 5, quant 0)
-+   *     [3] (type 4, quant 0, name "bar")
-+   *     [4] (type 4, quant 0, name "foo")
-+   *     [5] (type 4, quant 3, name "xyz")
-+   *   [2] (type 4, quant 2, name "zebra")
-+   */
-+  errorFlags |= ((xcstrcmp(name, XCS("junk")) == 0) ? 0 : (1u << 0));
-+  errorFlags |= ((model != NULL) ? 0 : (1u << 1));
-+
-+  errorFlags |= ((model[0].type == XML_CTYPE_SEQ) ? 0 : (1u << 2));
-+  errorFlags |= ((model[0].quant == XML_CQUANT_NONE) ? 0 : (1u << 3));
-+  errorFlags |= ((model[0].numchildren == 2) ? 0 : (1u << 4));
-+  errorFlags |= ((model[0].children == &model[1]) ? 0 : (1u << 5));
-+  errorFlags |= ((model[0].name == NULL) ? 0 : (1u << 6));
-+
-+  errorFlags |= ((model[1].type == XML_CTYPE_CHOICE) ? 0 : (1u << 7));
-+  errorFlags |= ((model[1].quant == XML_CQUANT_NONE) ? 0 : (1u << 8));
-+  errorFlags |= ((model[1].numchildren == 3) ? 0 : (1u << 9));
-+  errorFlags |= ((model[1].children == &model[3]) ? 0 : (1u << 10));
-+  errorFlags |= ((model[1].name == NULL) ? 0 : (1u << 11));
-+
-+  errorFlags |= ((model[2].type == XML_CTYPE_NAME) ? 0 : (1u << 12));
-+  errorFlags |= ((model[2].quant == XML_CQUANT_REP) ? 0 : (1u << 13));
-+  errorFlags |= ((model[2].numchildren == 0) ? 0 : (1u << 14));
-+  errorFlags |= ((model[2].children == NULL) ? 0 : (1u << 15));
-+  errorFlags |= ((xcstrcmp(model[2].name, XCS("zebra")) == 0) ? 0 : (1u << 16));
-+
-+  errorFlags |= ((model[3].type == XML_CTYPE_NAME) ? 0 : (1u << 17));
-+  errorFlags |= ((model[3].quant == XML_CQUANT_NONE) ? 0 : (1u << 18));
-+  errorFlags |= ((model[3].numchildren == 0) ? 0 : (1u << 19));
-+  errorFlags |= ((model[3].children == NULL) ? 0 : (1u << 20));
-+  errorFlags |= ((xcstrcmp(model[3].name, XCS("bar")) == 0) ? 0 : (1u << 21));
-+
-+  errorFlags |= ((model[4].type == XML_CTYPE_NAME) ? 0 : (1u << 22));
-+  errorFlags |= ((model[4].quant == XML_CQUANT_NONE) ? 0 : (1u << 23));
-+  errorFlags |= ((model[4].numchildren == 0) ? 0 : (1u << 24));
-+  errorFlags |= ((model[4].children == NULL) ? 0 : (1u << 25));
-+  errorFlags |= ((xcstrcmp(model[4].name, XCS("foo")) == 0) ? 0 : (1u << 26));
-+
-+  errorFlags |= ((model[5].type == XML_CTYPE_NAME) ? 0 : (1u << 27));
-+  errorFlags |= ((model[5].quant == XML_CQUANT_PLUS) ? 0 : (1u << 28));
-+  errorFlags |= ((model[5].numchildren == 0) ? 0 : (1u << 29));
-+  errorFlags |= ((model[5].children == NULL) ? 0 : (1u << 30));
-+  errorFlags |= ((xcstrcmp(model[5].name, XCS("xyz")) == 0) ? 0 : (1u << 31));
-+
-+  XML_SetUserData(parser, (void *)(uintptr_t)errorFlags);
-+  XML_FreeContentModel(parser, model);
-+}
-+
-+START_TEST(test_dtd_elements_nesting) {
-+  // Payload inspired by a test in Perl's XML::Parser
-+  const char *text = "\n"
-+                     "]>\n"
-+                     "";
-+
-+  XML_SetUserData(parser, (void *)(uintptr_t)-1);
-+
-+  XML_SetElementDeclHandler(parser, element_decl_check_model);
-+  if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE)
-+      == XML_STATUS_ERROR)
-+    xml_failure(parser);
-+
-+  if ((uint32_t)(uintptr_t)XML_GetUserData(parser) != 0)
-+    fail("Element declaration model regression detected");
-+}
-+END_TEST
-+
- /* Test foreign DTD handling */
- START_TEST(test_set_foreign_dtd)
- {
-@@ -12256,6 +12331,7 @@ make_suite(void)
-     tcase_add_test(tc_basic, test_memory_allocation);
-     tcase_add_test(tc_basic, test_default_current);
-     tcase_add_test(tc_basic, test_dtd_elements);
-+    tcase_add_test(tc_basic, test_dtd_elements_nesting);
-     tcase_add_test(tc_basic, test_set_foreign_dtd);
-     tcase_add_test(tc_basic, test_foreign_dtd_not_standalone);
-     tcase_add_test(tc_basic, test_invalid_foreign_dtd);
diff --git a/SOURCES/expat-2.2.5-Protect-against-malicious-namespace-declarations.patch b/SOURCES/expat-2.2.5-Protect-against-malicious-namespace-declarations.patch
deleted file mode 100644
index acd46fb..0000000
--- a/SOURCES/expat-2.2.5-Protect-against-malicious-namespace-declarations.patch
+++ /dev/null
@@ -1,229 +0,0 @@
-commit fd5473ef5873048eadef344a1f16f71ad8eefe99
-Author: Tomas Korbar 
-Date:   Mon Mar 14 12:17:41 2022 +0100
-
-    Protect against malicious namespace declarations
-
-diff --git a/lib/xmlparse.c b/lib/xmlparse.c
-index 581b9a4..6f3510b 100644
---- a/lib/xmlparse.c
-+++ b/lib/xmlparse.c
-@@ -661,8 +661,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);
- }
- 
-@@ -1288,8 +1287,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser,
-      would be otherwise.
-   */
-   if (parser->m_ns) {
--    XML_Char tmp[2];
--    *tmp = parser->m_namespaceSeparator;
-+    XML_Char tmp[2] = {parser->m_namespaceSeparator, 0};
-     parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
-   }
-   else {
-@@ -3640,6 +3638,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().
- */
-@@ -3700,6 +3809,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 ecc6f47..eabd55d 100644
---- a/tests/runtests.c
-+++ b/tests/runtests.c
-@@ -7950,6 +7950,38 @@ START_TEST(test_ns_double_colon_doctype)
- }
- 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, "", XCS('\n')},
-+      {XML_STATUS_ERROR, "", XCS('\n')},
-+      {XML_STATUS_OK, "", XCS(':')},
-+  };
-+
-+  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
-+
-+
- /* Control variable; the number of times duff_allocator() will successfully allocate */
- #define ALLOC_ALWAYS_SUCCEED (-1)
- #define REALLOC_ALWAYS_SUCCEED (-1)
-@@ -12290,6 +12322,7 @@ make_suite(void)
-     tcase_add_test(tc_namespace, test_ns_utf16_doctype);
-     tcase_add_test(tc_namespace, test_ns_invalid_doctype);
-     tcase_add_test(tc_namespace, test_ns_double_colon_doctype);
-+    tcase_add_test(tc_namespace, test_ns_separator_in_uri);
- 
-     suite_add_tcase(s, tc_misc);
-     tcase_add_checked_fixture(tc_misc, NULL, basic_teardown);
diff --git a/SOURCES/expat-2.2.5-doc2man.patch b/SOURCES/expat-2.2.5-doc2man.patch
deleted file mode 100644
index 59c7136..0000000
--- a/SOURCES/expat-2.2.5-doc2man.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-diff -uap libexpat-R_2_2_5/expat/configure.ac.doc2man libexpat-R_2_2_5/expat/configure.ac
---- libexpat-R_2_2_5/expat/configure.ac.doc2man
-+++ libexpat-R_2_2_5/expat/configure.ac
-@@ -241,7 +241,7 @@ AS_IF([test "x$with_docbook" != xno],
-   [if test "x$with_docbook" != xcheck; then 
-     AC_MSG_ERROR([Required program 'docbook2x-man' not found.])])])
- 
--AM_CONDITIONAL(WITH_DOCBOOK, [test x${DOCBOOK_TO_MAN} != x])
-+AM_CONDITIONAL(WITH_DOCBOOK, [test "x${DOCBOOK_TO_MAN}" != x])
- 
- AC_CONFIG_FILES([Makefile expat.pc])
- AC_CONFIG_FILES([
-diff -uap libexpat-R_2_2_5/expat/doc/Makefile.am.doc2man libexpat-R_2_2_5/expat/doc/Makefile.am
---- libexpat-R_2_2_5/expat/doc/Makefile.am.doc2man
-+++ libexpat-R_2_2_5/expat/doc/Makefile.am
-@@ -32,8 +32,9 @@ dist_man_MANS = xmlwf.1
- 
- xmlwf.1: xmlwf.xml
- if WITH_DOCBOOK
-+	-rm -f $@
- 	$(DOCBOOK_TO_MAN) $<
--	mv XMLWF.1 $@
-+	test -f $@ || mv XMLWF.1 $@
- else
- 	@echo 'ERROR: Configure with --with-docbook for "make dist".' 1>&2
- 	@false
diff --git a/SPECS/expat.spec b/SPECS/expat.spec
deleted file mode 100644
index a4080f1..0000000
--- a/SPECS/expat.spec
+++ /dev/null
@@ -1,430 +0,0 @@
-%global unversion 2_2_5
-
-Summary: An XML parser library
-Name: expat
-Version: %(echo %{unversion} | sed 's/_/./g')
-Release: 17%{?dist}
-Source: https://github.com/libexpat/libexpat/archive/R_%{unversion}.tar.gz#/expat-%{version}.tar.gz
-URL: https://libexpat.github.io/
-License: MIT
-BuildRequires: autoconf, libtool, xmlto, gcc-c++
-Patch0: expat-2.2.5-doc2man.patch
-Patch1: expat-2.2.5-CVE-2018-20843.patch
-Patch2: expat-2.2.5-CVE-2019-15903.patch
-Patch3:	expat-2.2.5-Detect-and-prevent-integer-overflow-in-XML_GetBuffer.patch
-Patch4:	expat-2.2.5-Detect-and-prevent-troublesome-left-shifts.patch
-Patch5:	expat-2.2.5-Prevent-integer-overflow-on-m_groupSize-in-function.patch
-Patch6:	expat-2.2.5-Prevent-more-integer-overflows.patch
-Patch7: expat-2.2.5-Protect-against-malicious-namespace-declarations.patch
-Patch8: expat-2.2.5-Add-missing-validation-of-encoding.patch
-Patch9: expat-2.2.5-Prevent-integer-overflow-in-storeRawNames.patch
-Patch10: expat-2.2.5-Prevent-integer-overflow-in-copyString.patch
-Patch11: expat-2.2.5-Prevent-stack-exhaustion-in-build_model.patch
-Patch12: expat-2.2.5-Ensure-raw-tagnames-are-safe-exiting-internalEntityParser.patch
-Patch13: expat-2.2.5-CVE-2022-43680.patch
-Patch14: expat-2.2.5-CVE-2023-52425.patch
-Patch15: expat-2.2.5-CVE-2024-45490.patch
-Patch16: expat-2.2.5-CVE-2024-45491.patch
-Patch17: expat-2.2.5-CVE-2024-45492.patch
-Patch18: expat-2.2.5-CVE-2024-50602.patch
-Patch19: expat-2.2.5-CVE-2024-8176.patch
-
-%description
-This is expat, the C library for parsing XML, written by James Clark. Expat
-is a stream oriented XML parser. This means that you register handlers with
-the parser prior to starting the parse. These handlers are called when the
-parser discovers the associated structures in the document being parsed. A
-start tag is an example of the kind of structures for which you may
-register handlers.
-
-%package devel
-Summary: Libraries and header files to develop applications using expat
-Requires: expat%{?_isa} = %{version}-%{release}
-
-%description devel
-The expat-devel package contains the libraries, include files and documentation
-to develop XML applications with expat.
-
-%package static
-Summary: expat XML parser static library
-Requires: expat-devel%{?_isa} = %{version}-%{release}
-
-%description static
-The expat-static package contains the static version of the expat library.
-Install it if you need to link statically with expat.
-
-%prep
-%setup -q -n libexpat-R_%{unversion}/expat
-%patch0 -p2 -b .doc2man
-%patch1 -p2 -b .cve20843
-%patch2 -p2 -b .cve15903
-%patch3 -p1 -b .CVE-2022-23852
-%patch4 -p1 -b .CVE-2021-45960
-%patch5 -p1 -b .CVE-2021-46143
-%patch6 -p1 -b .CVE-2022-22822-CVE-2022-22827
-%patch7 -p1 -b .CVE-2022-25236
-%patch8 -p1 -b .CVE-2022-25235
-%patch9 -p1 -b .CVE-2022-25315
-%patch10 -p1 -b .CVE-2022-25314
-%patch11 -p1 -b .CVE-2022-25313
-%patch12 -p1 -b .CVE-2022-40674
-%patch13 -p1 -b .CVE-2022-43680
-pushd ..
-%patch14 -p1 -b .CVE-2023-52425
-%patch15 -p1 -b .CVE-2024-45490
-%patch16 -p1 -b .CVE-2024-45491
-%patch17 -p1 -b .CVE-2024-45492
-%patch18 -p1 -b .CVE-2024-50602
-%patch19 -p1 -b .CVE-2024-8176
-popd
-
-sed -i 's/install-data-hook/do-nothing-please/' lib/Makefile.am
-./buildconf.sh
-
-%build
-export CFLAGS="$RPM_OPT_FLAGS -fPIC"
-export DOCBOOK_TO_MAN="xmlto man --skip-validation"
-%configure
-make %{?_smp_mflags}
-
-%install
-make install DESTDIR=$RPM_BUILD_ROOT
-
-rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
-
-%check
-bash -c "for i in {1..500000}; do printf AAAAAAAAAAAAAAAAAAAA >> achars.txt; done"
-for testfile in ../testdata/largefiles/aaaaaa_*; do
-        first_part="$(sed 's/\(.*\)ACHARS.*/\1/g' $testfile)"
-        second_part="$(sed 's/.*ACHARS\(.*\)/\1/g' $testfile)"
-        printf "$first_part" > "$testfile"
-        cat achars.txt >> "$testfile"
-        printf "$second_part" >> "$testfile"
-done
-
-make check
-
-%ldconfig_scriptlets
-
-%files
-%{!?_licensedir:%global license %%doc}
-%doc AUTHORS Changes
-%license COPYING
-%{_bindir}/*
-%{_libdir}/lib*.so.*
-%{_mandir}/*/*
-
-%files devel
-%doc doc/reference.html doc/*.png doc/*.css examples/*.c
-%{_libdir}/lib*.so
-%{_libdir}/pkgconfig/*.pc
-%{_includedir}/*.h
-
-%files static
-%{_libdir}/lib*.a
-
-%changelog
-* Mon Apr 07 2025 Tomas Korbar  - 2.2.5-17
-- Fix CVE-2024-8176
-- Resolves: RHEL-57477
-
-* Fri Nov 08 2024 Tomas Korbar  - 2.2.5-16
-- Fix CVE-2024-50602
-- Resolves: RHEL-65062
-
-* Wed Sep 11 2024 Tomas Korbar  - 2.2.5-15
-- Rebuild for test reconfiguration
-
-* Wed Sep 11 2024 Tomas Korbar  - 2.2.5-14
-- Fix multiple CVEs
-- Fix CVE-2024-45492 integer overflow
-- Fix CVE-2024-45491 Integer Overflow or Wraparound
-- Fix CVE-2024-45490 Negative Length Parsing Vulnerability
-- Resolves: RHEL-57505
-- Resolves: RHEL-57493
-- Resolves: RHEL-56751
-
-* Tue Mar 26 2024 Tomas Korbar  - 2.2.5-13
-- Fix wrongly exposed variables
-- Resolves: RHEL-29321
-
-* Thu Mar 21 2024 Tomas Korbar  - 2.2.5-12
-- CVE-2023-52425 expat: parsing large tokens can trigger a denial of service
-- Resolves: RHEL-29321
-
-* Mon Nov 14 2022 Tomas Korbar  - 2.2.5-11
-- CVE-2022-43680 expat: use-after free caused by overeager destruction of a shared DTD in XML_ExternalEntityParserCreate
-- Resolves: CVE-2022-43680
-
-* Fri Sep 30 2022 Tomas Korbar  - 2.2.5-10
-- Ensure raw tagnames are safe exiting internalEntityParser
-- Resolves: CVE-2022-40674
-
-* Fri May 06 2022 Tomas Korbar  - 2.2.5-9
-- Fix multiple CVEs
-- Resolves: CVE-2022-25314
-- Resolves: CVE-2022-25313
-
-* Mon Mar 14 2022 Tomas Korbar  - 2.2.5-8
-- Improve patch for CVE-2022-25236
-- Related: CVE-2022-25236
-
-* Fri Mar 04 2022 Tomas Korbar  - 2.2.5-7
-- Fix patch for CVE-2022-25235
-- Resolves: CVE-2022-25235
-
-* Thu Mar 03 2022 Tomas Korbar  - 2.2.5-6
-- 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
-
-* Fri Feb 14 2022 Tomas Korbar  -  2.2.5-5
-- 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
-
-* Fri Apr 24 2020 Joe Orton  - 2.2.5-4
-- add security fixes for CVE-2018-20843, CVE-2019-15903
-
-* Wed Feb 07 2018 Fedora Release Engineering  - 2.2.5-3
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
-
-* Sat Feb 03 2018 Igor Gnatenko  - 2.2.5-2
-- Switch to %%ldconfig_scriptlets
-
-* Thu Nov  2 2017 Joe Orton  - 2.2.5-1
-- update to 2.2.5 (#1508667)
-
-* Mon Aug 21 2017 Joe Orton  - 2.2.4-1
-- update to 2.2.4 (#1483359)
-
-* Fri Aug  4 2017 Joe Orton  - 2.2.3-1
-- fix tests with unsigned char (upstream PR 109)
-- update to 2.2.3 (#1473266)
-
-* Wed Aug 02 2017 Fedora Release Engineering  - 2.2.2-4
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
-
-* Wed Jul 26 2017 Fedora Release Engineering  - 2.2.2-3
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
-
-* Fri Jul 14 2017 Joe Orton  - 2.2.2-2
-- update to 2.2.2 (#1470891)
-
-* Fri Jul  7 2017 Joe Orton  - 2.2.1-2
-- trim unnecessary doc, examples content
-
-* Mon Jun 19 2017 Joe Orton  - 2.2.1-1
-- update to 2.2.1 (#1462474)
-
-* Fri Feb 10 2017 Fedora Release Engineering  - 2.2.0-2
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
-
-* Tue Jun 21 2016 Joe Orton  - 2.2.0-1
-- update to 2.2.0 (#1247348)
-
-* Thu Jun 16 2016 Joe Orton  - 2.1.1-2
-- add security fixes for CVE-2016-0718, CVE-2012-6702, CVE-2016-5300,
-  CVE-2016-4472
-
-* Mon Apr 18 2016 David Tardon  - 2.1.1-1
-- new upstream release
-
-* Wed Feb 03 2016 Fedora Release Engineering  - 2.1.0-13
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
-
-* Wed Jun 17 2015 Fedora Release Engineering  - 2.1.0-12
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
-
-* Sat Feb 21 2015 Till Maas  - 2.1.0-11
-- Rebuilt for Fedora 23 Change
-  https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code
-
-* Sat Aug 16 2014 Fedora Release Engineering  - 2.1.0-10
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
-
-* Sat Jul 12 2014 Tom Callaway  - 2.1.0-9
-- fix license handling
-
-* Sat Jun 07 2014 Fedora Release Engineering  - 2.1.0-8
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
-
-* Sat Aug 03 2013 Fedora Release Engineering  - 2.1.0-7
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
-
-* Mon Jun 17 2013 Joe Orton  - 2.1.0-6
-- fix "xmlwf -h" output (#948534)
-
-* Wed Feb 13 2013 Fedora Release Engineering  - 2.1.0-5
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
-
-* Thu Jul 19 2012 Fedora Release Engineering  - 2.1.0-4
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
-
-* Fri Apr 13 2012 Joe Orton  - 2.1.0-3
-- add -static subpackage (#722647)
-
-* Fri Mar 30 2012 Joe Orton  - 2.1.0-1
-- ship .pc file, move library back to libdir (#808399)
-
-* Mon Mar 26 2012 Joe Orton  - 2.1.0-1
-- update to 2.1.0 (#806602)
-
-* Fri Jan 13 2012 Fedora Release Engineering  - 2.0.1-12
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
-
-* Tue Feb 08 2011 Fedora Release Engineering  - 2.0.1-11
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
-
-* Mon Feb  8 2010 Joe Orton  - 2.0.1-10
-- revised fix for CVE-2009-3560 regression (#544996)
-
-* Sun Jan 31 2010 Joe Orton  - 2.0.1-9
-- drop static libraries (#556046)
-- add fix for regression in CVE-2009-3560 patch (#544996)
-
-* Tue Dec  1 2009 Joe Orton  - 2.0.1-8
-- add security fix for CVE-2009-3560 (#533174)
-- add security fix for CVE-2009-3720 (#531697)
-- run the test suite
-
-* Fri Jul 24 2009 Fedora Release Engineering  - 2.0.1-7
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
-
-* Tue Feb 24 2009 Fedora Release Engineering  - 2.0.1-6
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
-
-* Tue Feb 19 2008 Fedora Release Engineering  - 2.0.1-5
-- Autorebuild for GCC 4.3
-
-* Wed Jan 23 2008 Joe Orton  2.0.1-4
-- chmod 644 even more documentation (#429806)
-
-* Tue Jan  8 2008 Joe Orton  2.0.1-3
-- chmod 644 the documentation (#427950)
-
-* Wed Aug 22 2007 Joe Orton  2.0.1-2
-- rebuild
-
-* Wed Aug  8 2007 Joe Orton  2.0.1-1
-- update to 2.0.1
-- fix the License tag
-- drop the .la file
-
-* Sun Feb  4 2007 Joe Orton  1.95.8-10
-- remove trailing dot in Summary (#225742)
-- use preferred BuildRoot per packaging guidelines (#225742)
-
-* Tue Jan 30 2007 Joe Orton  1.95.8-9
-- regenerate configure/libtool correctly (#199361)
-- strip DSP files from examples (#186889)
-- fix expat.h compilation with g++ -pedantic (#190244)
-
-* Wed Jul 12 2006 Jesse Keating  - 1.95.8-8.2.1
-- rebuild
-
-* Fri Feb 10 2006 Jesse Keating  - 1.95.8-8.2
-- bump again for double-long bug on ppc(64)
-
-* Tue Feb 07 2006 Jesse Keating  - 1.95.8-8.1
-- rebuilt for new gcc4.1 snapshot and glibc changes
-
-* Tue Jan 31 2006 Joe Orton  1.95.8-8
-- restore .la file for apr-util
-
-* Mon Jan 30 2006 Joe Orton  1.95.8-7
-- move library to /lib (#178743)
-- omit .la file (#170031)
-
-* Fri Dec 09 2005 Jesse Keating 
-- rebuilt
-
-* Tue Mar  8 2005 Joe Orton  1.95.8-6
-- rebuild
-
-* Thu Nov 25 2004 Ivana Varekova  1.95.8
-- update to 1.95.8
-
-* Wed Jun 16 2004 Jeff Johnson  1.95.7-4
-- add -fPIC (#125586).
-
-* Tue Jun 15 2004 Elliot Lee 
-- rebuilt
-
-* Fri Jun 11 2004 Jeff Johnson  1.95.7-2
-- fix: malloc failure from dbus test suite (#124747).
-
-* Tue Mar 02 2004 Elliot Lee 
-- rebuilt
-
-* Sun Feb 22 2004 Joe Orton  1.95.7-1
-- update to 1.95.7, include COPYING file in main package
-
-* Fri Feb 13 2004 Elliot Lee 
-- rebuilt
-
-* Wed Sep 17 2003 Matt Wilson  1.95.5-6
-- rebuild again for #91211
-
-* Tue Sep 16 2003 Matt Wilson  1.95.5-5
-- rebuild to fix gzip'ed file md5sums (#91211)
-
-* Tue Jun 17 2003 Jeff Johnson  1.95.5-4
-- rebuilt because of crt breakage on ppc64.
-
-* Wed Jun 04 2003 Elliot Lee 
-- rebuilt
-
-* Wed Jan 22 2003 Tim Powers 
-- rebuilt
-
-* Mon Nov 11 2002 Jeff Johnson  1.95.5-1
-- update to 1.95.5.
-
-* Mon Aug 19 2002 Trond Eivind Glomsrød  1,95.4-1
-- 1.95.4. 1.95.3 was withdrawn by the expat developers.
-
-* Fri Jun 21 2002 Tim Powers 
-- automated rebuild
-
-* Thu Jun  6 2002 Trond Eivind Glomsrød  1,95.3-1
-- 1.95.3
-
-* Thu May 23 2002 Tim Powers 
-- automated rebuild
-
-* Fri Mar 22 2002 Trond Eivind Glomsrød 
-- Change a prereq in -devel on main package to a req
-- License from MIT/X11 to BSD
-
-* Mon Mar 11 2002 Trond Eivind Glomsrød 
-- 1.95.2
-
-* Sun Jun 24 2001 Elliot Lee 
-- Bump release + rebuild.
-
-* Tue Oct 24 2000 Jeff Johnson 
-- update to 1.95.1
-
-* Sun Oct  8 2000 Jeff Johnson 
-- Create.
diff --git a/expat-2.7.1.tar.gz.asc b/expat-2.7.1.tar.gz.asc
new file mode 100644
index 0000000..4319b77
--- /dev/null
+++ b/expat-2.7.1.tar.gz.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCAAdFiEEy43nCpDPv2w79cxWliYqz/vTrsYFAmflq3oACgkQliYqz/vT
+rsY1phAAro7vFcwzx48OT6wNkxzlQ+58oyfP+TJw7CPO/72UVmyv6D1JYqxumwIh
+Djve0rWDdxTyGvkjmFfzLQgDVZmUopBqKdvSYtkNN5zZo3FwMAgoRU8ZQbZ2B7nM
+W6q4t983tKqveazoWV8iPOBDm/tBgOsrWyLYT1dhoQTVJoo+ymFVkEEA6TnhD+jd
+u/LgRd/lu0qYjI4dKkNjv4e88UzyaYid4hN1nUT1k9aASYtvZq8Ep3MMaONG4OGM
+a6TZl2whZXgiiTxDg5fJWBGfUYHGzW1N4SM0D2c4PWAeH8SAmx9CMitqjEobhdmz
+Qk/NSEdVzmhbqY1SodPf6eqVpviPd7dZhe6WfPwxrGXvc2Siz7/6SvY7OjcnKqem
+D0H0tZybsCs17LQKVfBmofh/PPcc6aXOtCS1feDBnbyACox/B2HhPrjGtt+CSW77
+PsmIPVhn5CTHIy7ZwzPOVNPl+j0DXUEWaOGH0Hffb6JSpBU/KbtS/dgHpveN54M+
+yfhN23f3+wTzIorfwibSkGlPbqIv5vj90KcUJKDK7iYMT+N6o10CCeDLcUZceEx9
+lQU4R0LTaewBtK/JVnouLWL0I1ByORka8PWIdV19ASuFaiO6s+mpS2wrN6Gidbok
+69XXPMbrezeBzsBSq9Ne1ZEmgrwpeK+KRKS0pWd/vqXQUvwvpsI=
+=uuCt
+-----END PGP SIGNATURE-----
diff --git a/expat.spec b/expat.spec
new file mode 100644
index 0000000..f307bf5
--- /dev/null
+++ b/expat.spec
@@ -0,0 +1,485 @@
+## START: Set by rpmautospec
+## (rpmautospec version 0.6.5)
+## RPMAUTOSPEC: autorelease, autochangelog
+%define autorelease(e:s:pb:n) %{?-p:0.}%{lua:
+    release_number = 1;
+    base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}"));
+    print(release_number + base_release_number - 1);
+}%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}}
+## END: Set by rpmautospec
+
+%global unversion 2_7_1
+
+Summary: An XML parser library
+Name: expat
+Version: %(echo %{unversion} | sed 's/_/./g')
+Release: %autorelease
+Source0: https://github.com/libexpat/libexpat/releases/download/R_%{unversion}/expat-%{version}.tar.gz
+Source1: https://github.com/libexpat/libexpat/releases/download/R_%{unversion}/expat-%{version}.tar.gz.asc
+# Sebastian Pipping's PGP public key
+Source2: https://keys.openpgp.org/vks/v1/by-fingerprint/3176EF7DB2367F1FCA4F306B1F9B0E909AF37285
+
+URL: https://libexpat.github.io/
+License: MIT
+BuildRequires: autoconf, libtool, xmlto, gcc-c++
+BuildRequires: make
+BuildRequires: gnupg2
+
+%description
+This is expat, the C library for parsing XML, written by James Clark. Expat
+is a stream oriented XML parser. This means that you register handlers with
+the parser prior to starting the parse. These handlers are called when the
+parser discovers the associated structures in the document being parsed. A
+start tag is an example of the kind of structures for which you may
+register handlers.
+
+%package devel
+Summary: Libraries and header files to develop applications using expat
+Requires: expat%{?_isa} = %{version}-%{release}
+
+%description devel
+The expat-devel package contains the libraries, include files and documentation
+to develop XML applications with expat.
+
+%package static
+Summary: expat XML parser static library
+Requires: expat-devel%{?_isa} = %{version}-%{release}
+
+%description static
+The expat-static package contains the static version of the expat library.
+Install it if you need to link statically with expat.
+
+%prep
+%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
+%autosetup
+sed -i 's/install-data-hook/do-nothing-please/' lib/Makefile.am
+./buildconf.sh
+
+%build
+export CFLAGS="$RPM_OPT_FLAGS -fPIC"
+export DOCBOOK_TO_MAN="xmlto man"
+%configure
+%make_build
+
+%install
+%make_install
+
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+
+%check
+make check
+
+%ldconfig_scriptlets
+
+%files
+%doc AUTHORS Changes
+%license COPYING
+%{_bindir}/*
+%{_libdir}/libexpat.so.1
+%{_libdir}/libexpat.so.1.*
+%{_mandir}/*/*
+
+%files devel
+%doc doc/reference.html doc/*.css examples/*.c
+%{_libdir}/libexpat.so
+%{_libdir}/pkgconfig/*.pc
+%{_includedir}/*.h
+%{_libdir}/cmake/expat-%{version}
+
+%files static
+%{_libdir}/libexpat.a
+
+%changelog
+## START: Generated by rpmautospec
+* Fri Mar 28 2025 Tomas Korbar  - 2.7.1-1
+- Fix behavior change caused by fix for CVE-2024-8176
+
+* Fri Mar 14 2025 Tomas Korbar  - 2.7.0-1
+- Fix CVE-2024-8176
+
+* Thu Nov 07 2024 Tomas Korbar  - 2.6.4-1
+- Rebase to 2.6.4
+
+* Tue Oct 29 2024 Troy Dawson  - 2.6.2-2
+- Bump release for October 2024 mass rebuild:
+
+* Wed Jul 03 2024 Tomas Korbar  - 2.6.2-1
+- Rebase to 2.6.2
+
+* Mon Jun 24 2024 Troy Dawson  - 2.5.0-7
+- Bump release for June 2024 mass rebuild
+
+* Fri Jun 21 2024 František Hrdina  - 2.5.0-6
+- Update of fmf plans and gating for c10s
+
+* Wed Jan 24 2024 Fedora Release Engineering  - 2.5.0-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Fri Jan 19 2024 Fedora Release Engineering  - 2.5.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Wed Jul 19 2023 Fedora Release Engineering  - 2.5.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
+
+* Thu Jan 19 2023 Fedora Release Engineering  - 2.5.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
+
+* Mon Oct 31 2022 Tomas Korbar  - 2.5.0-1
+- Rebase to 2.5.0
+
+* Thu Sep 29 2022 Tomas Korbar  - 2.4.9-1
+- Rebase to 2.4.9
+
+* Thu Jul 21 2022 Fedora Release Engineering  - 2.4.8-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
+
+* Thu Apr 28 2022 Frantisek Hrdina  - 2.4.8-4
+- Removing tests since they are in tests repo
+
+* Thu Apr 28 2022 Frantisek Hrdina  - 2.4.8-3
+- Adding gating.yaml
+
+* Thu Apr 28 2022 Frantisek Hrdina  - 2.4.8-2
+- Adding fmf plan
+
+* Fri Apr 08 2022 Tomas Korbar  - 2.4.8-1
+- Rebase to version 2.4.8
+
+* Mon Mar 07 2022 Tomas Korbar  - 2.4.7-1
+- Rebase to version 2.4.7
+
+* Mon Feb 21 2022 Tomas Korbar  - 2.4.6-1
+- Rebase to version 2.4.6
+
+* Mon Jan 31 2022 Tomas Korbar  - 2.4.4-1
+- Rebase to version 2.4.4
+
+* Thu Jan 20 2022 Fedora Release Engineering  - 2.4.3-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
+
+* Tue Jan 18 2022 Tomas Korbar  - 2.4.3-2
+- Change specfile according to Sebastian Pippings suggestions
+
+* Mon Jan 17 2022 Tomas Korbar  - 2.4.3-1
+- Rebase to version 2.4.3
+
+* Wed Jul 21 2021 Fedora Release Engineering  - 2.4.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
+
+* Tue Jun 01 2021 Tomas Korbar  - 2.4.1-1
+- Rebase to 2.4.1 Resolves: rhbz#1963400
+
+* Thu Apr 15 2021 Tomas Korbar  - 2.3.0-1
+- Rebase to 2.3.0 Resolves: rhbz#1942794
+
+* Tue Jan 26 2021 Fedora Release Engineering  - 2.2.10-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Thu Dec 24 2020 Robert Scheck  - 2.2.10-3
+- Spec file cleanup
+
+* Fri Dec 18 2020 Tom Stellard  - 2.2.10-2
+- Add BuildRequires: make
+
+* Fri Nov 13 2020 Joe Orton  - 2.2.10-1
+- update to 2.2.10 (#1884940)
+
+* Mon Jul 27 2020 Fedora Release Engineering  - 2.2.8-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Tue Jan 28 2020 Fedora Release Engineering  - 2.2.8-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Mon Sep 16 2019 Joe Orton  - 2.2.8-1
+- update to 2.2.8 (#1752167) Resolves: rhbz#1752167
+
+* Thu Jul 25 2019 Fedora Release Engineering  - 2.2.7-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Thu Jun 27 2019 Joe Orton  - 2.2.7-1
+- update to 2.2.7 (#1723724, #1722224) Resolves: rhbz#1722224 Resolves:
+  rhbz#1723724
+
+* Thu Jan 31 2019 Fedora Release Engineering  - 2.2.6-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Wed Aug 15 2018 Joe Orton  - 2.2.6-1
+- update to 2.2.6
+
+* Fri Jul 13 2018 Fedora Release Engineering  - 2.2.5-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Wed Feb 07 2018 Fedora Release Engineering  - 2.2.5-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Sat Feb 03 2018 Igor Gnatenko  - 2.2.5-2
+- Switch to %%ldconfig_scriptlets
+
+* Thu Nov 02 2017 Joe Orton  - 2.2.5-1
+- update to 2.2.5 (#1508667) Resolves: rhbz#1508667
+
+* Fri Oct 13 2017 Bruno Goncalves  - 2.2.4-2
+- Add CI tests using the standard test interface
+
+* Mon Aug 21 2017 Joe Orton  - 2.2.4-1
+- update to 2.2.4 (#1483359) Resolves: rhbz#1483359
+
+* Fri Aug 04 2017 Joe Orton  - 2.2.3-3
+- Collapse changelog
+
+* Fri Aug 04 2017 Joe Orton  - 2.2.3-2
+- fix tests with unsigned char (upstream PR 109) Resolves: rhbz#1473266
+
+* Thu Aug 03 2017 Joe Orton  - 2.2.3-1
+- update to 2.2.3 (#1473266) Resolves: rhbz#1473266
+
+* Wed Aug 02 2017 Fedora Release Engineering  - 2.2.2-4
+- Rebuilt for
+  https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering  - 2.2.2-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Fri Jul 14 2017 Joe Orton  - 2.2.2-2
+- update to 2.2.2 (#1470891) Resolves: rhbz#1470891
+
+* Fri Jul 14 2017 Joe Orton  - 2.2.2-1
+- trim unnecessary doc, examples content (#1470891) Resolves: rhbz#1470891
+
+* Fri Jul 07 2017 Joe Orton  - 2.2.1-3
+- trim unnecessary doc, examples content
+
+* Mon Jun 19 2017 Joe Orton  - 2.2.1-2
+- update to 2.2.1
+
+* Mon Jun 19 2017 Joe Orton  - 2.2.1-1
+- update to 2.2.1 (#1462474) Resolves: rhbz#1462474
+
+* Fri Feb 10 2017 Fedora Release Engineering  - 2.2.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Thu Nov 24 2016 Joe Orton  - 2.2.0-2
+- Revise history to fix malformed date.
+
+* Tue Jun 21 2016 Joe Orton  - 2.2.0-1
+- update to 2.2.0 (#1247348)
+
+* Thu Jun 16 2016 Joe Orton  - 2.1.1-5
+- add security fixes for CVE-2016-0718, CVE-2012-6702, CVE-2016-5300,
+
+* Mon Apr 18 2016 David Tardon  - 2.1.1-4
+- make dep on expat arch-specific
+
+* Mon Apr 18 2016 David Tardon  - 2.1.1-3
+- modernize spec
+
+* Mon Apr 18 2016 David Tardon  - 2.1.1-2
+- drop unneeded build deps
+
+* Mon Apr 18 2016 David Tardon  - 2.1.1-1
+- new upstream release 2.1.1
+
+* Wed Feb 03 2016 Dennis Gilmore  - 2.1.0-14
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Wed Jun 17 2015 Dennis Gilmore  - 2.1.0-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Sat Feb 21 2015 Till Maas  - 2.1.0-12
+- Rebuilt for Fedora 23 Change
+
+* Sat Aug 16 2014 Peter Robinson  - 2.1.0-11
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Sat Jul 12 2014 Tom Callaway  - 2.1.0-10
+- fix license handling
+
+* Sat Jun 07 2014 Dennis Gilmore  - 2.1.0-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Sat Aug 03 2013 Dennis Gilmore  - 2.1.0-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Mon Jun 17 2013 Joe Orton  - 2.1.0-7
+- fix "xmlwf -h" output (#948534)
+
+* Wed Feb 13 2013 Dennis Gilmore  - 2.1.0-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Thu Jul 19 2012 Dennis Gilmore  - 2.1.0-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Fri Apr 13 2012 Joe Orton  - 2.1.0-4
+- bump build
+
+* Fri Apr 13 2012 Joe Orton  - 2.1.0-3
+- add -static subpackage (#722647)
+
+* Fri Mar 30 2012 Joe Orton  - 2.1.0-2
+- ship .pc file, move library back to libdir (#808399)
+
+* Mon Mar 26 2012 Joe Orton  - 2.1.0-1
+- update to 2.1.0 (#806602)
+
+* Fri Jan 13 2012 Dennis Gilmore  - 2.0.1-18
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Tue Feb 08 2011 Dennis Gilmore  - 2.0.1-17
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Wed Jul 28 2010 Fedora Release Engineering  - 2.0.1-16
+- dist-git conversion
+
+* Mon Feb 08 2010 jorton  - 2.0.1-15
+- bump release
+
+* Mon Feb 08 2010 jorton  - 2.0.1-14
+- revised fix for CVE-2009-3560 regression (#544996)
+
+* Sun Jan 31 2010 jorton  - 2.0.1-13
+- add patch
+
+* Sun Jan 31 2010 jorton  - 2.0.1-12
+- drop static libraries (#556046) - add fix for regression in CVE-2009-3560
+  patch (#544996)
+
+* Wed Jan 13 2010 Štěpán Kasal  - 2.0.1-11
+- fix sf.net url
+
+* Thu Dec 03 2009 jorton  - 2.0.1-10
+- add security fix for CVE-2009-3560 (#533174) - add security fix for
+  CVE-2009-3720 (#531697) - run the test suite
+
+* Wed Nov 25 2009 Bill Nottingham  - 2.0.1-9
+- Fix typo that causes a failure to update the common directory. (releng
+  #2781)
+
+* Fri Jul 24 2009 Jesse Keating  - 2.0.1-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Tue Feb 24 2009 Jesse Keating  - 2.0.1-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Tue Feb 19 2008 Jesse Keating  - 2.0.1-6
+- Autorebuild for GCC 4.3
+
+* Wed Jan 23 2008 jorton  - 2.0.1-5
+- chmod 644 even more documentation (#429806)
+
+* Tue Jan 08 2008 jorton  - 2.0.1-4
+- chmod 644 the documentation (#427950)
+
+* Mon Oct 15 2007 Bill Nottingham  - 2.0.1-3
+- makefile update to properly grab makefile.common
+
+* Wed Aug 22 2007 jorton  - 2.0.1-2
+- rebuild
+
+* Wed Aug 08 2007 jorton  - 2.0.1-1
+- update to 2.0.1 - fix the License tag - drop the .la file
+
+* Sun Feb 04 2007 jorton  - 1.95.8-15
+- remove trailing dot in Summary (#225742) - use preferred BuildRoot per
+  packaging guidelines (#225742)
+
+* Tue Jan 30 2007 jorton  - 1.95.8-14
+- add missing BRs
+
+* Tue Jan 30 2007 jorton  - 1.95.8-13
+- regenerate configure/libtool correctly (#199361) - strip DSP files from
+  examples (#186889) - fix expat.h compilation with g++ -pedantic (#190244)
+
+* Wed Jul 12 2006 Jesse Keating  - 1.95.8-12
+- bumped for rebuild
+
+* Sat Feb 11 2006 Jesse Keating  - 1.95.8-11
+- bump for bug in double-long on ppc(64)
+
+* Tue Feb 07 2006 Jesse Keating  - 1.95.8-10
+- bump for new gcc/glibc
+
+* Tue Jan 31 2006 jorton  - 1.95.8-9
+- restore .la file for apr-util
+
+* Mon Jan 30 2006 jorton  - 1.95.8-8
+- move library to /lib (#178743) - omit .la file (#170031)
+
+* Fri Dec 09 2005 Jesse Keating  - 1.95.8-7
+- gcc update bump
+
+* Tue Mar 08 2005 jorton  - 1.95.8-6
+- rebuild
+
+* Wed Dec 01 2004 Ivana Varekova  - 1.95.8-5
+- update to 1.95.8 build and small change in spec file
+
+* Thu Nov 25 2004 Ivana Varekova  - 1.95.8-4
+- update to 1.95.8
+
+* Thu Nov 25 2004 Ivana Varekova  - 1.95.8-3
+- update to 1.95.8
+
+* Thu Nov 25 2004 Ivana Varekova  - 1.95.8-2
+- update to 1.95.8
+
+* Thu Nov 25 2004 Ivana Varekova  - 1.95.8-1
+- update to 1.95.8
+
+* Thu Sep 09 2004 cvsdist  - 1.95.7-4
+- auto-import changelog data from expat-1.95.7-4.src.rpm Wed Jun 16 2004
+  Jeff Johnson  1.95.7-4 - add -fPIC (#125586).
+
+* Thu Sep 09 2004 cvsdist  - 1.95.7-3
+- auto-import changelog data from expat-1.95.7-3.src.rpm Tue Jun 15 2004
+  Elliot Lee  - rebuilt
+
+* Thu Sep 09 2004 cvsdist  - 1.95.7-2
+- auto-import changelog data from expat-1.95.7-2.src.rpm Fri Jun 11 2004
+  Jeff Johnson  1.95.7-2 - fix: malloc failure from dbus test
+  suite (#124747).
+
+* Thu Sep 09 2004 cvsdist  - 1.95.7-1
+- auto-import changelog data from expat-1.95.7-1.1.src.rpm Tue Mar 02 2004
+  Elliot Lee  - rebuilt Sun Feb 22 2004 Joe Orton
+   1.95.7-1 - update to 1.95.7, include COPYING file in
+  main package Fri Feb 13 2004 Elliot Lee  - rebuilt
+  Wed Sep 17 2003 Matt Wilson  1.95.5-6 - rebuild again for
+  #91211 Tue Sep 16 2003 Matt Wilson  1.95.5-5 - rebuild to
+  fix gzip'ed file md5sums (#91211) Tue Jun 17 2003 Jeff Johnson
+   1.95.5-4 - rebuilt because of crt breakage on ppc64.
+
+* Thu Sep 09 2004 cvsdist  - 1.95.5-2
+- auto-import changelog data from expat-1.95.5-3.src.rpm Wed Jun 04 2003
+  Elliot Lee  - rebuilt
+
+* Thu Sep 09 2004 cvsdist  - 1.95.5-1
+- auto-import changelog data from expat-1.95.5-2.src.rpm Wed Jan 22 2003
+  Tim Powers  - rebuilt Mon Nov 11 2002 Jeff Johnson
+   1.95.5-1 - update to 1.95.5.
+
+* Thu Sep 09 2004 cvsdist  - 1.95.4-1
+- auto-import changelog data from expat-1.95.4-1.src.rpm Mon Aug 19 2002
+  Trond Eivind Glomsrød  1,95.4-1 - 1.95.4. 1.95.3 was
+  withdrawn by the expat developers.
+
+* Thu Sep 09 2004 cvsdist  - 1.95.3-1
+- auto-import changelog data from expat-1.95.3-2.src.rpm Fri Jun 21 2002
+  Tim Powers  - automated rebuild Thu Jun 06 2002 Trond
+  Eivind Glomsr�d  1,95.3-1 - 1.95.3 Thu May 23 2002 Tim
+  Powers  - automated rebuild
+
+* Thu Sep 09 2004 cvsdist  - 1.95.2-1
+- auto-import changelog data from expat-1.95.2-2.src.rpm Fri Mar 22 2002
+  Trond Eivind Glomsr�d  - Change a prereq in -devel on
+  main package to a req - License from MIT/X11 to BSD Wed Mar 13 2002 Trond
+  Eivind Glomsr�d  - 1.95.2
+
+* Thu Sep 09 2004 cvsdist  - 1.95.1-2
+- auto-import changelog data from expat-1.95.1-7.src.rpm Sun Jun 24 2001
+  Elliot Lee  - Bump release + rebuild.
+
+* Thu Sep 09 2004 cvsdist  - 1.95.1-1
+- auto-import changelog data from expat-1.95.1-1.src.rpm Tue Oct 24 2000
+  Jeff Johnson  - update to 1.95.1 Sun Oct 08 2000 Jeff
+  Johnson  - Create.
+## END: Generated by rpmautospec
diff --git a/sources b/sources
new file mode 100644
index 0000000..47ee500
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+SHA512 (expat-2.7.1.tar.gz) = 1b6b94f3253ac3ab3f8c69d1c852db2334c99cb7990b9656f5f2458198d1eb854e79cce0e39151aef0d5e01a740fc965651c6a57fda585f9a24c543f2693f78c