diff --git a/Misc/NEWS.d/next/Library/2026-03-17-20-52-24.gh-issue-146083.NxZa_c.rst b/Misc/NEWS.d/next/Library/2026-03-17-20-52-24.gh-issue-146083.NxZa_c.rst
new file mode 100644
index 00000000000000..6805a40a03e734
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-03-17-20-52-24.gh-issue-146083.NxZa_c.rst
@@ -0,0 +1 @@
+Update bundled `libexpat `_ to version 2.7.5.
diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h
index 6c7c4186927725..18dbaebde293bc 100644
--- a/Modules/expat/expat.h
+++ b/Modules/expat/expat.h
@@ -1082,7 +1082,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
*/
# define XML_MAJOR_VERSION 2
# define XML_MINOR_VERSION 7
-# define XML_MICRO_VERSION 4
+# define XML_MICRO_VERSION 5
# ifdef __cplusplus
}
diff --git a/Modules/expat/expat_external.h b/Modules/expat/expat_external.h
index 6f3f3c48ce9cff..cf4d445e68b00c 100644
--- a/Modules/expat/expat_external.h
+++ b/Modules/expat/expat_external.h
@@ -12,7 +12,7 @@
Copyright (c) 2001-2002 Greg Stein
Copyright (c) 2002-2006 Karl Waclawek
Copyright (c) 2016 Cristian RodrÃguez
- Copyright (c) 2016-2025 Sebastian Pipping
+ Copyright (c) 2016-2026 Sebastian Pipping
Copyright (c) 2017 Rhodri James
Copyright (c) 2018 Yury Gribov
Licensed under the MIT license:
diff --git a/Modules/expat/refresh.sh b/Modules/expat/refresh.sh
index a3bf7d7d172bc5..663cceba5e9d16 100755
--- a/Modules/expat/refresh.sh
+++ b/Modules/expat/refresh.sh
@@ -12,9 +12,9 @@ fi
# Update this when updating to a new version after verifying that the changes
# the update brings in are good. These values are used for verifying the SBOM, too.
-expected_libexpat_tag="R_2_7_4"
-expected_libexpat_version="2.7.4"
-expected_libexpat_sha256="461ecc8aa98ab1a68c2db788175665d1a4db640dc05bf0e289b6ea17122144ec"
+expected_libexpat_tag="R_2_7_5"
+expected_libexpat_version="2.7.5"
+expected_libexpat_sha256="9931f9860d18e6cf72d183eb8f309bfb96196c00e1d40caa978e95bc9aa978b6"
expat_dir="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")"
cd ${expat_dir}
diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c
index 086fca59112ee1..0248b6651ffbff 100644
--- a/Modules/expat/xmlparse.c
+++ b/Modules/expat/xmlparse.c
@@ -1,4 +1,4 @@
-/* fab937ab8b186d7d296013669c332e6dfce2f99567882cff1f8eb24223c524a7 (2.7.4+)
+/* 93c1caa66e2b0310459482516af05505b57c5cb7b96df777105308fc585c85d1 (2.7.5+)
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
@@ -590,6 +590,8 @@ static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
const XML_Char *s);
+static const XML_Char *FASTCALL poolCopyStringNoFinish(STRING_POOL *pool,
+ const XML_Char *s);
static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
int n);
static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
@@ -5086,7 +5088,7 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
}
/* If we get this token, we have the start of what might be a
normal tag, but not a declaration (i.e. it doesn't begin with
- "= entityTextEnd) {
+ result = XML_ERROR_NONE;
+ goto endEntityValue;
+ }
+
for (;;) {
next
= entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
@@ -7439,16 +7457,24 @@ setContext(XML_Parser parser, const XML_Char *context) {
else {
if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
return XML_FALSE;
- prefix
- = (PREFIX *)lookup(parser, &dtd->prefixes,
- poolStart(&parser->m_tempPool), sizeof(PREFIX));
- if (! prefix)
+ const XML_Char *const prefixName = poolCopyStringNoFinish(
+ &dtd->pool, poolStart(&parser->m_tempPool));
+ if (! prefixName) {
return XML_FALSE;
- if (prefix->name == poolStart(&parser->m_tempPool)) {
- prefix->name = poolCopyString(&dtd->pool, prefix->name);
- if (! prefix->name)
- return XML_FALSE;
}
+
+ prefix = (PREFIX *)lookup(parser, &dtd->prefixes, prefixName,
+ sizeof(PREFIX));
+
+ const bool prefixNameUsed = prefix && prefix->name == prefixName;
+ if (prefixNameUsed)
+ poolFinish(&dtd->pool);
+ else
+ poolDiscard(&dtd->pool);
+
+ if (! prefix)
+ return XML_FALSE;
+
poolDiscard(&parser->m_tempPool);
}
for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
@@ -8036,6 +8062,23 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s) {
return s;
}
+// A version of `poolCopyString` that does not call `poolFinish`
+// and reverts any partial advancement upon failure.
+static const XML_Char *FASTCALL
+poolCopyStringNoFinish(STRING_POOL *pool, const XML_Char *s) {
+ const XML_Char *const original = s;
+ do {
+ if (! poolAppendChar(pool, *s)) {
+ // Revert any previously successful advancement
+ const ptrdiff_t advancedBy = s - original;
+ if (advancedBy > 0)
+ pool->ptr -= advancedBy;
+ return NULL;
+ }
+ } while (*s++);
+ return pool->start;
+}
+
static const XML_Char *
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
if (! pool->ptr && ! poolGrow(pool)) {
diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c
index d56bee82dd2d13..b1dfb456e5df87 100644
--- a/Modules/expat/xmlrole.c
+++ b/Modules/expat/xmlrole.c
@@ -12,7 +12,7 @@
Copyright (c) 2002-2006 Karl Waclawek
Copyright (c) 2002-2003 Fred L. Drake, Jr.
Copyright (c) 2005-2009 Steven Solie
- Copyright (c) 2016-2023 Sebastian Pipping
+ Copyright (c) 2016-2026 Sebastian Pipping
Copyright (c) 2017 Rhodri James
Copyright (c) 2019 David Loffredo
Copyright (c) 2021 Donghee Na
diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c
index 32cd5f147e9322..f6e5f742c928c8 100644
--- a/Modules/expat/xmltok.c
+++ b/Modules/expat/xmltok.c
@@ -12,7 +12,7 @@
Copyright (c) 2002 Greg Stein
Copyright (c) 2002-2016 Karl Waclawek
Copyright (c) 2005-2009 Steven Solie
- Copyright (c) 2016-2024 Sebastian Pipping
+ Copyright (c) 2016-2026 Sebastian Pipping
Copyright (c) 2016 Pascal Cuoq
Copyright (c) 2016 Don Lewis
Copyright (c) 2017 Rhodri James
diff --git a/Modules/expat/xmltok_ns.c b/Modules/expat/xmltok_ns.c
index 810ca2c6d0485e..1cd60de1e4fe51 100644
--- a/Modules/expat/xmltok_ns.c
+++ b/Modules/expat/xmltok_ns.c
@@ -11,7 +11,7 @@
Copyright (c) 2002 Greg Stein
Copyright (c) 2002 Fred L. Drake, Jr.
Copyright (c) 2002-2006 Karl Waclawek
- Copyright (c) 2017-2021 Sebastian Pipping
+ Copyright (c) 2017-2026 Sebastian Pipping
Copyright (c) 2025 Alfonso Gregory
Licensed under the MIT license: