git: 78f39a55b205 - stable/14 - MFC: MFV: libexpat 2.7.2

From: Xin LI <delphij_at_FreeBSD.org>
Date: Mon, 22 Sep 2025 05:56:18 UTC
The branch stable/14 has been updated by delphij:

URL: https://cgit.FreeBSD.org/src/commit/?id=78f39a55b205eace7f0a308066864aef1ec925ea

commit 78f39a55b205eace7f0a308066864aef1ec925ea
Author:     Xin LI <delphij@FreeBSD.org>
AuthorDate: 2025-09-19 02:43:17 +0000
Commit:     Xin LI <delphij@FreeBSD.org>
CommitDate: 2025-09-22 05:56:02 +0000

    MFC: MFV: libexpat 2.7.2
    
    (cherry picked from commit 627b778d9e6b603a44a010d22d823ca7c392b363)
---
 contrib/expat/Changes                       |  81 +++-
 contrib/expat/Makefile.am                   |   7 +-
 contrib/expat/Makefile.in                   | 128 +++---
 contrib/expat/README.md                     |   6 +-
 contrib/expat/configure.ac                  |  22 +-
 contrib/expat/doc/Makefile.in               |  29 +-
 contrib/expat/doc/reference.html            | 136 +++++-
 contrib/expat/doc/xmlwf.1                   |  30 +-
 contrib/expat/doc/xmlwf.xml                 |  28 +-
 contrib/expat/examples/Makefile.in          |  35 +-
 contrib/expat/expat_config.h.in             |  12 +-
 contrib/expat/fuzz/xml_lpm_fuzzer.cpp       |   6 +-
 contrib/expat/fuzz/xml_parse_fuzzer.c       |  20 +-
 contrib/expat/fuzz/xml_parsebuffer_fuzzer.c |  24 +-
 contrib/expat/lib/Makefile.in               |  49 ++-
 contrib/expat/lib/expat.h                   |  61 ++-
 contrib/expat/lib/expat_external.h          | 123 +++---
 contrib/expat/lib/internal.h                |   8 +
 contrib/expat/lib/xmlparse.c                | 658 +++++++++++++++++++++-------
 contrib/expat/lib/xmlrole.h                 |  34 +-
 contrib/expat/lib/xmltok.c                  |   4 +-
 contrib/expat/lib/xmltok.h                  | 226 +++++-----
 contrib/expat/tests/Makefile.in             |  99 +++--
 contrib/expat/tests/alloc_tests.c           | 220 +++++++++-
 contrib/expat/tests/basic_tests.c           |   8 +-
 contrib/expat/tests/benchmark/Makefile.in   |  35 +-
 contrib/expat/tests/common.c                |  11 +-
 contrib/expat/tests/handlers.c              |  29 +-
 contrib/expat/tests/minicheck.h             |   3 +-
 contrib/expat/tests/misc_tests.c            |   7 +-
 contrib/expat/tests/nsalloc_tests.c         |  11 +-
 contrib/expat/xmlwf/Makefile.in             |  37 +-
 contrib/expat/xmlwf/unixfilemap.c           |   6 +-
 contrib/expat/xmlwf/xmlfile.c               |  21 +-
 contrib/expat/xmlwf/xmlwf.c                 |  21 +-
 contrib/expat/xmlwf/xmlwf_helpgen.py        |  18 +-
 lib/libexpat/expat_config.h                 |  18 +-
 lib/libexpat/libbsdxml.3                    |   2 +-
 38 files changed, 1615 insertions(+), 658 deletions(-)

diff --git a/contrib/expat/Changes b/contrib/expat/Changes
index 9d6c64b6a460..092252ed1fa3 100644
--- a/contrib/expat/Changes
+++ b/contrib/expat/Changes
@@ -15,12 +15,16 @@
 !!   ClusterFuzz findings with few-days-max response times in communication  !!
 !!   in order to (1) have a sound fix ready before the end of a 90 days      !!
 !!   grace period and (2) in a sustainable manner,                           !!
