https://github.com/python/cpython/commit/4fda06832e19cd3e5f8e20024584f33a362e0bbc
commit: 4fda06832e19cd3e5f8e20024584f33a362e0bbc
branch: 3.10
author: Stan Ulbrych <[email protected]>
committer: pablogsal <[email protected]>
date: 2026-10-01T01:29:24+01:00
summary:

[3.10] gh-157953: Update bundled Expat to 2.8.5 (GH-157957) (#158327)

(cherry picked from commit 5f1f21894f56973078f170f6d0709b59a57605fd)
(cherry picked from commit 721007eeb8a182475d83061b131d3e85e43eee41)

files:
A Misc/NEWS.d/next/Security/2026-08-31-16-47-33.gh-issue-157953.KxCF5N.rst
A Modules/expat/hash_table.h
D Misc/NEWS.d/next/Security/2026-08-31-16-47-33.gh-issue-156723.KxCF5N.rst
M Modules/expat/expat.h
M Modules/expat/expat_external.h
M Modules/expat/internal.h
M Modules/expat/refresh.sh
M Modules/expat/xmlparse.c
M Modules/expat/xmlrole.c
M Modules/expat/xmlrole.h
M Modules/expat/xmltok.c
M Modules/expat/xmltok.h
M Modules/expat/xmltok_impl.c
M Modules/expat/xmltok_ns.c
M Modules/pyexpat.c
M PCbuild/_elementtree.vcxproj
M PCbuild/_elementtree.vcxproj.filters
M PCbuild/pyexpat.vcxproj
M PCbuild/pyexpat.vcxproj.filters

diff --git 
a/Misc/NEWS.d/next/Security/2026-08-31-16-47-33.gh-issue-156723.KxCF5N.rst 
b/Misc/NEWS.d/next/Security/2026-08-31-16-47-33.gh-issue-157953.KxCF5N.rst
similarity index 85%
rename from 
Misc/NEWS.d/next/Security/2026-08-31-16-47-33.gh-issue-156723.KxCF5N.rst
rename to 
Misc/NEWS.d/next/Security/2026-08-31-16-47-33.gh-issue-157953.KxCF5N.rst
index 3dda6055f307d94..5b3ea77cb368632 100644
--- a/Misc/NEWS.d/next/Security/2026-08-31-16-47-33.gh-issue-156723.KxCF5N.rst
+++ b/Misc/NEWS.d/next/Security/2026-08-31-16-47-33.gh-issue-157953.KxCF5N.rst
@@ -1 +1 @@
-Update bundled `libexpat <https://libexpat.github.io/>`_ to version 2.8.4.
+Update bundled `libexpat <https://libexpat.github.io/>`_ to version 2.8.5.
diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h
index b296be9dbad2dc6..4c3851d50a5fdf3 100644
--- a/Modules/expat/expat.h
+++ b/Modules/expat/expat.h
@@ -20,6 +20,7 @@
    Copyright (c) 2023      Sony Corporation / Snild Dolkow <[email protected]>
    Copyright (c) 2024      Taichi Haradaguchi <[email protected]>
    Copyright (c) 2025      Matthew Fernandez <[email protected]>
+   Copyright (c) 2026      Braian Plaku <[email protected]>
    Licensed under the MIT license:
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -921,7 +922,9 @@ XML_SetParamEntityParsing(XML_Parser parser,
    Returns 1 if successful, 0 when called after parsing has started.
    Note: If parser == NULL, the function will do nothing and return 0.
    DEPRECATED since Expat 2.8.0.
+   Please use XML_SetHashSalt16Bytes instead.
 */
+XML_ATTR_DEPRECATED("please use XML_SetHashSalt16Bytes instead")
 XMLPARSEAPI(int)
 XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt);
 
@@ -1040,8 +1043,11 @@ enum XML_FeatureEnum {
   XML_FEATURE_MIN_SIZE,
   XML_FEATURE_SIZEOF_XML_CHAR,
   XML_FEATURE_SIZEOF_XML_LCHAR,
+  /* Added in Expat 2.0.0. */
   XML_FEATURE_NS,
+  /* Added in Expat 2.0.1. */
   XML_FEATURE_LARGE_SIZE,
+  /* Added in Expat 2.1.0. */
   XML_FEATURE_ATTR_INFO,
   /* Added in Expat 2.4.0. */
   XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
@@ -1096,7 +1102,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool 
enabled);
 */
 #  define XML_MAJOR_VERSION 2
 #  define XML_MINOR_VERSION 8
-#  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 6cc3f19ed7dbc89..a6c8a97881795e5 100644
--- a/Modules/expat/expat_external.h
+++ b/Modules/expat/expat_external.h
@@ -16,6 +16,7 @@
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2018      Yury Gribov <[email protected]>
    Copyright (c) 2026      Matthew Fernandez <[email protected]>
+   Copyright (c) 2026      Braian Plaku <[email protected]>
    Licensed under the MIT license:
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -128,6 +129,17 @@
 #    define XML_ATTR_ALLOC_SIZE(x)
 #  endif
 
+/* Marks a function that Expat still provides but that callers should move off
+   of. */
+#  if defined(__clang__) || defined(__GNUC__)
+#    define XML_ATTR_DEPRECATED(message)                                       
\
+      __attribute__((__deprecated__(message)))
+#  elif defined(_MSC_VER)
+#    define XML_ATTR_DEPRECATED(message) __declspec(deprecated(message))
+#  else
+#    define XML_ATTR_DEPRECATED(message) // empty i.e. no deprecation
+#  endif
+
 #  define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
 
 #  ifdef __cplusplus
diff --git a/Modules/expat/hash_table.h b/Modules/expat/hash_table.h
new file mode 100644
index 000000000000000..f290aad18693feb
--- /dev/null
+++ b/Modules/expat/hash_table.h
@@ -0,0 +1,78 @@
+/* Hash table related internal API
+                            __  __            _
+                         ___\ \/ /_ __   __ _| |_
+                        / _ \\  /| '_ \ / _` | __|
+                       |  __//  \| |_) | (_| | |_
+                        \___/_/\_\ .__/ \__,_|\__|
+                                 |_| XML parser
+
+   Copyright (c) 2026 Sebastian Pipping <[email protected]>
+   Licensed under the MIT license:
+
+   Permission is  hereby granted,  free of charge,  to any  person obtaining
+   a  copy  of  this  software   and  associated  documentation  files  (the
+   "Software"),  to  deal in  the  Software  without restriction,  including
+   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
+   distribute, sublicense, and/or sell copies of the Software, and to permit
+   persons  to whom  the Software  is  furnished to  do so,  subject to  the
+   following conditions:
+
+   The above copyright  notice and this permission notice  shall be included
+   in all copies or substantial portions of the Software.
+
+   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
+   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
+   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+   USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+   SPDX-License-Identifier: MIT
+*/
+
+#if ! defined(HASH_TABLE_H)
+#  define HASH_TABLE_H 1
+
+#  include "expat.h"    // for XML_Bool, XML_Parser
+#  include "internal.h" // for XML_NONTESTING_STATIC
+
+#  include <stddef.h> // for size_t
+
+typedef const XML_Char *KEY;
+
+typedef struct {
+  KEY name;
+} NAMED;
+
+typedef struct {
+  NAMED **v;
+  unsigned char power;
+  size_t size;
+  size_t used;
+  XML_Parser parser;
+} HASH_TABLE;
+
+typedef struct {
+  NAMED **p;
+  NAMED **end;
+} HASH_TABLE_ITER;
+
+XML_NONTESTING_STATIC NAMED *lookupWithLength(XML_Parser parser,
+                                              HASH_TABLE *table, KEY name,
+                                              size_t nameLen,
+                                              size_t createSize);
+XML_NONTESTING_STATIC NAMED *lookup(XML_Parser parser, HASH_TABLE *table,
+                                    KEY name, size_t createSize);
+
+XML_NONTESTING_STATIC void hashTableInit(HASH_TABLE *table, XML_Parser parser);
+XML_NONTESTING_STATIC void hashTableClear(HASH_TABLE *table);
+XML_NONTESTING_STATIC void hashTableDestroy(HASH_TABLE *table);
+XML_NONTESTING_STATIC void hashTableIterInit(HASH_TABLE_ITER *iter,
+                                             const HASH_TABLE *table);
+XML_NONTESTING_STATIC NAMED *hashTableIterNext(HASH_TABLE_ITER *iter);
+
+XML_NONTESTING_STATIC XML_Bool keyeq(KEY s1, size_t s1len, KEY s2);
+XML_NONTESTING_STATIC size_t keylen(KEY s);
+
+#endif // ! defined(HASH_TABLE_H)
diff --git a/Modules/expat/internal.h b/Modules/expat/internal.h
index 6311028e94b8f5f..86655371d29033e 100644
--- a/Modules/expat/internal.h
+++ b/Modules/expat/internal.h
@@ -6,13 +6,6 @@
    The following calling convention macros are defined for frequently
    called functions:
 
-   FASTCALL    - Used for those internal functions that have a simple
-                 body and a low number of arguments and local variables.
-
-   PTRCALL     - Used for functions called though function pointers.
-
-   PTRFASTCALL - Like PTRCALL, but for low number of arguments.
-
    inline      - Used for selected internal functions for which inlining
                  may improve performance on some platforms.
 
@@ -34,6 +27,8 @@
    Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <[email protected]>
    Copyright (c) 2024      Taichi Haradaguchi <[email protected]>
    Copyright (c) 2026      Matthew Wozniczka <[email protected]>
+   Copyright (c) 2026      Braian Plaku <[email protected]>
+   Copyright (c) 2026      Florian Schmaus <[email protected]>
    Licensed under the MIT license:
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -58,132 +53,104 @@
    SPDX-License-Identifier: MIT
 */
 
-#if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__)
-/* We'll use this version by default only where we know it helps.
-
-   regparm() generates warnings on Solaris boxes.   See SF bug #692878.
-
-   Instability reported with egcs on a RedHat Linux 7.3.
-   Let's comment out:
-   #define FASTCALL __attribute__((stdcall, regparm(3)))
-   and let's try this:
-*/
-#  define FASTCALL __attribute__((regparm(3)))
-#  define PTRFASTCALL __attribute__((regparm(3)))
-#endif
-
-/* Using __fastcall seems to have an unexpected negative effect under
-   MS VC++, especially for function pointers, so we won't use it for
-   now on that platform. It may be reconsidered for a future release
-   if it can be made more effective.
-   Likely reason: __fastcall on Windows is like stdcall, therefore
-   the compiler cannot perform stack optimizations for call clusters.
-*/
-
-/* Make sure all of these are defined if they aren't already. */
-
-#ifndef FASTCALL
-#  define FASTCALL
-#endif
+#if ! defined(INTERNAL_H)
+#  define INTERNAL_H 1
 
-#ifndef PTRCALL
-#  define PTRCALL
-#endif
-
-#ifndef PTRFASTCALL
-#  define PTRFASTCALL
-#endif
-
-#ifndef XML_MIN_SIZE
-#  if ! defined(__cplusplus) && ! defined(inline)
-#    ifdef __GNUC__
-#      define inline __inline
-#    endif /* __GNUC__ */
-#  endif
-#endif /* XML_MIN_SIZE */
+#  ifndef XML_MIN_SIZE
+#    if ! defined(inline)
+#      ifdef __GNUC__
+#        define inline __inline
+#      endif /* __GNUC__ */
+#    endif
+#  endif /* XML_MIN_SIZE */
 
-#ifdef __cplusplus
-#  define inline inline
-#else
 #  ifndef inline
 #    define inline
 #  endif
-#endif
-
-#include <limits.h> // ULONG_MAX
-#include <stddef.h> // size_t
-
-#if defined(_WIN32)                                                            
\
-    && (! defined(__USE_MINGW_ANSI_STDIO)                                      
\
-        || (1 - __USE_MINGW_ANSI_STDIO - 1 == 0))
-#  define EXPAT_FMT_LLX(midpart) "%" midpart "I64x"
-#  define EXPAT_FMT_ULL(midpart) "%" midpart "I64u"
-#  if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW
-#    define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d"
-#    define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u"
+
+#  if ! defined(XML_NONTESTING_STATIC)
+#    if defined(XML_TESTING)
+#      define XML_NONTESTING_STATIC // empty i.e. not static
+#    else
+#      define XML_NONTESTING_STATIC static
+#    endif
+#  endif
+
+#  include <limits.h> // ULONG_MAX
+#  include <stddef.h> // size_t
+
+#  if defined(_WIN32)                                                          
\
+      && (! defined(__USE_MINGW_ANSI_STDIO)                                    
\
+          || (1 - __USE_MINGW_ANSI_STDIO - 1 == 0))
+#    define EXPAT_FMT_LLX(midpart) "%" midpart "I64x"
+#    define EXPAT_FMT_ULL(midpart) "%" midpart "I64u"
+#    if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW
+#      define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d"
+#      define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u"
+#    else
+#      define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
+#      define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
+#    endif
 #  else
-#    define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
-#    define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
+#    include <inttypes.h> // PRIdPTR, PRIuPTR
+#    define EXPAT_FMT_LLX(midpart) "%" midpart "llx"
+#    define EXPAT_FMT_ULL(midpart) "%" midpart "llu"
+#    define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart PRIdPTR
+#    define EXPAT_FMT_SIZE_T(midpart) "%" midpart PRIuPTR
+#  endif
+
+#  ifndef UNUSED_P
+#    define UNUSED_P(p) (void)p
 #  endif
-#else
-#  include <inttypes.h> // PRIdPTR, PRIuPTR
-#  define EXPAT_FMT_LLX(midpart) "%" midpart "llx"
-#  define EXPAT_FMT_ULL(midpart) "%" midpart "llu"
-#  define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart PRIdPTR
-#  define EXPAT_FMT_SIZE_T(midpart) "%" midpart PRIuPTR
-#endif
-
-#ifndef UNUSED_P
-#  define UNUSED_P(p) (void)p
-#endif
 
 /* NOTE BEGIN If you ever patch these defaults to greater values
               for non-attack XML payload in your environment,
               please file a bug report with libexpat.  Thank you!
 */
-#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT   
\
-  100.0f
-#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT    
\
-  8388608 // 8 MiB, 2^23
+#  define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT 
\
+    100.0f
+#  define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT  
\
+    8388608 // 8 MiB, 2^23
 
-#define EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT 100.0f
-#define EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT                       
\
-  67108864 // 64 MiB, 2^26
+#  define EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT 100.0f
+#  define EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT                     
\
+    67108864 // 64 MiB, 2^26
 
 // NOTE: If function expat_alloc was user facing, EXPAT_MALLOC_ALIGNMENT would
 //       have to take sizeof(long double) into account
-#define EXPAT_MALLOC_ALIGNMENT sizeof(long long) // largest parser (sub)member
-#define EXPAT_MALLOC_PADDING ((EXPAT_MALLOC_ALIGNMENT) - sizeof(size_t))
+union expat_align {
+  long long l;
+  void *p;
+};
+#  define EXPAT_MALLOC_ALIGNMENT sizeof(union expat_align)
+#  define EXPAT_MALLOC_PADDING ((EXPAT_MALLOC_ALIGNMENT) - sizeof(size_t))
 
 /* NOTE END */
 
-#include "expat.h" // so we can use type XML_Parser below
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#  include "expat.h" // so we can use type XML_Parser below
 
 void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
                                                 const char **fromLimRef);
 
