File CVE-2025-59375.patch of Package expat.40893

Index: expat-2.7.1/fuzz/xml_lpm_fuzzer.cpp
===================================================================
--- expat-2.7.1.orig/fuzz/xml_lpm_fuzzer.cpp
+++ expat-2.7.1/fuzz/xml_lpm_fuzzer.cpp
@@ -354,8 +354,10 @@ ExternalEntityRefHandler(XML_Parser pars
   if (g_external_entity) {
     XML_Parser ext_parser
         = XML_ExternalEntityParserCreate(parser, context, g_encoding);
-    rc = Parse(ext_parser, g_external_entity, g_external_entity_size, 1);
-    XML_ParserFree(ext_parser);
+    if (ext_parser != NULL) {
+      rc = Parse(ext_parser, g_external_entity, g_external_entity_size, 1);
+      XML_ParserFree(ext_parser);
+    }
   }
 
   return rc;
Index: expat-2.7.1/fuzz/xml_parsebuffer_fuzzer.c
===================================================================
--- expat-2.7.1.orig/fuzz/xml_parsebuffer_fuzzer.c
+++ expat-2.7.1/fuzz/xml_parsebuffer_fuzzer.c
@@ -15,6 +15,7 @@
  */
 
 #include <assert.h>
+#include <limits.h> // for INT_MAX
 #include <stdint.h>
 #include <string.h>
 
@@ -66,16 +67,17 @@ ParseOneInput(XML_Parser p, const uint8_
   XML_SetUserData(p, p);
   XML_SetElementHandler(p, start, end);
   XML_SetCharacterDataHandler(p, may_stop_character_handler);
-  void *buf = XML_GetBuffer(p, size);
+  assert(size <= INT_MAX);
+  void *buf = XML_GetBuffer(p, (int)size);
   assert(buf);
   memcpy(buf, data, size);
-  XML_ParseBuffer(p, size, 0);
-  buf = XML_GetBuffer(p, size);
+  XML_ParseBuffer(p, (int)size, 0);
+  buf = XML_GetBuffer(p, (int)size);
   if (buf == NULL) {
     return;
   }
   memcpy(buf, data, size);
-  if (XML_ParseBuffer(p, size, 1) == XML_STATUS_ERROR) {
+  if (XML_ParseBuffer(p, (int)size, 1) == XML_STATUS_ERROR) {
     XML_ErrorString(XML_GetErrorCode(p));
   }
   XML_GetCurrentLineNumber(p);
@@ -101,15 +103,17 @@ LLVMFuzzerTestOneInput(const uint8_t *da
 
   XML_Parser externalEntityParser
       = XML_ExternalEntityParserCreate(parentParser, "e1", NULL);
-  assert(externalEntityParser);
-  ParseOneInput(externalEntityParser, data, size);
-  XML_ParserFree(externalEntityParser);
+  if (externalEntityParser != NULL) {
+    ParseOneInput(externalEntityParser, data, size);
+    XML_ParserFree(externalEntityParser);
+  }
 
   XML_Parser externalDtdParser
       = XML_ExternalEntityParserCreate(parentParser, NULL, NULL);
-  assert(externalDtdParser);
-  ParseOneInput(externalDtdParser, data, size);
-  XML_ParserFree(externalDtdParser);
+  if (externalDtdParser != NULL) {
+    ParseOneInput(externalDtdParser, data, size);
+    XML_ParserFree(externalDtdParser);
+  }
 
   // finally frees this parser which served as parent
   XML_ParserFree(parentParser);
Index: expat-2.7.1/fuzz/xml_parse_fuzzer.c
===================================================================
--- expat-2.7.1.orig/fuzz/xml_parse_fuzzer.c
+++ expat-2.7.1/fuzz/xml_parse_fuzzer.c
@@ -15,6 +15,7 @@
  */
 
 #include <assert.h>
+#include <limits.h> // for INT_MAX
 #include <stdint.h>
 
 #include "expat.h"
@@ -65,8 +66,9 @@ ParseOneInput(XML_Parser p, const uint8_
   XML_SetUserData(p, p);
   XML_SetElementHandler(p, start, end);
   XML_SetCharacterDataHandler(p, may_stop_character_handler);
-  XML_Parse(p, (const XML_Char *)data, size, 0);
-  if (XML_Parse(p, (const XML_Char *)data, size, 1) == XML_STATUS_ERROR) {
+  assert(size <= INT_MAX);
+  XML_Parse(p, (const XML_Char *)data, (int)size, 0);
+  if (XML_Parse(p, (const XML_Char *)data, (int)size, 1) == XML_STATUS_ERROR) {
     XML_ErrorString(XML_GetErrorCode(p));
   }
   XML_GetCurrentLineNumber(p);
@@ -89,15 +91,17 @@ LLVMFuzzerTestOneInput(const uint8_t *da
 
   XML_Parser externalEntityParser
       = XML_ExternalEntityParserCreate(parentParser, "e1", NULL);
-  assert(externalEntityParser);
-  ParseOneInput(externalEntityParser, data, size);
-  XML_ParserFree(externalEntityParser);
+  if (externalEntityParser != NULL) {
+    ParseOneInput(externalEntityParser, data, size);
+    XML_ParserFree(externalEntityParser);
+  }
 
   XML_Parser externalDtdParser
       = XML_ExternalEntityParserCreate(parentParser, NULL, NULL);
-  assert(externalDtdParser);
-  ParseOneInput(externalDtdParser, data, size);
-  XML_ParserFree(externalDtdParser);
+  if (externalDtdParser != NULL) {
+    ParseOneInput(externalDtdParser, data, size);
+    XML_ParserFree(externalDtdParser);
+  }
 
   // finally frees this parser which served as parent
   XML_ParserFree(parentParser);
Index: expat-2.7.1/lib/expat_external.h
===================================================================
--- expat-2.7.1.orig/lib/expat_external.h
+++ expat-2.7.1/lib/expat_external.h
@@ -38,7 +38,7 @@
 */
 
 #ifndef Expat_External_INCLUDED
-#define Expat_External_INCLUDED 1
+#  define Expat_External_INCLUDED 1
 
 /* External API definitions */
 
@@ -64,12 +64,12 @@
    compiled with the cdecl calling convention as the default since
    system headers may assume the cdecl convention.
 */
-#ifndef XMLCALL
-#  if defined(_MSC_VER)
-#    define XMLCALL __cdecl
-#  elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER)
-#    define XMLCALL __attribute__((cdecl))
-#  else
+#  ifndef XMLCALL
+#    if defined(_MSC_VER)
+#      define XMLCALL __cdecl
+#    elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER)
+#      define XMLCALL __attribute__((cdecl))
+#    else
 /* For any platform which uses this definition and supports more than
    one calling convention, we need to extend this definition to
    declare the convention used on that platform, if it's possible to
@@ -80,86 +80,87 @@
    pre-processor and how to specify the same calling convention as the
    platform's malloc() implementation.
 */
-#    define XMLCALL
-#  endif
-#endif /* not defined XMLCALL */
+#      define XMLCALL
+#    endif
+#  endif /* not defined XMLCALL */
 
-#if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
-#  ifndef XML_BUILDING_EXPAT
+#  if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
+#    ifndef XML_BUILDING_EXPAT
 /* using Expat from an application */
 
-#    if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__)
-#      define XMLIMPORT __declspec(dllimport)
+#      if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__)                      \
+          && ! defined(__CYGWIN__)
+#        define XMLIMPORT __declspec(dllimport)
+#      endif
+
 #    endif
+#  endif /* not defined XML_STATIC */
 
+#  ifndef XML_ENABLE_VISIBILITY
+#    define XML_ENABLE_VISIBILITY 0
 #  endif
-#endif /* not defined XML_STATIC */
 
-#ifndef XML_ENABLE_VISIBILITY
-#  define XML_ENABLE_VISIBILITY 0
-#endif
-
-#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
-#  define XMLIMPORT __attribute__((visibility("default")))
-#endif
+#  if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
+#    define XMLIMPORT __attribute__((visibility("default")))
+#  endif
 
 /* If we didn't define it above, define it away: */
-#ifndef XMLIMPORT
-#  define XMLIMPORT
-#endif
-
-#if defined(__GNUC__)                                                          \
-    && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
-#  define XML_ATTR_MALLOC __attribute__((__malloc__))
-#else
-#  define XML_ATTR_MALLOC
-#endif
-
-#if defined(__GNUC__)                                                          \
-    && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
-#  define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
-#else
-#  define XML_ATTR_ALLOC_SIZE(x)
-#endif
-
-#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
+#  ifndef XMLIMPORT
+#    define XMLIMPORT
+#  endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#  if defined(__GNUC__)                                                        \
+      && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+#    define XML_ATTR_MALLOC __attribute__((__malloc__))
+#  else
+#    define XML_ATTR_MALLOC
+#  endif
 
-#ifdef XML_UNICODE_WCHAR_T
-#  ifndef XML_UNICODE
-#    define XML_UNICODE
+#  if defined(__GNUC__)                                                        \
+      && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#    define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
+#  else
+#    define XML_ATTR_ALLOC_SIZE(x)
 #  endif
-#  if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
-#    error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
+
+#  define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
+
+#  ifdef __cplusplus
+extern "C" {
 #  endif
-#endif
 
-#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
 #  ifdef XML_UNICODE_WCHAR_T
+#    ifndef XML_UNICODE
+#      define XML_UNICODE
+#    endif
+#    if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
+#      error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
+#    endif
+#  endif
+
+#  ifdef XML_UNICODE /* Information is UTF-16 encoded. */
+#    ifdef XML_UNICODE_WCHAR_T
 typedef wchar_t XML_Char;
 typedef wchar_t XML_LChar;
-#  else
+#    else
 typedef unsigned short XML_Char;
 typedef char XML_LChar;
-#  endif /* XML_UNICODE_WCHAR_T */
-#else    /* Information is UTF-8 encoded. */
+#    endif /* XML_UNICODE_WCHAR_T */
+#  else    /* Information is UTF-8 encoded. */
 typedef char XML_Char;
 typedef char XML_LChar;
-#endif   /* XML_UNICODE */
+#  endif   /* XML_UNICODE */
 
-#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
+#  ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
 typedef long long XML_Index;
 typedef unsigned long long XML_Size;
-#else
+#  else
 typedef long XML_Index;
 typedef unsigned long XML_Size;
-#endif /* XML_LARGE_SIZE */
+#  endif /* XML_LARGE_SIZE */
 
-#ifdef __cplusplus
+#  ifdef __cplusplus
 }
-#endif
+#  endif
 
 #endif /* not Expat_External_INCLUDED */
Index: expat-2.7.1/lib/expat.h
===================================================================
--- expat-2.7.1.orig/lib/expat.h
+++ expat-2.7.1/lib/expat.h
@@ -42,21 +42,21 @@
 */
 
 #ifndef Expat_INCLUDED
-#define Expat_INCLUDED 1
+#  define Expat_INCLUDED 1
 
-#include <stdlib.h>
-#include "expat_external.h"
+#  include <stdlib.h>
+#  include "expat_external.h"
 
-#ifdef __cplusplus
+#  ifdef __cplusplus
 extern "C" {
-#endif
+#  endif
 
 struct XML_ParserStruct;
 typedef struct XML_ParserStruct *XML_Parser;
 
 typedef unsigned char XML_Bool;
-#define XML_TRUE ((XML_Bool)1)
-#define XML_FALSE ((XML_Bool)0)
+#  define XML_TRUE ((XML_Bool)1)
+#  define XML_FALSE ((XML_Bool)0)
 
 /* The XML_Status enum gives the possible return values for several
    API functions.  The preprocessor #defines are included so this
@@ -73,11 +73,11 @@ typedef unsigned char XML_Bool;
 */
 enum XML_Status {
   XML_STATUS_ERROR = 0,
-#define XML_STATUS_ERROR XML_STATUS_ERROR
+#  define XML_STATUS_ERROR XML_STATUS_ERROR
   XML_STATUS_OK = 1,
-#define XML_STATUS_OK XML_STATUS_OK
+#  define XML_STATUS_OK XML_STATUS_OK
   XML_STATUS_SUSPENDED = 2
-#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
+#  define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
 };
 
 enum XML_Error {
@@ -680,7 +680,7 @@ XMLPARSEAPI(void)
 XML_SetUserData(XML_Parser parser, void *userData);
 
 /* Returns the last value set by XML_SetUserData or NULL. */
-#define XML_GetUserData(parser) (*(void **)(parser))
+#  define XML_GetUserData(parser) (*(void **)(parser))
 
 /* This is equivalent to supplying an encoding argument to
    XML_ParserCreate. On success XML_SetEncoding returns non-zero,
@@ -752,7 +752,7 @@ XML_GetSpecifiedAttributeCount(XML_Parse
 XMLPARSEAPI(int)
 XML_GetIdAttributeIndex(XML_Parser parser);
 
-#ifdef XML_ATTR_INFO
+#  ifdef XML_ATTR_INFO
 /* Source file byte offsets for the start and end of attribute names and values.
    The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
    file an attribute value of "blah" will yield:
@@ -773,7 +773,7 @@ typedef struct {
 */
 XMLPARSEAPI(const XML_AttrInfo *)
 XML_GetAttributeInfo(XML_Parser parser);
-#endif
+#  endif
 
 /* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
    detected.  The last call to XML_Parse must have isFinal true; len
@@ -970,9 +970,9 @@ XMLPARSEAPI(const char *)
 XML_GetInputContext(XML_Parser parser, int *offset, int *size);
 
 /* For backwards compatibility with previous versions. */
-#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
-#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
-#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
+#  define XML_GetErrorLineNumber XML_GetCurrentLineNumber
+#  define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#  define XML_GetErrorByteIndex XML_GetCurrentByteIndex
 
 /* Frees the content model passed to the element declaration handler */
 XMLPARSEAPI(void)
@@ -1032,7 +1032,10 @@ enum XML_FeatureEnum {
   XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
   XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
   /* Added in Expat 2.6.0. */
-  XML_FEATURE_GE
+  XML_FEATURE_GE,
+  /* Added in Expat 2.7.2. */
+  XML_FEATURE_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT,
+  XML_FEATURE_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT,
   /* Additional features must be added to the end of this enum. */
 };
 
@@ -1045,7 +1048,7 @@ typedef struct {
 XMLPARSEAPI(const XML_Feature *)
 XML_GetFeatureList(void);
 
-#if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1)
+#  if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1)
 /* Added in Expat 2.4.0 for XML_DTD defined and
  * added in Expat 2.6.0 for XML_GE == 1. */
 XMLPARSEAPI(XML_Bool)
@@ -1057,7 +1060,17 @@ XML_SetBillionLaughsAttackProtectionMaxi
 XMLPARSEAPI(XML_Bool)
 XML_SetBillionLaughsAttackProtectionActivationThreshold(
     XML_Parser parser, unsigned long long activationThresholdBytes);
-#endif
+
+/* Added in Expat 2.7.2. */
+XMLPARSEAPI(XML_Bool)
+XML_SetAllocTrackerMaximumAmplification(XML_Parser parser,
+                                        float maximumAmplificationFactor);
+
+/* Added in Expat 2.7.2. */
+XMLPARSEAPI(XML_Bool)
+XML_SetAllocTrackerActivationThreshold(
+    XML_Parser parser, unsigned long long activationThresholdBytes);
+#  endif
 
 /* Added in Expat 2.6.0. */
 XMLPARSEAPI(XML_Bool)
@@ -1066,12 +1079,12 @@ XML_SetReparseDeferralEnabled(XML_Parser
 /* Expat follows the semantic versioning convention.
    See https://semver.org
 */
-#define XML_MAJOR_VERSION 2
-#define XML_MINOR_VERSION 7
-#define XML_MICRO_VERSION 1
+#  define XML_MAJOR_VERSION 2
+#  define XML_MINOR_VERSION 7
+#  define XML_MICRO_VERSION 2
 
-#ifdef __cplusplus
+#  ifdef __cplusplus
 }
-#endif
+#  endif
 
 #endif /* not Expat_INCLUDED */
Index: expat-2.7.1/lib/internal.h
===================================================================
--- expat-2.7.1.orig/lib/internal.h
+++ expat-2.7.1/lib/internal.h
@@ -148,6 +148,11 @@
   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
+
 /* NOTE END */
 
 #include "expat.h" // so we can use type XML_Parser below
@@ -171,6 +176,9 @@ extern
 #endif
     XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
 #if defined(XML_TESTING)
+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
 
Index: expat-2.7.1/lib/Makefile.in
===================================================================
--- expat-2.7.1.orig/lib/Makefile.in
+++ expat-2.7.1/lib/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# Makefile.in generated by automake 1.18.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+# Copyright (C) 1994-2025 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -104,6 +104,8 @@ am__make_running_with_option = \
   test $$has_opt = yes
 am__make_dryrun = (target_option=n; $(am__make_running_with_option))
 am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+am__rm_f = rm -f $(am__rm_f_notfound)
+am__rm_rf = rm -rf $(am__rm_f_notfound)
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -168,10 +170,9 @@ am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
 am__uninstall_files_from_dir = { \
-  test -z "$$files" \
-    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
-    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
-         $(am__cd) "$$dir" && rm -f $$files; }; \
+  { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+  || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+       $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
   }
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" \
 	"$(DESTDIR)$(includedir)"
@@ -368,8 +369,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
+am__rm_f_notfound = @am__rm_f_notfound@
 am__tar = @am__tar@
 am__untar = @am__untar@
+am__xargs_n = @am__xargs_n@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -513,26 +516,22 @@ uninstall-libLTLIBRARIES:
 	done
 
 clean-libLTLIBRARIES:
-	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	-$(am__rm_f) $(lib_LTLIBRARIES)
 	@list='$(lib_LTLIBRARIES)'; \
 	locs=`for p in $$list; do echo $$p; done | \
 	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
 	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
+	echo rm -f $${locs}; \
+	$(am__rm_f) $${locs}
 
 clean-noinstLTLIBRARIES:
-	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	-$(am__rm_f) $(noinst_LTLIBRARIES)
 	@list='$(noinst_LTLIBRARIES)'; \
 	locs=`for p in $$list; do echo $$p; done | \
 	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
 	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
+	echo rm -f $${locs}; \
+	$(am__rm_f) $${locs}
 
 libexpat.la: $(libexpat_la_OBJECTS) $(libexpat_la_DEPENDENCIES) $(EXTRA_libexpat_la_DEPENDENCIES) 
 	$(AM_V_CCLD)$(libexpat_la_LINK) -rpath $(libdir) $(libexpat_la_OBJECTS) $(libexpat_la_LIBADD) $(LIBS)
@@ -555,7 +554,7 @@ distclean-compile:
 
 $(am__depfiles_remade):
 	@$(MKDIR_P) $(@D)
-	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+	@: >>$@
 
 am--depfiles: $(am__depfiles_remade)
 
@@ -700,6 +699,7 @@ cscopelist-am: $(am__tagged_files)
 
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
 distdir: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -764,8 +764,8 @@ mostlyclean-generic:
 clean-generic:
 
 distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-$(am__rm_f) $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -776,7 +776,7 @@ clean-am: clean-generic clean-libLTLIBRA
 	clean-noinstLTLIBRARIES mostlyclean-am
 
 distclean: distclean-am
-		-rm -f ./$(DEPDIR)/libtestpat_la-xmlparse.Plo
+	-rm -f ./$(DEPDIR)/libtestpat_la-xmlparse.Plo
 	-rm -f ./$(DEPDIR)/libtestpat_la-xmlrole.Plo
 	-rm -f ./$(DEPDIR)/libtestpat_la-xmltok.Plo
 	-rm -f ./$(DEPDIR)/xmlparse.Plo
@@ -828,7 +828,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-		-rm -f ./$(DEPDIR)/libtestpat_la-xmlparse.Plo
+	-rm -f ./$(DEPDIR)/libtestpat_la-xmlparse.Plo
 	-rm -f ./$(DEPDIR)/libtestpat_la-xmlrole.Plo
 	-rm -f ./$(DEPDIR)/libtestpat_la-xmltok.Plo
 	-rm -f ./$(DEPDIR)/xmlparse.Plo
@@ -885,3 +885,10 @@ uninstall-local:
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
+
+# Tell GNU make to disable its built-in pattern rules.
+%:: %,v
+%:: RCS/%,v
+%:: RCS/%
+%:: s.%
+%:: SCCS/s.%
Index: expat-2.7.1/lib/xmlparse.c
===================================================================
--- expat-2.7.1.orig/lib/xmlparse.c
+++ expat-2.7.1/lib/xmlparse.c
@@ -1,4 +1,4 @@
-/* d19ae032c224863c1527ba44d228cc34b99192c3a4c5a27af1f4e054d45ee031 (2.7.1+)
+/* 60e137abb91af642d6c3988f8f133d23329b32638659c74d47125fc0faf6ddd5 (2.7.2+)
                             __  __            _
                          ___\ \/ /_ __   __ _| |_
                         / _ \\  /| '_ \ / _` | __|
@@ -97,7 +97,7 @@
 #include <stddef.h>
 #include <string.h> /* memset(), memcpy() */
 #include <assert.h>
-#include <limits.h> /* UINT_MAX */
+#include <limits.h> /* INT_MAX, UINT_MAX */
 #include <stdio.h>  /* fprintf */
 #include <stdlib.h> /* getenv, rand_s */
 #include <stdint.h> /* uintptr_t */
@@ -234,7 +234,7 @@ typedef struct {
   unsigned char power;
   size_t size;
   size_t used;
-  const XML_Memory_Handling_Suite *mem;
+  XML_Parser parser;
 } HASH_TABLE;
 
 static size_t keylen(KEY s);
@@ -357,7 +357,7 @@ typedef struct {
   const XML_Char *end;
   XML_Char *ptr;
   XML_Char *start;
-  const XML_Memory_Handling_Suite *mem;
+  XML_Parser parser;
 } STRING_POOL;
 
 /* The XML_Char before the name is used to determine whether
@@ -452,6 +452,14 @@ typedef struct accounting {
   unsigned long long activationThresholdBytes;
 } ACCOUNTING;
 
+typedef struct MALLOC_TRACKER {
+  XmlBigCount bytesAllocated;
+  XmlBigCount peakBytesAllocated; // updated live only for debug level >=2
+  unsigned long debugLevel;
+  float maximumAmplificationFactor; // >=1.0
+  XmlBigCount activationThresholdBytes;
+} MALLOC_TRACKER;
+
 typedef struct entity_stats {
   unsigned int countEverOpened;
   unsigned int currentDepth;
@@ -555,27 +563,24 @@ static XML_Bool setContext(XML_Parser pa
 
 static void FASTCALL normalizePublicId(XML_Char *s);
 
-static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);
+static DTD *dtdCreate(XML_Parser parser);
 /* do not call if m_parentParser != NULL */
-static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
-static void dtdDestroy(DTD *p, XML_Bool isDocEntity,
-                       const XML_Memory_Handling_Suite *ms);
+static void dtdReset(DTD *p, XML_Parser parser);
+static void dtdDestroy(DTD *p, XML_Bool isDocEntity, XML_Parser parser);
 static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
-                   const XML_Memory_Handling_Suite *ms);
+                   XML_Parser parser);
 static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
                            STRING_POOL *newPool, const HASH_TABLE *oldTable);
 static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
                      size_t createSize);
-static void FASTCALL hashTableInit(HASH_TABLE *table,
-                                   const XML_Memory_Handling_Suite *ms);
+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,
-                              const XML_Memory_Handling_Suite *ms);
+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 XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
@@ -595,15 +600,15 @@ static XML_Content *build_model(XML_Pars
 static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
                                     const char *ptr, const char *end);
 
-static XML_Char *copyString(const XML_Char *s,
-                            const XML_Memory_Handling_Suite *memsuite);
+static XML_Char *copyString(const XML_Char *s, XML_Parser parser);
 
 static unsigned long generate_hash_secret_salt(XML_Parser parser);
 static XML_Bool startParsing(XML_Parser parser);
 
 static XML_Parser parserCreate(const XML_Char *encodingName,
                                const XML_Memory_Handling_Suite *memsuite,
-                               const XML_Char *nameSep, DTD *dtd);
+                               const XML_Char *nameSep, DTD *dtd,
+                               XML_Parser parentParser);
 
 static void parserInit(XML_Parser parser, const XML_Char *encodingName);
 
@@ -627,10 +632,10 @@ static void entityTrackingOnOpen(XML_Par
                                  int sourceLine);
 static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity,
                                   int sourceLine);
+#endif /* XML_GE == 1 */
 
 static XML_Parser getRootParserOf(XML_Parser parser,
                                   unsigned int *outLevelDiff);
-#endif /* XML_GE == 1 */
 
 static unsigned long getDebugLevel(const char *variableName,
                                    unsigned long defaultDebugLevel);
@@ -773,14 +778,232 @@ struct XML_ParserStruct {
   unsigned long m_hash_secret_salt;
 #if XML_GE == 1
   ACCOUNTING m_accounting;
+  MALLOC_TRACKER m_alloc_tracker;
   ENTITY_STATS m_entity_stats;
 #endif
   XML_Bool m_reenter;
 };
 
-#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
-#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
-#define FREE(parser, p) (parser->m_mem.free_fcn((p)))
+#if XML_GE == 1
+#  define MALLOC(parser, s) (expat_malloc((parser), (s), __LINE__))
+#  define REALLOC(parser, p, s) (expat_realloc((parser), (p), (s), __LINE__))
+#  define FREE(parser, p) (expat_free((parser), (p), __LINE__))
+#else
+#  define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
+#  define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
+#  define FREE(parser, p) (parser->m_mem.free_fcn((p)))
+#endif
+
+#if XML_GE == 1
+static void
+expat_heap_stat(XML_Parser rootParser, char operator, XmlBigCount absDiff,
+                XmlBigCount newTotal, XmlBigCount peakTotal, int sourceLine) {
+  // NOTE: This can be +infinity or -nan
+  const float amplification
+      = (float)newTotal / (float)rootParser->m_accounting.countBytesDirect;
+  fprintf(
+      stderr,
+      "expat: Allocations(%p): Direct " EXPAT_FMT_ULL("10") ", allocated %c" EXPAT_FMT_ULL(
+          "10") " to " EXPAT_FMT_ULL("10") " (" EXPAT_FMT_ULL("10") " peak), amplification %8.2f (xmlparse.c:%d)\n",
+      (void *)rootParser, rootParser->m_accounting.countBytesDirect, operator,
+      absDiff, newTotal, peakTotal, (double)amplification, sourceLine);
+}
+
+static bool
+expat_heap_increase_tolerable(XML_Parser rootParser, XmlBigCount increase,
+                              int sourceLine) {
+  assert(rootParser != NULL);
+  assert(increase > 0);
+
+  XmlBigCount newTotal = 0;
+  bool tolerable = true;
+
+  // Detect integer overflow
+  if ((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated < increase) {
+    tolerable = false;
+  } else {
+    newTotal = rootParser->m_alloc_tracker.bytesAllocated + increase;
+
+    if (newTotal >= rootParser->m_alloc_tracker.activationThresholdBytes) {
+      assert(newTotal > 0);
+      // NOTE: This can be +infinity when dividing by zero but not -nan
+      const float amplification
+          = (float)newTotal / (float)rootParser->m_accounting.countBytesDirect;
+      if (amplification
+          > rootParser->m_alloc_tracker.maximumAmplificationFactor) {
+        tolerable = false;
+      }
+    }
+  }
+
+  if (! tolerable && (rootParser->m_alloc_tracker.debugLevel >= 1)) {
+    expat_heap_stat(rootParser, '+', increase, newTotal, newTotal, sourceLine);
+  }
+
+  return tolerable;
+}
+
+#  if defined(XML_TESTING)
+void *
+#  else
+static void *
+#  endif
+expat_malloc(XML_Parser parser, size_t size, int sourceLine) {
+  // Detect integer overflow
+  if (SIZE_MAX - size < sizeof(size_t)) {
+    return NULL;
+  }
+
+  const XML_Parser rootParser = getRootParserOf(parser, NULL);
+  assert(rootParser->m_parentParser == NULL);
+
+  const size_t bytesToAllocate = sizeof(size_t) + size;
+
+  if ((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated
+      < bytesToAllocate) {
+    return NULL; // i.e. signal integer overflow as out-of-memory
+  }
+
+  if (! expat_heap_increase_tolerable(rootParser, bytesToAllocate,
+                                      sourceLine)) {
+    return NULL; // i.e. signal violation as out-of-memory
+  }
+
+  // Actually allocate
+  void *const mallocedPtr = parser->m_mem.malloc_fcn(bytesToAllocate);
+
+  if (mallocedPtr == NULL) {
+    return NULL;
+  }
+
+  // Update in-block recorded size
+  *(size_t *)mallocedPtr = size;
+
+  // Update accounting
+  rootParser->m_alloc_tracker.bytesAllocated += bytesToAllocate;
+
+  // Report as needed
+  if (rootParser->m_alloc_tracker.debugLevel >= 2) {
+    if (rootParser->m_alloc_tracker.bytesAllocated
+        > rootParser->m_alloc_tracker.peakBytesAllocated) {
+      rootParser->m_alloc_tracker.peakBytesAllocated
+          = rootParser->m_alloc_tracker.bytesAllocated;
+    }
+    expat_heap_stat(rootParser, '+', bytesToAllocate,
+                    rootParser->m_alloc_tracker.bytesAllocated,
+                    rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine);
+  }
+
+  return (char *)mallocedPtr + sizeof(size_t);
+}
+
+#  if defined(XML_TESTING)
+void
+#  else
+static void
+#  endif
+expat_free(XML_Parser parser, void *ptr, int sourceLine) {
+  assert(parser != NULL);
+
+  if (ptr == NULL) {
+    return;
+  }
+
+  const XML_Parser rootParser = getRootParserOf(parser, NULL);
+  assert(rootParser->m_parentParser == NULL);
+
+  // Extract size (to the eyes of malloc_fcn/realloc_fcn) and
+  // the original pointer returned by malloc/realloc
+  void *const mallocedPtr = (char *)ptr - sizeof(size_t);
+  const size_t bytesAllocated = sizeof(size_t) + *(size_t *)mallocedPtr;
+
+  // Update accounting
+  assert(rootParser->m_alloc_tracker.bytesAllocated >= bytesAllocated);
+  rootParser->m_alloc_tracker.bytesAllocated -= bytesAllocated;
+
+  // Report as needed
+  if (rootParser->m_alloc_tracker.debugLevel >= 2) {
+    expat_heap_stat(rootParser, '-', bytesAllocated,
+                    rootParser->m_alloc_tracker.bytesAllocated,
+                    rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine);
+  }
+
+  // NOTE: This may be freeing rootParser, so freeing has to come last
+  parser->m_mem.free_fcn(mallocedPtr);
+}
+
+#  if defined(XML_TESTING)
+void *
+#  else
+static void *
+#  endif
+expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine) {
+  assert(parser != NULL);
+
+  if (ptr == NULL) {
+    return expat_malloc(parser, size, sourceLine);
+  }
+
+  if (size == 0) {
+    expat_free(parser, ptr, sourceLine);
+    return NULL;
+  }
+
+  const XML_Parser rootParser = getRootParserOf(parser, NULL);
+  assert(rootParser->m_parentParser == NULL);
+
+  // Extract original size (to the eyes of the caller) and the original
+  // pointer returned by malloc/realloc
+  void *mallocedPtr = (char *)ptr - sizeof(size_t);
+  const size_t prevSize = *(size_t *)mallocedPtr;
+
+  // Classify upcoming change
+  const bool isIncrease = (size > prevSize);
+  const size_t absDiff
+      = (size > prevSize) ? (size - prevSize) : (prevSize - size);
+
+  // Ask for permission from accounting
+  if (isIncrease) {
+    if (! expat_heap_increase_tolerable(rootParser, absDiff, sourceLine)) {
+      return NULL; // i.e. signal violation as out-of-memory
+    }
+  }
+
+  // Actually allocate
+  mallocedPtr = parser->m_mem.realloc_fcn(mallocedPtr, sizeof(size_t) + size);
+
+  if (mallocedPtr == NULL) {
+    return NULL;
+  }
+
+  // Update accounting
+  if (isIncrease) {
+    assert((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated
+           >= absDiff);
+    rootParser->m_alloc_tracker.bytesAllocated += absDiff;
+  } else { // i.e. decrease
+    assert(rootParser->m_alloc_tracker.bytesAllocated >= absDiff);
+    rootParser->m_alloc_tracker.bytesAllocated -= absDiff;
+  }
+
+  // Report as needed
+  if (rootParser->m_alloc_tracker.debugLevel >= 2) {
+    if (rootParser->m_alloc_tracker.bytesAllocated
+        > rootParser->m_alloc_tracker.peakBytesAllocated) {
+      rootParser->m_alloc_tracker.peakBytesAllocated
+          = rootParser->m_alloc_tracker.bytesAllocated;
+    }
+    expat_heap_stat(rootParser, isIncrease ? '+' : '-', absDiff,
+                    rootParser->m_alloc_tracker.bytesAllocated,
+                    rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine);
+  }
+
+  // Update in-block recorded size
+  *(size_t *)mallocedPtr = size;
+
+  return (char *)mallocedPtr + sizeof(size_t);
+}
+#endif // XML_GE == 1
 
 XML_Parser XMLCALL
 XML_ParserCreate(const XML_Char *encodingName) {
@@ -821,11 +1044,14 @@ writeRandomBytes_getrandom_nonblock(void
     void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
     const size_t bytesToWrite = count - bytesWrittenTotal;
 
+    assert(bytesToWrite <= INT_MAX);
+
     const int bytesWrittenMore =
 #    if defined(HAVE_GETRANDOM)
-        getrandom(currentTarget, bytesToWrite, getrandomFlags);
+        (int)getrandom(currentTarget, bytesToWrite, getrandomFlags);
 #    else
-        syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
+        (int)syscall(SYS_getrandom, currentTarget, bytesToWrite,
+                     getrandomFlags);
 #    endif
 
     if (bytesWrittenMore > 0) {
@@ -1012,9 +1238,10 @@ generate_hash_secret_salt(XML_Parser par
 
 static unsigned long
 get_hash_secret_salt(XML_Parser parser) {
-  if (parser->m_parentParser != NULL)
-    return get_hash_secret_salt(parser->m_parentParser);
-  return parser->m_hash_secret_salt;
+  const XML_Parser rootParser = getRootParserOf(parser, NULL);
+  assert(! rootParser->m_parentParser);
+
+  return rootParser->m_hash_secret_salt;
 }
 
 static enum XML_Error
@@ -1100,19 +1327,40 @@ XML_Parser XMLCALL
 XML_ParserCreate_MM(const XML_Char *encodingName,
                     const XML_Memory_Handling_Suite *memsuite,
                     const XML_Char *nameSep) {
-  return parserCreate(encodingName, memsuite, nameSep, NULL);
+  return parserCreate(encodingName, memsuite, nameSep, NULL, NULL);
 }
 
 static XML_Parser
 parserCreate(const XML_Char *encodingName,
              const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
-             DTD *dtd) {
-  XML_Parser parser;
+             DTD *dtd, XML_Parser parentParser) {
+  XML_Parser parser = NULL;
+
+#if XML_GE == 1
+  const size_t increase = sizeof(size_t) + sizeof(struct XML_ParserStruct);
+
+  if (parentParser != NULL) {
+    const XML_Parser rootParser = getRootParserOf(parentParser, NULL);
+    if (! expat_heap_increase_tolerable(rootParser, increase, __LINE__)) {
+      return NULL;
+    }
+  }
+#else
+  UNUSED_P(parentParser);
+#endif
 
   if (memsuite) {
     XML_Memory_Handling_Suite *mtemp;
+#if XML_GE == 1
+    void *const sizeAndParser = memsuite->malloc_fcn(
+        sizeof(size_t) + sizeof(struct XML_ParserStruct));
+    if (sizeAndParser != NULL) {
+      *(size_t *)sizeAndParser = sizeof(struct XML_ParserStruct);
+      parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t));
+#else
     parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
     if (parser != NULL) {
+#endif
       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
       mtemp->malloc_fcn = memsuite->malloc_fcn;
       mtemp->realloc_fcn = memsuite->realloc_fcn;
@@ -1120,39 +1368,85 @@ parserCreate(const XML_Char *encodingNam
     }
   } else {
     XML_Memory_Handling_Suite *mtemp;
-    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
+#if XML_GE == 1
+    void *const sizeAndParser
+        = malloc(sizeof(size_t) + sizeof(struct XML_ParserStruct));
+    if (sizeAndParser != NULL) {
+      *(size_t *)sizeAndParser = sizeof(struct XML_ParserStruct);
+      parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t));
+#else
+    parser = malloc(sizeof(struct XML_ParserStruct));
     if (parser != NULL) {
+#endif
       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
       mtemp->malloc_fcn = malloc;
       mtemp->realloc_fcn = realloc;
       mtemp->free_fcn = free;
     }
-  }
+  } // cppcheck-suppress[memleak symbolName=sizeAndParser] // Cppcheck >=2.18.0
 
   if (! parser)
     return parser;
 
+#if XML_GE == 1
+  // Initialize .m_alloc_tracker
+  memset(&parser->m_alloc_tracker, 0, sizeof(MALLOC_TRACKER));
+  if (parentParser == NULL) {
+    parser->m_alloc_tracker.debugLevel
+        = getDebugLevel("EXPAT_MALLOC_DEBUG", 0u);
+    parser->m_alloc_tracker.maximumAmplificationFactor
+        = EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT;
+    parser->m_alloc_tracker.activationThresholdBytes
+        = EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT;
+
+    // NOTE: This initialization needs to come this early because these fields
+    //       are read by allocation tracking code
+    parser->m_parentParser = NULL;
+    parser->m_accounting.countBytesDirect = 0;
+  } else {
+    parser->m_parentParser = parentParser;
+  }
+
+  // Record XML_ParserStruct allocation we did a few lines up before
+  const XML_Parser rootParser = getRootParserOf(parser, NULL);
+  assert(rootParser->m_parentParser == NULL);
+  assert(SIZE_MAX - rootParser->m_alloc_tracker.bytesAllocated >= increase);
+  rootParser->m_alloc_tracker.bytesAllocated += increase;
+
+  // Report on allocation
+  if (rootParser->m_alloc_tracker.debugLevel >= 2) {
+    if (rootParser->m_alloc_tracker.bytesAllocated
+        > rootParser->m_alloc_tracker.peakBytesAllocated) {
+      rootParser->m_alloc_tracker.peakBytesAllocated
+          = rootParser->m_alloc_tracker.bytesAllocated;
+    }
+
+    expat_heap_stat(rootParser, '+', increase,
+                    rootParser->m_alloc_tracker.bytesAllocated,
+                    rootParser->m_alloc_tracker.peakBytesAllocated, __LINE__);
+  }
+#else
+  parser->m_parentParser = NULL;
+#endif // XML_GE == 1
+
   parser->m_buffer = NULL;
   parser->m_bufferLim = NULL;
 
   parser->m_attsSize = INIT_ATTS_SIZE;
-  parser->m_atts
-      = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
+  parser->m_atts = MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
   if (parser->m_atts == NULL) {
     FREE(parser, parser);
     return NULL;
   }
 #ifdef XML_ATTR_INFO
-  parser->m_attInfo = (XML_AttrInfo *)MALLOC(
-      parser, parser->m_attsSize * sizeof(XML_AttrInfo));
+  parser->m_attInfo = MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo));
   if (parser->m_attInfo == NULL) {
     FREE(parser, parser->m_atts);
     FREE(parser, parser);
     return NULL;
   }
 #endif
-  parser->m_dataBuf
-      = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  parser->m_dataBuf = MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
   if (parser->m_dataBuf == NULL) {
     FREE(parser, parser->m_atts);
 #ifdef XML_ATTR_INFO
@@ -1166,7 +1460,7 @@ parserCreate(const XML_Char *encodingNam
   if (dtd)
     parser->m_dtd = dtd;
   else {
-    parser->m_dtd = dtdCreate(&parser->m_mem);
+    parser->m_dtd = dtdCreate(parser);
     if (parser->m_dtd == NULL) {
       FREE(parser, parser->m_dataBuf);
       FREE(parser, parser->m_atts);
@@ -1200,8 +1494,8 @@ parserCreate(const XML_Char *encodingNam
 
   parser->m_protocolEncodingName = NULL;
 
-  poolInit(&parser->m_tempPool, &(parser->m_mem));
-  poolInit(&parser->m_temp2Pool, &(parser->m_mem));
+  poolInit(&parser->m_tempPool, parser);
+  poolInit(&parser->m_temp2Pool, parser);
   parserInit(parser, encodingName);
 
   if (encodingName && ! parser->m_protocolEncodingName) {
@@ -1233,7 +1527,7 @@ parserInit(XML_Parser parser, const XML_
   parser->m_processor = prologInitProcessor;
   XmlPrologStateInit(&parser->m_prologState);
   if (encodingName != NULL) {
-    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
+    parser->m_protocolEncodingName = copyString(encodingName, parser);
   }
   parser->m_curBase = NULL;
   XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
@@ -1295,7 +1589,6 @@ parserInit(XML_Parser parser, const XML_
   parser->m_unknownEncodingMem = NULL;
   parser->m_unknownEncodingRelease = NULL;
   parser->m_unknownEncodingData = NULL;
-  parser->m_parentParser = NULL;
   parser->m_parsingStatus.parsing = XML_INITIALIZED;
   // Reentry can only be triggered inside m_processor calls
   parser->m_reenter = XML_FALSE;
@@ -1385,7 +1678,7 @@ XML_ParserReset(XML_Parser parser, const
   FREE(parser, (void *)parser->m_protocolEncodingName);
   parser->m_protocolEncodingName = NULL;
   parserInit(parser, encodingName);
-  dtdReset(parser->m_dtd, &parser->m_mem);
+  dtdReset(parser->m_dtd, parser);
   return XML_TRUE;
 }
 
@@ -1421,7 +1714,7 @@ XML_SetEncoding(XML_Parser parser, const
     parser->m_protocolEncodingName = NULL;
   else {
     /* Copy the new encoding name into allocated memory */
-    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
+    parser->m_protocolEncodingName = copyString(encodingName, parser);
     if (! parser->m_protocolEncodingName)
       return XML_STATUS_ERROR;
   }
@@ -1530,9 +1823,10 @@ XML_ExternalEntityParserCreate(XML_Parse
   */
   if (parser->m_ns) {
     XML_Char tmp[2] = {parser->m_namespaceSeparator, 0};
-    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
+    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd, oldParser);
   } else {
-    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
+    parser
+        = parserCreate(encodingName, &parser->m_mem, NULL, newDtd, oldParser);
   }
 
   if (! parser)
@@ -1576,7 +1870,7 @@ XML_ExternalEntityParserCreate(XML_Parse
   parser->m_prologState.inEntityValue = oldInEntityValue;
   if (context) {
 #endif /* XML_DTD */
-    if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
+    if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, parser)
         || ! setContext(parser, context)) {
       XML_ParserFree(parser);
       return NULL;
@@ -1688,14 +1982,16 @@ XML_ParserFree(XML_Parser parser) {
 #else
   if (parser->m_dtd)
 #endif /* XML_DTD */
-    dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
-               &parser->m_mem);
-  FREE(parser, (void *)parser->m_atts);
+    dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, parser);
+  FREE(parser, parser->m_atts);
 #ifdef XML_ATTR_INFO
-  FREE(parser, (void *)parser->m_attInfo);
+  FREE(parser, parser->m_attInfo);
 #endif
   FREE(parser, parser->m_groupConnector);
-  FREE(parser, parser->m_buffer);
+  // NOTE: We are avoiding FREE(..) here because parser->m_buffer
+  //       is not being allocated with MALLOC(..) but with plain
+  //       .malloc_fcn(..).
+  parser->m_mem.free_fcn(parser->m_buffer);
   FREE(parser, parser->m_dataBuf);
   FREE(parser, parser->m_nsAtts);
   FREE(parser, parser->m_unknownEncodingMem);
@@ -2014,12 +2310,14 @@ int XMLCALL
 XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
   if (parser == NULL)
     return 0;
-  if (parser->m_parentParser)
-    return XML_SetHashSalt(parser->m_parentParser, hash_salt);
+
+  const XML_Parser rootParser = getRootParserOf(parser, NULL);
+  assert(! rootParser->m_parentParser);
+
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
-  if (parserBusy(parser))
+  if (parserBusy(rootParser))
     return 0;
-  parser->m_hash_secret_salt = hash_salt;
+  rootParser->m_hash_secret_salt = hash_salt;
   return 1;
 }
 
@@ -2287,7 +2585,9 @@ XML_GetBuffer(XML_Parser parser, int len
         parser->m_errorCode = XML_ERROR_NO_MEMORY;
         return NULL;
       }
-      newBuf = (char *)MALLOC(parser, bufferSize);
+      // NOTE: We are avoiding MALLOC(..) here to leave limiting
+      //       the input size to the application using Expat.
+      newBuf = parser->m_mem.malloc_fcn(bufferSize);
       if (newBuf == 0) {
         parser->m_errorCode = XML_ERROR_NO_MEMORY;
         return NULL;
@@ -2298,7 +2598,10 @@ XML_GetBuffer(XML_Parser parser, int len
         memcpy(newBuf, &parser->m_bufferPtr[-keep],
                EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
                    + keep);
-        FREE(parser, parser->m_buffer);
+        // NOTE: We are avoiding FREE(..) here because parser->m_buffer
+        //       is not being allocated with MALLOC(..) but with plain
+        //       .malloc_fcn(..).
+        parser->m_mem.free_fcn(parser->m_buffer);
         parser->m_buffer = newBuf;
         parser->m_bufferEnd
             = parser->m_buffer
@@ -2314,7 +2617,10 @@ XML_GetBuffer(XML_Parser parser, int len
       if (parser->m_bufferPtr) {
         memcpy(newBuf, parser->m_bufferPtr,
                EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
-        FREE(parser, parser->m_buffer);
+        // NOTE: We are avoiding FREE(..) here because parser->m_buffer
+        //       is not being allocated with MALLOC(..) but with plain
+        //       .malloc_fcn(..).
+        parser->m_mem.free_fcn(parser->m_buffer);
         parser->m_bufferEnd
             = newBuf
               + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
@@ -2492,28 +2798,43 @@ XML_GetCurrentColumnNumber(XML_Parser pa
 
 void XMLCALL
 XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
-  if (parser != NULL)
-    FREE(parser, model);
+  if (parser == NULL)
+    return;
+
+  // NOTE: We are avoiding FREE(..) here because the content model
+  //       has been created using plain .malloc_fcn(..) rather than MALLOC(..).
+  parser->m_mem.free_fcn(model);
 }
 
 void *XMLCALL
 XML_MemMalloc(XML_Parser parser, size_t size) {
   if (parser == NULL)
     return NULL;
-  return MALLOC(parser, size);
+
+  // NOTE: We are avoiding MALLOC(..) here to not include
+  //       user allocations with allocation tracking and limiting.
+  return parser->m_mem.malloc_fcn(size);
 }
 
 void *XMLCALL
 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
   if (parser == NULL)
     return NULL;
-  return REALLOC(parser, ptr, size);
+
+  // NOTE: We are avoiding REALLOC(..) here to not include
+  //       user allocations with allocation tracking and limiting.
+  return parser->m_mem.realloc_fcn(ptr, size);
 }
 
 void XMLCALL
 XML_MemFree(XML_Parser parser, void *ptr) {
-  if (parser != NULL)
-    FREE(parser, ptr);
+  if (parser == NULL)
+    return;
+
+  // NOTE: We are avoiding FREE(..) here because XML_MemMalloc and
+  //       XML_MemRealloc are not using MALLOC(..) and REALLOC(..)
+  //       but plain .malloc_fcn(..) and .realloc_fcn(..), internally.
+  parser->m_mem.free_fcn(ptr);
 }
 
 void XMLCALL
@@ -2713,6 +3034,13 @@ XML_GetFeatureList(void) {
        EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT},
       /* Added in Expat 2.6.0. */
       {XML_FEATURE_GE, XML_L("XML_GE"), 0},
+      /* Added in Expat 2.7.2. */
+      {XML_FEATURE_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT,
+       XML_L("XML_AT_MAX_AMP"),
+       (long int)EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT},
+      {XML_FEATURE_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT,
+       XML_L("XML_AT_ACT_THRES"),
+       (long int)EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT},
 #endif
       {XML_FEATURE_END, NULL, 0}};
 
@@ -2741,6 +3069,29 @@ XML_SetBillionLaughsAttackProtectionActi
   parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
   return XML_TRUE;
 }
+
+XML_Bool XMLCALL
+XML_SetAllocTrackerMaximumAmplification(XML_Parser parser,
+                                        float maximumAmplificationFactor) {
+  if ((parser == NULL) || (parser->m_parentParser != NULL)
+      || isnan(maximumAmplificationFactor)
+      || (maximumAmplificationFactor < 1.0f)) {
+    return XML_FALSE;
+  }
+  parser->m_alloc_tracker.maximumAmplificationFactor
+      = maximumAmplificationFactor;
+  return XML_TRUE;
+}
+
+XML_Bool XMLCALL
+XML_SetAllocTrackerActivationThreshold(
+    XML_Parser parser, unsigned long long activationThresholdBytes) {
+  if ((parser == NULL) || (parser->m_parentParser != NULL)) {
+    return XML_FALSE;
+  }
+  parser->m_alloc_tracker.activationThresholdBytes = activationThresholdBytes;
+  return XML_TRUE;
+}
 #endif /* XML_GE == 1 */
 
 XML_Bool XMLCALL
@@ -2761,8 +3112,8 @@ static XML_Bool
 storeRawNames(XML_Parser parser) {
   TAG *tag = parser->m_tagStack;
   while (tag) {
-    int bufSize;
-    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
+    size_t bufSize;
+    size_t nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
     size_t rawNameLen;
     char *rawNameBuf = tag->buf + nameLen;
     /* Stop if already stored.  Since m_tagStack is a stack, we can stop
@@ -2779,9 +3130,9 @@ storeRawNames(XML_Parser parser) {
     /* Detect and prevent integer overflow. */
     if (rawNameLen > (size_t)INT_MAX - nameLen)
       return XML_FALSE;
-    bufSize = nameLen + (int)rawNameLen;
-    if (bufSize > tag->bufEnd - tag->buf) {
-      char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
+    bufSize = nameLen + rawNameLen;
+    if (bufSize > (size_t)(tag->bufEnd - tag->buf)) {
+      char *temp = REALLOC(parser, tag->buf, bufSize);
       if (temp == NULL)
         return XML_FALSE;
       /* if tag->name.str points to tag->buf (only when namespace
@@ -3107,10 +3458,10 @@ doContent(XML_Parser parser, int startTa
         tag = parser->m_freeTagList;
         parser->m_freeTagList = parser->m_freeTagList->parent;
       } else {
-        tag = (TAG *)MALLOC(parser, sizeof(TAG));
+        tag = MALLOC(parser, sizeof(TAG));
         if (! tag)
           return XML_ERROR_NO_MEMORY;
-        tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
+        tag->buf = MALLOC(parser, INIT_TAG_BUF_SIZE);
         if (! tag->buf) {
           FREE(parser, tag);
           return XML_ERROR_NO_MEMORY;
@@ -3143,7 +3494,7 @@ doContent(XML_Parser parser, int startTa
           }
           bufSize = (int)(tag->bufEnd - tag->buf) << 1;
           {
-            char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
+            char *temp = REALLOC(parser, tag->buf, bufSize);
             if (temp == NULL)
               return XML_ERROR_NO_MEMORY;
             tag->buf = temp;
@@ -3522,8 +3873,8 @@ storeAtts(XML_Parser parser, const ENCOD
     }
 #endif
 
-    temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
-                                parser->m_attsSize * sizeof(ATTRIBUTE));
+    temp = REALLOC(parser, parser->m_atts,
+                   parser->m_attsSize * sizeof(ATTRIBUTE));
     if (temp == NULL) {
       parser->m_attsSize = oldAttsSize;
       return XML_ERROR_NO_MEMORY;
@@ -3541,8 +3892,8 @@ storeAtts(XML_Parser parser, const ENCOD
     }
 #  endif
 
-    temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
-                                    parser->m_attsSize * sizeof(XML_AttrInfo));
+    temp2 = REALLOC(parser, parser->m_attInfo,
+                    parser->m_attsSize * sizeof(XML_AttrInfo));
     if (temp2 == NULL) {
       parser->m_attsSize = oldAttsSize;
       return XML_ERROR_NO_MEMORY;
@@ -3677,7 +4028,7 @@ storeAtts(XML_Parser parser, const ENCOD
      and clear flags that say whether attributes were specified */
   i = 0;
   if (nPrefixes) {
-    int j; /* hash table index */
+    unsigned int j; /* hash table index */
     unsigned long version = parser->m_nsAttsVersion;
 
     /* Detect and prevent invalid shift */
@@ -3718,8 +4069,7 @@ storeAtts(XML_Parser parser, const ENCOD
       }
 #endif
 
-      temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
-                               nsAttsSize * sizeof(NS_ATT));
+      temp = REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT));
       if (! temp) {
         /* Restore actual size of memory in m_nsAtts */
         parser->m_nsAttsPower = oldNsAttsPower;
@@ -3772,7 +4122,7 @@ storeAtts(XML_Parser parser, const ENCOD
         if (! b)
           return XML_ERROR_UNBOUND_PREFIX;
 
-        for (j = 0; j < b->uriLen; j++) {
+        for (j = 0; j < (unsigned int)b->uriLen; j++) {
           const XML_Char c = b->uri[j];
           if (! poolAppendChar(&parser->m_tempPool, c))
             return XML_ERROR_NO_MEMORY;
@@ -3866,7 +4216,7 @@ storeAtts(XML_Parser parser, const ENCOD
     return XML_ERROR_NONE;
   prefixLen = 0;
   if (parser->m_ns_triplets && binding->prefix->name) {
-    for (; binding->prefix->name[prefixLen++];)
+    while (binding->prefix->name[prefixLen++])
       ; /* prefixLen includes null terminator */
   }
   tagNamePtr->localPart = localPart;
@@ -3900,7 +4250,7 @@ storeAtts(XML_Parser parser, const ENCOD
     }
 #endif
 
-    uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
+    uri = MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
     if (! uri)
       return XML_ERROR_NO_MEMORY;
     binding->uriAlloc = n + EXPAND_SPARE;
@@ -4146,8 +4496,8 @@ addBinding(XML_Parser parser, PREFIX *pr
       }
 #endif
 
-      XML_Char *temp = (XML_Char *)REALLOC(
-          parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
+      XML_Char *temp
+          = REALLOC(parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
       if (temp == NULL)
         return XML_ERROR_NO_MEMORY;
       b->uri = temp;
@@ -4155,7 +4505,7 @@ addBinding(XML_Parser parser, PREFIX *pr
     }
     parser->m_freeBindingList = b->nextTagBinding;
   } else {
-    b = (BINDING *)MALLOC(parser, sizeof(BINDING));
+    b = MALLOC(parser, sizeof(BINDING));
     if (! b)
       return XML_ERROR_NO_MEMORY;
 
@@ -4173,8 +4523,7 @@ addBinding(XML_Parser parser, PREFIX *pr
     }
 #endif
 
-    b->uri
-        = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
+    b->uri = MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
     if (! b->uri) {
       FREE(parser, b);
       return XML_ERROR_NO_MEMORY;
@@ -5545,7 +5894,7 @@ doProlog(XML_Parser parser, const ENCODI
               return XML_ERROR_NO_MEMORY;
             }
 
-            char *const new_connector = (char *)REALLOC(
+            char *const new_connector = REALLOC(
                 parser, parser->m_groupConnector, parser->m_groupSize *= 2);
             if (new_connector == NULL) {
               parser->m_groupSize /= 2;
@@ -5565,15 +5914,14 @@ doProlog(XML_Parser parser, const ENCODI
             }
 #endif
 
-            int *const new_scaff_index = (int *)REALLOC(
+            int *const new_scaff_index = REALLOC(
                 parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
             if (new_scaff_index == NULL)
               return XML_ERROR_NO_MEMORY;
             dtd->scaffIndex = new_scaff_index;
           }
         } else {
-          parser->m_groupConnector
-              = (char *)MALLOC(parser, parser->m_groupSize = 32);
+          parser->m_groupConnector = MALLOC(parser, parser->m_groupSize = 32);
           if (! parser->m_groupConnector) {
             parser->m_groupSize = 0;
             return XML_ERROR_NO_MEMORY;
@@ -5730,8 +6078,11 @@ doProlog(XML_Parser parser, const ENCODI
     case XML_ROLE_CONTENT_EMPTY:
       if (dtd->in_eldecl) {
         if (parser->m_elementDeclHandler) {
-          XML_Content *content
-              = (XML_Content *)MALLOC(parser, sizeof(XML_Content));
+          // NOTE: We are avoiding MALLOC(..) here to so that
+          //       applications that are not using XML_FreeContentModel but
+          //       plain free(..) or .free_fcn() to free the content model's
+          //       memory are safe.
+          XML_Content *content = parser->m_mem.malloc_fcn(sizeof(XML_Content));
           if (! content)
             return XML_ERROR_NO_MEMORY;
           content->quant = XML_CQUANT_NONE;
@@ -5787,7 +6138,7 @@ doProlog(XML_Parser parser, const ENCODI
         name = el->name;
         dtd->scaffold[myindex].name = name;
         nameLen = 0;
-        for (; name[nameLen++];)
+        while (name[nameLen++])
           ;
 
         /* Detect and prevent integer overflow */
@@ -6008,8 +6359,7 @@ processEntity(XML_Parser parser, ENTITY
     openEntity = *freeEntityList;
     *freeEntityList = openEntity->next;
   } else {
-    openEntity
-        = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
+    openEntity = MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
     if (! openEntity)
       return XML_ERROR_NO_MEMORY;
   }
@@ -6277,7 +6627,7 @@ appendAttributeValue(XML_Parser parser,
     case XML_TOK_ENTITY_REF: {
       const XML_Char *name;
       ENTITY *entity;
-      char checkEntityDecl;
+      bool checkEntityDecl;
       XML_Char ch = (XML_Char)XmlPredefinedEntityName(
           enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
       if (ch) {
@@ -6804,8 +7154,8 @@ defineAttribute(ELEMENT_TYPE *type, ATTR
   if (type->nDefaultAtts == type->allocDefaultAtts) {
     if (type->allocDefaultAtts == 0) {
       type->allocDefaultAtts = 8;
-      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
-          parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+      type->defaultAtts
+          = MALLOC(parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
       if (! type->defaultAtts) {
         type->allocDefaultAtts = 0;
         return 0;
@@ -6830,8 +7180,8 @@ defineAttribute(ELEMENT_TYPE *type, ATTR
       }
 #endif
 
-      temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
-                                          (count * sizeof(DEFAULT_ATTRIBUTE)));
+      temp = REALLOC(parser, type->defaultAtts,
+                     (count * sizeof(DEFAULT_ATTRIBUTE)));
       if (temp == NULL)
         return 0;
       type->allocDefaultAtts = count;
@@ -7122,19 +7472,19 @@ normalizePublicId(XML_Char *publicId) {
 }
 
 static DTD *
-dtdCreate(const XML_Memory_Handling_Suite *ms) {
-  DTD *p = ms->malloc_fcn(sizeof(DTD));
+dtdCreate(XML_Parser parser) {
+  DTD *p = MALLOC(parser, sizeof(DTD));
   if (p == NULL)
     return p;
-  poolInit(&(p->pool), ms);
-  poolInit(&(p->entityValuePool), ms);
-  hashTableInit(&(p->generalEntities), ms);
-  hashTableInit(&(p->elementTypes), ms);
-  hashTableInit(&(p->attributeIds), ms);
-  hashTableInit(&(p->prefixes), ms);
+  poolInit(&(p->pool), parser);
+  poolInit(&(p->entityValuePool), parser);
+  hashTableInit(&(p->generalEntities), parser);
+  hashTableInit(&(p->elementTypes), parser);
+  hashTableInit(&(p->attributeIds), parser);
+  hashTableInit(&(p->prefixes), parser);
 #ifdef XML_DTD
   p->paramEntityRead = XML_FALSE;
-  hashTableInit(&(p->paramEntities), ms);
+  hashTableInit(&(p->paramEntities), parser);
 #endif /* XML_DTD */
   p->defaultPrefix.name = NULL;
   p->defaultPrefix.binding = NULL;
@@ -7154,7 +7504,7 @@ dtdCreate(const XML_Memory_Handling_Suit
 }
 
 static void
-dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
+dtdReset(DTD *p, XML_Parser parser) {
   HASH_TABLE_ITER iter;
   hashTableIterInit(&iter, &(p->elementTypes));
   for (;;) {
@@ -7162,7 +7512,7 @@ dtdReset(DTD *p, const XML_Memory_Handli
     if (! e)
       break;
     if (e->allocDefaultAtts != 0)
-      ms->free_fcn(e->defaultAtts);
+      FREE(parser, e->defaultAtts);
   }
   hashTableClear(&(p->generalEntities));
 #ifdef XML_DTD
@@ -7179,9 +7529,9 @@ dtdReset(DTD *p, const XML_Memory_Handli
 
   p->in_eldecl = XML_FALSE;
 
-  ms->free_fcn(p->scaffIndex);
+  FREE(parser, p->scaffIndex);
   p->scaffIndex = NULL;
-  ms->free_fcn(p->scaffold);
+  FREE(parser, p->scaffold);
   p->scaffold = NULL;
 
   p->scaffLevel = 0;
@@ -7195,7 +7545,7 @@ dtdReset(DTD *p, const XML_Memory_Handli
 }
 
 static void
-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
+dtdDestroy(DTD *p, XML_Bool isDocEntity, XML_Parser parser) {
   HASH_TABLE_ITER iter;
   hashTableIterInit(&iter, &(p->elementTypes));
   for (;;) {
@@ -7203,7 +7553,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity,
     if (! e)
       break;
     if (e->allocDefaultAtts != 0)
-      ms->free_fcn(e->defaultAtts);
+      FREE(parser, e->defaultAtts);
   }
   hashTableDestroy(&(p->generalEntities));
 #ifdef XML_DTD
@@ -7215,10 +7565,10 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity,
   poolDestroy(&(p->pool));
   poolDestroy(&(p->entityValuePool));
   if (isDocEntity) {
-    ms->free_fcn(p->scaffIndex);
-    ms->free_fcn(p->scaffold);
+    FREE(parser, p->scaffIndex);
+    FREE(parser, p->scaffold);
   }
-  ms->free_fcn(p);
+  FREE(parser, p);
 }
 
 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
@@ -7226,7 +7576,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity,
 */
 static int
 dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
-        const XML_Memory_Handling_Suite *ms) {
+        XML_Parser parser) {
   HASH_TABLE_ITER iter;
 
   /* Copy the prefix table. */
@@ -7307,7 +7657,7 @@ dtdCopy(XML_Parser oldParser, DTD *newDt
       }
 #endif
       newE->defaultAtts
-          = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+          = MALLOC(parser, oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
       if (! newE->defaultAtts) {
         return 0;
       }
@@ -7469,7 +7819,7 @@ lookup(XML_Parser parser, HASH_TABLE *ta
     /* table->size is a power of 2 */
     table->size = (size_t)1 << INIT_POWER;
     tsize = table->size * sizeof(NAMED *);
-    table->v = table->mem->malloc_fcn(tsize);
+    table->v = MALLOC(table->parser, tsize);
     if (! table->v) {
       table->size = 0;
       return NULL;
@@ -7509,7 +7859,7 @@ lookup(XML_Parser parser, HASH_TABLE *ta
       }
 
       size_t tsize = newSize * sizeof(NAMED *);
-      NAMED **newV = table->mem->malloc_fcn(tsize);
+      NAMED **newV = MALLOC(table->parser, tsize);
       if (! newV)
         return NULL;
       memset(newV, 0, tsize);
@@ -7525,7 +7875,7 @@ lookup(XML_Parser parser, HASH_TABLE *ta
           }
           newV[j] = table->v[i];
         }
-      table->mem->free_fcn(table->v);
+      FREE(table->parser, table->v);
       table->v = newV;
       table->power = newPower;
       table->size = newSize;
@@ -7538,7 +7888,7 @@ lookup(XML_Parser parser, HASH_TABLE *ta
       }
     }
   }
-  table->v[i] = table->mem->malloc_fcn(createSize);
+  table->v[i] = MALLOC(table->parser, createSize);
   if (! table->v[i])
     return NULL;
   memset(table->v[i], 0, createSize);
@@ -7551,7 +7901,7 @@ static void FASTCALL
 hashTableClear(HASH_TABLE *table) {
   size_t i;
   for (i = 0; i < table->size; i++) {
-    table->mem->free_fcn(table->v[i]);
+    FREE(table->parser, table->v[i]);
     table->v[i] = NULL;
   }
   table->used = 0;
@@ -7561,17 +7911,17 @@ static void FASTCALL
 hashTableDestroy(HASH_TABLE *table) {
   size_t i;
   for (i = 0; i < table->size; i++)
-    table->mem->free_fcn(table->v[i]);
-  table->mem->free_fcn(table->v);
+    FREE(table->parser, table->v[i]);
+  FREE(table->parser, table->v);
 }
 
 static void FASTCALL
-hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
+hashTableInit(HASH_TABLE *p, XML_Parser parser) {
   p->power = 0;
   p->size = 0;
   p->used = 0;
   p->v = NULL;
-  p->mem = ms;
+  p->parser = parser;
 }
 
 static void FASTCALL
@@ -7591,13 +7941,13 @@ hashTableIterNext(HASH_TABLE_ITER *iter)
 }
 
 static void FASTCALL
-poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
+poolInit(STRING_POOL *pool, XML_Parser parser) {
   pool->blocks = NULL;
   pool->freeBlocks = NULL;
   pool->start = NULL;
   pool->ptr = NULL;
   pool->end = NULL;
-  pool->mem = ms;
+  pool->parser = parser;
 }
 
 static void FASTCALL
@@ -7624,13 +7974,13 @@ poolDestroy(STRING_POOL *pool) {
   BLOCK *p = pool->blocks;
   while (p) {
     BLOCK *tem = p->next;
-    pool->mem->free_fcn(p);
+    FREE(pool->parser, p);
     p = tem;
   }
   p = pool->freeBlocks;
   while (p) {
     BLOCK *tem = p->next;
-    pool->mem->free_fcn(p);
+    FREE(pool->parser, p);
     p = tem;
   }
 }
@@ -7785,8 +8135,7 @@ poolGrow(STRING_POOL *pool) {
     if (bytesToAllocate == 0)
       return XML_FALSE;
 
-    temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
-                                           (unsigned)bytesToAllocate);
+    temp = REALLOC(pool->parser, pool->blocks, (unsigned)bytesToAllocate);
     if (temp == NULL)
       return XML_FALSE;
     pool->blocks = temp;
@@ -7826,7 +8175,7 @@ poolGrow(STRING_POOL *pool) {
     if (bytesToAllocate == 0)
       return XML_FALSE;
 
-    tem = pool->mem->malloc_fcn(bytesToAllocate);
+    tem = MALLOC(pool->parser, bytesToAllocate);
     if (! tem)
       return XML_FALSE;
     tem->size = blockSize;
@@ -7857,12 +8206,17 @@ nextScaffoldPart(XML_Parser parser) {
       return -1;
     }
 #endif
-    dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
+    dtd->scaffIndex = MALLOC(parser, parser->m_groupSize * sizeof(int));
     if (! dtd->scaffIndex)
       return -1;
     dtd->scaffIndex[0] = 0;
   }
 
+  // Will casting to int be safe further down?
+  if (dtd->scaffCount > INT_MAX) {
+    return -1;
+  }
+
   if (dtd->scaffCount >= dtd->scaffSize) {
     CONTENT_SCAFFOLD *temp;
     if (dtd->scaffold) {
@@ -7880,21 +8234,20 @@ nextScaffoldPart(XML_Parser parser) {
       }
 #endif
 
-      temp = (CONTENT_SCAFFOLD *)REALLOC(
-          parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
+      temp = REALLOC(parser, dtd->scaffold,
+                     dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
       if (temp == NULL)
         return -1;
       dtd->scaffSize *= 2;
     } else {
-      temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
-                                                    * sizeof(CONTENT_SCAFFOLD));
+      temp = MALLOC(parser, INIT_SCAFFOLD_ELEMENTS * sizeof(CONTENT_SCAFFOLD));
       if (temp == NULL)
         return -1;
       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
     }
     dtd->scaffold = temp;
   }
-  next = dtd->scaffCount++;
+  next = (int)dtd->scaffCount++;
   me = &dtd->scaffold[next];
   if (dtd->scaffLevel) {
     CONTENT_SCAFFOLD *parent
@@ -7941,7 +8294,10 @@ build_model(XML_Parser parser) {
   const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content)
                             + (dtd->contentStringLen * sizeof(XML_Char)));
 
-  ret = (XML_Content *)MALLOC(parser, allocsize);
+  // NOTE: We are avoiding MALLOC(..) here to so that
+  //       applications that are not using XML_FreeContentModel but plain
+  //       free(..) or .free_fcn() to free the content model's memory are safe.
+  ret = parser->m_mem.malloc_fcn(allocsize);
   if (! ret)
     return NULL;
 
@@ -8062,7 +8418,7 @@ getElementType(XML_Parser parser, const
 }
 
 static XML_Char *
-copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
+copyString(const XML_Char *s, XML_Parser parser) {
   size_t charsRequired = 0;
   XML_Char *result;
 
@@ -8074,7 +8430,7 @@ copyString(const XML_Char *s, const XML_
   charsRequired++;
 
   /* Now allocate space for the copy */
-  result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
+  result = MALLOC(parser, charsRequired * sizeof(XML_Char));
   if (result == NULL)
     return NULL;
   /* Copy the original into place */
@@ -8093,10 +8449,10 @@ accountingGetCurrentAmplification(XML_Pa
         + rootParser->m_accounting.countBytesIndirect;
   const float amplificationFactor
       = rootParser->m_accounting.countBytesDirect
-            ? (countBytesOutput
+            ? ((float)countBytesOutput
                / (float)(rootParser->m_accounting.countBytesDirect))
-            : ((lenOfShortestInclude
-                + rootParser->m_accounting.countBytesIndirect)
+            : ((float)(lenOfShortestInclude
+                       + rootParser->m_accounting.countBytesIndirect)
                / (float)lenOfShortestInclude);
   assert(! rootParser->m_parentParser);
   return amplificationFactor;
@@ -8280,6 +8636,8 @@ entityTrackingOnClose(XML_Parser originP
   rootParser->m_entity_stats.currentDepth--;
 }
 
+#endif /* XML_GE == 1 */
+
 static XML_Parser
 getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) {
   XML_Parser rootParser = parser;
@@ -8295,6 +8653,8 @@ getRootParserOf(XML_Parser parser, unsig
   return rootParser;
 }
 
+#if XML_GE == 1
+
 const char *
 unsignedCharToPrintable(unsigned char c) {
   switch (c) {
Index: expat-2.7.1/lib/xmlrole.h
===================================================================
--- expat-2.7.1.orig/lib/xmlrole.h
+++ expat-2.7.1/lib/xmlrole.h
@@ -34,19 +34,13 @@
 */
 
 #ifndef XmlRole_INCLUDED
-#define XmlRole_INCLUDED 1
+#  define XmlRole_INCLUDED 1
 
-#ifdef __VMS
-/*      0        1         2         3      0        1         2         3
-        1234567890123456789012345678901     1234567890123456789012345678901 */
-#  define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
-#endif
+#  include "xmltok.h"
 
-#include "xmltok.h"
-
-#ifdef __cplusplus
+#  ifdef __cplusplus
 extern "C" {
-#endif
+#  endif
 
 enum {
   XML_ROLE_ERROR = -1,
@@ -107,11 +101,11 @@ enum {
   XML_ROLE_CONTENT_ELEMENT_PLUS,
   XML_ROLE_PI,
   XML_ROLE_COMMENT,
-#ifdef XML_DTD
+#  ifdef XML_DTD
   XML_ROLE_TEXT_DECL,
   XML_ROLE_IGNORE_SECT,
   XML_ROLE_INNER_PARAM_ENTITY_REF,
-#endif /* XML_DTD */
+#  endif /* XML_DTD */
   XML_ROLE_PARAM_ENTITY_REF
 };
 
@@ -120,23 +114,23 @@ typedef struct prolog_state {
                         const char *end, const ENCODING *enc);
   unsigned level;
   int role_none;
-#ifdef XML_DTD
+#  ifdef XML_DTD
   unsigned includeLevel;
   int documentEntity;
   int inEntityValue;
-#endif /* XML_DTD */
+#  endif /* XML_DTD */
 } PROLOG_STATE;
 
 void XmlPrologStateInit(PROLOG_STATE *state);
-#ifdef XML_DTD
+#  ifdef XML_DTD
 void XmlPrologStateInitExternalEntity(PROLOG_STATE *state);
-#endif /* XML_DTD */
+#  endif /* XML_DTD */
 
-#define XmlTokenRole(state, tok, ptr, end, enc)                                \
-  (((state)->handler)(state, tok, ptr, end, enc))
+#  define XmlTokenRole(state, tok, ptr, end, enc)                              \
+    (((state)->handler)(state, tok, ptr, end, enc))
 
-#ifdef __cplusplus
+#  ifdef __cplusplus
 }
-#endif
+#  endif
 
 #endif /* not XmlRole_INCLUDED */
Index: expat-2.7.1/lib/xmltok.c
===================================================================
--- expat-2.7.1.orig/lib/xmltok.c
+++ expat-2.7.1/lib/xmltok.c
@@ -1398,7 +1398,7 @@ unknown_toUtf16(const ENCODING *enc, con
 }
 
 ENCODING *
-XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
+XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert,
                        void *userData) {
   int i;
   struct unknown_encoding *e = (struct unknown_encoding *)mem;
@@ -1661,7 +1661,7 @@ initScan(const ENCODING *const *encoding
 #  undef ns
 
 ENCODING *
-XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
+XmlInitUnknownEncodingNS(void *mem, const int *table, CONVERTER convert,
                          void *userData) {
   ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
   if (enc)
Index: expat-2.7.1/lib/xmltok.h
===================================================================
--- expat-2.7.1.orig/lib/xmltok.h
+++ expat-2.7.1/lib/xmltok.h
@@ -35,113 +35,113 @@
 */
 
 #ifndef XmlTok_INCLUDED
-#define XmlTok_INCLUDED 1
+#  define XmlTok_INCLUDED 1
 
-#ifdef __cplusplus
+#  ifdef __cplusplus
 extern "C" {
-#endif
+#  endif
 
 /* The following token may be returned by XmlContentTok */
-#define XML_TOK_TRAILING_RSQB                                                  \
-  -5 /* ] or ]] at the end of the scan; might be                               \
-        start of illegal ]]> sequence */
+#  define XML_TOK_TRAILING_RSQB                                                \
+    -5 /* ] or ]] at the end of the scan; might be                             \
+          start of illegal ]]> sequence */
 /* The following tokens may be returned by both XmlPrologTok and
    XmlContentTok.
 */
-#define XML_TOK_NONE -4 /* The string to be scanned is empty */
-#define XML_TOK_TRAILING_CR                                                    \
-  -3                            /* A CR at the end of the scan;                \
-                                   might be part of CRLF sequence */
-#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
-#define XML_TOK_PARTIAL -1      /* only part of a token */
-#define XML_TOK_INVALID 0
+#  define XML_TOK_NONE -4 /* The string to be scanned is empty */
+#  define XML_TOK_TRAILING_CR                                                  \
+    -3                            /* A CR at the end of the scan;              \
+                                     might be part of CRLF sequence */
+#  define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
+#  define XML_TOK_PARTIAL -1      /* only part of a token */
+#  define XML_TOK_INVALID 0
 
 /* The following tokens are returned by XmlContentTok; some are also
    returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
 */
-#define XML_TOK_START_TAG_WITH_ATTS 1
-#define XML_TOK_START_TAG_NO_ATTS 2
-#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
-#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
-#define XML_TOK_END_TAG 5
-#define XML_TOK_DATA_CHARS 6
-#define XML_TOK_DATA_NEWLINE 7
-#define XML_TOK_CDATA_SECT_OPEN 8
-#define XML_TOK_ENTITY_REF 9
-#define XML_TOK_CHAR_REF 10 /* numeric character reference */
+#  define XML_TOK_START_TAG_WITH_ATTS 1
+#  define XML_TOK_START_TAG_NO_ATTS 2
+#  define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
+#  define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
+#  define XML_TOK_END_TAG 5
+#  define XML_TOK_DATA_CHARS 6
+#  define XML_TOK_DATA_NEWLINE 7
+#  define XML_TOK_CDATA_SECT_OPEN 8
+#  define XML_TOK_ENTITY_REF 9
+#  define XML_TOK_CHAR_REF 10 /* numeric character reference */
 
 /* The following tokens may be returned by both XmlPrologTok and
    XmlContentTok.
 */
-#define XML_TOK_PI 11       /* processing instruction */
-#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
-#define XML_TOK_COMMENT 13
-#define XML_TOK_BOM 14 /* Byte order mark */
+#  define XML_TOK_PI 11       /* processing instruction */
+#  define XML_TOK_XML_DECL 12 /* XML decl or text decl */
+#  define XML_TOK_COMMENT 13
+#  define XML_TOK_BOM 14 /* Byte order mark */
 
 /* The following tokens are returned only by XmlPrologTok */
-#define XML_TOK_PROLOG_S 15
-#define XML_TOK_DECL_OPEN 16  /* <!foo */
-#define XML_TOK_DECL_CLOSE 17 /* > */
-#define XML_TOK_NAME 18
-#define XML_TOK_NMTOKEN 19
-#define XML_TOK_POUND_NAME 20 /* #name */
-#define XML_TOK_OR 21         /* | */
-#define XML_TOK_PERCENT 22
-#define XML_TOK_OPEN_PAREN 23
-#define XML_TOK_CLOSE_PAREN 24
-#define XML_TOK_OPEN_BRACKET 25
-#define XML_TOK_CLOSE_BRACKET 26
-#define XML_TOK_LITERAL 27
-#define XML_TOK_PARAM_ENTITY_REF 28
-#define XML_TOK_INSTANCE_START 29
+#  define XML_TOK_PROLOG_S 15
+#  define XML_TOK_DECL_OPEN 16  /* <!foo */
+#  define XML_TOK_DECL_CLOSE 17 /* > */
+#  define XML_TOK_NAME 18
+#  define XML_TOK_NMTOKEN 19
+#  define XML_TOK_POUND_NAME 20 /* #name */
+#  define XML_TOK_OR 21         /* | */
+#  define XML_TOK_PERCENT 22
+#  define XML_TOK_OPEN_PAREN 23
+#  define XML_TOK_CLOSE_PAREN 24
+#  define XML_TOK_OPEN_BRACKET 25
+#  define XML_TOK_CLOSE_BRACKET 26
+#  define XML_TOK_LITERAL 27
+#  define XML_TOK_PARAM_ENTITY_REF 28
+#  define XML_TOK_INSTANCE_START 29
 
 /* The following occur only in element type declarations */
-#define XML_TOK_NAME_QUESTION 30        /* name? */
-#define XML_TOK_NAME_ASTERISK 31        /* name* */
-#define XML_TOK_NAME_PLUS 32            /* name+ */
-#define XML_TOK_COND_SECT_OPEN 33       /* <![ */
-#define XML_TOK_COND_SECT_CLOSE 34      /* ]]> */
-#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
-#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
-#define XML_TOK_CLOSE_PAREN_PLUS 37     /* )+ */
-#define XML_TOK_COMMA 38
+#  define XML_TOK_NAME_QUESTION 30        /* name? */
+#  define XML_TOK_NAME_ASTERISK 31        /* name* */
+#  define XML_TOK_NAME_PLUS 32            /* name+ */
+#  define XML_TOK_COND_SECT_OPEN 33       /* <![ */
+#  define XML_TOK_COND_SECT_CLOSE 34      /* ]]> */
+#  define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
+#  define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
+#  define XML_TOK_CLOSE_PAREN_PLUS 37     /* )+ */
+#  define XML_TOK_COMMA 38
 
 /* The following token is returned only by XmlAttributeValueTok */
-#define XML_TOK_ATTRIBUTE_VALUE_S 39
+#  define XML_TOK_ATTRIBUTE_VALUE_S 39
 
 /* The following token is returned only by XmlCdataSectionTok */
-#define XML_TOK_CDATA_SECT_CLOSE 40
+#  define XML_TOK_CDATA_SECT_CLOSE 40
 
 /* With namespace processing this is returned by XmlPrologTok for a
    name with a colon.
 */
-#define XML_TOK_PREFIXED_NAME 41
+#  define XML_TOK_PREFIXED_NAME 41
 
-#ifdef XML_DTD
-#  define XML_TOK_IGNORE_SECT 42
-#endif /* XML_DTD */
-
-#ifdef XML_DTD
-#  define XML_N_STATES 4
-#else /* not XML_DTD */
-#  define XML_N_STATES 3
-#endif /* not XML_DTD */
-
-#define XML_PROLOG_STATE 0
-#define XML_CONTENT_STATE 1
-#define XML_CDATA_SECTION_STATE 2
-#ifdef XML_DTD
-#  define XML_IGNORE_SECTION_STATE 3
-#endif /* XML_DTD */
-
-#define XML_N_LITERAL_TYPES 2
-#define XML_ATTRIBUTE_VALUE_LITERAL 0
-#define XML_ENTITY_VALUE_LITERAL 1
+#  ifdef XML_DTD
+#    define XML_TOK_IGNORE_SECT 42
+#  endif /* XML_DTD */
+
+#  ifdef XML_DTD
+#    define XML_N_STATES 4
+#  else /* not XML_DTD */
+#    define XML_N_STATES 3
+#  endif /* not XML_DTD */
+
+#  define XML_PROLOG_STATE 0
+#  define XML_CONTENT_STATE 1
+#  define XML_CDATA_SECTION_STATE 2
+#  ifdef XML_DTD
+#    define XML_IGNORE_SECTION_STATE 3
+#  endif /* XML_DTD */
+
+#  define XML_N_LITERAL_TYPES 2
+#  define XML_ATTRIBUTE_VALUE_LITERAL 0
+#  define XML_ENTITY_VALUE_LITERAL 1
 
 /* The size of the buffer passed to XmlUtf8Encode must be at least this. */
-#define XML_UTF8_ENCODE_MAX 4
+#  define XML_UTF8_ENCODE_MAX 4
 /* The size of the buffer passed to XmlUtf16Encode must be at least this. */
-#define XML_UTF16_ENCODE_MAX 2
+#  define XML_UTF16_ENCODE_MAX 2
 
 typedef struct position {
   /* first line and first column are 0 not 1 */
@@ -220,63 +220,63 @@ struct encoding {
    the prolog outside literals, comments and processing instructions.
 */
 
-#define XmlTok(enc, state, ptr, end, nextTokPtr)                               \
-  (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
+#  define XmlTok(enc, state, ptr, end, nextTokPtr)                             \
+    (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
 
-#define XmlPrologTok(enc, ptr, end, nextTokPtr)                                \
-  XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+#  define XmlPrologTok(enc, ptr, end, nextTokPtr)                              \
+    XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
 
-#define XmlContentTok(enc, ptr, end, nextTokPtr)                               \
-  XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+#  define XmlContentTok(enc, ptr, end, nextTokPtr)                             \
+    XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
 
-#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr)                          \
-  XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+#  define XmlCdataSectionTok(enc, ptr, end, nextTokPtr)                        \
+    XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
 
-#ifdef XML_DTD
+#  ifdef XML_DTD
 
-#  define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr)                       \
-    XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+#    define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr)                     \
+      XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
 
-#endif /* XML_DTD */
+#  endif /* XML_DTD */
 
 /* This is used for performing a 2nd-level tokenization on the content
    of a literal that has already been returned by XmlTok.
 */
-#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr)                  \
-  (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
+#  define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr)                \
+    (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
 
-#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr)                        \
-  XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
+#  define XmlAttributeValueTok(enc, ptr, end, nextTokPtr)                      \
+    XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
 
-#define XmlEntityValueTok(enc, ptr, end, nextTokPtr)                           \
-  XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+#  define XmlEntityValueTok(enc, ptr, end, nextTokPtr)                         \
+    XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
 
-#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2)                             \
-  (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
+#  define XmlNameMatchesAscii(enc, ptr1, end1, ptr2)                           \
+    (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
 
-#define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr))
+#  define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr))
 
-#define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr))
+#  define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr))
 
-#define XmlGetAttributes(enc, ptr, attsMax, atts)                              \
-  (((enc)->getAtts)(enc, ptr, attsMax, atts))
+#  define XmlGetAttributes(enc, ptr, attsMax, atts)                            \
+    (((enc)->getAtts)(enc, ptr, attsMax, atts))
 
-#define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr))
+#  define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr))
 
-#define XmlPredefinedEntityName(enc, ptr, end)                                 \
-  (((enc)->predefinedEntityName)(enc, ptr, end))
+#  define XmlPredefinedEntityName(enc, ptr, end)                               \
+    (((enc)->predefinedEntityName)(enc, ptr, end))
 
-#define XmlUpdatePosition(enc, ptr, end, pos)                                  \
-  (((enc)->updatePosition)(enc, ptr, end, pos))
+#  define XmlUpdatePosition(enc, ptr, end, pos)                                \
+    (((enc)->updatePosition)(enc, ptr, end, pos))
 
-#define XmlIsPublicId(enc, ptr, end, badPtr)                                   \
-  (((enc)->isPublicId)(enc, ptr, end, badPtr))
+#  define XmlIsPublicId(enc, ptr, end, badPtr)                                 \
+    (((enc)->isPublicId)(enc, ptr, end, badPtr))
 
-#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim)                        \
-  (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
+#  define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim)                      \
+    (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
 
-#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim)                       \
-  (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
+#  define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim)                     \
+    (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
 
 typedef struct {
   ENCODING initEnc;
@@ -299,7 +299,7 @@ int XmlSizeOfUnknownEncoding(void);
 
 typedef int(XMLCALL *CONVERTER)(void *userData, const char *p);
 
-ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
+ENCODING *XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert,
                                  void *userData);
 
 int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc,
@@ -312,10 +312,10 @@ int XmlInitEncodingNS(INIT_ENCODING *p,
                       const char *name);
 const ENCODING *XmlGetUtf8InternalEncodingNS(void);
 const ENCODING *XmlGetUtf16InternalEncodingNS(void);
-ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
-                                   void *userData);
-#ifdef __cplusplus
+ENCODING *XmlInitUnknownEncodingNS(void *mem, const int *table,
+                                   CONVERTER convert, void *userData);
+#  ifdef __cplusplus
 }
-#endif
+#  endif
 
 #endif /* not XmlTok_INCLUDED */
Index: expat-2.7.1/tests/alloc_tests.c
===================================================================
--- expat-2.7.1.orig/tests/alloc_tests.c
+++ expat-2.7.1/tests/alloc_tests.c
@@ -10,7 +10,7 @@
    Copyright (c) 2003      Greg Stein <gstein@users.sourceforge.net>
    Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
    Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
-   Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
+   Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
    Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
    Copyright (c) 2017      Joe Orton <jorton@redhat.com>
    Copyright (c) 2017      José Gutiérrez de la Concha <jose@zeroc.com>
@@ -46,10 +46,16 @@
 #  undef NDEBUG /* because test suite relies on assert(...) at the moment */
 #endif
 
+#include <math.h> /* NAN, INFINITY */
+#include <stdbool.h>
+#include <stdint.h> /* for SIZE_MAX */
 #include <string.h>
 #include <assert.h>
 
+#include "expat_config.h"
+
 #include "expat.h"
+#include "internal.h"
 #include "common.h"
 #include "minicheck.h"
 #include "dummy.h"
@@ -323,7 +329,7 @@ START_TEST(test_alloc_run_external_parse
     XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
     XML_SetUserData(g_parser, foo_text);
     XML_SetExternalEntityRefHandler(g_parser, external_entity_null_loader);
-    g_allocation_count = i;
+    g_allocation_count = (int)i;
     if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
         != XML_STATUS_ERROR)
       break;
@@ -434,7 +440,7 @@ START_TEST(test_alloc_internal_entity) {
   const unsigned int max_alloc_count = 20;
 
   for (i = 0; i < max_alloc_count; i++) {
-    g_allocation_count = i;
+    g_allocation_count = (int)i;
     XML_SetUnknownEncodingHandler(g_parser, unknown_released_encoding_handler,
                                   NULL);
     if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
@@ -2085,6 +2091,203 @@ START_TEST(test_alloc_reset_after_extern
 }
 END_TEST
 
+START_TEST(test_alloc_tracker_size_recorded) {
+  XML_Memory_Handling_Suite memsuite = {malloc, realloc, free};
+
+  bool values[] = {true, false};
+  for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
+    const bool useMemSuite = values[i];
+    set_subtest("useMemSuite=%d", (int)useMemSuite);
+    XML_Parser parser = useMemSuite
+                            ? XML_ParserCreate_MM(NULL, &memsuite, XCS("|"))
+                            : XML_ParserCreate(NULL);
+
+#if XML_GE == 1
+    void *ptr = expat_malloc(parser, 10, -1);
+
+    assert_true(ptr != NULL);
+    assert_true(*((size_t *)ptr - 1) == 10);
+
+    assert_true(expat_realloc(parser, ptr, SIZE_MAX / 2, -1) == NULL);
+
+    assert_true(*((size_t *)ptr - 1) == 10); // i.e. unchanged
+
+    ptr = expat_realloc(parser, ptr, 20, -1);
+
+    assert_true(ptr != NULL);
+    assert_true(*((size_t *)ptr - 1) == 20);
+
+    expat_free(parser, ptr, -1);
+#endif
+
+    XML_ParserFree(parser);
+  }
+}
+END_TEST
+
+START_TEST(test_alloc_tracker_maximum_amplification) {
+  if (g_reparseDeferralEnabledDefault == XML_TRUE) {
+    return;
+  }
+
+  XML_Parser parser = XML_ParserCreate(NULL);
+
+  // Get .m_accounting.countBytesDirect from 0 to 3
+  const char *const chunk = "<e>";
+  assert_true(_XML_Parse_SINGLE_BYTES(parser, chunk, (int)strlen(chunk),
+                                      /*isFinal=*/XML_FALSE)
+              == XML_STATUS_OK);
+
+#if XML_GE == 1
+  // Stop activation threshold from interfering
+  assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE);
+
+  // Exceed maximum amplification: should be rejected.
+  assert_true(expat_malloc(parser, 1000, -1) == NULL);
+
+  // Increase maximum amplification, and try the same amount once more: should
+  // work.
+  assert_true(XML_SetAllocTrackerMaximumAmplification(parser, 3000.0f)
+              == XML_TRUE);
+
+  void *const ptr = expat_malloc(parser, 1000, -1);
+  assert_true(ptr != NULL);
+  expat_free(parser, ptr, -1);
+#endif
+
+  XML_ParserFree(parser);
+}
+END_TEST
+
+START_TEST(test_alloc_tracker_threshold) {
+  XML_Parser parser = XML_ParserCreate(NULL);
+
+#if XML_GE == 1
+  // Exceed maximum amplification *before* (default) threshold: should work.
+  void *const ptr = expat_malloc(parser, 1000, -1);
+  assert_true(ptr != NULL);
+  expat_free(parser, ptr, -1);
+
+  // Exceed maximum amplification *after* threshold: should be rejected.
+  assert_true(XML_SetAllocTrackerActivationThreshold(parser, 999) == XML_TRUE);
+  assert_true(expat_malloc(parser, 1000, -1) == NULL);
+#endif
+
+  XML_ParserFree(parser);
+}
+END_TEST
+
+START_TEST(test_alloc_tracker_getbuffer_unlimited) {
+  XML_Parser parser = XML_ParserCreate(NULL);
+
+#if XML_GE == 1
+  // Artificially lower threshold
+  assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE);
+
+  // Self-test: Prove that threshold is as rejecting as expected
+  assert_true(expat_malloc(parser, 1000, -1) == NULL);
+#endif
+  // XML_GetBuffer should be allowed to pass, though
+  assert_true(XML_GetBuffer(parser, 1000) != NULL);
+
+  XML_ParserFree(parser);
+}
+END_TEST
+
+START_TEST(test_alloc_tracker_api) {
+  XML_Parser parserWithoutParent = XML_ParserCreate(NULL);
+  XML_Parser parserWithParent = XML_ExternalEntityParserCreate(
+      parserWithoutParent, XCS("entity123"), NULL);
+  if (parserWithoutParent == NULL)
+    fail("parserWithoutParent is NULL");
+  if (parserWithParent == NULL)
+    fail("parserWithParent is NULL");
+
+#if XML_GE == 1
+  // XML_SetAllocTrackerMaximumAmplification, error cases
+  if (XML_SetAllocTrackerMaximumAmplification(NULL, 123.0f) == XML_TRUE)
+    fail("Call with NULL parser is NOT supposed to succeed");
+  if (XML_SetAllocTrackerMaximumAmplification(parserWithParent, 123.0f)
+      == XML_TRUE)
+    fail("Call with non-root parser is NOT supposed to succeed");
+  if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, NAN)
+      == XML_TRUE)
+    fail("Call with NaN limit is NOT supposed to succeed");
+  if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, -1.0f)
+      == XML_TRUE)
+    fail("Call with negative limit is NOT supposed to succeed");
+  if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 0.9f)
+      == XML_TRUE)
+    fail("Call with positive limit <1.0 is NOT supposed to succeed");
+
+  // XML_SetAllocTrackerMaximumAmplification, success cases
+  if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 1.0f)
+      == XML_FALSE)
+    fail("Call with positive limit >=1.0 is supposed to succeed");
+  if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 123456.789f)
+      == XML_FALSE)
+    fail("Call with positive limit >=1.0 is supposed to succeed");
+  if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, INFINITY)
+      == XML_FALSE)
+    fail("Call with positive limit >=1.0 is supposed to succeed");
+
+  // XML_SetAllocTrackerActivationThreshold, error cases
+  if (XML_SetAllocTrackerActivationThreshold(NULL, 123) == XML_TRUE)
+    fail("Call with NULL parser is NOT supposed to succeed");
+  if (XML_SetAllocTrackerActivationThreshold(parserWithParent, 123) == XML_TRUE)
+    fail("Call with non-root parser is NOT supposed to succeed");
+
+  // XML_SetAllocTrackerActivationThreshold, success cases
+  if (XML_SetAllocTrackerActivationThreshold(parserWithoutParent, 123)
+      == XML_FALSE)
+    fail("Call with non-NULL parentless parser is supposed to succeed");
+#endif // XML_GE == 1
+
+  XML_ParserFree(parserWithParent);
+  XML_ParserFree(parserWithoutParent);
+}
+END_TEST
+
+START_TEST(test_mem_api_cycle) {
+  XML_Parser parser = XML_ParserCreate(NULL);
+
+  void *ptr = XML_MemMalloc(parser, 10);
+
+  assert_true(ptr != NULL);
+  memset(ptr, 'x', 10); // assert writability, with ASan in mind
+
+  ptr = XML_MemRealloc(parser, ptr, 20);
+
+  assert_true(ptr != NULL);
+  memset(ptr, 'y', 20); // assert writability, with ASan in mind
+
+  XML_MemFree(parser, ptr);
+
+  XML_ParserFree(parser);
+}
+END_TEST
+
+START_TEST(test_mem_api_unlimited) {
+  XML_Parser parser = XML_ParserCreate(NULL);
+
+#if XML_GE == 1
+  assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE);
+#endif
+
+  void *ptr = XML_MemMalloc(parser, 1000);
+
+  assert_true(ptr != NULL);
+
+  ptr = XML_MemRealloc(parser, ptr, 2000);
+
+  assert_true(ptr != NULL);
+
+  XML_MemFree(parser, ptr);
+
+  XML_ParserFree(parser);
+}
+END_TEST
+
 void
 make_alloc_test_case(Suite *s) {
   TCase *tc_alloc = tcase_create("allocation tests");
@@ -2151,4 +2354,15 @@ make_alloc_test_case(Suite *s) {
 
   tcase_add_test__ifdef_xml_dtd(
       tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail);
+
+  tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_tracker_size_recorded);
+  tcase_add_test__ifdef_xml_dtd(tc_alloc,
+                                test_alloc_tracker_maximum_amplification);
+  tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_tracker_threshold);
+  tcase_add_test__ifdef_xml_dtd(tc_alloc,
+                                test_alloc_tracker_getbuffer_unlimited);
+  tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_tracker_api);
+
+  tcase_add_test(tc_alloc, test_mem_api_cycle);
+  tcase_add_test__ifdef_xml_dtd(tc_alloc, test_mem_api_unlimited);
 }
Index: expat-2.7.1/tests/basic_tests.c
===================================================================
--- expat-2.7.1.orig/tests/basic_tests.c
+++ expat-2.7.1/tests/basic_tests.c
@@ -412,13 +412,13 @@ START_TEST(test_utf16_le_epilog_newline)
 
   if (first_chunk_bytes >= sizeof(text) - 1)
     fail("bad value of first_chunk_bytes");
-  if (_XML_Parse_SINGLE_BYTES(g_parser, text, first_chunk_bytes, XML_FALSE)
+  if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)first_chunk_bytes, XML_FALSE)
       == XML_STATUS_ERROR)
     xml_failure(g_parser);
   else {
     enum XML_Status rc;
     rc = _XML_Parse_SINGLE_BYTES(g_parser, text + first_chunk_bytes,
-                                 sizeof(text) - first_chunk_bytes - 1,
+                                 (int)(sizeof(text) - first_chunk_bytes - 1),
                                  XML_TRUE);
     if (rc == XML_STATUS_ERROR)
       xml_failure(g_parser);
@@ -3123,6 +3123,10 @@ START_TEST(test_buffer_can_grow_to_max)
   for (int i = 0; i < num_prefixes; ++i) {
     set_subtest("\"%s\"", prefixes[i]);
     XML_Parser parser = XML_ParserCreate(NULL);
+#if XML_GE == 1
+    assert_true(XML_SetAllocTrackerActivationThreshold(parser, (size_t)-1)
+                == XML_TRUE); // i.e. deactivate
+#endif
     const int prefix_len = (int)strlen(prefixes[i]);
     const enum XML_Status s
         = _XML_Parse_SINGLE_BYTES(parser, prefixes[i], prefix_len, XML_FALSE);
Index: expat-2.7.1/tests/benchmark/Makefile.in
===================================================================
--- expat-2.7.1.orig/tests/benchmark/Makefile.in
+++ expat-2.7.1/tests/benchmark/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# Makefile.in generated by automake 1.18.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+# Copyright (C) 1994-2025 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -101,6 +101,8 @@ am__make_running_with_option = \
   test $$has_opt = yes
 am__make_dryrun = (target_option=n; $(am__make_running_with_option))
 am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+am__rm_f = rm -f $(am__rm_f_notfound)
+am__rm_rf = rm -rf $(am__rm_f_notfound)
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -320,8 +322,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
+am__rm_f_notfound = @am__rm_f_notfound@
 am__tar = @am__tar@
 am__untar = @am__untar@
+am__xargs_n = @am__xargs_n@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -403,13 +407,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(
 $(am__aclocal_m4_deps):
 
 clean-noinstPROGRAMS:
-	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
-	echo " rm -f" $$list; \
-	rm -f $$list || exit $$?; \
-	test -n "$(EXEEXT)" || exit 0; \
-	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-	echo " rm -f" $$list; \
-	rm -f $$list
+	$(am__rm_f) $(noinst_PROGRAMS)
+	test -z "$(EXEEXT)" || $(am__rm_f) $(noinst_PROGRAMS:$(EXEEXT)=)
 
 benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) $(EXTRA_benchmark_DEPENDENCIES) 
 	@rm -f benchmark$(EXEEXT)
@@ -425,7 +424,7 @@ distclean-compile:
 
 $(am__depfiles_remade):
 	@$(MKDIR_P) $(@D)
-	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+	@: >>$@
 
 am--depfiles: $(am__depfiles_remade)
 
@@ -507,6 +506,7 @@ cscopelist-am: $(am__tagged_files)
 
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
 distdir: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -568,8 +568,8 @@ mostlyclean-generic:
 clean-generic:
 
 distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-$(am__rm_f) $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -580,7 +580,7 @@ clean-am: clean-generic clean-libtool cl
 	mostlyclean-am
 
 distclean: distclean-am
-		-rm -f ./$(DEPDIR)/benchmark.Po
+	-rm -f ./$(DEPDIR)/benchmark.Po
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -626,7 +626,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-		-rm -f ./$(DEPDIR)/benchmark.Po
+	-rm -f ./$(DEPDIR)/benchmark.Po
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -667,3 +667,10 @@ uninstall-am:
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
+
+# Tell GNU make to disable its built-in pattern rules.
+%:: %,v
+%:: RCS/%,v
+%:: RCS/%
+%:: s.%
+%:: SCCS/s.%
Index: expat-2.7.1/tests/common.c
===================================================================
--- expat-2.7.1.orig/tests/common.c
+++ expat-2.7.1/tests/common.c
@@ -303,7 +303,14 @@ duff_reallocator(void *ptr, size_t size)
   return realloc(ptr, size);
 }
 
-// Portable remake of strndup(3) for C99; does not care about space efficiency
+// Portable remake of strnlen(3) for C99
+static size_t
+portable_strnlen(const char *s, size_t maxlen) {
+  const char *const end = (const char *)memchr(s, '\0', maxlen);
+  return (end == NULL) ? maxlen : (size_t)(end - s);
+}
+
+// Portable remake of strndup(3) for C99
 char *
 portable_strndup(const char *s, size_t n) {
   if ((s == NULL) || (n == SIZE_MAX)) {
@@ -311,6 +318,8 @@ portable_strndup(const char *s, size_t n
     return NULL;
   }
 
+  n = portable_strnlen(s, n);
+
   char *const buffer = (char *)malloc(n + 1);
   if (buffer == NULL) {
     errno = ENOMEM;
Index: expat-2.7.1/tests/handlers.c
===================================================================
--- expat-2.7.1.orig/tests/handlers.c
+++ expat-2.7.1/tests/handlers.c
@@ -10,7 +10,7 @@
    Copyright (c) 2003      Greg Stein <gstein@users.sourceforge.net>
    Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
    Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
-   Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
+   Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
    Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
    Copyright (c) 2017      Joe Orton <jorton@redhat.com>
    Copyright (c) 2017      José Gutiérrez de la Concha <jose@zeroc.com>
@@ -89,15 +89,15 @@ start_element_event_handler2(void *userD
                              const XML_Char **attr) {
   StructData *storage = (StructData *)userData;
   UNUSED_P(attr);
-  StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser),
-                     XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG);
+  StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
+                     (int)XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG);
 }
 
 void XMLCALL
 end_element_event_handler2(void *userData, const XML_Char *name) {
   StructData *storage = (StructData *)userData;
-  StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser),
-                     XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG);
+  StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
+                     (int)XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG);
 }
 
 void XMLCALL
@@ -132,7 +132,7 @@ counting_start_element_handler(void *use
     fail("ID not present");
     return;
   }
-  if (id != -1 && xcstrcmp(atts[id], info->id_name)) {
+  if (id != -1 && xcstrcmp(atts[id], info->id_name) != 0) {
     fail("ID does not have the correct name");
     return;
   }
@@ -147,7 +147,7 @@ counting_start_element_handler(void *use
       fail("Attribute not recognised");
       return;
     }
-    if (xcstrcmp(atts[1], attr->value)) {
+    if (xcstrcmp(atts[1], attr->value) != 0) {
       fail("Attribute has wrong value");
       return;
     }
@@ -1110,7 +1110,7 @@ external_entity_devaluer(XML_Parser pars
   UNUSED_P(publicId);
   if (systemId == NULL || ! xcstrcmp(systemId, XCS("bar")))
     return XML_STATUS_OK;
-  if (xcstrcmp(systemId, XCS("foo")))
+  if (xcstrcmp(systemId, XCS("foo")) != 0)
     fail("Unexpected system ID");
   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   if (ext_parser == NULL)
@@ -1276,7 +1276,7 @@ external_entity_duff_loader(XML_Parser p
   UNUSED_P(publicId);
   /* Try a few different allocation levels */
   for (i = 0; i < max_alloc_count; i++) {
-    g_allocation_count = i;
+    g_allocation_count = (int)i;
     new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
     if (new_parser != NULL) {
       XML_ParserFree(new_parser);
@@ -1552,15 +1552,16 @@ verify_attlist_decl_handler(void *userDa
                             const XML_Char *default_value, int is_required) {
   AttTest *at = (AttTest *)userData;
 
-  if (xcstrcmp(element_name, at->element_name))
+  if (xcstrcmp(element_name, at->element_name) != 0)
     fail("Unexpected element name in attribute declaration");
-  if (xcstrcmp(attr_name, at->attr_name))
+  if (xcstrcmp(attr_name, at->attr_name) != 0)
     fail("Unexpected attribute name in attribute declaration");
-  if (xcstrcmp(attr_type, at->attr_type))
+  if (xcstrcmp(attr_type, at->attr_type) != 0)
     fail("Unexpected attribute type in attribute declaration");
   if ((default_value == NULL && at->default_value != NULL)
       || (default_value != NULL && at->default_value == NULL)
-      || (default_value != NULL && xcstrcmp(default_value, at->default_value)))
+      || (default_value != NULL
+          && xcstrcmp(default_value, at->default_value) != 0))
     fail("Unexpected default value in attribute declaration");
   if (is_required != at->is_required)
     fail("Requirement mismatch in attribute declaration");
@@ -1751,7 +1752,7 @@ param_entity_match_handler(void *userDat
      * going to overflow an int.
      */
     if (value_length != (int)xcstrlen(entity_value_to_match)
-        || xcstrncmp(value, entity_value_to_match, value_length)) {
+        || xcstrncmp(value, entity_value_to_match, value_length) != 0) {
       entity_match_flag = ENTITY_MATCH_FAIL;
     } else {
       entity_match_flag = ENTITY_MATCH_SUCCESS;
Index: expat-2.7.1/tests/Makefile.in
===================================================================
--- expat-2.7.1.orig/tests/Makefile.in
+++ expat-2.7.1/tests/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# Makefile.in generated by automake 1.18.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+# Copyright (C) 1994-2025 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -102,6 +102,8 @@ am__make_running_with_option = \
   test $$has_opt = yes
 am__make_dryrun = (target_option=n; $(am__make_running_with_option))
 am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+am__rm_f = rm -f $(am__rm_f_notfound)
+am__rm_rf = rm -rf $(am__rm_f_notfound)
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -324,10 +326,9 @@ am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
 am__uninstall_files_from_dir = { \
-  test -z "$$files" \
-    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
-    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
-         $(am__cd) "$$dir" && rm -f $$files; }; \
+  { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+  || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+       $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
   }
 am__recheck_rx = ^[ 	]*:recheck:[ 	]*
 am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
@@ -415,12 +416,13 @@ am__sh_e_setup = case $$- in *e*) set +e
 # Default flags passed to test drivers.
 am__common_driver_flags = \
   --color-tests "$$am__color_tests" \
+  $$am__collect_skipped_logs \
   --enable-hard-errors "$$am__enable_hard_errors" \
   --expect-failure "$$am__expect_failure"
 # To be inserted before the command running the test.  Creates the
 # directory for the log if needed.  Stores in $dir the directory
 # containing $f, in $tst the test, in $log the log.  Executes the
-# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# developer-defined test setup AM_TESTS_ENVIRONMENT (if any), and
 # passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
 # will run the test scripts (or their associated LOG_COMPILER, if
 # thy have one).
@@ -439,6 +441,11 @@ if test -f "./$$f"; then dir=./;			\
 elif test -f "$$f"; then dir=;				\
 else dir="$(srcdir)/"; fi;				\
 tst=$$dir$$f; log='$@'; 				\
+if test -n '$(IGNORE_SKIPPED_LOGS)'; then		\
+  am__collect_skipped_logs='--collect-skipped-logs no';	\
+else							\
+  am__collect_skipped_logs='';				\
+fi;							\
 if test -n '$(DISABLE_HARD_ERRORS)'; then		\
   am__enable_hard_errors=no; 				\
 else							\
@@ -620,8 +627,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
+am__rm_f_notfound = @am__rm_f_notfound@
 am__tar = @am__tar@
 am__untar = @am__untar@
+am__xargs_n = @am__xargs_n@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -757,13 +766,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(
 $(am__aclocal_m4_deps):
 
 clean-checkPROGRAMS:
-	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
-	echo " rm -f" $$list; \
-	rm -f $$list || exit $$?; \
-	test -n "$(EXEEXT)" || exit 0; \
-	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-	echo " rm -f" $$list; \
-	rm -f $$list
+	$(am__rm_f) $(check_PROGRAMS)
+	test -z "$(EXEEXT)" || $(am__rm_f) $(check_PROGRAMS:$(EXEEXT)=)
 
 runtests$(EXEEXT): $(runtests_OBJECTS) $(runtests_DEPENDENCIES) $(EXTRA_runtests_DEPENDENCIES) 
 	@rm -f runtests$(EXEEXT)
@@ -810,7 +814,7 @@ distclean-compile:
 
 $(am__depfiles_remade):
 	@$(MKDIR_P) $(@D)
-	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+	@: >>$@
 
 am--depfiles: $(am__depfiles_remade)
 
@@ -974,7 +978,6 @@ distclean-tags:
 am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
 am--force-recheck:
 	@:
-
 $(TEST_SUITE_LOG): $(TEST_LOGS)
 	@$(am__set_TESTS_bases); \
 	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
@@ -1050,10 +1053,37 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	  result_count $$1 "XPASS:" $$xpass "$$red"; \
 	  result_count $$1 "ERROR:" $$error "$$mgn"; \
 	}; \
+	output_system_information () \
+	{ \
+          echo;                                     \
+	  { uname -a | $(AWK) '{                    \
+  printf "System information (uname -a):";          \
+  for (i = 1; i < NF; ++i)                          \
+    {                                               \
+      if (i != 2)                                   \
+        printf " %s", $$i;                          \
+    }                                               \
+  printf "\n";                                      \
+}'; } 2>&1;                                         \
+	  if test -r /etc/os-release; then          \
+	    echo "Distribution information (/etc/os-release):"; \
+	    sed 8q /etc/os-release;                 \
+	  elif test -r /etc/issue; then             \
+	    echo "Distribution information (/etc/issue):";      \
+	    cat /etc/issue;                         \
+	  fi;                                       \
+	}; \
+	please_report () \
+	{ \
+echo "Some test(s) failed.  Please report this to $(PACKAGE_BUGREPORT),";    \
+echo "together with the test-suite.log file (gzipped) and your system";      \
+echo "information.  Thanks.";                                                \
+	}; \
 	{								\
 	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
 	    $(am__rst_title);						\
 	  create_testsuite_report --no-color;				\
+	  output_system_information;                                    \
 	  echo;								\
 	  echo ".. contents:: :depth: 2";				\
 	  echo;								\
@@ -1073,26 +1103,25 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	create_testsuite_report --maybe-color;				\
 	echo "$$col$$br$$std";						\
 	if $$success; then :; else					\
-	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG) for debugging.$${std}";\
 	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
-	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	    please_report | sed -e "s/^/$${col}/" -e s/'$$'/"$${std}"/; \
 	  fi;								\
 	  echo "$$col$$br$$std";					\
 	fi;								\
 	$$success || exit 1
 
 check-TESTS: $(check_PROGRAMS)
-	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
-	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
-	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@$(am__rm_f) $(RECHECK_LOGS)
+	@$(am__rm_f) $(RECHECK_LOGS:.log=.trs)
+	@$(am__rm_f) $(TEST_SUITE_LOG)
 	@set +e; $(am__set_TESTS_bases); \
 	log_list=`for i in $$bases; do echo $$i.log; done`; \
-	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
-	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	log_list=`echo $$log_list`; \
 	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
 	exit $$?;
 recheck: all $(check_PROGRAMS)
-	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@$(am__rm_f) $(TEST_SUITE_LOG)
 	@set +e; $(am__set_TESTS_bases); \
 	bases=`for i in $$bases; do echo $$i; done \
 	         | $(am__list_recheck_tests)` || exit 1; \
@@ -1130,6 +1159,7 @@ runtests_cxx.log: runtests_cxx$(EXEEXT)
 @am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
 @am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
 distdir: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -1215,15 +1245,15 @@ install-strip:
 	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
 	fi
 mostlyclean-generic:
-	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
-	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
-	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	-$(am__rm_f) $(TEST_LOGS)
+	-$(am__rm_f) $(TEST_LOGS:.log=.trs)
+	-$(am__rm_f) $(TEST_SUITE_LOG)
 
 clean-generic:
 
 distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-$(am__rm_f) $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -1234,7 +1264,7 @@ clean-am: clean-checkPROGRAMS clean-gene
 	mostlyclean-am
 
 distclean: distclean-recursive
-		-rm -f ./$(DEPDIR)/acc_tests.Po
+	-rm -f ./$(DEPDIR)/acc_tests.Po
 	-rm -f ./$(DEPDIR)/acc_tests_cxx.Po
 	-rm -f ./$(DEPDIR)/alloc_tests.Po
 	-rm -f ./$(DEPDIR)/alloc_tests_cxx.Po
@@ -1307,7 +1337,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
-		-rm -f ./$(DEPDIR)/acc_tests.Po
+	-rm -f ./$(DEPDIR)/acc_tests.Po
 	-rm -f ./$(DEPDIR)/acc_tests_cxx.Po
 	-rm -f ./$(DEPDIR)/alloc_tests.Po
 	-rm -f ./$(DEPDIR)/alloc_tests_cxx.Po
@@ -1376,3 +1406,10 @@ uninstall-am:
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
+
+# Tell GNU make to disable its built-in pattern rules.
+%:: %,v
+%:: RCS/%,v
+%:: RCS/%
+%:: s.%
+%:: SCCS/s.%
Index: expat-2.7.1/tests/minicheck.h
===================================================================
--- expat-2.7.1.orig/tests/minicheck.h
+++ expat-2.7.1/tests/minicheck.h
@@ -134,8 +134,7 @@ void _check_set_test_info(char const *fu
 __attribute__((noreturn))
 #    endif
 #  endif
-void
-_fail(const char *file, int line, const char *msg);
+void _fail(const char *file, int line, const char *msg);
 Suite *suite_create(const char *name);
 TCase *tcase_create(const char *name);
 void suite_add_tcase(Suite *suite, TCase *tc);
Index: expat-2.7.1/tests/misc_tests.c
===================================================================
--- expat-2.7.1.orig/tests/misc_tests.c
+++ expat-2.7.1/tests/misc_tests.c
@@ -70,7 +70,7 @@ START_TEST(test_misc_alloc_create_parser
 
   /* Something this simple shouldn't need more than 10 allocations */
   for (i = 0; i < max_alloc_count; i++) {
-    g_allocation_count = i;
+    g_allocation_count = (int)i;
     g_parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
     if (g_parser != NULL)
       break;
@@ -90,7 +90,7 @@ START_TEST(test_misc_alloc_create_parser
 
   /* Try several levels of allocation */
   for (i = 0; i < max_alloc_count; i++) {
-    g_allocation_count = i;
+    g_allocation_count = (int)i;
     g_parser = XML_ParserCreate_MM(XCS("us-ascii"), &memsuite, NULL);
     if (g_parser != NULL)
       break;
@@ -211,7 +211,8 @@ START_TEST(test_misc_version) {
   if (! versions_equal(&read_version, &parsed_version))
     fail("Version mismatch");
 
-  if (xcstrcmp(version_text, XCS("expat_2.7.1"))) /* needs bump on releases */
+  if (xcstrcmp(version_text, XCS("expat_2.7.2"))
+      != 0) /* needs bump on releases */
     fail("XML_*_VERSION in expat.h out of sync?\n");
 }
 END_TEST
Index: expat-2.7.1/tests/nsalloc_tests.c
===================================================================
--- expat-2.7.1.orig/tests/nsalloc_tests.c
+++ expat-2.7.1/tests/nsalloc_tests.c
@@ -10,7 +10,7 @@
    Copyright (c) 2003      Greg Stein <gstein@users.sourceforge.net>
    Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
    Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
-   Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
+   Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
    Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
    Copyright (c) 2017      Joe Orton <jorton@redhat.com>
    Copyright (c) 2017      José Gutiérrez de la Concha <jose@zeroc.com>
@@ -83,7 +83,7 @@ START_TEST(test_nsalloc_xmlns) {
   const unsigned int max_alloc_count = 30;
 
   for (i = 0; i < max_alloc_count; i++) {
-    g_allocation_count = i;
+    g_allocation_count = (int)i;
     /* Exercise more code paths with a default handler */
     XML_SetDefaultHandler(g_parser, dummy_default_handler);
     if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
@@ -454,10 +454,15 @@ START_TEST(test_nsalloc_realloc_attribut
     nsalloc_teardown();
     nsalloc_setup();
   }
+#if XML_GE == 1
+  assert_true(
+      i == 0); // because expat_realloc relies on expat_malloc to some extent
+#else
   if (i == 0)
     fail("Parsing worked despite failing reallocations");
   else if (i == max_realloc_count)
     fail("Parsing failed at max reallocation count");
+#endif
 }
 END_TEST
 
@@ -523,7 +528,7 @@ START_TEST(test_nsalloc_realloc_binding_
   /* Now repeat with a longer URI and a duff reallocator */
   for (i = 0; i < max_realloc_count; i++) {
     XML_ParserReset(g_parser, NULL);
-    g_reallocation_count = i;
+    g_reallocation_count = (int)i;
     if (_XML_Parse_SINGLE_BYTES(g_parser, second, (int)strlen(second), XML_TRUE)
         != XML_STATUS_ERROR)
       break;
Index: expat-2.7.1/xmlwf/Makefile.in
===================================================================
--- expat-2.7.1.orig/xmlwf/Makefile.in
+++ expat-2.7.1/xmlwf/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# Makefile.in generated by automake 1.18.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+# Copyright (C) 1994-2025 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -100,6 +100,8 @@ am__make_running_with_option = \
   test $$has_opt = yes
 am__make_dryrun = (target_option=n; $(am__make_running_with_option))
 am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+am__rm_f = rm -f $(am__rm_f_notfound)
+am__rm_rf = rm -rf $(am__rm_f_notfound)
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -328,8 +330,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
+am__rm_f_notfound = @am__rm_f_notfound@
 am__tar = @am__tar@
 am__untar = @am__untar@
+am__xargs_n = @am__xargs_n@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -464,16 +468,11 @@ uninstall-binPROGRAMS:
 	`; \
 	test -n "$$list" || exit 0; \
 	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+	cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files
 
 clean-binPROGRAMS:
-	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
-	echo " rm -f" $$list; \
-	rm -f $$list || exit $$?; \
-	test -n "$(EXEEXT)" || exit 0; \
-	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-	echo " rm -f" $$list; \
-	rm -f $$list
+	$(am__rm_f) $(bin_PROGRAMS)
+	test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=)
 
 xmlwf$(EXEEXT): $(xmlwf_OBJECTS) $(xmlwf_DEPENDENCIES) $(EXTRA_xmlwf_DEPENDENCIES) 
 	@rm -f xmlwf$(EXEEXT)
@@ -492,7 +491,7 @@ distclean-compile:
 
 $(am__depfiles_remade):
 	@$(MKDIR_P) $(@D)
-	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+	@: >>$@
 
 am--depfiles: $(am__depfiles_remade)
 
@@ -630,6 +629,7 @@ cscopelist-am: $(am__tagged_files)
 
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
 distdir: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -694,8 +694,8 @@ mostlyclean-generic:
 clean-generic:
 
 distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-$(am__rm_f) $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -705,7 +705,7 @@ clean: clean-am
 clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
-		-rm -f ./$(DEPDIR)/xmlwf-@FILEMAP@.Po
+	-rm -f ./$(DEPDIR)/xmlwf-@FILEMAP@.Po
 	-rm -f ./$(DEPDIR)/xmlwf-codepage.Po
 	-rm -f ./$(DEPDIR)/xmlwf-xmlfile.Po
 	-rm -f ./$(DEPDIR)/xmlwf-xmlwf.Po
@@ -754,7 +754,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-		-rm -f ./$(DEPDIR)/xmlwf-@FILEMAP@.Po
+	-rm -f ./$(DEPDIR)/xmlwf-@FILEMAP@.Po
 	-rm -f ./$(DEPDIR)/xmlwf-codepage.Po
 	-rm -f ./$(DEPDIR)/xmlwf-xmlfile.Po
 	-rm -f ./$(DEPDIR)/xmlwf-xmlwf.Po
@@ -798,3 +798,10 @@ uninstall-am: uninstall-binPROGRAMS
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
+
+# Tell GNU make to disable its built-in pattern rules.
+%:: %,v
+%:: RCS/%,v
+%:: RCS/%
+%:: s.%
+%:: SCCS/s.%
Index: expat-2.7.1/xmlwf/unixfilemap.c
===================================================================
--- expat-2.7.1.orig/xmlwf/unixfilemap.c
+++ expat-2.7.1/xmlwf/unixfilemap.c
@@ -10,7 +10,7 @@
    Copyright (c) 2000      Clark Cooper <coopercc@users.sourceforge.net>
    Copyright (c) 2001-2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
    Copyright (c) 2006      Karl Waclawek <karl@waclawek.net>
-   Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
+   Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
    Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
    Licensed under the MIT license:
 
@@ -41,6 +41,7 @@
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
+#include <stdlib.h> // NULL
 #include <unistd.h>
 
 #ifndef MAP_FILE
@@ -93,8 +94,7 @@ filemap(const tchar *name,
     close(fd);
     return 1;
   }
-  p = (void *)mmap((void *)0, (size_t)nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE,
-                   fd, (off_t)0);
+  p = mmap(NULL, nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, (off_t)0);
   if (p == (void *)-1) {
     tperror(name);
     close(fd);
Index: expat-2.7.1/xmlwf/xmlfile.c
===================================================================
--- expat-2.7.1.orig/xmlwf/xmlfile.c
+++ expat-2.7.1/xmlwf/xmlfile.c
@@ -11,7 +11,7 @@
    Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
    Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net>
    Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
-   Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
+   Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
    Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
    Copyright (c) 2019      David Loffredo <loffredo@steptools.com>
    Copyright (c) 2021      Donghee Na <donghee.na@python.org>
@@ -56,12 +56,19 @@
 #include "xmltchar.h"
 #include "filemap.h"
 
+/* Function "read": */
 #if defined(_MSC_VER)
 #  include <io.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
+/* https://msdn.microsoft.com/en-us/library/wyssk1bs(v=vs.100).aspx */
+#  define EXPAT_read _read
+#  define EXPAT_read_count_t int
+#  define EXPAT_read_req_t unsigned int
+#else /* POSIX */
 #  include <unistd.h>
+/* https://pubs.opengroup.org/onlinepubs/009695399/functions/read.html */
+#  define EXPAT_read read
+#  define EXPAT_read_count_t ssize_t
+#  define EXPAT_read_req_t size_t
 #endif
 
 #ifndef O_BINARY
@@ -192,7 +199,7 @@ processStream(const XML_Char *filename,
     }
   }
   for (;;) {
-    int nread;
+    EXPAT_read_count_t nread;
     char *buf = (char *)XML_GetBuffer(parser, g_read_size_bytes);
     if (! buf) {
       if (filename != NULL)
@@ -201,14 +208,14 @@ processStream(const XML_Char *filename,
                filename != NULL ? filename : T("xmlwf"));
       return 0;
     }
-    nread = read(fd, buf, g_read_size_bytes);
+    nread = EXPAT_read(fd, buf, (EXPAT_read_req_t)g_read_size_bytes);
     if (nread < 0) {
       tperror(filename != NULL ? filename : T("STDIN"));
       if (filename != NULL)
         close(fd);
       return 0;
     }
-    if (XML_ParseBuffer(parser, nread, nread == 0) == XML_STATUS_ERROR) {
+    if (XML_ParseBuffer(parser, (int)nread, nread == 0) == XML_STATUS_ERROR) {
       reportError(parser, filename != NULL ? filename : T("STDIN"));
       if (filename != NULL)
         close(fd);
Index: expat-2.7.1/xmlwf/xmlwf.c
===================================================================
--- expat-2.7.1.orig/xmlwf/xmlwf.c
+++ expat-2.7.1/xmlwf/xmlwf.c
@@ -11,7 +11,7 @@
    Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
    Copyright (c) 2004-2009 Karl Waclawek <karl@waclawek.net>
    Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
-   Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
+   Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
    Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
    Copyright (c) 2019      David Loffredo <loffredo@steptools.com>
    Copyright (c) 2020      Joe Orton <jorton@redhat.com>
@@ -305,7 +305,7 @@ static XML_Char *
 xcsdup(const XML_Char *s) {
   XML_Char *result;
   int count = 0;
-  int numBytes;
+  size_t numBytes;
 
   /* Get the length of the string, including terminator */
   while (s[count++] != 0) {
@@ -913,11 +913,11 @@ usage(const XML_Char *prog, int rc) {
       T("  -t             write no XML output for [t]iming of plain parsing\n")
       T("  -N             enable adding doctype and [n]otation declarations\n")
       T("\n")
-      T("billion laughs attack protection:\n")
+      T("amplification attack protection (e.g. billion laughs):\n")
       T("  NOTE: If you ever need to increase these values for non-attack payload, please file a bug report.\n")
       T("\n")
       T("  -a FACTOR      set maximum tolerated [a]mplification factor (default: 100.0)\n")
-      T("  -b BYTES       set number of output [b]ytes needed to activate (default: 8 MiB)\n")
+      T("  -b BYTES       set number of output [b]ytes needed to activate (default: 8 MiB/64 MiB)\n")
       T("\n")
       T("reparse deferral:\n")
       T("  -q             disable reparse deferral, and allow [q]uadratic parse runtime with large tokens\n")
@@ -926,6 +926,16 @@ usage(const XML_Char *prog, int rc) {
       T("  -h, --help     show this [h]elp message and exit\n")
       T("  -v, --version  show program's [v]ersion number and exit\n")
       T("\n")
+      T("environment variables:\n")
+      T("  EXPAT_ACCOUNTING_DEBUG=(0|1|2|3)\n")
+      T("                 Control verbosity of accounting debugging (default: 0)\n")
+      T("  EXPAT_ENTITY_DEBUG=(0|1)\n")
+      T("                 Control verbosity of entity debugging (default: 0)\n")
+      T("  EXPAT_ENTROPY_DEBUG=(0|1)\n")
+      T("                 Control verbosity of entropy debugging (default: 0)\n")
+      T("  EXPAT_MALLOC_DEBUG=(0|1|2)\n")
+      T("                 Control verbosity of allocation tracker (default: 0)\n")
+      T("\n")
       T("exit status:\n")
       T("  0              the input files are well-formed and the output (if requested) was written successfully\n")
       T("  1              could not allocate data structures, signals a serious problem with execution environment\n")
@@ -1171,12 +1181,15 @@ tmain(int argc, XML_Char **argv) {
 #if XML_GE == 1
       XML_SetBillionLaughsAttackProtectionMaximumAmplification(
           parser, attackMaximumAmplification);
+      XML_SetAllocTrackerMaximumAmplification(parser,
+                                              attackMaximumAmplification);
 #endif
     }
     if (attackThresholdGiven) {
 #if XML_GE == 1
       XML_SetBillionLaughsAttackProtectionActivationThreshold(
           parser, attackThresholdBytes);
+      XML_SetAllocTrackerActivationThreshold(parser, attackThresholdBytes);
 #else
       (void)attackThresholdBytes; // silence -Wunused-but-set-variable
 #endif
Index: expat-2.7.1/xmlwf/xmlwf_helpgen.py
===================================================================
--- expat-2.7.1.orig/xmlwf/xmlwf_helpgen.py
+++ expat-2.7.1/xmlwf/xmlwf_helpgen.py
@@ -6,7 +6,7 @@
 #                      \___/_/\_\ .__/ \__,_|\__|
 #                               |_| XML parser
 #
-# Copyright (c) 2019-2023 Sebastian Pipping <sebastian@pipping.org>
+# Copyright (c) 2019-2025 Sebastian Pipping <sebastian@pipping.org>
 # Copyright (c) 2021      Tim Bray <tbray@textuality.com>
 # Licensed under the MIT license:
 #
@@ -32,6 +32,16 @@
 import argparse
 
 epilog = """
+environment variables:
+  EXPAT_ACCOUNTING_DEBUG=(0|1|2|3)
+                 Control verbosity of accounting debugging (default: 0)
+  EXPAT_ENTITY_DEBUG=(0|1)
+                 Control verbosity of entity debugging (default: 0)
+  EXPAT_ENTROPY_DEBUG=(0|1)
+                 Control verbosity of entropy debugging (default: 0)
+  EXPAT_MALLOC_DEBUG=(0|1|2)
+                 Control verbosity of allocation tracker (default: 0)
+
 exit status:
   0              the input files are well-formed and the output (if requested) was written successfully
   1              could not allocate data structures, signals a serious problem with execution environment
@@ -74,16 +84,16 @@ output_mode.add_argument('-m', action='s
 output_mode.add_argument('-t', action='store_true', help='write no XML output for [t]iming of plain parsing')
 output_related.add_argument('-N', action='store_true', help='enable adding doctype and [n]otation declarations')
 
-billion_laughs = parser.add_argument_group('billion laughs attack protection',
+billion_laughs = parser.add_argument_group('amplification attack protection (e.g. billion laughs)',
                                            description='NOTE: '
                                                        'If you ever need to increase these values '
                                                        'for non-attack payload, please file a bug report.')
 billion_laughs.add_argument('-a', metavar='FACTOR',
                             help='set maximum tolerated [a]mplification factor (default: 100.0)')
-billion_laughs.add_argument('-b', metavar='BYTES', help='set number of output [b]ytes needed to activate (default: 8 MiB)')
+billion_laughs.add_argument('-b', metavar='BYTES', help='set number of output [b]ytes needed to activate (default: 8 MiB/64 MiB)')
 
 reparse_deferral = parser.add_argument_group('reparse deferral')
-reparse_deferral.add_argument('-q', metavar='FACTOR',
+reparse_deferral.add_argument('-q', action='store_true',
                             help='disable reparse deferral, and allow [q]uadratic parse runtime with large tokens')
 
 parser.add_argument('files', metavar='FILE', nargs='*', help='file to process (default: STDIN)')
openSUSE Build Service is sponsored by