-!! - helping CPython Expat bindings with supporting Expat's billion laughs   !!
+!! - helping CPython Expat bindings with supporting Expat's amplification    !!
 !!   attack protection API (https://github.com/python/cpython/issues/90949): !!
+!!   - XML_SetAllocTrackerActivationThreshold                                !!
+!!   - XML_SetAllocTrackerMaximumAmplification                               !!
 !!   - XML_SetBillionLaughsAttackProtectionActivationThreshold               !!
 !!   - XML_SetBillionLaughsAttackProtectionMaximumAmplification              !!
 !! - helping Perl's XML::Parser Expat bindings with supporting Expat's       !!
 !!   security API (https://github.com/cpan-authors/XML-Parser/issues/102):   !!
+!!   - XML_SetAllocTrackerActivationThreshold                                !!
+!!   - XML_SetAllocTrackerMaximumAmplification                               !!
 !!   - XML_SetBillionLaughsAttackProtectionActivationThreshold               !!
 !!   - XML_SetBillionLaughsAttackProtectionMaximumAmplification              !!
 !!   - XML_SetReparseDeferralEnabled                                         !!
@@ -37,6 +41,79 @@
 !! THANK YOU!                        Sebastian Pipping -- Berlin, 2024-03-09 !!
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
+Release 2.7.2 Tue September 16 2025
+        Security fixes:
+     #1018 #1034  CVE-2025-59375 -- Disallow use of disproportional amounts of
+                    dynamic memory from within an Expat parser (e.g. previously
+                    a ~250 KiB sized document was able to cause allocation of
+                    ~800 MiB from the heap, i.e. an "amplification" of factor
+                    ~3,300); once a threshold (that defaults to 64 MiB) is
+                    reached, a maximum amplification factor (that defaults to
+                    100.0) is enforced, and violating documents are rejected
+                    with an out-of-memory error.
+                    There are two new API functions to fine-tune this new
+                    behavior:
+                      - XML_SetAllocTrackerActivationThreshold
+                      - XML_SetAllocTrackerMaximumAmplification .
+                    If you ever need to increase these defaults for non-attack
+                    XML payload, please file a bug report with libexpat.
+                      There is also a new environment variable
+                    EXPAT_MALLOC_DEBUG=(0|1|2) to control the verbosity
+                    of allocations debugging at runtime, disabled by default.
+                      Known impact is (reliable and easy) denial of service:
+                    CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H/E:H/RL:O/RC:C
+                    (Base Score: 7.5, Temporal Score: 7.2)
+                    Please note that a layer of compression around XML can
+                    significantly reduce the minimum attack payload size.
+                      Distributors intending to backport (or cherry-pick) the
+                    fix need to copy 99% of the related pull request, not just
+                    the "lib: Implement tracking of dynamic memory allocations"
+                    commit, to not end up with a state that literally does both
+                    too much and too little at the same time. Appending ".diff"
+                    to the pull request URL could be of help.
+
+        Other changes:
+     #1008 #1017  Autotools: Sync CMake templates with CMake 3.31 for macOS
+           #1007  CMake: Drop support for CMake <3.15
+           #1004  CMake: Fix off_t detection for -Werror
+           #1007  CMake|Windows: Fix -DEXPAT_MSVC_STATIC_CRT=ON
+           #1013  Windows: Drop support for Visual Studio <=16.0/2019
+           #1026  xmlwf: Mention supported environment variables in
+                    --help output
+           #1024  xmlwf: Fix (internal) help generator
+           #1034  docs: Promote the contract to call function
+                    XML_FreeContentModel when registering a custom
+                    element declaration handler (via a call to function
+                    XML_SetElementDeclHandler)
+           #1027  docs: Add missing <p>..</p> wrap
+            #994  docs: Drop AppVeyor badge
+           #1000  tests: Fix portable_strndup
+           #1036  Drop casts around malloc/free/realloc that C99 does not need
+           #1010  Replace empty for-loops with while loops
+           #1011  Add const with internal XmlInitUnknownEncodingNS
+       #14 #1037  Drop an OpenVMS support leftover
+      #999 #1001  Address more clang-tidy warnings
+     #1030 #1038  Version info bumped from 11:2:10 (libexpat*.so.1.10.2)
+                    to 12:0:11 (libexpat*.so.1.11.0); see https://verbump.de/
+                    for what these numbers do
+
+        Infrastructure:
+           #1003  CI: Cover compilation on FreeBSD
+     #1009 #1035  CI: Upgrade Clang from 19 to 21
+           #1031  CI: Make calling Cppcheck without --suppress=objectIndex
+                    and --suppress=unknownMacro possible
+           #1013  CI|Windows: Get off of deprecated image "windows-2019"
+  #1008 #1017 ..
+     #1023 #1025  CI: Adapt to breaking changes in GitHub Actions
+
+        Special thanks to:
+            Alexander Bluhm
+            Neil Pang
+            Theo Buehler
+                 and
+            OSS-Fuzz / ClusterFuzz
+            Perl XML::Parser
+
 Release 2.7.1 Thu March 27 2025
         Bug fixes:
        #980 #989  Restore event pointer behavior from Expat 2.6.4
@@ -54,7 +131,7 @@ Release 2.7.1 Thu March 27 2025
        #983 #984  Fix printf format specifiers for 32bit Emscripten
             #992  docs: Promote OpenSSF Best Practices self-certification
             #978  tests/benchmark: Resolve mistaken double close
-            #986  Address compiler warnings
+            #986  Address Frama-C warnings
        #990 #993  Version info bumped from 11:1:10 (libexpat*.so.1.10.1)
                     to 11:2:10 (libexpat*.so.1.10.2); see https://verbump.de/
                     for what these numbers do
diff --git a/contrib/expat/Makefile.am b/contrib/expat/Makefile.am
index c20531a8d6c6..d612d432becb 100644
--- a/contrib/expat/Makefile.am
+++ b/contrib/expat/Makefile.am
@@ -58,10 +58,8 @@ pkgconfig_DATA = expat.pc
 pkgconfigdir = $(libdir)/pkgconfig
 
 
-dist_cmake_DATA = \
-    cmake/autotools/expat.cmake
-
 nodist_cmake_DATA = \
+    cmake/autotools/expat.cmake \
     cmake/autotools/expat-config-version.cmake \
     cmake/autotools/expat-noconfig.cmake \
     cmake/expat-config.cmake
@@ -70,6 +68,9 @@ cmakedir = $(libdir)/cmake/expat-@PACKAGE_VERSION@
 
 
 _EXTRA_DIST_CMAKE = \
+    cmake/autotools/expat__linux.cmake.in \
+    cmake/autotools/expat__macos.cmake.in \
+    cmake/autotools/expat__windows.cmake.in \
     cmake/autotools/expat-noconfig__linux.cmake.in \
     cmake/autotools/expat-noconfig__macos.cmake.in \
     cmake/autotools/expat-noconfig__windows.cmake.in \
diff --git a/contrib/expat/Makefile.in b/contrib/expat/Makefile.in
index 069ec4047eea..b799591f2fc2 100644
--- a/contrib/expat/Makefile.in
+++ b/contrib/expat/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,
@@ -105,6 +105,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@
@@ -145,12 +147,13 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
-	$(am__configure_deps) $(dist_cmake_DATA) $(am__DIST_COMMON)
+	$(am__configure_deps) $(am__DIST_COMMON)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = expat_config.h
 CONFIG_CLEAN_FILES = expat.pc cmake/expat-config.cmake \
+	cmake/autotools/expat.cmake \
 	cmake/autotools/expat-config-version.cmake \
 	cmake/autotools/expat-noconfig.cmake run.sh
 CONFIG_CLEAN_VPATH_FILES =
@@ -203,14 +206,12 @@ 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)$(cmakedir)" "$(DESTDIR)$(cmakedir)" \
-	"$(DESTDIR)$(pkgconfigdir)"
-DATA = $(dist_cmake_DATA) $(nodist_cmake_DATA) $(pkgconfig_DATA)
+am__installdirs = "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(pkgconfigdir)"
+DATA = $(nodist_cmake_DATA) $(pkgconfig_DATA)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
   distclean-recursive maintainer-clean-recursive
 am__recursive_targets = \
@@ -256,8 +257,8 @@ distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
 am__remove_distdir = \
   if test -d "$(distdir)"; then \
-    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
-      && rm -rf "$(distdir)" \
+    find "$(distdir)" -type d ! -perm -700 -exec chmod u+rwx {} ';' \
+      ; rm -rf "$(distdir)" \
       || { sleep 5 && rm -rf "$(distdir)"; }; \
   else :; fi
 am__post_remove_distdir = $(am__remove_distdir)
@@ -288,14 +289,16 @@ am__relativize = \
   reldir="$$dir2"
 DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).tar.lz \
 	$(distdir).tar.xz