-#if defined(XML_GE) && XML_GE == 1
+#  if defined(XML_GE) && XML_GE == 1
 unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
 unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
 const char *unsignedCharToPrintable(unsigned char c);
-#endif
+#  endif
 
 extern
-#if ! defined(XML_TESTING)
+#  if ! defined(XML_TESTING)
     const
-#endif
+#  endif
     XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
-#if defined(XML_TESTING)
+#  if defined(XML_TESTING)
+
+int xmlSetHashSalt(XML_Parser parser, unsigned long hash_salt);
+
 void *expat_malloc(XML_Parser parser, size_t size, int sourceLine);
 void expat_free(XML_Parser parser, void *ptr, int sourceLine);
 void *expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine);
 extern unsigned int g_bytesScanned; // used for testing only
-#endif
+#  endif
 
-#ifdef __cplusplus
-}
-#endif
+#endif // not defined INTERNAL_H
diff --git a/Modules/expat/refresh.sh b/Modules/expat/refresh.sh
index a7ff6afbe456f12..7203f2a3a8d6650 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_8_4"
-expected_libexpat_version="2.8.4"
-expected_libexpat_sha256="b8ece2437692dad44d851c4532723390a5a330990007706be9c8d2b90d294f36"
+expected_libexpat_tag="R_2_8_5"
+expected_libexpat_version="2.8.5"
+expected_libexpat_sha256="920dde485e15eda0cce8d2310b41d492c534e5e3d89ad407a0b4176dd2ff88fe"
 
 expat_dir="$(realpath "$(dirname -- "${BASH_SOURCE[0]}")")"
 cd ${expat_dir}
@@ -34,6 +34,7 @@ lib_files=(
   expat.h
   expat_external.h
   fallthrough.h
+  hash_table.h
   iasciitab.h
   internal.h
   latin1tab.h
diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c
index 9a05da21d5a7fd3..9fb4f9d480a2e3a 100644
--- a/Modules/expat/xmlparse.c
+++ b/Modules/expat/xmlparse.c
@@ -1,4 +1,4 @@
-/* 13c4e8da8fccffb0e8e599684e0d447ad14c1bb0b48792cf5dd77d8712301871 (2.8.4+)
+/* 0864fe2d216f47b742263b698bc051c865b342e8b820e42c234717098ea507e3 (2.8.5+)
                             __  __            _
                          ___\ \/ /_ __   __ _| |_
                         / _ \\  /| '_ \ / _` | __|
@@ -54,6 +54,8 @@
    Copyright (c) 2026      Darren Carreras <[email protected]>
    Copyright (c) 2026      Alberto Maschietto <[email protected]>
    Copyright (c) 2026      Zeyou Liu <[email protected]>
+   Copyright (c) 2026      Stan Ulbrych <[email protected]>
+   Copyright (c) 2026      Braian Plaku <[email protected]>
    Licensed under the MIT license:
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -226,25 +228,10 @@ typedef char ICHAR;
 #define EXPAT_MIN(a, b) (((a) < (b)) ? (a) : (b))
 
 #include "internal.h"
+#include "hash_table.h"
 #include "xmltok.h"
 #include "xmlrole.h"
 
-typedef const XML_Char *KEY;
-
-typedef struct {
-  KEY name;
-} NAMED;
-
-typedef struct {
-  NAMED **v;
-  unsigned char power;
-  size_t size;
-  size_t used;
-  XML_Parser parser;
-} HASH_TABLE;
-
-static size_t keylen(KEY s);
-
 static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
 
 /* For probing (after a collision) we need a step size relative prime
@@ -260,11 +247,6 @@ static void copy_salt_to_sipkey(XML_Parser parser, struct 
sipkey *key);
 #define PROBE_STEP(hash, mask, power)                                          
\
   ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
 
-typedef struct {
-  NAMED **p;
-  NAMED **end;
-} HASH_TABLE_ITER;
-
 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
 #define INIT_DATA_BUF_SIZE 1024
 #define INIT_ATTS_SIZE 16
@@ -334,12 +316,12 @@ typedef struct {
   const XML_Char *publicId;
   const XML_Char *notation;
   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
+  bool hasMore; /* true if entity has not been completely processed */
+  /* An entity can be open while being already completely processed (!hasMore).
+    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 */
+  bool is_param;
+  bool is_internal; /* true if declared in internal subset outside PE */
 } ENTITY;
 
 typedef struct {
@@ -374,8 +356,8 @@ typedef struct {
 typedef struct attribute_id {
   XML_Char *name;
   PREFIX *prefix;
-  XML_Bool maybeTokenized;
-  XML_Bool xmlns;
+  bool maybeTokenized;
+  bool xmlns;
 } ATTRIBUTE_ID;
 
 typedef struct {
@@ -431,12 +413,12 @@ typedef struct {
   XML_Bool standalone;
 #ifdef XML_DTD
   /* indicates if external PE has been read */
-  XML_Bool paramEntityRead;
+  bool paramEntityRead;
   HASH_TABLE paramEntities;
 #endif /* XML_DTD */
   PREFIX defaultPrefix;
   /* === scaffolding for building content model === */
-  XML_Bool in_eldecl;
+  bool in_eldecl;
   CONTENT_SCAFFOLD *scaffold;
   unsigned contentStringLen;
   unsigned scaffSize;
@@ -458,7 +440,7 @@ typedef struct open_internal_entity {
   struct open_internal_entity *next;
   ENTITY *entity;
   int startTagLevel;
-  XML_Bool betweenDecl; /* WFC: PE Between Declarations */
+  bool betweenDecl; /* WFC: PE Between Declarations */
   enum EntityType type;
 } OPEN_INTERNAL_ENTITY;
 
@@ -495,8 +477,8 @@ typedef struct entity_stats {
 } ENTITY_STATS;
 #endif /* XML_GE == 1 */
 
-typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
-                                         const char *end, const char **endPtr);
+typedef enum XML_Error Processor(XML_Parser parser, const char *start,
+                                 const char *end, const char **endPtr);
 
 static Processor prologProcessor;
 static Processor prologInitProcessor;
@@ -528,7 +510,7 @@ static enum XML_Error doProlog(XML_Parser parser, const 
ENCODING *enc,
                                XML_Bool haveMore, XML_Bool allowClosingDoctype,
                                enum XML_Account account);
 static enum XML_Error processEntity(XML_Parser parser, ENTITY *entity,
-                                    XML_Bool betweenDecl, enum EntityType 
type);
+                                    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,
@@ -588,7 +570,7 @@ static void reportDefault(XML_Parser parser, const ENCODING 
*enc,
 static const XML_Char *getContext(XML_Parser parser);
 static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
 
-static void FASTCALL normalizePublicId(XML_Char *s);
+static void normalizePublicId(XML_Char *s);
 
 static DTD *dtdCreate(XML_Parser parser);
 /* do not call if m_parentParser != NULL */
@@ -598,36 +580,24 @@ static int dtdCopy(XML_Parser oldParser, DTD *newDtd, 
const DTD *oldDtd,
                    XML_Parser parser);
 static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
                            STRING_POOL *newPool, const HASH_TABLE *oldTable);
-static NAMED *lookupWithLength(XML_Parser parser, HASH_TABLE *table, KEY name,
-                               size_t nameLen, size_t createSize);
-static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
-                     size_t createSize);
-static void FASTCALL hashTableInit(HASH_TABLE *table, XML_Parser parser);
-static void FASTCALL hashTableClear(HASH_TABLE *table);
-static void FASTCALL hashTableDestroy(HASH_TABLE *table);
-static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *iter,
-                                       const HASH_TABLE *table);
-static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *iter);
-
-static void FASTCALL poolInit(STRING_POOL *pool, XML_Parser parser);
-static void FASTCALL poolClear(STRING_POOL *pool);
-static void FASTCALL poolDestroy(STRING_POOL *pool);
+
+static void poolInit(STRING_POOL *pool, XML_Parser parser);
+static void poolClear(STRING_POOL *pool);
+static void poolDestroy(STRING_POOL *pool);
 static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
                             const char *ptr, const char *end);
 static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
                                  const char *ptr, const char *end);