-GZIP_ENV = --best
+GZIP_ENV = -9
 DIST_TARGETS = dist-lzip dist-xz dist-bzip2 dist-gzip
 # Exists only to be overridden by the user if desired.
 AM_DISTCHECK_DVI_TARGET = dvi
 distuninstallcheck_listfiles = find . -type f -print
 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
   | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
-distcleancheck_listfiles = find . -type f -print
+distcleancheck_listfiles = \
+  find . \( -type f -a \! \
+            \( -name .nfs* -o -name .smb* -o -name .__afs* \) \) -print
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AM_CFLAGS = @AM_CFLAGS@
@@ -403,8 +406,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@
@@ -458,16 +463,17 @@ LIBTOOLFLAGS = --verbose
 SUBDIRS = lib $(am__append_1) $(am__append_2) $(am__append_3)
 pkgconfig_DATA = expat.pc
 pkgconfigdir = $(libdir)/pkgconfig
-dist_cmake_DATA = \
-    cmake/autotools/expat.cmake
-
 nodist_cmake_DATA = \
+    cmake/autotools/expat.cmake \
     cmake/autotools/expat-config-version.cmake \
     cmake/autotools/expat-noconfig.cmake \
     cmake/expat-config.cmake
 
 cmakedir = $(libdir)/cmake/expat-@PACKAGE_VERSION@
 _EXTRA_DIST_CMAKE = \
+    cmake/autotools/expat__linux.cmake.in \
+    cmake/autotools/expat__macos.cmake.in \
+    cmake/autotools/expat__windows.cmake.in \
     cmake/autotools/expat-noconfig__linux.cmake.in \
     cmake/autotools/expat-noconfig__macos.cmake.in \
     cmake/autotools/expat-noconfig__windows.cmake.in \