-static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
-static bool FASTCALL poolGrowUntil(STRING_POOL *pool, size_t needed);
-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 XML_Bool poolGrow(STRING_POOL *pool);
+static bool poolGrowUntil(STRING_POOL *pool, size_t needed);
+static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *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,
-                                                 const XML_Char *s);
+static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
 
-static int FASTCALL nextScaffoldPart(XML_Parser parser);
+static int nextScaffoldPart(XML_Parser parser);
 static XML_Content *build_model(XML_Parser parser);
 static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
                                     const char *ptr, const char *end);
@@ -1596,7 +1566,7 @@ parserInit(XML_Parser parser, const XML_Char 
*encodingName) {
 }
 
 /* moves list of bindings to m_freeBindingList */
-static void FASTCALL
+static void
 moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
   while (bindings) {
     BINDING *b = bindings;
@@ -1869,7 +1839,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, 
const XML_Char *context,
   return parser;
 }
 
-static void FASTCALL
+static void
 destroyBindings(BINDING *bindings, XML_Parser parser) {
   for (;;) {
     BINDING *b = bindings;
@@ -2268,9 +2238,10 @@ XML_SetParamEntityParsing(XML_Parser parser,
 #endif
 }
 
-// DEPRECATED since Expat 2.8.0.
-int XMLCALL
-XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
+/* The body of XML_SetHashSalt, so that Expat's own tests can reach it
+   without tripping the deprecation of the public function. */
+XML_NONTESTING_STATIC int
+xmlSetHashSalt(XML_Parser parser, unsigned long hash_salt) {
   if (parser == NULL)
     return 0;
 
@@ -2296,6 +2267,12 @@ XML_SetHashSalt(XML_Parser parser, unsigned long 
hash_salt) {
   return 1;
 }
 
+// DEPRECATED since Expat 2.8.0.
+int XMLCALL
+XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
+  return xmlSetHashSalt(parser, hash_salt);
+}
+
 XML_Bool XMLCALL
 XML_SetHashSalt16Bytes(XML_Parser parser, const uint8_t entropy[16]) {
   if (parser == NULL)
@@ -3168,7 +3145,7 @@ storeRawNames(XML_Parser parser) {
   return XML_TRUE;
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 contentProcessor(XML_Parser parser, const char *start, const char *end,
                  const char **endPtr) {
   enum XML_Error result = doContent(
@@ -3182,7 +3159,7 @@ contentProcessor(XML_Parser parser, const char *start, 
const char *end,
   return result;
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 externalEntityInitProcessor(XML_Parser parser, const char *start,
                             const char *end, const char **endPtr) {
   enum XML_Error result = initializeEncoding(parser);
@@ -3192,7 +3169,7 @@ externalEntityInitProcessor(XML_Parser parser, const char 
*start,
   return externalEntityInitProcessor2(parser, start, end, endPtr);
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 externalEntityInitProcessor2(XML_Parser parser, const char *start,
                              const char *end, const char **endPtr) {
   const char *next = start; /* XmlContentTok doesn't always set the last arg */
@@ -3237,7 +3214,7 @@ externalEntityInitProcessor2(XML_Parser parser, const 
char *start,
   return externalEntityInitProcessor3(parser, start, end, endPtr);
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 externalEntityInitProcessor3(XML_Parser parser, const char *start,
                              const char *end, const char **endPtr) {
   int tok;
@@ -3289,7 +3266,7 @@ externalEntityInitProcessor3(XML_Parser parser, const 
char *start,
   return externalEntityContentProcessor(parser, start, end, endPtr);
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 externalEntityContentProcessor(XML_Parser parser, const char *start,
                                const char *end, const char **endPtr) {
   enum XML_Error result
@@ -4551,6 +4528,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const 
ATTRIBUTE_ID *attId,
     /* Detect and prevent integer overflow */
     if (len > SIZE_MAX - EXPAND_SPARE
         || len + EXPAND_SPARE > SIZE_MAX / sizeof(XML_Char)) {
+      FREE(parser, b);
       return XML_ERROR_NO_MEMORY;
     }
 
@@ -4588,7 +4566,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const 
ATTRIBUTE_ID *attId,
 /* The idea here is to avoid using stack for each CDATA section when
    the whole file is parsed with one call.
 */
-static enum XML_Error PTRCALL
+static enum XML_Error
 cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
                       const char **endPtr) {
   enum XML_Error result = doCdataSection(
@@ -4754,7 +4732,7 @@ doCdataSection(XML_Parser parser, const ENCODING *enc, 
const char **startPtr,
 /* The idea here is to avoid using stack for each IGNORE section when
    the whole file is parsed with one call.
 */
-static enum XML_Error PTRCALL
+static enum XML_Error
 ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
                        const char **endPtr) {
   enum XML_Error result
@@ -5024,7 +5002,7 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char 
*encodingName) {
   return XML_ERROR_UNKNOWN_ENCODING;
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 prologInitProcessor(XML_Parser parser, const char *s, const char *end,
                     const char **nextPtr) {
   enum XML_Error result = initializeEncoding(parser);
@@ -5036,7 +5014,7 @@ prologInitProcessor(XML_Parser parser, const char *s, 
const char *end,
 
 #ifdef XML_DTD
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
                             const char **nextPtr) {
   enum XML_Error result = initializeEncoding(parser);
@@ -5045,7 +5023,7 @@ externalParEntInitProcessor(XML_Parser parser, const char 
*s, const char *end,
 
   /* we know now that XML_Parse(Buffer) has been called,
      so we consider the external parameter entity read */
-  parser->m_dtd->paramEntityRead = XML_TRUE;
+  parser->m_dtd->paramEntityRead = true;
 
   if (parser->m_prologState.inEntityValue) {
     parser->m_processor = entityValueInitProcessor;
@@ -5056,7 +5034,7 @@ externalParEntInitProcessor(XML_Parser parser, const char 
*s, const char *end,
   }
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
                          const char **nextPtr) {
   int tok;
@@ -5140,7 +5118,7 @@ entityValueInitProcessor(XML_Parser parser, const char 
*s, const char *end,
   }
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
                         const char **nextPtr) {
   const char *next = s;
@@ -5186,7 +5164,7 @@ externalParEntProcessor(XML_Parser parser, const char *s, 
const char *end,
                   XML_ACCOUNT_DIRECT);
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 entityValueProcessor(XML_Parser parser, const char *s, const char *end,
                      const char **nextPtr) {
   const char *start = s;
@@ -5233,7 +5211,7 @@ entityValueProcessor(XML_Parser parser, const char *s, 
const char *end,
 
 #endif /* XML_DTD */
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 prologProcessor(XML_Parser parser, const char *s, const char *end,
                 const char **nextPtr) {
   const char *next = s;
@@ -5479,7 +5457,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
           }
           if (parser->m_useForeignDTD)
             entity->base = parser->m_curBase;
-          dtd->paramEntityRead = XML_FALSE;
+          dtd->paramEntityRead = false;
           beforeHandler(parser);
           const int status = parser->m_externalEntityRefHandler(
               parser->m_externalEntityRefHandlerArg, 0, entity->base,
@@ -5529,7 +5507,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
           if (! entity)
             return XML_ERROR_NO_MEMORY;
           entity->base = parser->m_curBase;
-          dtd->paramEntityRead = XML_FALSE;
+          dtd->paramEntityRead = false;
           beforeHandler(parser);
           const int status = parser->m_externalEntityRefHandler(
               parser->m_externalEntityRefHandlerArg, 0, entity->base,
@@ -5872,7 +5850,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
         } else {
           poolFinish(&dtd->pool);
           parser->m_declEntity->publicId = NULL;
-          parser->m_declEntity->is_param = XML_FALSE;
+          parser->m_declEntity->is_param = false;
           /* if we have a parent parser or are reading an internal parameter
              entity, then the entity declaration is not considered "internal"
           */
@@ -5902,7 +5880,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
         } else {
           poolFinish(&dtd->pool);
           parser->m_declEntity->publicId = NULL;
-          parser->m_declEntity->is_param = XML_TRUE;
+          parser->m_declEntity->is_param = true;
           /* if we have a parent parser or are reading an internal parameter
              entity, then the entity declaration is not considered "internal"
           */
@@ -6137,8 +6115,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
           return XML_ERROR_RECURSIVE_ENTITY_REF;
         if (entity->textPtr) {
           enum XML_Error result;
-          XML_Bool betweenDecl
-              = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
+          bool betweenDecl = (role == XML_ROLE_PARAM_ENTITY_REF);
           result = processEntity(parser, entity, betweenDecl, ENTITY_INTERNAL);
           if (result != XML_ERROR_NONE)
             return result;
@@ -6146,7 +6123,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
           break;
         }
         if (parser->m_externalEntityRefHandler) {
-          dtd->paramEntityRead = XML_FALSE;
+          dtd->paramEntityRead = false;
           entity->open = true;
           entityTrackingOnOpen(parser, entity, __LINE__);
           beforeHandler(parser);
@@ -6190,7 +6167,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
           return XML_ERROR_NO_MEMORY;
         dtd->scaffLevel = 0;
         dtd->scaffCount = 0;
-        dtd->in_eldecl = XML_TRUE;
+        dtd->in_eldecl = true;
         handleDefault = XML_FALSE;
       }
       break;
@@ -6219,7 +6196,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
           afterHandler(parser);
           handleDefault = XML_FALSE;
         }
-        dtd->in_eldecl = XML_FALSE;
+        dtd->in_eldecl = false;
       }
       break;
 
@@ -6301,7 +6278,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
                 parser->m_handlerArg, parser->m_declElementType->name, model);
             afterHandler(parser);
           }
-          dtd->in_eldecl = XML_FALSE;
+          dtd->in_eldecl = false;
           dtd->contentStringLen = 0;
         }
       }
@@ -6370,7 +6347,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const 
char *s, const char *end,
   /* not reached */
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 epilogProcessor(XML_Parser parser, const char *s, const char *end,
                 const char **nextPtr) {
   parser->m_processor = epilogProcessor;
@@ -6449,7 +6426,7 @@ epilogProcessor(XML_Parser parser, const char *s, const 
char *end,
 }
 
 static enum XML_Error
-processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl,
+processEntity(XML_Parser parser, ENTITY *entity, bool betweenDecl,
               enum EntityType type) {
   OPEN_INTERNAL_ENTITY *openEntity, **openEntityList;
   OPEN_INTERNAL_ENTITY **const freeEntityList = &parser->m_freeEntities;
@@ -6485,7 +6462,7 @@ processEntity(XML_Parser parser, ENTITY *entity, XML_Bool 
betweenDecl,
       return XML_ERROR_NO_MEMORY;
   }
   entity->open = true;
-  entity->hasMore = XML_TRUE;
+  entity->hasMore = true;
 #if XML_GE == 1
   entityTrackingOnOpen(parser, entity, __LINE__);
 #endif
@@ -6507,7 +6484,7 @@ processEntity(XML_Parser parser, ENTITY *entity, XML_Bool 
betweenDecl,
   return XML_ERROR_NONE;
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
                         const char **nextPtr) {
   UNUSED_P(s);
@@ -6557,7 +6534,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, 
const char *end,
     // 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;
+    entity->hasMore = false;
     if (! entity->is_param
         && (openEntity->startTagLevel != parser->m_tagLevel)) {
       return XML_ERROR_ASYNC_ENTITY;
@@ -6589,7 +6566,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, 
const char *end,
   return XML_ERROR_NONE;
 }
 
-static enum XML_Error PTRCALL
+static enum XML_Error
 errorProcessor(XML_Parser parser, const char *s, const char *end,
                const char **nextPtr) {
   UNUSED_P(s);
@@ -6640,7 +6617,7 @@ storeAttributeValue(XML_Parser parser, const ENCODING 
*enc, XML_Bool isCdata,
         // 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;
+        entity->hasMore = false;
         continue;
       } // End of entity processing, "if" block skips the rest
 
@@ -6948,7 +6925,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
         }
         if (entity->systemId) {
           if (parser->m_externalEntityRefHandler) {
-            dtd->paramEntityRead = XML_FALSE;
+            dtd->paramEntityRead = false;
             entity->open = true;
             entityTrackingOnOpen(parser, entity, __LINE__);
             beforeHandler(parser);
@@ -7100,7 +7077,7 @@ callStoreEntityValue(XML_Parser parser, const ENCODING 
*enc,
         // 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;
+        entity->hasMore = false;
         continue;
       } // End of entity processing, "if" block skips the rest
 
@@ -7162,7 +7139,7 @@ storeSelfEntityValue(XML_Parser parser, ENTITY *entity) {
 
 #endif /* XML_GE == 0 */
 
-static void FASTCALL
+static void
 normalizeLines(XML_Char *s) {
   XML_Char *p;
   for (;; s++) {
@@ -7328,7 +7305,7 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, 
XML_Bool isCdata,
   att->value = value;
   att->isCdata = isCdata;
   if (! isCdata)
-    attId->maybeTokenized = XML_TRUE;
+    attId->maybeTokenized = true;
 
   NAME_AND_DEFAULT_ATTRIBUTE *const nameAndDefaultAttribute
       = (NAME_AND_DEFAULT_ATTRIBUTE *)lookup(
@@ -7413,7 +7390,7 @@ getAttributeId(XML_Parser parser, const ENCODING *enc, 
const char *start,
       else
         id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
                                       sizeof(PREFIX));
-      id->xmlns = XML_TRUE;
+      id->xmlns = true;
     } else {
       int i;
       for (i = 0; name[i]; i++) {
@@ -7603,7 +7580,7 @@ setContext(XML_Parser parser, const XML_Char *context) {
   return XML_TRUE;
 }
 
-static void FASTCALL
+static void
 normalizePublicId(XML_Char *publicId) {
   XML_Char *p = publicId;
   XML_Char *s;
@@ -7636,13 +7613,13 @@ dtdCreate(XML_Parser parser) {
   hashTableInit(&(p->attributeIds), parser);
   hashTableInit(&(p->prefixes), parser);
 #ifdef XML_DTD
-  p->paramEntityRead = XML_FALSE;
+  p->paramEntityRead = false;
   hashTableInit(&(p->paramEntities), parser);
 #endif /* XML_DTD */
   p->defaultPrefix.name = NULL;
   p->defaultPrefix.binding = NULL;
 
-  p->in_eldecl = XML_FALSE;
+  p->in_eldecl = false;
   p->scaffIndex = NULL;
   p->scaffIndexSize = 0;
   p->scaffold = NULL;
@@ -7670,7 +7647,7 @@ dtdReset(DTD *p, XML_Parser parser) {
   }
   hashTableClear(&(p->generalEntities));
 #ifdef XML_DTD
-  p->paramEntityRead = XML_FALSE;
+  p->paramEntityRead = false;
   hashTableClear(&(p->paramEntities));
 #endif /* XML_DTD */
   hashTableClear(&(p->elementTypes));
@@ -7681,7 +7658,7 @@ dtdReset(DTD *p, XML_Parser parser) {
   p->defaultPrefix.name = NULL;
   p->defaultPrefix.binding = NULL;
 
-  p->in_eldecl = XML_FALSE;
+  p->in_eldecl = false;
 
   FREE(parser, p->scaffIndex);
   p->scaffIndex = NULL;
@@ -7949,7 +7926,7 @@ copyEntityTable(XML_Parser oldParser, HASH_TABLE 
*newTable,
 // Compares two strings `s1` and `s2` whereas:
 // - `s2` is zero-terminated but
 // - `s1` is made up of exactly (not just up to) `s1len` non-zero characters.
-static XML_Bool FASTCALL
+XML_NONTESTING_STATIC XML_Bool
 keyeq(KEY s1, size_t s1len, KEY s2) {
 #ifdef XML_UNICODE
 #  ifdef XML_UNICODE_WCHAR_T
@@ -7966,7 +7943,7 @@ keyeq(KEY s1, size_t s1len, KEY s2) {
 #endif
 }
 
-static size_t
+XML_NONTESTING_STATIC size_t
 keylen(KEY s) {
   return xcslen(s);
 }
@@ -7979,7 +7956,7 @@ copy_salt_to_sipkey(XML_Parser parser, struct sipkey 
*key) {
   *key = rootParser->m_hash_secret_salt_128;
 }
 
-static unsigned long FASTCALL
+static unsigned long
 hash(XML_Parser parser, KEY s, size_t keyLen) {
   struct siphash state;
   struct sipkey key;
@@ -8009,7 +7986,7 @@ hash(XML_Parser parser, KEY s, size_t keyLen) {
 //       read-write mode does, because keys can be re-hashed later and the
 //       hash table does not store key length information.
 //
-static NAMED *
+XML_NONTESTING_STATIC NAMED *
 lookupWithLength(XML_Parser parser, HASH_TABLE *table, KEY name, size_t 
nameLen,
                  size_t createSize) {
   size_t i;
@@ -8116,12 +8093,12 @@ lookupWithLength(XML_Parser parser, HASH_TABLE *table, 
KEY name, size_t nameLen,
 // be used to tell cases "existed and found" and "newly inserted" apart
 // with the structure returned.
 //
-static NAMED *
+XML_NONTESTING_STATIC NAMED *
 lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
   return lookupWithLength(parser, table, name, keylen(name), createSize);
 }
 
-static void FASTCALL
+XML_NONTESTING_STATIC void
 hashTableClear(HASH_TABLE *table) {
   size_t i;
   for (i = 0; i < table->size; i++) {
@@ -8131,7 +8108,7 @@ hashTableClear(HASH_TABLE *table) {
   table->used = 0;
 }
 
-static void FASTCALL
+XML_NONTESTING_STATIC void
 hashTableDestroy(HASH_TABLE *table) {
   size_t i;
   for (i = 0; i < table->size; i++)
@@ -8139,7 +8116,7 @@ hashTableDestroy(HASH_TABLE *table) {
   FREE(table->parser, table->v);
 }
 
-static void FASTCALL
+XML_NONTESTING_STATIC void
 hashTableInit(HASH_TABLE *p, XML_Parser parser) {
   p->power = 0;
   p->size = 0;
@@ -8148,13 +8125,13 @@ hashTableInit(HASH_TABLE *p, XML_Parser parser) {
   p->parser = parser;
 }
 
-static void FASTCALL
+XML_NONTESTING_STATIC void
 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
   iter->p = table->v;
   iter->end = iter->p ? iter->p + table->size : NULL;
 }
 
-static NAMED *FASTCALL
+XML_NONTESTING_STATIC NAMED *
 hashTableIterNext(HASH_TABLE_ITER *iter) {
   while (iter->p != iter->end) {
     NAMED *tem = *(iter->p)++;
@@ -8164,7 +8141,7 @@ hashTableIterNext(HASH_TABLE_ITER *iter) {
   return NULL;
 }
 
-static void FASTCALL
+static void
 poolInit(STRING_POOL *pool, XML_Parser parser) {
   pool->blocks = NULL;
   pool->freeBlocks = NULL;
@@ -8174,7 +8151,7 @@ poolInit(STRING_POOL *pool, XML_Parser parser) {
   pool->parser = parser;
 }
 
-static void FASTCALL
+static void
 poolClear(STRING_POOL *pool) {
   if (! pool->freeBlocks)
     pool->freeBlocks = pool->blocks;
@@ -8193,7 +8170,7 @@ poolClear(STRING_POOL *pool) {
   pool->end = NULL;
 }
 
-static void FASTCALL
+static void
 poolDestroy(STRING_POOL *pool) {
   BLOCK *p = pool->blocks;
   while (p) {
@@ -8226,7 +8203,7 @@ poolAppend(STRING_POOL *pool, const ENCODING *enc, const 
char *ptr,
   return pool->start;
 }
 
-static const XML_Char *FASTCALL
+static const XML_Char *
 poolCopyString(STRING_POOL *pool, const XML_Char *s) {
   if (! poolAppendChars(pool, s, xcslen(s) + /*null terminator*/ 1))
     return NULL;
@@ -8237,7 +8214,7 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s) {
 
 // A version of `poolCopyString` that does not call `poolFinish`
 // and reverts any partial advancement upon failure.
-static const XML_Char *FASTCALL
+static const XML_Char *
 poolCopyStringNoFinish(STRING_POOL *pool, const XML_Char *s) {
   const XML_Char *const original = s;
   do {
@@ -8275,7 +8252,7 @@ poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int 
n) {
   return s;
 }
 
-static const XML_Char *FASTCALL
+static const XML_Char *
 poolAppendString(STRING_POOL *pool, const XML_Char *s) {
   if (! poolAppendChars(pool, s, xcslen(s)))
     return NULL;
@@ -8320,7 +8297,7 @@ poolBytesToAllocateFor(int blockSize) {
   }
 }
 
-static XML_Bool FASTCALL
+static XML_Bool
 poolGrow(STRING_POOL *pool) {
   if (pool->freeBlocks) {
     if (pool->start == NULL) {
@@ -8425,7 +8402,7 @@ poolGrow(STRING_POOL *pool) {
   return XML_TRUE;
 }
 
-static bool FASTCALL
+static bool
 poolGrowUntil(STRING_POOL *pool, size_t needed) {
   for (;;) {
     const size_t available = pool->end - pool->ptr;
@@ -8438,7 +8415,7 @@ poolGrowUntil(STRING_POOL *pool, size_t needed) {
   }
 }
 
-static int FASTCALL
+static int
 nextScaffoldPart(XML_Parser parser) {
   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   CONTENT_SCAFFOLD *me;
diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c
index 8f6bedda71652d7..dbf4a2d1b8f7080 100644
--- a/Modules/expat/xmlrole.c
+++ b/Modules/expat/xmlrole.c
@@ -12,7 +12,7 @@
    Copyright (c) 2002-2006 Karl Waclawek <[email protected]>
    Copyright (c) 2002-2003 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2005-2009 Steven Solie <[email protected]>
-   Copyright (c) 2016-2023 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2026 Sebastian Pipping <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2019      David Loffredo <[email protected]>
    Copyright (c) 2021      Donghee Na <[email protected]>
@@ -121,9 +121,8 @@ static const char KW_SYSTEM[]
 #  define setTopLevel(state) ((state)->handler = internalSubset)
 #endif /* not XML_DTD */
 
-typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok,
-                                   const char *ptr, const char *end,
-                                   const ENCODING *enc);
+typedef int PROLOG_HANDLER(PROLOG_STATE *state, int tok, const char *ptr,
+                           const char *end, const ENCODING *enc);
 
 static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2,
     doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2,
@@ -137,9 +136,9 @@ static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, 
doctype1, doctype2,
 #endif /* XML_DTD */
     declClose, error;
 
-static int FASTCALL common(PROLOG_STATE *state, int tok);
+static int common(PROLOG_STATE *state, int tok);
 
-static int PTRCALL
+static int
 prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   switch (tok) {
@@ -170,7 +169,7 @@ prolog0(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   switch (tok) {
@@ -202,7 +201,7 @@ prolog1(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -222,7 +221,7 @@ prolog2(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -239,7 +238,7 @@ doctype0(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   switch (tok) {
@@ -265,7 +264,7 @@ doctype1(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -281,7 +280,7 @@ doctype2(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -297,7 +296,7 @@ doctype3(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -316,7 +315,7 @@ doctype4(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -332,7 +331,7 @@ doctype5(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
                const ENCODING *enc) {
   switch (tok) {
@@ -377,7 +376,7 @@ internalSubset(PROLOG_STATE *state, int tok, const char 
*ptr, const char *end,
 
 #ifdef XML_DTD
 
-static int PTRCALL
+static int
 externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
                 const ENCODING *enc) {
   state->handler = externalSubset1;
@@ -386,7 +385,7 @@ externalSubset0(PROLOG_STATE *state, int tok, const char 
*ptr, const char *end,
   return externalSubset1(state, tok, ptr, end, enc);
 }
 
-static int PTRCALL
+static int
 externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
                 const ENCODING *enc) {
   switch (tok) {
@@ -414,7 +413,7 @@ externalSubset1(PROLOG_STATE *state, int tok, const char 
*ptr, const char *end,
 
 #endif /* XML_DTD */
 
-static int PTRCALL
+static int
 entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -433,7 +432,7 @@ entity0(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -449,7 +448,7 @@ entity1(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   switch (tok) {
@@ -473,7 +472,7 @@ entity2(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -489,7 +488,7 @@ entity3(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -505,7 +504,7 @@ entity4(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   switch (tok) {
@@ -524,7 +523,7 @@ entity5(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -541,7 +540,7 @@ entity6(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   switch (tok) {
@@ -565,7 +564,7 @@ entity7(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -581,7 +580,7 @@ entity8(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
         const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -597,7 +596,7 @@ entity9(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -613,7 +612,7 @@ entity10(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
           const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -629,7 +628,7 @@ notation0(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
           const ENCODING *enc) {
   switch (tok) {
@@ -649,7 +648,7 @@ notation1(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
           const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -665,7 +664,7 @@ notation2(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
           const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -682,7 +681,7 @@ notation3(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
           const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -702,7 +701,7 @@ notation4(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -719,7 +718,7 @@ attlist0(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -739,7 +738,7 @@ attlist1(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   switch (tok) {
@@ -769,7 +768,7 @@ attlist2(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -787,7 +786,7 @@ attlist3(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -806,7 +805,7 @@ attlist4(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -822,7 +821,7 @@ attlist5(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -838,7 +837,7 @@ attlist6(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -858,7 +857,7 @@ attlist7(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
 }
 
 /* default value */
-static int PTRCALL
+static int
 attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   switch (tok) {
@@ -888,7 +887,7 @@ attlist8(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -904,7 +903,7 @@ attlist9(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -921,7 +920,7 @@ element0(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   switch (tok) {
@@ -947,7 +946,7 @@ element1(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   switch (tok) {
@@ -981,7 +980,7 @@ element2(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -1005,7 +1004,7 @@ element3(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -1022,7 +1021,7 @@ element4(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -1042,7 +1041,7 @@ element5(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -1071,7 +1070,7 @@ element6(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
          const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -1120,7 +1119,7 @@ element7(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
 
 #ifdef XML_DTD
 
-static int PTRCALL
+static int
 condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
           const ENCODING *enc) {
   switch (tok) {
@@ -1140,7 +1139,7 @@ condSect0(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
           const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -1157,7 +1156,7 @@ condSect1(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
   return common(state, tok);
 }
 
-static int PTRCALL
+static int
 condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
           const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -1175,7 +1174,7 @@ condSect2(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
 
 #endif /* XML_DTD */
 
-static int PTRCALL
+static int
 declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
           const ENCODING *enc) {
   UNUSED_P(ptr);
@@ -1211,7 +1210,7 @@ declClose(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
  *
  * LCOV_EXCL_START
  */
-static int PTRCALL
+static int
 error(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
       const ENCODING *enc) {
   UNUSED_P(state);
@@ -1223,7 +1222,7 @@ error(PROLOG_STATE *state, int tok, const char *ptr, 
const char *end,
 }
 /* LCOV_EXCL_STOP */
 
-static int FASTCALL
+static int
 common(PROLOG_STATE *state, int tok) {
 #ifdef XML_DTD
   if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
diff --git a/Modules/expat/xmlrole.h b/Modules/expat/xmlrole.h
index 903a6951f434e2e..f4aba4079f5cdfa 100644
--- a/Modules/expat/xmlrole.h
+++ b/Modules/expat/xmlrole.h
@@ -10,7 +10,7 @@
    Copyright (c) 2000      Clark Cooper <[email protected]>
    Copyright (c) 2002      Karl Waclawek <[email protected]>
    Copyright (c) 2002      Fred L. Drake, Jr. <[email protected]>
-   Copyright (c) 2017-2025 Sebastian Pipping <[email protected]>
+   Copyright (c) 2017-2026 Sebastian Pipping <[email protected]>
    Licensed under the MIT license:
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -40,10 +40,6 @@
 
 #  include "xmltok.h"
 
-#  ifdef __cplusplus
-extern "C" {
-#  endif
-
 enum {
   XML_ROLE_ERROR = -1,
   XML_ROLE_NONE = 0,
@@ -112,8 +108,8 @@ enum {
 };
 
 typedef struct prolog_state {
-  int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr,
-                        const char *end, const ENCODING *enc);
+  int (*handler)(struct prolog_state *state, int tok, const char *ptr,
+                 const char *end, const ENCODING *enc);
   unsigned level;
   int role_none;
 #  ifdef XML_DTD
@@ -131,8 +127,4 @@ void XmlPrologStateInitExternalEntity(PROLOG_STATE *state);
 #  define XmlTokenRole(state, tok, ptr, end, enc)                              
\
     (((state)->handler)(state, tok, ptr, end, enc))
 
-#  ifdef __cplusplus
-}
-#  endif
-
 #endif /* not XmlRole_INCLUDED */
diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c
index d66af6045f07aca..a3bf5e0e95b0e03 100644
--- a/Modules/expat/xmltok.c
+++ b/Modules/expat/xmltok.c
@@ -27,6 +27,7 @@
    Copyright (c) 2025      Alfonso Gregory <[email protected]>
    Copyright (c) 2026      Nick Begg <[email protected]>
    Copyright (c) 2026      Kartik Kenchi <[email protected]>
+   Copyright (c) 2026      Afonso Januário <[email protected]>
    Licensed under the MIT license:
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -136,20 +137,20 @@
            : ((p)[1] & 0x80) == 0                                              
\
                  || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
 
-static int PTRFASTCALL
+static int
 isNever(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   UNUSED_P(p);
   return 0;
 }
 
-static int PTRFASTCALL
+static int
 utf8_isName2(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
 }
 
-static int PTRFASTCALL
+static int
 utf8_isName3(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
@@ -157,13 +158,13 @@ utf8_isName3(const ENCODING *enc, const char *p) {
 
 #define utf8_isName4 isNever
 
-static int PTRFASTCALL
+static int
 utf8_isNmstrt2(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
 }
 
-static int PTRFASTCALL
+static int
 utf8_isNmstrt3(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
@@ -171,19 +172,19 @@ utf8_isNmstrt3(const ENCODING *enc, const char *p) {
 
 #define utf8_isNmstrt4 isNever
 
-static int PTRFASTCALL
+static int
 utf8_isInvalid2(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return UTF8_INVALID2((const unsigned char *)p);
 }
 
-static int PTRFASTCALL
+static int
 utf8_isInvalid3(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return UTF8_INVALID3((const unsigned char *)p);
 }
 
-static int PTRFASTCALL
+static int
 utf8_isInvalid4(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return UTF8_INVALID4((const unsigned char *)p);
@@ -193,21 +194,21 @@ struct normal_encoding {
   ENCODING enc;
   unsigned char type[256];
 #ifdef XML_MIN_SIZE
-  int(PTRFASTCALL *byteType)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
-  int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
-  int(PTRCALL *charMatches)(const ENCODING *, const char *, int);
+  int (*byteType)(const ENCODING *, const char *);
+  int (*isNameMin)(const ENCODING *, const char *);
+  int (*isNmstrtMin)(const ENCODING *, const char *);
+  int (*byteToAscii)(const ENCODING *, const char *);
+  int (*charMatches)(const ENCODING *, const char *, int);
 #endif /* XML_MIN_SIZE */
-  int(PTRFASTCALL *isName2)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isName3)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isName4)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
-  int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
+  int (*isName2)(const ENCODING *, const char *);
+  int (*isName3)(const ENCODING *, const char *);
+  int (*isName4)(const ENCODING *, const char *);
+  int (*isNmstrt2)(const ENCODING *, const char *);
+  int (*isNmstrt3)(const ENCODING *, const char *);
+  int (*isNmstrt4)(const ENCODING *, const char *);
+  int (*isInvalid2)(const ENCODING *, const char *);
+  int (*isInvalid3)(const ENCODING *, const char *);
+  int (*isInvalid4)(const ENCODING *, const char *);
 };
 
 #define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc))
@@ -232,7 +233,20 @@ struct normal_encoding {
       /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL,        
\
       /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL
 
-static int FASTCALL checkCharRefNumber(int result);
+/* Like NULL_VTABLE but with a real isInvalid4 so the UTF-16 encodings reject a
+   high surrogate that is not followed by a low surrogate.  Only needed for the
+   XML_MIN_SIZE build, where the shared tokenizer dispatches through the 
vtable;
+   the regular build inlines the same check via IS_INVALID_CHAR. */
+#ifdef XML_MIN_SIZE
+#  define UTF16_NULL_VTABLE(E)                                                 
\
+    /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL,                
\
+        /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL,      
\
+        /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, E##isInvalid4
+#else
+#  define UTF16_NULL_VTABLE(E) NULL_VTABLE
+#endif
+
+static int checkCharRefNumber(int result);
 
 #include "xmltok_impl.h"
 #include "ascii.h"
@@ -253,7 +267,7 @@ static int FASTCALL checkCharRefNumber(int result);
   (((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
 
 #ifdef XML_MIN_SIZE
-static int PTRFASTCALL
+static int
 sb_byteType(const ENCODING *enc, const char *p) {
   return SB_BYTE_TYPE(enc, p);
 }
@@ -264,7 +278,7 @@ sb_byteType(const ENCODING *enc, const char *p) {
 
 #ifdef XML_MIN_SIZE
 #  define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
-static int PTRFASTCALL
+static int
 sb_byteToAscii(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return *p;
@@ -297,7 +311,7 @@ sb_byteToAscii(const ENCODING *enc, const char *p) {
 #ifdef XML_MIN_SIZE
 #  define CHAR_MATCHES(enc, p, c)                                              
\
     (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
-static int PTRCALL
+static int
 sb_charMatches(const ENCODING *enc, const char *p, int c) {
   UNUSED_P(enc);
   return *p == c;
@@ -368,7 +382,7 @@ _INTERNAL_trim_to_complete_utf8_characters(const char *from,
   *fromLimRef = fromLim;
 }
 
-static enum XML_Convert_Result PTRCALL
+static enum XML_Convert_Result
 utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
             char **toP, const char *toLim) {
   bool input_incomplete = false;
@@ -407,7 +421,7 @@ utf8_toUtf8(const ENCODING *enc, const char **fromP, const 
char *fromLim,
     return XML_CONVERT_COMPLETED;
 }
 
-static enum XML_Convert_Result PTRCALL
+static enum XML_Convert_Result
 utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
              unsigned short **toP, const unsigned short *toLim) {
   enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
@@ -505,7 +519,7 @@ static const struct normal_encoding internal_utf8_encoding
        },
        STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
 
-static enum XML_Convert_Result PTRCALL
+static enum XML_Convert_Result
 latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
               char **toP, const char *toLim) {
   UNUSED_P(enc);
@@ -528,7 +542,7 @@ latin1_toUtf8(const ENCODING *enc, const char **fromP, 
const char *fromLim,
   }
 }
 
-static enum XML_Convert_Result PTRCALL
+static enum XML_Convert_Result
 latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
                unsigned short **toP, const unsigned short *toLim) {
   UNUSED_P(enc);
@@ -563,7 +577,7 @@ static const struct normal_encoding latin1_encoding
        },
        STANDARD_VTABLE(sb_) NULL_VTABLE};
 
-static enum XML_Convert_Result PTRCALL
+static enum XML_Convert_Result
 ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
              char **toP, const char *toLim) {
   UNUSED_P(enc);
@@ -598,7 +612,7 @@ static const struct normal_encoding ascii_encoding
        },
        STANDARD_VTABLE(sb_) NULL_VTABLE};
 
-static int PTRFASTCALL
+static int
 unicode_byte_type(char hi, char lo) {
   switch ((unsigned char)hi) {
   /* 0xD800-0xDBFF first 16-bit code unit or high surrogate (W1) */
@@ -625,7 +639,7 @@ unicode_byte_type(char hi, char lo) {
 }
 
 #define DEFINE_UTF16_TO_UTF8(E)                                                
\
-  static enum XML_Convert_Result PTRCALL E##toUtf8(                            
\
+  static enum XML_Convert_Result E##toUtf8(                                    
\
       const ENCODING *enc, const char **fromP, const char *fromLim,            
\
       char **toP, const char *toLim) {                                         
\
     const char *from = *fromP;                                                 
\
@@ -702,7 +716,7 @@ unicode_byte_type(char hi, char lo) {
   }
 
 #define DEFINE_UTF16_TO_UTF16(E)                                               
\
-  static enum XML_Convert_Result PTRCALL E##toUtf16(                           
\
+  static enum XML_Convert_Result E##toUtf16(                                   
\
       const ENCODING *enc, const char **fromP, const char *fromLim,            
\
       unsigned short **toP, const unsigned short *toLim) {                     
\
     enum XML_Convert_Result res = XML_CONVERT_COMPLETED;                       
\
@@ -749,38 +763,49 @@ DEFINE_UTF16_TO_UTF16(big2_)
   UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
 #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)                                       
\
   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
+/* A 4-byte UTF-16 character is a surrogate pair; byteType only reports 
BT_LEAD4
+   for a high surrogate, so the pair is invalid unless the second unit is a low
+   surrogate (U+DC00..U+DFFF, i.e. high byte 0xDC..0xDF). */
+#define LITTLE2_IS_INVALID_CHAR(p, n)                                          
\
+  ((n) == 4 && ((unsigned char)(p)[3] & 0xFC) != 0xDC)
 
 #ifdef XML_MIN_SIZE
 
-static int PTRFASTCALL
+static int
 little2_byteType(const ENCODING *enc, const char *p) {
   return LITTLE2_BYTE_TYPE(enc, p);
 }
 
-static int PTRFASTCALL
+static int
 little2_byteToAscii(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return LITTLE2_BYTE_TO_ASCII(p);
 }
 
-static int PTRCALL
+static int
 little2_charMatches(const ENCODING *enc, const char *p, int c) {
   UNUSED_P(enc);
   return LITTLE2_CHAR_MATCHES(p, c);
 }
 
-static int PTRFASTCALL
+static int
 little2_isNameMin(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return LITTLE2_IS_NAME_CHAR_MINBPC(p);
 }
 
-static int PTRFASTCALL
+static int
 little2_isNmstrtMin(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p);
 }
 
+static int
+little2_isInvalid4(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
+  return LITTLE2_IS_INVALID_CHAR(p, 4);
+}
+
 #  undef VTABLE
 #  define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
 
@@ -797,6 +822,7 @@ little2_isNmstrtMin(const ENCODING *enc, const char *p) {
 #  define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p)
 #  define IS_NMSTRT_CHAR(enc, p, n) (0)
 #  define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)
+#  define IS_INVALID_CHAR(enc, p, n) LITTLE2_IS_INVALID_CHAR(p, n)
 
 #  define XML_TOK_IMPL_C
 #  include "xmltok_impl.c"
@@ -828,7 +854,7 @@ static const struct normal_encoding little2_encoding_ns
 #  include "asciitab.h"
 #  include "latin1tab.h"
        },
-       STANDARD_VTABLE(little2_) NULL_VTABLE};
+       STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)};
 
 #endif
 
@@ -846,7 +872,7 @@ static const struct normal_encoding little2_encoding
 #undef BT_COLON
 #include "latin1tab.h"
        },
-       STANDARD_VTABLE(little2_) NULL_VTABLE};
+       STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)};
 
 #if BYTEORDER != 4321
 
@@ -858,7 +884,7 @@ static const struct normal_encoding 
internal_little2_encoding_ns
 #    include "iasciitab.h"
 #    include "latin1tab.h"
        },
-       STANDARD_VTABLE(little2_) NULL_VTABLE};
+       STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)};
 
 #  endif
 
@@ -870,7 +896,7 @@ static const struct normal_encoding 
internal_little2_encoding
 #  undef BT_COLON
 #  include "latin1tab.h"
        },
-       STANDARD_VTABLE(little2_) NULL_VTABLE};
+       STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)};
 
 #endif
 
@@ -882,38 +908,49 @@ static const struct normal_encoding 
internal_little2_encoding
   UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
 #define BIG2_IS_NMSTRT_CHAR_MINBPC(p)                                          
\
   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
+/* A 4-byte UTF-16 character is a surrogate pair; byteType only reports 
BT_LEAD4
+   for a high surrogate, so the pair is invalid unless the second unit is a low
+   surrogate (U+DC00..U+DFFF, i.e. high byte 0xDC..0xDF). */
+#define BIG2_IS_INVALID_CHAR(p, n)                                             
\
+  ((n) == 4 && ((unsigned char)(p)[2] & 0xFC) != 0xDC)
 
 #ifdef XML_MIN_SIZE
 
-static int PTRFASTCALL
+static int
 big2_byteType(const ENCODING *enc, const char *p) {
   return BIG2_BYTE_TYPE(enc, p);
 }
 
-static int PTRFASTCALL
+static int
 big2_byteToAscii(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return BIG2_BYTE_TO_ASCII(p);
 }
 
-static int PTRCALL
+static int
 big2_charMatches(const ENCODING *enc, const char *p, int c) {
   UNUSED_P(enc);
   return BIG2_CHAR_MATCHES(p, c);
 }
 
-static int PTRFASTCALL
+static int
 big2_isNameMin(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return BIG2_IS_NAME_CHAR_MINBPC(p);
 }
 
-static int PTRFASTCALL
+static int
 big2_isNmstrtMin(const ENCODING *enc, const char *p) {
   UNUSED_P(enc);
   return BIG2_IS_NMSTRT_CHAR_MINBPC(p);
 }
 
+static int
+big2_isInvalid4(const ENCODING *enc, const char *p) {
+  UNUSED_P(enc);
+  return BIG2_IS_INVALID_CHAR(p, 4);
+}
+
 #  undef VTABLE
 #  define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
 
@@ -930,6 +967,7 @@ big2_isNmstrtMin(const ENCODING *enc, const char *p) {
 #  define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p)
 #  define IS_NMSTRT_CHAR(enc, p, n) (0)
 #  define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p)
+#  define IS_INVALID_CHAR(enc, p, n) BIG2_IS_INVALID_CHAR(p, n)
 
 #  define XML_TOK_IMPL_C
 #  include "xmltok_impl.c"
@@ -961,7 +999,7 @@ static const struct normal_encoding big2_encoding_ns
 #  include "asciitab.h"
 #  include "latin1tab.h"
        },
-       STANDARD_VTABLE(big2_) NULL_VTABLE};
+       STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)};
 
 #endif
 
@@ -979,7 +1017,7 @@ static const struct normal_encoding big2_encoding
 #undef BT_COLON
 #include "latin1tab.h"
        },
-       STANDARD_VTABLE(big2_) NULL_VTABLE};
+       STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)};
 
 #if BYTEORDER != 1234
 
@@ -991,7 +1029,7 @@ static const struct normal_encoding 
internal_big2_encoding_ns
 #    include "iasciitab.h"
 #    include "latin1tab.h"
        },
-       STANDARD_VTABLE(big2_) NULL_VTABLE};
+       STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)};
 
 #  endif
 
@@ -1003,13 +1041,13 @@ static const struct normal_encoding 
internal_big2_encoding
 #  undef BT_COLON
 #  include "latin1tab.h"
        },
-       STANDARD_VTABLE(big2_) NULL_VTABLE};
+       STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)};
 
 #endif
 
 #undef PREFIX
 
-static int FASTCALL
+static int
 streqci(const char *s1, const char *s2) {
   for (;;) {
     char c1 = *s1++;
@@ -1030,7 +1068,7 @@ streqci(const char *s1, const char *s2) {
   return 1;
 }
 
-static void PTRCALL
+static void
 initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end,
                    POSITION *pos) {
   UNUSED_P(enc);
@@ -1048,7 +1086,7 @@ toAscii(const ENCODING *enc, const char *ptr, const char 
*end) {
     return buf[0];
 }
 
-static int FASTCALL
+static int
 isSpace(int c) {
   switch (c) {
   case 0x20:
@@ -1154,6 +1192,34 @@ static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, 
'\0'};
 
 static const char KW_no[] = {ASCII_n, ASCII_o, '\0'};
 
+static const char KW_1_dot[] = {ASCII_1, ASCII_PERIOD, '\0'};
+
+/* Checks a version pseudo-attribute value against the VersionNum production.
+   XML 1.0 Fourth Edition only allows the literal "1.0", but the Fifth
+   Edition relaxed this to "1." followed by one or more digits, since Expat
+   only implements 1.0 itself but plans to track the Fifth Edition's laxer
+   grammar here so that "1.1" and similar aren't rejected only to have that
+   rejection reverted later. Returns true for a value matching "1.[0-9]+".
+   val/valEnd bound the value itself; valEnd is the upper bound used when
+   decoding the individual characters between them. */
+static bool
+checkXmlDeclVersionNum(const ENCODING *enc, const char *val,
+                       const char *valEnd) {
+  if (valEnd - val < 2 * enc->minBytesPerChar
+      || ! XmlNameMatchesAscii(enc, val, val + 2 * enc->minBytesPerChar,
+                               KW_1_dot))
+    return false;
+  val += 2 * enc->minBytesPerChar;
+  if (val == valEnd)
+    return false;
+  for (; val != valEnd; val += enc->minBytesPerChar) {
+    int c = toAscii(enc, val, valEnd);
+    if (c < ASCII_0 || c > ASCII_9)
+      return false;
+  }
+  return true;
+}
+
 static int
 doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char 
*,
                                                  const char *),
@@ -1188,6 +1254,15 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const 
ENCODING *, const char *,
       *badPtr = val;
       return 0;
     }
+    /* Expat implements XML 1.0 only, so any version outside the "1.0"/"1.x"
+       family is rejected. Following the Fifth Edition's VersionNum
+       production (rather than the Fourth Edition's exact "1.0") avoids
+       rejecting "1.1" now only to have to revert that once Expat tracks
+       the newer edition. */
+    if (! checkXmlDeclVersionNum(enc, val, ptr - enc->minBytesPerChar)) {
+      *badPtr = val;
+      return 0;
+    }
     if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
       *badPtr = ptr;
       return 0;
@@ -1242,7 +1317,7 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const 
ENCODING *, const char *,
   return 1;
 }
 
-static int FASTCALL
+static int
 checkCharRefNumber(int result) {
   switch (result >> 8) {
   case 0xD8:
@@ -1266,7 +1341,7 @@ checkCharRefNumber(int result) {
   return result;
 }
 
-int FASTCALL
+int
 XmlUtf8Encode(int c, char *buf) {
   enum {
     /* minN is minimum legal resulting value for N byte sequence */
@@ -1302,7 +1377,7 @@ XmlUtf8Encode(int c, char *buf) {
   return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
 }
 
-int FASTCALL
+int
 XmlUtf16Encode(int charNum, unsigned short *buf) {
   if (charNum < 0)
     return 0;
@@ -1334,7 +1409,7 @@ XmlSizeOfUnknownEncoding(void) {
   return sizeof(struct unknown_encoding);
 }
 
-static int PTRFASTCALL
+static int
 unknown_isName(const ENCODING *enc, const char *p) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   int c = uenc->convert(uenc->userData, p);
@@ -1343,7 +1418,7 @@ unknown_isName(const ENCODING *enc, const char *p) {
   return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
 }
 
-static int PTRFASTCALL
+static int
 unknown_isNmstrt(const ENCODING *enc, const char *p) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   int c = uenc->convert(uenc->userData, p);
@@ -1352,14 +1427,14 @@ unknown_isNmstrt(const ENCODING *enc, const char *p) {
   return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
 }
 
-static int PTRFASTCALL
+static int
 unknown_isInvalid(const ENCODING *enc, const char *p) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   int c = uenc->convert(uenc->userData, p);
   return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
 }
 
-static enum XML_Convert_Result PTRCALL
+static enum XML_Convert_Result
 unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
                char **toP, const char *toLim) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
@@ -1389,7 +1464,7 @@ unknown_toUtf8(const ENCODING *enc, const char **fromP, 
const char *fromLim,
   }
 }
 
-static enum XML_Convert_Result PTRCALL
+static enum XML_Convert_Result
 unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
                 unsigned short **toP, const unsigned short *toLim) {
   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
@@ -1513,7 +1588,7 @@ static const char KW_UTF_16LE[]
     = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
        ASCII_6, ASCII_L, ASCII_E, '\0'};
 
-static int FASTCALL
+static int
 getEncodingIndex(const char *name) {
   static const char *const encodingNames[] = {
       KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, 
KW_UTF_16LE,
diff --git a/Modules/expat/xmltok.h b/Modules/expat/xmltok.h
index 76be2c7c5ca1bab..bf641af6d4f77f0 100644
--- a/Modules/expat/xmltok.h
+++ b/Modules/expat/xmltok.h
@@ -41,10 +41,6 @@
 
 #  include <stdint.h> // uint64_t
 
-#  ifdef __cplusplus
-extern "C" {
-#  endif
-
 /* The following token may be returned by XmlContentTok */
 #  define XML_TOK_TRAILING_RSQB                                                
\
     -5 /* ] or ]] at the end of the scan; might be                             
\
@@ -163,8 +159,8 @@ typedef struct {
 struct encoding;
 typedef struct encoding ENCODING;
 
-typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *,
-                              const char **);
+typedef int (*SCANNER)(const ENCODING *, const char *, const char *,
+                       const char **);
 
 enum XML_Convert_Result {
   XML_CONVERT_COMPLETED = 0,
@@ -176,28 +172,27 @@ enum XML_Convert_Result {
 struct encoding {
   SCANNER scanners[XML_N_STATES];
   SCANNER literalScanners[XML_N_LITERAL_TYPES];
-  int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *,
-                                 const char *);
-  int(PTRFASTCALL *nameLength)(const ENCODING *, const char *);
-  const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
-  int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
-                        ATTRIBUTE *atts);
-  int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
-  int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *,
-                                     const char *);
-  void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr,
-                                const char *end, POSITION *);
-  int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr,
-                           const char *end, const char **badPtr);
-  enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc,
-                                                const char **fromP,
-                                                const char *fromLim, char 
**toP,
-                                                const char *toLim);
-  enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc,
-                                                 const char **fromP,
-                                                 const char *fromLim,
-                                                 unsigned short **toP,
-                                                 const unsigned short *toLim);
+  int (*nameMatchesAscii)(const ENCODING *, const char *, const char *,
+                          const char *);
+  int (*nameLength)(const ENCODING *, const char *);
+  const char *(*skipS)(const ENCODING *, const char *);
+  int (*getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
+                 ATTRIBUTE *atts);
+  int (*charRefNumber)(const ENCODING *enc, const char *ptr);
+  int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
+  void (*updatePosition)(const ENCODING *, const char *ptr, const char *end,
+                         POSITION *);
+  int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **badPtr);
+  enum XML_Convert_Result (*utf8Convert)(const ENCODING *enc,
+                                         const char **fromP,
+                                         const char *fromLim, char **toP,
+                                         const char *toLim);
+  enum XML_Convert_Result (*utf16Convert)(const ENCODING *enc,
+                                          const char **fromP,
+                                          const char *fromLim,
+                                          unsigned short **toP,
+                                          const unsigned short *toLim);
   int minBytesPerChar;
   char isUtf8;
   char isUtf16;
@@ -297,8 +292,8 @@ int XmlInitEncoding(INIT_ENCODING *p, const ENCODING 
**encPtr,
                     const char *name);
 const ENCODING *XmlGetUtf8InternalEncoding(void);
 const ENCODING *XmlGetUtf16InternalEncoding(void);
-int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
-int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
+int XmlUtf8Encode(int charNumber, char *buf);
+int XmlUtf16Encode(int charNumber, unsigned short *buf);
 int XmlSizeOfUnknownEncoding(void);
 
 typedef int(XMLCALL *CONVERTER)(void *userData, const char *p);
@@ -318,8 +313,5 @@ const ENCODING *XmlGetUtf8InternalEncodingNS(void);
 const ENCODING *XmlGetUtf16InternalEncodingNS(void);
 ENCODING *XmlInitUnknownEncodingNS(void *mem, const int *table,
                                    CONVERTER convert, void *userData);
-#  ifdef __cplusplus
-}
-#  endif
 
 #endif /* not XmlTok_INCLUDED */
diff --git a/Modules/expat/xmltok_impl.c b/Modules/expat/xmltok_impl.c
index 1d8e457d9de5445..a71a2fd88c704b6 100644
--- a/Modules/expat/xmltok_impl.c
+++ b/Modules/expat/xmltok_impl.c
@@ -10,7 +10,7 @@
    Copyright (c) 2000      Clark Cooper <[email protected]>
    Copyright (c) 2002      Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2002-2016 Karl Waclawek <[email protected]>
-   Copyright (c) 2016-2022 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2026 Sebastian Pipping <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2018      Benjamin Peterson <[email protected]>
    Copyright (c) 2018      Anton Maklakov <[email protected]>
@@ -18,6 +18,7 @@
    Copyright (c) 2020      Boris Kolpackov <[email protected]>
    Copyright (c) 2022      Martin Ettl <[email protected]>
    Copyright (c) 2026      Nick Begg <[email protected]>
+   Copyright (c) 2026      Kartik Kenchi <[email protected]>
    Licensed under the MIT license:
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -44,10 +45,6 @@
 
 #ifdef XML_TOK_IMPL_C
 
-#  ifndef IS_INVALID_CHAR // i.e. for UTF-16 and XML_MIN_SIZE not defined
-#    define IS_INVALID_CHAR(enc, ptr, n) (0)
-#  endif
-
 #  define INVALID_LEAD_CASE(n, ptr, nextTokPtr)                                
\
   case BT_LEAD##n:                                                             
\
     if (end - ptr < n)                                                         
\
@@ -144,7 +141,7 @@
 
 /* ptr points to character following "<!-" */
 
-static int PTRCALL
+static int
 PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
                     const char **nextTokPtr) {
   if (HAS_CHAR(enc, ptr, end)) {
@@ -181,7 +178,7 @@ PREFIX(scanComment)(const ENCODING *enc, const char *ptr, 
const char *end,
 
 /* ptr points to character following "<!" */
 
-static int PTRCALL
+static int
 PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
                  const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
@@ -230,7 +227,7 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, 
const char *end,
   return XML_TOK_PARTIAL;
 }
 
-static int PTRCALL
+static int
 PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end,
                       int *tokPtr) {
   int upper = 0;
@@ -275,7 +272,7 @@ PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, 
const char *end,
 
 /* ptr points to character following "<?" */
 
-static int PTRCALL
+static int
 PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
                const char **nextTokPtr) {
   int tok;
@@ -335,7 +332,7 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const 
char *end,
   return XML_TOK_PARTIAL;
 }
 
-static int PTRCALL
+static int
 PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
                          const char **nextTokPtr) {
   static const char CDATA_LSQB[]
@@ -354,7 +351,7 @@ PREFIX(scanCdataSection)(const ENCODING *enc, const char 
*ptr, const char *end,
   return XML_TOK_CDATA_SECT_OPEN;
 }
 
-static int PTRCALL
+static int
 PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
                         const char **nextTokPtr) {
   if (ptr >= end)
@@ -430,7 +427,7 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char 
*ptr, const char *end,
 
 /* ptr points to character following "</" */
 
-static int PTRCALL
+static int
 PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
                    const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
@@ -481,7 +478,7 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, 
const char *end,
 
 /* ptr points to character following "&#X" */
 
-static int PTRCALL
+static int
 PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
                        const char **nextTokPtr) {
   if (HAS_CHAR(enc, ptr, end)) {
@@ -512,7 +509,7 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char 
*ptr, const char *end,
 
 /* ptr points to character following "&#" */
 
-static int PTRCALL
+static int
 PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
                     const char **nextTokPtr) {
   if (HAS_CHAR(enc, ptr, end)) {
@@ -543,7 +540,7 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, 
const char *end,
 
 /* ptr points to character following "&" */
 
-static int PTRCALL
+static int
 PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
                 const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
@@ -571,7 +568,7 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const 
char *end,
 
 /* ptr points to character following first character of attribute name */
 
-static int PTRCALL
+static int
 PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
                  const char **nextTokPtr) {
 #  ifdef XML_NS
@@ -724,7 +721,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, 
const char *end,
 
 /* ptr points to character following "<" */
 
-static int PTRCALL
+static int
 PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
                const char **nextTokPtr) {
 #  ifdef XML_NS
@@ -822,7 +819,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const 
char *end,
   return XML_TOK_PARTIAL;
 }
 
-static int PTRCALL
+static int
 PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
                    const char **nextTokPtr) {
   if (ptr >= end)
@@ -922,7 +919,7 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, 
const char *end,
 
 /* ptr points to character following "%" */
 
-static int PTRCALL
+static int
 PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
                     const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
@@ -952,7 +949,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, 
const char *end,
   return XML_TOK_PARTIAL;
 }
 
-static int PTRCALL
+static int
 PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
                       const char **nextTokPtr) {
   REQUIRE_CHAR(enc, ptr, end);
@@ -982,7 +979,7 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, 
const char *end,
   return -XML_TOK_POUND_NAME;
 }
 
-static int PTRCALL
+static int
 PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char 
*end,
                 const char **nextTokPtr) {
   while (HAS_CHAR(enc, ptr, end)) {
@@ -1016,7 +1013,7 @@ PREFIX(scanLit)(int open, const ENCODING *enc, const char 
*ptr, const char *end,
   return XML_TOK_PARTIAL;
 }
 
-static int PTRCALL
+static int
 PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
                   const char **nextTokPtr) {
   int tok;
@@ -1260,7 +1257,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, 
const char *end,
   return -tok;
 }
 
-static int PTRCALL
+static int
 PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char 
*end,
                           const char **nextTokPtr) {
   const char *start;
@@ -1329,7 +1326,7 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char 
*ptr, const char *end,
   return XML_TOK_DATA_CHARS;
 }
 
-static int PTRCALL
+static int
 PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
                        const char **nextTokPtr) {
   const char *start;
@@ -1396,7 +1393,7 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char 
*ptr, const char *end,
 
 #  ifdef XML_DTD
 
-static int PTRCALL
+static int
 PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
                          const char **nextTokPtr) {
   int level = 0;
@@ -1448,7 +1445,7 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char 
*ptr, const char *end,
 
 #  endif /* XML_DTD */
 
-static int PTRCALL
+static int
 PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
                    const char **badPtr) {
   ptr += MINBPC(enc);
@@ -1508,7 +1505,7 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, 
const char *end,
    first attsMax attributes are stored in atts.
 */
 
-static int PTRCALL
+static int
 PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
                 ATTRIBUTE *atts) {
   enum { other, inName, inValue } state = inName;
@@ -1601,7 +1598,7 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int 
attsMax,
   /* not reached */
 }
 
-static int PTRFASTCALL
+static int
 PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) {
   int result = 0;
   /* skip &# */
@@ -1659,7 +1656,7 @@ PREFIX(charRefNumber)(const ENCODING *enc, const char 
*ptr) {
   return checkCharRefNumber(result);
 }
 
-static int PTRCALL
+static int
 PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
                              const char *end) {
   UNUSED_P(enc);
@@ -1713,7 +1710,7 @@ PREFIX(predefinedEntityName)(const ENCODING *enc, const 
char *ptr,
   return 0;
 }
 
-static int PTRCALL
+static int
 PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
                          const char *end1, const char *ptr2) {
   UNUSED_P(enc);
@@ -1732,7 +1729,7 @@ PREFIX(nameMatchesAscii)(const ENCODING *enc, const char 
*ptr1,
   return ptr1 == end1;
 }
 
-static int PTRFASTCALL
+static int
 PREFIX(nameLength)(const ENCODING *enc, const char *ptr) {
   const char *start = ptr;
   for (;;) {
@@ -1762,7 +1759,7 @@ PREFIX(nameLength)(const ENCODING *enc, const char *ptr) {
   }
 }
 
-static const char *PTRFASTCALL
+static const char *
 PREFIX(skipS)(const ENCODING *enc, const char *ptr) {
   for (;;) {
     switch (BYTE_TYPE(enc, ptr)) {
@@ -1777,7 +1774,7 @@ PREFIX(skipS)(const ENCODING *enc, const char *ptr) {
   }
 }
 
-static void PTRCALL
+static void
 PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end,
                        POSITION *pos) {
   while (HAS_CHAR(enc, ptr, end)) {
diff --git a/Modules/expat/xmltok_ns.c b/Modules/expat/xmltok_ns.c
index 40a02a0308b563c..d9f69abb92ef39f 100644
--- a/Modules/expat/xmltok_ns.c
+++ b/Modules/expat/xmltok_ns.c
@@ -11,7 +11,7 @@
    Copyright (c) 2002      Greg Stein <[email protected]>
    Copyright (c) 2002      Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2002-2006 Karl Waclawek <[email protected]>
-   Copyright (c) 2017-2021 Sebastian Pipping <[email protected]>
+   Copyright (c) 2017-2026 Sebastian Pipping <[email protected]>
    Copyright (c) 2025      Alfonso Gregory <[email protected]>
    Licensed under the MIT license:
 
@@ -64,14 +64,14 @@ static const ENCODING *const NS(encodings)[] = {
     &ns(utf8_encoding).enc /* NO_ENC */
 };
 
-static int PTRCALL
+static int
 NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
                    const char **nextTokPtr) {
   return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE,
                   ptr, end, nextTokPtr);
 }
 
-static int PTRCALL
+static int
 NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
                     const char **nextTokPtr) {
   return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE,
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index 80ff3c02a55b0ac..80bc6dc70b5b03a 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -2260,7 +2260,10 @@ pyexpat_exec(PyObject *mod)
     capi.SetEncoding = XML_SetEncoding;
     capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler;
 #if XML_COMBINED_VERSION >= 20100
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
     capi.SetHashSalt = XML_SetHashSalt;
+_Py_COMP_DIAG_POP
 #else
     capi.SetHashSalt = NULL;
 #endif
diff --git a/PCbuild/_elementtree.vcxproj b/PCbuild/_elementtree.vcxproj
index 8aad9513e35319d..9c4210cfef9c202 100644
--- a/PCbuild/_elementtree.vcxproj
+++ b/PCbuild/_elementtree.vcxproj
@@ -104,6 +104,7 @@
     <ClInclude Include="..\Modules\expat\expat_config.h" />
     <ClInclude Include="..\Modules\expat\expat_external.h" />
     <ClInclude Include="..\Modules\expat\fallthrough.h" />
+    <ClInclude Include="..\Modules\expat\hash_table.h" />
     <ClInclude Include="..\Modules\expat\iasciitab.h" />
     <ClInclude Include="..\Modules\expat\internal.h" />
     <ClInclude Include="..\Modules\expat\latin1tab.h" />
diff --git a/PCbuild/_elementtree.vcxproj.filters 
b/PCbuild/_elementtree.vcxproj.filters
index f6b55d8ff82a68c..9e2e062af3f3877 100644
--- a/PCbuild/_elementtree.vcxproj.filters
+++ b/PCbuild/_elementtree.vcxproj.filters
@@ -36,6 +36,9 @@
     <ClInclude Include="..\Modules\expat\fallthrough.h">
       <Filter>Header Files\expat</Filter>
     </ClInclude>
+    <ClInclude Include="..\Modules\expat\hash_table.h">
+      <Filter>Header Files\expat</Filter>
+    </ClInclude>
     <ClInclude Include="..\Modules\expat\iasciitab.h">
       <Filter>Header Files\expat</Filter>
     </ClInclude>
diff --git a/PCbuild/pyexpat.vcxproj b/PCbuild/pyexpat.vcxproj
index 27b0123c777e9a2..a81383a81304bea 100644
--- a/PCbuild/pyexpat.vcxproj
+++ b/PCbuild/pyexpat.vcxproj
@@ -96,6 +96,7 @@
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClInclude Include="..\Modules\expat\fallthrough.h" />
+    <ClInclude Include="..\Modules\expat\hash_table.h" />
     <ClInclude Include="..\Modules\expat\memory_sanitizer.h" />
     <ClInclude Include="..\Modules\expat\xmlrole.h" />
     <ClInclude Include="..\Modules\expat\xmltok.h" />
diff --git a/PCbuild/pyexpat.vcxproj.filters b/PCbuild/pyexpat.vcxproj.filters
index 230531033fccd87..e63cb9c63063aca 100644
--- a/PCbuild/pyexpat.vcxproj.filters
+++ b/PCbuild/pyexpat.vcxproj.filters
@@ -15,6 +15,9 @@
     <ClInclude Include="..\Modules\expat\fallthrough.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\Modules\expat\hash_table.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\Modules\expat\memory_sanitizer.h">
       <Filter>Header Files</Filter>
     </ClInclude>

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to