@@ -552,12 +558,12 @@ expat_config.h: stamp-h1
 	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
 
 stamp-h1: $(srcdir)/expat_config.h.in $(top_builddir)/config.status
-	@rm -f stamp-h1
-	cd $(top_builddir) && $(SHELL) ./config.status expat_config.h
+	$(AM_V_at)rm -f stamp-h1
+	$(AM_V_GEN)cd $(top_builddir) && $(SHELL) ./config.status expat_config.h
 $(srcdir)/expat_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
-	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
-	rm -f stamp-h1
-	touch $@
+	$(AM_V_GEN)($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	$(AM_V_at)rm -f stamp-h1
+	$(AM_V_at)touch $@
 
 distclean-hdr:
 	-rm -f expat_config.h stamp-h1
@@ -565,6 +571,8 @@ expat.pc: $(top_builddir)/config.status $(srcdir)/expat.pc.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 cmake/expat-config.cmake: $(top_builddir)/config.status $(top_srcdir)/cmake/expat-config.cmake.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
+cmake/autotools/expat.cmake: $(top_builddir)/config.status 
+	cd $(top_builddir) && $(SHELL) ./config.status $@
 cmake/autotools/expat-config-version.cmake: $(top_builddir)/config.status $(top_srcdir)/cmake/autotools/expat-config-version.cmake.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 cmake/autotools/expat-noconfig.cmake: $(top_builddir)/config.status 
@@ -580,27 +588,6 @@ clean-libtool:
 
 distclean-libtool:
 	-rm -f libtool config.lt
-install-dist_cmakeDATA: $(dist_cmake_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(dist_cmake_DATA)'; test -n "$(cmakedir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(cmakedir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(cmakedir)" || exit 1; \
-	fi; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(cmakedir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(cmakedir)" || exit $$?; \
-	done
-
-uninstall-dist_cmakeDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(dist_cmake_DATA)'; test -n "$(cmakedir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(cmakedir)'; $(am__uninstall_files_from_dir)
 install-nodist_cmakeDATA: $(nodist_cmake_DATA)
 	@$(NORMAL_INSTALL)
 	@list='$(nodist_cmake_DATA)'; test -n "$(cmakedir)" || list=; \
@@ -749,12 +736,13 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
 distdir: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) distdir-am
 
 distdir-am: $(DISTFILES)
 	$(am__remove_distdir)
-	test -d "$(distdir)" || mkdir "$(distdir)"
+	$(AM_V_at)$(MKDIR_P) "$(distdir)"
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	list='$(DISTFILES)'; \
@@ -822,6 +810,10 @@ dist-gzip: distdir
 dist-bzip2: distdir
 	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
 	$(am__post_remove_distdir)
+
+dist-bzip3: distdir
+	tardir=$(distdir) && $(am__tar) | bzip3 -c >$(distdir).tar.bz3
+	$(am__post_remove_distdir)
 dist-lzip: distdir
 	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
 	$(am__post_remove_distdir)
@@ -862,9 +854,11 @@ dist dist-all:
 distcheck: dist
 	case '$(DIST_ARCHIVES)' in \
 	*.tar.gz*) \
-	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
+	  eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
 	*.tar.bz2*) \
 	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.bz3*) \
+	  bzip3 -dc $(distdir).tar.bz3 | $(am__untar) ;;\
 	*.tar.lz*) \
 	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
 	*.tar.xz*) \
@@ -872,7 +866,7 @@ distcheck: dist
 	*.tar.Z*) \
 	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
 	*.shar.gz*) \
-	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
+	  eval GZIP= gzip -dc $(distdir).shar.gz | unshar ;;\
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
 	*.tar.zst*) \
@@ -948,7 +942,7 @@ check: check-recursive
 all-am: Makefile $(DATA) expat_config.h
 installdirs: installdirs-recursive
 installdirs-am:
-	for dir in "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(pkgconfigdir)"; do \
+	for dir in "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(pkgconfigdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-recursive
@@ -975,8 +969,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"
@@ -1003,8 +997,7 @@ info: info-recursive
 
 info-am:
 
-install-data-am: install-dist_cmakeDATA install-nodist_cmakeDATA \
-	install-pkgconfigDATA
+install-data-am: install-nodist_cmakeDATA install-pkgconfigDATA
 
 install-dvi: install-dvi-recursive
 
@@ -1050,29 +1043,27 @@ ps: ps-recursive
 
 ps-am:
 
-uninstall-am: uninstall-dist_cmakeDATA uninstall-nodist_cmakeDATA \
-	uninstall-pkgconfigDATA
+uninstall-am: uninstall-nodist_cmakeDATA uninstall-pkgconfigDATA
 
 .MAKE: $(am__recursive_targets) all install-am install-strip
 
 .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
 	am--refresh check check-am clean clean-cscope clean-generic \
 	clean-libtool cscope cscopelist-am ctags ctags-am dist \
-	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
-	dist-xz dist-zip dist-zstd distcheck distclean \
+	dist-all dist-bzip2 dist-bzip3 dist-gzip dist-lzip dist-shar \
+	dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \
 	distclean-generic distclean-hdr distclean-libtool \
 	distclean-tags distcleancheck distdir distuninstallcheck dvi \
 	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dist_cmakeDATA \
-	install-dvi install-dvi-am install-exec install-exec-am \
-	install-html install-html-am install-info install-info-am \
-	install-man install-nodist_cmakeDATA install-pdf \
-	install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
-	install-strip installcheck installcheck-am installdirs \
-	installdirs-am maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
-	ps ps-am tags tags-am uninstall uninstall-am \
-	uninstall-dist_cmakeDATA uninstall-nodist_cmakeDATA \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man \
+	install-nodist_cmakeDATA install-pdf install-pdf-am \
+	install-pkgconfigDATA install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs installdirs-am \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-nodist_cmakeDATA \
 	uninstall-pkgconfigDATA
 
 .PRECIOUS: Makefile
@@ -1149,3 +1140,10 @@ qa:
 # 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.%
diff --git a/contrib/expat/README.md b/contrib/expat/README.md
index 77c6bf27d307..fdaaf459e204 100644
--- a/contrib/expat/README.md
+++ b/contrib/expat/README.md
@@ -1,5 +1,4 @@
 [![Run Linux CI tasks](https://github.com/libexpat/libexpat/actions/workflows/linux.yml/badge.svg)](https://github.com/libexpat/libexpat/actions/workflows/linux.yml)
-[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/libexpat/libexpat?svg=true)](https://ci.appveyor.com/project/libexpat/libexpat)
 [![Packaging status](https://repology.org/badge/tiny-repos/expat.svg)](https://repology.org/metapackage/expat/versions)
 [![Downloads SourceForge](https://img.shields.io/sourceforge/dt/expat?label=Downloads%20SourceForge)](https://sourceforge.net/projects/expat/files/)
 [![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
@@ -12,7 +11,7 @@
 > at the top of the `Changes` file.
 
 
-# Expat, Release 2.7.1
+# Expat, Release 2.7.2
 
 This is Expat, a C99 library for parsing
 [XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by
@@ -27,7 +26,8 @@ Expat supports the following C99 compilers:
 
 - GNU GCC >=4.5 (for use from C) or GNU GCC >=4.8.1 (for use from C++)
 - LLVM Clang >=3.5
-- Microsoft Visual Studio >=16.0/2019 (rolling `${today} minus 5 years`)
+- Microsoft Visual Studio >=17.0/2022
+  (the oldest version supported by the [official GitHub Actions Windows images](https://github.com/actions/runner-images))
 
 Windows users can use the
 [`expat-win32bin-*.*.*.{exe,zip}` download](https://github.com/libexpat/libexpat/releases),
diff --git a/contrib/expat/configure.ac b/contrib/expat/configure.ac
index 0c88b8867019..b9966eabcd60 100644
--- a/contrib/expat/configure.ac
+++ b/contrib/expat/configure.ac
@@ -84,9 +84,9 @@ dnl
 dnl If the API changes incompatibly set LIBAGE back to 0
 dnl
 
-LIBCURRENT=11  # sync
-LIBREVISION=2  # with
-LIBAGE=10      # CMakeLists.txt!
+LIBCURRENT=12  # sync
+LIBREVISION=0  # with
+LIBAGE=11      # CMakeLists.txt!
 
 AC_CONFIG_HEADERS([expat_config.h])
 AH_TOP([#ifndef EXPAT_CONFIG_H
@@ -440,12 +440,22 @@ AC_MSG_RESULT([${CMAKE_SHARED_LIBRARY_PREFIX}])
 AC_SUBST([CMAKE_SHARED_LIBRARY_PREFIX])
 
 AS_CASE("${host_os}",
-  [darwin*], [CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__macos.cmake.in],
-  [mingw*|cygwin*], [CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__windows.cmake.in],
-  [CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__linux.cmake.in])
+  [darwin*], [
+    CMAKE_SOURCE=cmake/autotools/expat__macos.cmake.in
+    CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__macos.cmake.in
+  ],
+  [mingw*|cygwin*], [
+    CMAKE_SOURCE=cmake/autotools/expat__windows.cmake.in
+    CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__windows.cmake.in
+  ],
+  [
+    CMAKE_SOURCE=cmake/autotools/expat__linux.cmake.in
+    CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__linux.cmake.in
+  ])
 AC_CONFIG_FILES([Makefile]
   [expat.pc]
   [cmake/expat-config.cmake]
+  [cmake/autotools/expat.cmake:${CMAKE_SOURCE}]
   [cmake/autotools/expat-config-version.cmake]
   [cmake/autotools/expat-noconfig.cmake:${CMAKE_NOCONFIG_SOURCE}]
   [doc/Makefile]
diff --git a/contrib/expat/doc/Makefile.in b/contrib/expat/doc/Makefile.in
index 72deb0565d94..13be5107f89b 100644
--- a/contrib/expat/doc/Makefile.in
+++ b/contrib/expat/doc/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@
@@ -184,10 +186,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); }; \
   }
 man1dir = $(mandir)/man1
 am__installdirs = "$(DESTDIR)$(man1dir)"
@@ -303,8 +304,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@
@@ -442,6 +445,7 @@ ctags CTAGS:
 cscope cscopelist:
 
 @WITH_DISTRIBUTABLE_MANPAGE_TRUE@dist-hook:
+
 distdir: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -507,11 +511,11 @@ install-strip:
 mostlyclean-generic:
 
 clean-generic:
-	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+	-$(am__rm_f) $(CLEANFILES)
 
 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"
@@ -616,3 +620,10 @@ uninstall-man: uninstall-man1
 # 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.%
diff --git a/contrib/expat/doc/reference.html b/contrib/expat/doc/reference.html
index 2b3bd39580a9..12b12b92ff6d 100644
--- a/contrib/expat/doc/reference.html
+++ b/contrib/expat/doc/reference.html
@@ -52,7 +52,7 @@
   <div>
     <h1>
       The Expat XML Parser
-      <small>Release 2.7.1</small>
+      <small>Release 2.7.2</small>
     </h1>
   </div>
 <div class="content">
@@ -157,6 +157,8 @@ interface.</p>
       <ul>
         <li><a href="#XML_SetBillionLaughsAttackProtectionMaximumAmplification">XML_SetBillionLaughsAttackProtectionMaximumAmplification</a></li>
         <li><a href="#XML_SetBillionLaughsAttackProtectionActivationThreshold">XML_SetBillionLaughsAttackProtectionActivationThreshold</a></li>
+        <li><a href="#XML_SetAllocTrackerMaximumAmplification">XML_SetAllocTrackerMaximumAmplification</a></li>
+        <li><a href="#XML_SetAllocTrackerActivationThreshold">XML_SetAllocTrackerActivationThreshold</a></li>
         <li><a href="#XML_SetReparseDeferralEnabled">XML_SetReparseDeferralEnabled</a></li>
       </ul>
     </li>
@@ -319,7 +321,7 @@ directions in the next section. Otherwise if you have Microsoft's
 Developer Studio installed,
 you can use CMake to generate a <code>.sln</code> file, e.g.
 <code>
-cmake -G"Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=RelWithDebInfo .
+cmake -G"Visual Studio 17 2022" -DCMAKE_BUILD_TYPE=RelWithDebInfo .
 </code>, and build Expat using <code>msbuild /m expat.sln</code> after.</p>
 
 <p>Alternatively, you may download the Win32 binary package that
@@ -1905,7 +1907,7 @@ struct XML_cp {
 <p>Sets a handler for element declarations in a DTD. The handler gets
 called with the name of the element in the declaration and a pointer
 to a structure that contains the element model. It's the user code's 
-responsibility to free model when finished with it. See <code>
+responsibility to free model when finished with via a call to <code>
 <a href="#XML_FreeContentModel">XML_FreeContentModel</a></code>.
 There is no need to free the model from the handler, it can be kept
 around and freed at a later stage.</p>
@@ -2198,13 +2200,13 @@ XML_SetBillionLaughsAttackProtectionMaximumAmplification(XML_Parser p,
     returns <code>XML_TRUE</code> upon success and <code>XML_FALSE</code> upon error.
   </p>
 
-  The amplification factor is calculated as ..
-  <pre>
-    amplification := (direct + indirect) / direct
-  </pre>
-  .. while parsing, whereas
-  <code>direct</code> is the number of bytes read from the primary document in parsing and
-  <code>indirect</code> is the number of bytes added by expanding entities and reading of external DTD files, combined.
+  <p>The amplification factor is calculated as ..</p>
+  <pre>amplification := (direct + indirect) / direct</pre>
+  <p>
+    .. while parsing, whereas
+    <code>direct</code> is the number of bytes read from the primary document in parsing and
+    <code>indirect</code> is the number of bytes added by expanding entities and reading of external DTD files, combined.
+  </p>
 
   <p>For a call to <code>XML_SetBillionLaughsAttackProtectionMaximumAmplification</code> to succeed:</p>
   <ul>
@@ -2267,6 +2269,120 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(XML_Parser p,
   </p>
 </div>
 
+<h4 id="XML_SetAllocTrackerMaximumAmplification">XML_SetAllocTrackerMaximumAmplification</h4>
+<pre class="fcndec">
+/* Added in Expat 2.7.2. */
+XML_Bool
+XML_SetAllocTrackerMaximumAmplification(XML_Parser p,
+                                        float maximumAmplificationFactor);
+</pre>
+<div class="fcndef">
+  <p>
+    Sets the maximum tolerated amplification factor
+    between direct input and bytes of dynamic memory allocated
+    (default: <code>100.0</code>)
+    of parser <code>p</code> to <code>maximumAmplificationFactor</code>, and
+    returns <code>XML_TRUE</code> upon success and <code>XML_FALSE</code> upon error.
+  </p>
+
+  <p>
+    <strong>Note:</strong>
+    There are three types of allocations that intentionally bypass tracking and limiting:
+  </p>
+  <ul>
+    <li>
+      application calls to functions
+      <code><a href="#XML_MemMalloc">XML_MemMalloc</a></code>
+      and
+      <code><a href="#XML_MemRealloc">XML_MemRealloc</a></code>
+      &mdash;
+      <em>healthy</em> use of these two functions continues to be a responsibility
+      of the application using Expat
+      &mdash;,
+    </li>
+    <li>
+      the main character buffer used by functions
+      <code><a href="#XML_GetBuffer">XML_GetBuffer</a></code>
+      and
+      <code><a href="#XML_ParseBuffer">XML_ParseBuffer</a></code>
+      (and thus also by plain
+      <code><a href="#XML_Parse">XML_Parse</a></code>), and
+    </li>
+    <li>
+      the <a href="#XML_SetElementDeclHandler">content model memory</a>
+      (that is passed to the
+      <a href="#XML_SetElementDeclHandler">element declaration handler</a>
+      and freed by a call to
+      <code><a href="#XML_FreeContentModel">XML_FreeContentModel</a></code>).
+    </li>
+  </ul>
+
+  <p>The amplification factor is calculated as ..</p>
+  <pre>amplification := allocated / direct</pre>
+  <p>
+    .. while parsing, whereas
+    <code>direct</code> is the number of bytes read from the primary document in parsing and
+    <code>allocated</code> is the number of bytes of dynamic memory allocated in the parser hierarchy.
+  </p>
+
+  <p>For a call to <code>XML_SetAllocTrackerMaximumAmplification</code> to succeed:</p>
+  <ul>
+    <li>parser <code>p</code> must be a non-<code>NULL</code> root parser (without any parent parsers) and</li>
+    <li><code>maximumAmplificationFactor</code> must be non-<code>NaN</code> and greater than or equal to <code>1.0</code>.</li>
+  </ul>
+
+  <p>
+    <strong>Note:</strong>
+    If you ever need to increase this value for non-attack payload,
+    please <a href="https://github.com/libexpat/libexpat/issues">file a bug report</a>.
+  </p>
+
+  <p>
+    <strong>Note:</strong>
+    Amplifications factors greater than 100 can been observed near the start of parsing
+    even with benign files in practice.
+
+    So if you do reduce the maximum allowed amplification,
+    please make sure that the activation threshold is still big enough
+    to not end up with undesired false positives (i.e. benign files being rejected).
+  </p>
+</div>
+
+<h4 id="XML_SetAllocTrackerActivationThreshold">XML_SetAllocTrackerActivationThreshold</h4>
+<pre class="fcndec">
+/* Added in Expat 2.7.2. */
+XML_Bool
+XML_SetAllocTrackerActivationThreshold(XML_Parser p,
+                                       unsigned long long activationThresholdBytes);
+</pre>
+<div class="fcndef">
+  <p>
+    Sets number of allocated bytes of dynamic memory
+    needed to activate protection against disproportionate use of RAM
+    (default: <code>64 MiB</code>)
+    of parser <code>p</code> to <code>activationThresholdBytes</code>, and
+    returns <code>XML_TRUE</code> upon success and <code>XML_FALSE</code> upon error.
+  </p>
+
+  <p>
+    <strong>Note:</strong>
+    For types of allocations that intentionally bypass tracking and limiting, please see
+    <code><a href="#XML_SetAllocTrackerMaximumAmplification">XML_SetAllocTrackerMaximumAmplification</a></code>
+    above.
+  </p>
+
+  <p>For a call to <code>XML_SetAllocTrackerActivationThreshold</code> to succeed:</p>
+  <ul>
+    <li>parser <code>p</code> must be a non-<code>NULL</code> root parser (without any parent parsers).</li>
+  </ul>
+
+  <p>
+    <strong>Note:</strong>
+    If you ever need to increase this value for non-attack payload,
+    please <a href="https://github.com/libexpat/libexpat/issues">file a bug report</a>.
+  </p>
+</div>
+
 <h4 id="XML_SetReparseDeferralEnabled">XML_SetReparseDeferralEnabled</h4>
 <pre class="fcndec">
 /* Added in Expat 2.6.0. */
diff --git a/contrib/expat/doc/xmlwf.1 b/contrib/expat/doc/xmlwf.1
index 76aa7e30d074..5f50ba9e4d00 100644
--- a/contrib/expat/doc/xmlwf.1
+++ b/contrib/expat/doc/xmlwf.1
@@ -5,7 +5,7 @@
 \\$2 \(la\\$1\(ra\\$3
 ..
 .if \n(.g .mso www.tmac
-.TH XMLWF 1 "March 27, 2025" "" ""
+.TH XMLWF 1 "September 16, 2025" "" ""
 .SH NAME
 xmlwf \- Determines if an XML document is well-formed
 .SH SYNOPSIS
@@ -88,7 +88,11 @@ supports both.
 .TP 
 \*(T<\fB\-a\fR\*(T> \fIfactor\fR
 Sets the maximum tolerated amplification factor
-for protection against billion laughs attacks (default: 100.0).
+for protection against amplification attacks
+like the billion laughs attack
+(default: 100.0
+for the sum of direct and indirect output and also
+for allocations of dynamic memory).
 The amplification factor is calculated as ..
 
 .nf
@@ -97,12 +101,22 @@ The amplification factor is calculated as ..
           
 .fi
 
-\&.. while parsing, whereas
+\&.. with regard to use of entities and ..
+
+.nf
+
+            amplification := allocated / direct
+          
+.fi
+
+\&.. with regard to dynamic memory while parsing.
 <direct> is the number of bytes read
-from the primary document in parsing and
+from the primary document in parsing,
 <indirect> is the number of bytes
 added by expanding entities and reading of external DTD files,
-combined.
+combined, and
+<allocated> is the total number of bytes of dynamic memory
+allocated (and not freed) per hierarchy of parsers.
 
 \fINOTE\fR:
 If you ever need to increase this value for non-attack payload,
@@ -110,8 +124,10 @@ please file a bug report.
 .TP 
 \*(T<\fB\-b\fR\*(T> \fIbytes\fR
 Sets the number of output bytes (including amplification)
-needed to activate protection against billion laughs attacks
-(default: 8 MiB).
+needed to activate protection against amplification attacks
+like billion laughs
+(default: 8 MiB for the sum of direct and indirect output,
+and 64 MiB for allocations of dynamic memory).
 This can be thought of as an "activation threshold".
 
 \fINOTE\fR:
diff --git a/contrib/expat/doc/xmlwf.xml b/contrib/expat/doc/xmlwf.xml
index 17e9cf51c191..defe9df8e46a 100644
--- a/contrib/expat/doc/xmlwf.xml
+++ b/contrib/expat/doc/xmlwf.xml
@@ -21,7 +21,7 @@
           "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
   <!ENTITY dhfirstname "<firstname>Scott</firstname>">
   <!ENTITY dhsurname   "<surname>Bronson</surname>">
-  <!ENTITY dhdate      "<date>March 27, 2025</date>">
+  <!ENTITY dhdate      "<date>September 16, 2025</date>">
   <!-- Please adjust this^^ date whenever cutting a new release. -->
   <!ENTITY dhsection   "<manvolnum>1</manvolnum>">
   <!ENTITY dhemail     "<email>bronson@rinspin.com</email>">
@@ -158,19 +158,31 @@ supports both.
         <listitem>
           <para>
             Sets the maximum tolerated amplification factor
-            for protection against billion laughs attacks (default: 100.0).
+            for protection against amplification attacks
+            like the billion laughs attack
+            (default: 100.0
+            for the sum of direct and indirect output and also
+            for allocations of dynamic memory).
             The amplification factor is calculated as ..
           </para>
           <literallayout>
             amplification := (direct + indirect) / direct
           </literallayout>
           <para>
-            .. while parsing, whereas
+            .. with regard to use of entities and ..
+          </para>
+          <literallayout>
+            amplification := allocated / direct
+          </literallayout>
+          <para>
+            .. with regard to dynamic memory while parsing.
             &lt;direct&gt; is the number of bytes read
-              from the primary document in parsing and
+              from the primary document in parsing,
             &lt;indirect&gt; is the number of bytes
               added by expanding entities and reading of external DTD files,
-              combined.
+              combined, and
+            &lt;allocated&gt; is the total number of bytes of dynamic memory
+              allocated (and not freed) per hierarchy of parsers.
           </para>
           <para>
             <emphasis>NOTE</emphasis>:
@@ -185,8 +197,10 @@ supports both.
         <listitem>
           <para>
             Sets the number of output bytes (including amplification)
-            needed to activate protection against billion laughs attacks
-            (default: 8 MiB).
+            needed to activate protection against amplification attacks
+            like billion laughs
+            (default: 8 MiB for the sum of direct and indirect output,
+            and 64 MiB for allocations of dynamic memory).
             This can be thought of as an &quot;activation threshold&quot;.
           </para>
           <para>
diff --git a/contrib/expat/examples/Makefile.in b/contrib/expat/examples/Makefile.in
index 044c9089c565..0e55052ce6e4 100644
--- a/contrib/expat/examples/Makefile.in
+++ b/contrib/expat/examples/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@
@@ -330,8 +332,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
*** 3751 LINES SKIPPED ***