Vendor import of expat 2.7.2.

This commit is contained in:
Xin LI
2025-09-18 19:01:56 -07:00
parent b09cf48da4
commit 14feafd16d
36 changed files with 1602 additions and 645 deletions
+79 -2
View File
@@ -15,12 +15,16 @@
!! ClusterFuzz findings with few-days-max response times in communication !! !! 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 !! !! in order to (1) have a sound fix ready before the end of a 90 days !!
!! grace period and (2) in a sustainable manner, !! !! 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): !! !! attack protection API (https://github.com/python/cpython/issues/90949): !!
!! - XML_SetAllocTrackerActivationThreshold !!
!! - XML_SetAllocTrackerMaximumAmplification !!
!! - XML_SetBillionLaughsAttackProtectionActivationThreshold !! !! - XML_SetBillionLaughsAttackProtectionActivationThreshold !!
!! - XML_SetBillionLaughsAttackProtectionMaximumAmplification !! !! - XML_SetBillionLaughsAttackProtectionMaximumAmplification !!
!! - helping Perl's XML::Parser Expat bindings with supporting Expat's !! !! - helping Perl's XML::Parser Expat bindings with supporting Expat's !!
!! security API (https://github.com/cpan-authors/XML-Parser/issues/102): !! !! security API (https://github.com/cpan-authors/XML-Parser/issues/102): !!
!! - XML_SetAllocTrackerActivationThreshold !!
!! - XML_SetAllocTrackerMaximumAmplification !!
!! - XML_SetBillionLaughsAttackProtectionActivationThreshold !! !! - XML_SetBillionLaughsAttackProtectionActivationThreshold !!
!! - XML_SetBillionLaughsAttackProtectionMaximumAmplification !! !! - XML_SetBillionLaughsAttackProtectionMaximumAmplification !!
!! - XML_SetReparseDeferralEnabled !! !! - XML_SetReparseDeferralEnabled !!
@@ -37,6 +41,79 @@
!! THANK YOU! Sebastian Pipping -- Berlin, 2024-03-09 !! !! 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 Release 2.7.1 Thu March 27 2025
Bug fixes: Bug fixes:
#980 #989 Restore event pointer behavior from Expat 2.6.4 #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 #983 #984 Fix printf format specifiers for 32bit Emscripten
#992 docs: Promote OpenSSF Best Practices self-certification #992 docs: Promote OpenSSF Best Practices self-certification
#978 tests/benchmark: Resolve mistaken double close #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) #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/ to 11:2:10 (libexpat*.so.1.10.2); see https://verbump.de/
for what these numbers do for what these numbers do
+4 -3
View File
@@ -58,10 +58,8 @@ pkgconfig_DATA = expat.pc
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
dist_cmake_DATA = \
cmake/autotools/expat.cmake
nodist_cmake_DATA = \ nodist_cmake_DATA = \
cmake/autotools/expat.cmake \
cmake/autotools/expat-config-version.cmake \ cmake/autotools/expat-config-version.cmake \
cmake/autotools/expat-noconfig.cmake \ cmake/autotools/expat-noconfig.cmake \
cmake/expat-config.cmake cmake/expat-config.cmake
@@ -70,6 +68,9 @@ cmakedir = $(libdir)/cmake/expat-@PACKAGE_VERSION@
_EXTRA_DIST_CMAKE = \ _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__linux.cmake.in \
cmake/autotools/expat-noconfig__macos.cmake.in \ cmake/autotools/expat-noconfig__macos.cmake.in \
cmake/autotools/expat-noconfig__windows.cmake.in \ cmake/autotools/expat-noconfig__windows.cmake.in \
+62 -64
View File
@@ -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@ # @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 # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@@ -105,6 +105,8 @@ am__make_running_with_option = \
test $$has_opt = yes test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(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@ pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@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) \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4) $(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ 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 \ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = expat_config.h CONFIG_HEADER = expat_config.h
CONFIG_CLEAN_FILES = expat.pc cmake/expat-config.cmake \ CONFIG_CLEAN_FILES = expat.pc cmake/expat-config.cmake \
cmake/autotools/expat.cmake \
cmake/autotools/expat-config-version.cmake \ cmake/autotools/expat-config-version.cmake \
cmake/autotools/expat-noconfig.cmake run.sh cmake/autotools/expat-noconfig.cmake run.sh
CONFIG_CLEAN_VPATH_FILES = 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;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \ am__uninstall_files_from_dir = { \
test -z "$$files" \ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
} }
am__installdirs = "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(cmakedir)" \ am__installdirs = "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(pkgconfigdir)"
"$(DESTDIR)$(pkgconfigdir)" DATA = $(nodist_cmake_DATA) $(pkgconfig_DATA)
DATA = $(dist_cmake_DATA) $(nodist_cmake_DATA) $(pkgconfig_DATA)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive distclean-recursive maintainer-clean-recursive
am__recursive_targets = \ am__recursive_targets = \
@@ -256,8 +257,8 @@ distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir) top_distdir = $(distdir)
am__remove_distdir = \ am__remove_distdir = \
if test -d "$(distdir)"; then \ if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ find "$(distdir)" -type d ! -perm -700 -exec chmod u+rwx {} ';' \
&& rm -rf "$(distdir)" \ ; rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \ || { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi else :; fi
am__post_remove_distdir = $(am__remove_distdir) am__post_remove_distdir = $(am__remove_distdir)
@@ -288,14 +289,16 @@ am__relativize = \
reldir="$$dir2" reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).tar.lz \ DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).tar.lz \
$(distdir).tar.xz $(distdir).tar.xz
GZIP_ENV = --best GZIP_ENV = -9
DIST_TARGETS = dist-lzip dist-xz dist-bzip2 dist-gzip DIST_TARGETS = dist-lzip dist-xz dist-bzip2 dist-gzip
# Exists only to be overridden by the user if desired. # Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' | 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@ ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@ AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@ AM_CFLAGS = @AM_CFLAGS@
@@ -403,8 +406,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@ am__tar = @am__tar@
am__untar = @am__untar@ am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
@@ -458,16 +463,17 @@ LIBTOOLFLAGS = --verbose
SUBDIRS = lib $(am__append_1) $(am__append_2) $(am__append_3) SUBDIRS = lib $(am__append_1) $(am__append_2) $(am__append_3)
pkgconfig_DATA = expat.pc pkgconfig_DATA = expat.pc
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
dist_cmake_DATA = \
cmake/autotools/expat.cmake
nodist_cmake_DATA = \ nodist_cmake_DATA = \
cmake/autotools/expat.cmake \
cmake/autotools/expat-config-version.cmake \ cmake/autotools/expat-config-version.cmake \
cmake/autotools/expat-noconfig.cmake \ cmake/autotools/expat-noconfig.cmake \
cmake/expat-config.cmake cmake/expat-config.cmake
cmakedir = $(libdir)/cmake/expat-@PACKAGE_VERSION@ cmakedir = $(libdir)/cmake/expat-@PACKAGE_VERSION@
_EXTRA_DIST_CMAKE = \ _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__linux.cmake.in \
cmake/autotools/expat-noconfig__macos.cmake.in \ cmake/autotools/expat-noconfig__macos.cmake.in \
cmake/autotools/expat-noconfig__windows.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 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/expat_config.h.in $(top_builddir)/config.status stamp-h1: $(srcdir)/expat_config.h.in $(top_builddir)/config.status
@rm -f stamp-h1 $(AM_V_at)rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status expat_config.h $(AM_V_GEN)cd $(top_builddir) && $(SHELL) ./config.status expat_config.h
$(srcdir)/expat_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(srcdir)/expat_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER)) $(AM_V_GEN)($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1 $(AM_V_at)rm -f stamp-h1
touch $@ $(AM_V_at)touch $@
distclean-hdr: distclean-hdr:
-rm -f expat_config.h stamp-h1 -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 $@ cd $(top_builddir) && $(SHELL) ./config.status $@
cmake/expat-config.cmake: $(top_builddir)/config.status $(top_srcdir)/cmake/expat-config.cmake.in cmake/expat-config.cmake: $(top_builddir)/config.status $(top_srcdir)/cmake/expat-config.cmake.in
cd $(top_builddir) && $(SHELL) ./config.status $@ 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 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 $@ cd $(top_builddir) && $(SHELL) ./config.status $@
cmake/autotools/expat-noconfig.cmake: $(top_builddir)/config.status cmake/autotools/expat-noconfig.cmake: $(top_builddir)/config.status
@@ -580,27 +588,6 @@ clean-libtool:
distclean-libtool: distclean-libtool:
-rm -f libtool config.lt -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) install-nodist_cmakeDATA: $(nodist_cmake_DATA)
@$(NORMAL_INSTALL) @$(NORMAL_INSTALL)
@list='$(nodist_cmake_DATA)'; test -n "$(cmakedir)" || list=; \ @list='$(nodist_cmake_DATA)'; test -n "$(cmakedir)" || list=; \
@@ -749,12 +736,13 @@ cscopelist-am: $(am__tagged_files)
distclean-tags: distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(BUILT_SOURCES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am $(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES) distdir-am: $(DISTFILES)
$(am__remove_distdir) $(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)" $(AM_V_at)$(MKDIR_P) "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \ list='$(DISTFILES)'; \
@@ -822,6 +810,10 @@ dist-gzip: distdir
dist-bzip2: distdir dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__post_remove_distdir) $(am__post_remove_distdir)
dist-bzip3: distdir
tardir=$(distdir) && $(am__tar) | bzip3 -c >$(distdir).tar.bz3
$(am__post_remove_distdir)
dist-lzip: distdir dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__post_remove_distdir) $(am__post_remove_distdir)
@@ -862,9 +854,11 @@ dist dist-all:
distcheck: dist distcheck: dist
case '$(DIST_ARCHIVES)' in \ case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \ *.tar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \ *.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.bz3*) \
bzip3 -dc $(distdir).tar.bz3 | $(am__untar) ;;\
*.tar.lz*) \ *.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \ *.tar.xz*) \
@@ -872,7 +866,7 @@ distcheck: dist
*.tar.Z*) \ *.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \ *.shar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ eval GZIP= gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \ *.zip*) \
unzip $(distdir).zip ;;\ unzip $(distdir).zip ;;\
*.tar.zst*) \ *.tar.zst*) \
@@ -948,7 +942,7 @@ check: check-recursive
all-am: Makefile $(DATA) expat_config.h all-am: Makefile $(DATA) expat_config.h
installdirs: installdirs-recursive installdirs: installdirs-recursive
installdirs-am: 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"; \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done done
install: install-recursive install: install-recursive
@@ -975,8 +969,8 @@ mostlyclean-generic:
clean-generic: clean-generic:
distclean-generic: distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@@ -1003,8 +997,7 @@ info: info-recursive
info-am: info-am:
install-data-am: install-dist_cmakeDATA install-nodist_cmakeDATA \ install-data-am: install-nodist_cmakeDATA install-pkgconfigDATA
install-pkgconfigDATA
install-dvi: install-dvi-recursive install-dvi: install-dvi-recursive
@@ -1050,29 +1043,27 @@ ps: ps-recursive
ps-am: ps-am:
uninstall-am: uninstall-dist_cmakeDATA uninstall-nodist_cmakeDATA \ uninstall-am: uninstall-nodist_cmakeDATA uninstall-pkgconfigDATA
uninstall-pkgconfigDATA
.MAKE: $(am__recursive_targets) all install-am install-strip .MAKE: $(am__recursive_targets) all install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--refresh check check-am clean clean-cscope clean-generic \ am--refresh check check-am clean clean-cscope clean-generic \
clean-libtool cscope cscopelist-am ctags ctags-am dist \ clean-libtool cscope cscopelist-am ctags ctags-am dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-all dist-bzip2 dist-bzip3 dist-gzip dist-lzip dist-shar \
dist-xz dist-zip dist-zstd distcheck distclean \ dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \
distclean-generic distclean-hdr distclean-libtool \ distclean-generic distclean-hdr distclean-libtool \
distclean-tags distcleancheck distdir distuninstallcheck dvi \ distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \ dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dist_cmakeDATA \ install-data install-data-am install-dvi install-dvi-am \
install-dvi install-dvi-am install-exec install-exec-am \ install-exec install-exec-am install-html install-html-am \
install-html install-html-am install-info install-info-am \ install-info install-info-am install-man \
install-man install-nodist_cmakeDATA install-pdf \ install-nodist_cmakeDATA install-pdf install-pdf-am \
install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ install-pkgconfigDATA install-ps install-ps-am install-strip \
install-strip installcheck installcheck-am installdirs \ installcheck installcheck-am installdirs installdirs-am \
installdirs-am maintainer-clean maintainer-clean-generic \ maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
ps ps-am tags tags-am uninstall uninstall-am \ tags tags-am uninstall uninstall-am uninstall-nodist_cmakeDATA \
uninstall-dist_cmakeDATA uninstall-nodist_cmakeDATA \
uninstall-pkgconfigDATA uninstall-pkgconfigDATA
.PRECIOUS: Makefile .PRECIOUS: Makefile
@@ -1149,3 +1140,10 @@ qa:
# Tell versions [3.59,3.63) of GNU make to not export all variables. # 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. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+3 -3
View File
@@ -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) [![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) [![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 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) [![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. > 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 This is Expat, a C99 library for parsing
[XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by [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++) - GNU GCC >=4.5 (for use from C) or GNU GCC >=4.8.1 (for use from C++)
- LLVM Clang >=3.5 - 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 Windows users can use the
[`expat-win32bin-*.*.*.{exe,zip}` download](https://github.com/libexpat/libexpat/releases), [`expat-win32bin-*.*.*.{exe,zip}` download](https://github.com/libexpat/libexpat/releases),
+16 -6
View File
@@ -84,9 +84,9 @@ dnl
dnl If the API changes incompatibly set LIBAGE back to 0 dnl If the API changes incompatibly set LIBAGE back to 0
dnl dnl
LIBCURRENT=11 # sync LIBCURRENT=12 # sync
LIBREVISION=2 # with LIBREVISION=0 # with
LIBAGE=10 # CMakeLists.txt! LIBAGE=11 # CMakeLists.txt!
AC_CONFIG_HEADERS([expat_config.h]) AC_CONFIG_HEADERS([expat_config.h])
AH_TOP([#ifndef 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]) AC_SUBST([CMAKE_SHARED_LIBRARY_PREFIX])
AS_CASE("${host_os}", AS_CASE("${host_os}",
[darwin*], [CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__macos.cmake.in], [darwin*], [
[mingw*|cygwin*], [CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__windows.cmake.in], CMAKE_SOURCE=cmake/autotools/expat__macos.cmake.in
[CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__linux.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] AC_CONFIG_FILES([Makefile]
[expat.pc] [expat.pc]
[cmake/expat-config.cmake] [cmake/expat-config.cmake]
[cmake/autotools/expat.cmake:${CMAKE_SOURCE}]
[cmake/autotools/expat-config-version.cmake] [cmake/autotools/expat-config-version.cmake]
[cmake/autotools/expat-noconfig.cmake:${CMAKE_NOCONFIG_SOURCE}] [cmake/autotools/expat-noconfig.cmake:${CMAKE_NOCONFIG_SOURCE}]
[doc/Makefile] [doc/Makefile]
+19 -8
View File
@@ -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@ # @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 # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@@ -102,6 +102,8 @@ am__make_running_with_option = \
test $$has_opt = yes test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(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@ pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@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;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \ am__uninstall_files_from_dir = { \
test -z "$$files" \ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
} }
man1dir = $(mandir)/man1 man1dir = $(mandir)/man1
am__installdirs = "$(DESTDIR)$(man1dir)" am__installdirs = "$(DESTDIR)$(man1dir)"
@@ -303,8 +304,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@ am__tar = @am__tar@
am__untar = @am__untar@ am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
@@ -442,6 +445,7 @@ ctags CTAGS:
cscope cscopelist: cscope cscopelist:
@WITH_DISTRIBUTABLE_MANPAGE_TRUE@dist-hook: @WITH_DISTRIBUTABLE_MANPAGE_TRUE@dist-hook:
distdir: $(BUILT_SOURCES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am $(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -507,11 +511,11 @@ install-strip:
mostlyclean-generic: mostlyclean-generic:
clean-generic: clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) -$(am__rm_f) $(CLEANFILES)
distclean-generic: distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @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. # 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. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+123 -7
View File
@@ -52,7 +52,7 @@
<div> <div>
<h1> <h1>
The Expat XML Parser The Expat XML Parser
<small>Release 2.7.1</small> <small>Release 2.7.2</small>
</h1> </h1>
</div> </div>
<div class="content"> <div class="content">
@@ -157,6 +157,8 @@ interface.</p>
<ul> <ul>
<li><a href="#XML_SetBillionLaughsAttackProtectionMaximumAmplification">XML_SetBillionLaughsAttackProtectionMaximumAmplification</a></li> <li><a href="#XML_SetBillionLaughsAttackProtectionMaximumAmplification">XML_SetBillionLaughsAttackProtectionMaximumAmplification</a></li>
<li><a href="#XML_SetBillionLaughsAttackProtectionActivationThreshold">XML_SetBillionLaughsAttackProtectionActivationThreshold</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> <li><a href="#XML_SetReparseDeferralEnabled">XML_SetReparseDeferralEnabled</a></li>
</ul> </ul>
</li> </li>
@@ -319,7 +321,7 @@ directions in the next section. Otherwise if you have Microsoft's
Developer Studio installed, Developer Studio installed,
you can use CMake to generate a <code>.sln</code> file, e.g. you can use CMake to generate a <code>.sln</code> file, e.g.
<code> <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> </code>, and build Expat using <code>msbuild /m expat.sln</code> after.</p>
<p>Alternatively, you may download the Win32 binary package that <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 <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 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 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>. <a href="#XML_FreeContentModel">XML_FreeContentModel</a></code>.
There is no need to free the model from the handler, it can be kept There is no need to free the model from the handler, it can be kept
around and freed at a later stage.</p> 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. returns <code>XML_TRUE</code> upon success and <code>XML_FALSE</code> upon error.
</p> </p>
The amplification factor is calculated as .. <p>The amplification factor is calculated as ..</p>
<pre> <pre>amplification := (direct + indirect) / direct</pre>
amplification := (direct + indirect) / direct <p>
</pre>
.. while parsing, whereas .. while parsing, whereas
<code>direct</code> is the number of bytes read from the primary document in parsing and <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. <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> <p>For a call to <code>XML_SetBillionLaughsAttackProtectionMaximumAmplification</code> to succeed:</p>
<ul> <ul>
@@ -2267,6 +2269,120 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(XML_Parser p,
</p> </p>
</div> </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> <h4 id="XML_SetReparseDeferralEnabled">XML_SetReparseDeferralEnabled</h4>
<pre class="fcndec"> <pre class="fcndec">
/* Added in Expat 2.6.0. */ /* Added in Expat 2.6.0. */
+23 -7
View File
@@ -5,7 +5,7 @@
\\$2 \(la\\$1\(ra\\$3 \\$2 \(la\\$1\(ra\\$3
.. ..
.if \n(.g .mso www.tmac .if \n(.g .mso www.tmac
.TH XMLWF 1 "March 27, 2025" "" "" .TH XMLWF 1 "September 16, 2025" "" ""
.SH NAME .SH NAME
xmlwf \- Determines if an XML document is well-formed xmlwf \- Determines if an XML document is well-formed
.SH SYNOPSIS .SH SYNOPSIS
@@ -88,7 +88,11 @@ supports both.
.TP .TP
\*(T<\fB\-a\fR\*(T> \fIfactor\fR \*(T<\fB\-a\fR\*(T> \fIfactor\fR
Sets the maximum tolerated amplification factor 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 .. The amplification factor is calculated as ..
.nf .nf
@@ -97,12 +101,22 @@ The amplification factor is calculated as ..
.fi .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 <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 <indirect> is the number of bytes
added by expanding entities and reading of external DTD files, 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: \fINOTE\fR:
If you ever need to increase this value for non-attack payload, If you ever need to increase this value for non-attack payload,
@@ -110,8 +124,10 @@ please file a bug report.
.TP .TP
\*(T<\fB\-b\fR\*(T> \fIbytes\fR \*(T<\fB\-b\fR\*(T> \fIbytes\fR
Sets the number of output bytes (including amplification) Sets the number of output bytes (including amplification)
needed to activate protection against billion laughs attacks needed to activate protection against amplification attacks
(default: 8 MiB). 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". This can be thought of as an "activation threshold".
\fINOTE\fR: \fINOTE\fR:
+21 -7
View File
@@ -21,7 +21,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY dhfirstname "<firstname>Scott</firstname>"> <!ENTITY dhfirstname "<firstname>Scott</firstname>">
<!ENTITY dhsurname "<surname>Bronson</surname>"> <!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. --> <!-- Please adjust this^^ date whenever cutting a new release. -->
<!ENTITY dhsection "<manvolnum>1</manvolnum>"> <!ENTITY dhsection "<manvolnum>1</manvolnum>">
<!ENTITY dhemail "<email>bronson@rinspin.com</email>"> <!ENTITY dhemail "<email>bronson@rinspin.com</email>">
@@ -158,19 +158,31 @@ supports both.
<listitem> <listitem>
<para> <para>
Sets the maximum tolerated amplification factor 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 .. The amplification factor is calculated as ..
</para> </para>
<literallayout> <literallayout>
amplification := (direct + indirect) / direct amplification := (direct + indirect) / direct
</literallayout> </literallayout>
<para> <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 &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 &lt;indirect&gt; is the number of bytes
added by expanding entities and reading of external DTD files, 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>
<para> <para>
<emphasis>NOTE</emphasis>: <emphasis>NOTE</emphasis>:
@@ -185,8 +197,10 @@ supports both.
<listitem> <listitem>
<para> <para>
Sets the number of output bytes (including amplification) Sets the number of output bytes (including amplification)
needed to activate protection against billion laughs attacks needed to activate protection against amplification attacks
(default: 8 MiB). 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;. This can be thought of as an &quot;activation threshold&quot;.
</para> </para>
<para> <para>
+19 -12
View File
@@ -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@ # @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 # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@@ -101,6 +101,8 @@ am__make_running_with_option = \
test $$has_opt = yes test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(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@ pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@
@@ -330,8 +332,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@ am__tar = @am__tar@
am__untar = @am__untar@ am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
@@ -414,13 +418,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps): $(am__aclocal_m4_deps):
clean-noinstPROGRAMS: clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ $(am__rm_f) $(noinst_PROGRAMS)
echo " rm -f" $$list; \ test -z "$(EXEEXT)" || $(am__rm_f) $(noinst_PROGRAMS:$(EXEEXT)=)
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
element_declarations$(EXEEXT): $(element_declarations_OBJECTS) $(element_declarations_DEPENDENCIES) $(EXTRA_element_declarations_DEPENDENCIES) element_declarations$(EXEEXT): $(element_declarations_OBJECTS) $(element_declarations_DEPENDENCIES) $(EXTRA_element_declarations_DEPENDENCIES)
@rm -f element_declarations$(EXEEXT) @rm -f element_declarations$(EXEEXT)
@@ -446,7 +445,7 @@ distclean-compile:
$(am__depfiles_remade): $(am__depfiles_remade):
@$(MKDIR_P) $(@D) @$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@ @: >>$@
am--depfiles: $(am__depfiles_remade) am--depfiles: $(am__depfiles_remade)
@@ -528,6 +527,7 @@ cscopelist-am: $(am__tagged_files)
distclean-tags: distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am $(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -589,8 +589,8 @@ mostlyclean-generic:
clean-generic: clean-generic:
distclean-generic: distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@@ -692,3 +692,10 @@ uninstall-am:
# Tell versions [3.59,3.63) of GNU make to not export all variables. # 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. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+6 -6
View File
@@ -24,7 +24,7 @@
/* Define to 1 if you have the <fcntl.h> header file. */ /* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H #undef HAVE_FCNTL_H
/* Define to 1 if you have the `getpagesize' function. */ /* Define to 1 if you have the 'getpagesize' function. */
#undef HAVE_GETPAGESIZE #undef HAVE_GETPAGESIZE
/* Define to 1 if you have the `getrandom' function. */ /* Define to 1 if you have the `getrandom' function. */
@@ -33,10 +33,10 @@
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H #undef HAVE_INTTYPES_H
/* Define to 1 if you have the `bsd' library (-lbsd). */ /* Define to 1 if you have the 'bsd' library (-lbsd). */
#undef HAVE_LIBBSD #undef HAVE_LIBBSD
/* Define to 1 if you have a working `mmap' system call. */ /* Define to 1 if you have a working 'mmap' system call. */
#undef HAVE_MMAP #undef HAVE_MMAP
/* Define to 1 if you have the <stdint.h> header file. */ /* Define to 1 if you have the <stdint.h> header file. */
@@ -93,7 +93,7 @@
/* Define to the version of this package. */ /* Define to the version of this package. */
#undef PACKAGE_VERSION #undef PACKAGE_VERSION
/* Define to 1 if all of the C90 standard headers exist (not just the ones /* Define to 1 if all of the C89 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */ backward compatibility; new code need not use it. */
#undef STDC_HEADERS #undef STDC_HEADERS
@@ -133,10 +133,10 @@
/* Define to make XML Namespaces functionality available. */ /* Define to make XML Namespaces functionality available. */
#undef XML_NS #undef XML_NS
/* Define to empty if `const' does not conform to ANSI C. */ /* Define to empty if 'const' does not conform to ANSI C. */
#undef const #undef const
/* Define to `long int' if <sys/types.h> does not define. */ /* Define to 'long int' if <sys/types.h> does not define. */
#undef off_t #undef off_t
#endif // ndef EXPAT_CONFIG_H #endif // ndef EXPAT_CONFIG_H
+2
View File
@@ -354,9 +354,11 @@ ExternalEntityRefHandler(XML_Parser parser, const XML_Char *context,
if (g_external_entity) { if (g_external_entity) {
XML_Parser ext_parser XML_Parser ext_parser
= XML_ExternalEntityParserCreate(parser, context, g_encoding); = XML_ExternalEntityParserCreate(parser, context, g_encoding);
if (ext_parser != NULL) {
rc = Parse(ext_parser, g_external_entity, g_external_entity_size, 1); rc = Parse(ext_parser, g_external_entity, g_external_entity_size, 1);
XML_ParserFree(ext_parser); XML_ParserFree(ext_parser);
} }
}
return rc; return rc;
} }
+8 -4
View File
@@ -15,6 +15,7 @@
*/ */
#include <assert.h> #include <assert.h>
#include <limits.h> // for INT_MAX
#include <stdint.h> #include <stdint.h>
#include "expat.h" #include "expat.h"
@@ -65,8 +66,9 @@ ParseOneInput(XML_Parser p, const uint8_t *data, size_t size) {
XML_SetUserData(p, p); XML_SetUserData(p, p);
XML_SetElementHandler(p, start, end); XML_SetElementHandler(p, start, end);
XML_SetCharacterDataHandler(p, may_stop_character_handler); XML_SetCharacterDataHandler(p, may_stop_character_handler);
XML_Parse(p, (const XML_Char *)data, size, 0); assert(size <= INT_MAX);
if (XML_Parse(p, (const XML_Char *)data, size, 1) == XML_STATUS_ERROR) { 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_ErrorString(XML_GetErrorCode(p));
} }
XML_GetCurrentLineNumber(p); XML_GetCurrentLineNumber(p);
@@ -89,15 +91,17 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
XML_Parser externalEntityParser XML_Parser externalEntityParser
= XML_ExternalEntityParserCreate(parentParser, "e1", NULL); = XML_ExternalEntityParserCreate(parentParser, "e1", NULL);
assert(externalEntityParser); if (externalEntityParser != NULL) {
ParseOneInput(externalEntityParser, data, size); ParseOneInput(externalEntityParser, data, size);
XML_ParserFree(externalEntityParser); XML_ParserFree(externalEntityParser);
}
XML_Parser externalDtdParser XML_Parser externalDtdParser
= XML_ExternalEntityParserCreate(parentParser, NULL, NULL); = XML_ExternalEntityParserCreate(parentParser, NULL, NULL);
assert(externalDtdParser); if (externalDtdParser != NULL) {
ParseOneInput(externalDtdParser, data, size); ParseOneInput(externalDtdParser, data, size);
XML_ParserFree(externalDtdParser); XML_ParserFree(externalDtdParser);
}
// finally frees this parser which served as parent // finally frees this parser which served as parent
XML_ParserFree(parentParser); XML_ParserFree(parentParser);
+10 -6
View File
@@ -15,6 +15,7 @@
*/ */
#include <assert.h> #include <assert.h>
#include <limits.h> // for INT_MAX
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -66,16 +67,17 @@ ParseOneInput(XML_Parser p, const uint8_t *data, size_t size) {
XML_SetUserData(p, p); XML_SetUserData(p, p);
XML_SetElementHandler(p, start, end); XML_SetElementHandler(p, start, end);
XML_SetCharacterDataHandler(p, may_stop_character_handler); 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); assert(buf);
memcpy(buf, data, size); memcpy(buf, data, size);
XML_ParseBuffer(p, size, 0); XML_ParseBuffer(p, (int)size, 0);
buf = XML_GetBuffer(p, size); buf = XML_GetBuffer(p, (int)size);
if (buf == NULL) { if (buf == NULL) {
return; return;
} }
memcpy(buf, data, size); 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_ErrorString(XML_GetErrorCode(p));
} }
XML_GetCurrentLineNumber(p); XML_GetCurrentLineNumber(p);
@@ -101,15 +103,17 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
XML_Parser externalEntityParser XML_Parser externalEntityParser
= XML_ExternalEntityParserCreate(parentParser, "e1", NULL); = XML_ExternalEntityParserCreate(parentParser, "e1", NULL);
assert(externalEntityParser); if (externalEntityParser != NULL) {
ParseOneInput(externalEntityParser, data, size); ParseOneInput(externalEntityParser, data, size);
XML_ParserFree(externalEntityParser); XML_ParserFree(externalEntityParser);
}
XML_Parser externalDtdParser XML_Parser externalDtdParser
= XML_ExternalEntityParserCreate(parentParser, NULL, NULL); = XML_ExternalEntityParserCreate(parentParser, NULL, NULL);
assert(externalDtdParser); if (externalDtdParser != NULL) {
ParseOneInput(externalDtdParser, data, size); ParseOneInput(externalDtdParser, data, size);
XML_ParserFree(externalDtdParser); XML_ParserFree(externalDtdParser);
}
// finally frees this parser which served as parent // finally frees this parser which served as parent
XML_ParserFree(parentParser); XML_ParserFree(parentParser);
+23 -16
View File
@@ -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@ # @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 # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@@ -104,6 +104,8 @@ am__make_running_with_option = \
test $$has_opt = yes test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(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@ pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@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;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \ am__uninstall_files_from_dir = { \
test -z "$$files" \ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
} }
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" \ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" \
"$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"
@@ -368,8 +369,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@ am__tar = @am__tar@
am__untar = @am__untar@ am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
@@ -513,26 +516,22 @@ uninstall-libLTLIBRARIES:
done done
clean-libLTLIBRARIES: clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) -$(am__rm_f) $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \ @list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \ locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \ sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \ echo rm -f $${locs}; \
rm -f $${locs}; \ $(am__rm_f) $${locs}
}
clean-noinstLTLIBRARIES: clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) -$(am__rm_f) $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \ @list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \ locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \ sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \ echo rm -f $${locs}; \
rm -f $${locs}; \ $(am__rm_f) $${locs}
}
libexpat.la: $(libexpat_la_OBJECTS) $(libexpat_la_DEPENDENCIES) $(EXTRA_libexpat_la_DEPENDENCIES) 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) $(AM_V_CCLD)$(libexpat_la_LINK) -rpath $(libdir) $(libexpat_la_OBJECTS) $(libexpat_la_LIBADD) $(LIBS)
@@ -555,7 +554,7 @@ distclean-compile:
$(am__depfiles_remade): $(am__depfiles_remade):
@$(MKDIR_P) $(@D) @$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@ @: >>$@
am--depfiles: $(am__depfiles_remade) am--depfiles: $(am__depfiles_remade)
@@ -700,6 +699,7 @@ cscopelist-am: $(am__tagged_files)
distclean-tags: distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am $(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -764,8 +764,8 @@ mostlyclean-generic:
clean-generic: clean-generic:
distclean-generic: distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@@ -885,3 +885,10 @@ uninstall-local:
# Tell versions [3.59,3.63) of GNU make to not export all variables. # 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. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+15 -2
View File
@@ -1032,7 +1032,10 @@ enum XML_FeatureEnum {
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT, XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
/* Added in Expat 2.6.0. */ /* 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. */ /* Additional features must be added to the end of this enum. */
}; };
@@ -1057,6 +1060,16 @@ XML_SetBillionLaughsAttackProtectionMaximumAmplification(
XMLPARSEAPI(XML_Bool) XMLPARSEAPI(XML_Bool)
XML_SetBillionLaughsAttackProtectionActivationThreshold( XML_SetBillionLaughsAttackProtectionActivationThreshold(
XML_Parser parser, unsigned long long activationThresholdBytes); XML_Parser parser, unsigned long long activationThresholdBytes);
/* 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 # endif
/* Added in Expat 2.6.0. */ /* Added in Expat 2.6.0. */
@@ -1068,7 +1081,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
*/ */
# define XML_MAJOR_VERSION 2 # define XML_MAJOR_VERSION 2
# define XML_MINOR_VERSION 7 # define XML_MINOR_VERSION 7
#define XML_MICRO_VERSION 1 # define XML_MICRO_VERSION 2
# ifdef __cplusplus # ifdef __cplusplus
} }
+2 -1
View File
@@ -88,7 +88,8 @@
# ifndef XML_BUILDING_EXPAT # ifndef XML_BUILDING_EXPAT
/* using Expat from an application */ /* using Expat from an application */
# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__) # if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) \
&& ! defined(__CYGWIN__)
# define XMLIMPORT __declspec(dllimport) # define XMLIMPORT __declspec(dllimport)
# endif # endif
+8
View File
@@ -148,6 +148,11 @@
100.0f 100.0f
#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \ #define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \
8388608 // 8 MiB, 2^23 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 */ /* NOTE END */
#include "expat.h" // so we can use type XML_Parser below #include "expat.h" // so we can use type XML_Parser below
@@ -171,6 +176,9 @@ extern
#endif #endif
XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
#if defined(XML_TESTING) #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 extern unsigned int g_bytesScanned; // used for testing only
#endif #endif
+502 -142
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -36,12 +36,6 @@
#ifndef XmlRole_INCLUDED #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
+2 -2
View File
@@ -1398,7 +1398,7 @@ unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
} }
ENCODING * ENCODING *
XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert, XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert,
void *userData) { void *userData) {
int i; int i;
struct unknown_encoding *e = (struct unknown_encoding *)mem; struct unknown_encoding *e = (struct unknown_encoding *)mem;
@@ -1661,7 +1661,7 @@ initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc,
# undef ns # undef ns
ENCODING * ENCODING *
XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, XmlInitUnknownEncodingNS(void *mem, const int *table, CONVERTER convert,
void *userData) { void *userData) {
ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
if (enc) if (enc)
+3 -3
View File
@@ -299,7 +299,7 @@ int XmlSizeOfUnknownEncoding(void);
typedef int(XMLCALL *CONVERTER)(void *userData, const char *p); 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); void *userData);
int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc, int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc,
@@ -312,8 +312,8 @@ int XmlInitEncodingNS(INIT_ENCODING *p, const ENCODING **encPtr,
const char *name); const char *name);
const ENCODING *XmlGetUtf8InternalEncodingNS(void); const ENCODING *XmlGetUtf8InternalEncodingNS(void);
const ENCODING *XmlGetUtf16InternalEncodingNS(void); const ENCODING *XmlGetUtf16InternalEncodingNS(void);
ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, ENCODING *XmlInitUnknownEncodingNS(void *mem, const int *table,
void *userData); CONVERTER convert, void *userData);
# ifdef __cplusplus # ifdef __cplusplus
} }
# endif # endif
+64 -27
View File
@@ -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@ # @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 # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@@ -102,6 +102,8 @@ am__make_running_with_option = \
test $$has_opt = yes test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(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@ pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@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;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \ am__uninstall_files_from_dir = { \
test -z "$$files" \ { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \ $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
} }
am__recheck_rx = ^[ ]*:recheck:[ ]* am__recheck_rx = ^[ ]*:recheck:[ ]*
am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
@@ -415,6 +416,7 @@ am__sh_e_setup = case $$- in *e*) set +e;; esac
# Default flags passed to test drivers. # Default flags passed to test drivers.
am__common_driver_flags = \ am__common_driver_flags = \
--color-tests "$$am__color_tests" \ --color-tests "$$am__color_tests" \
$$am__collect_skipped_logs \
--enable-hard-errors "$$am__enable_hard_errors" \ --enable-hard-errors "$$am__enable_hard_errors" \
--expect-failure "$$am__expect_failure" --expect-failure "$$am__expect_failure"
# To be inserted before the command running the test. Creates the # To be inserted before the command running the test. Creates the
@@ -439,6 +441,11 @@ if test -f "./$$f"; then dir=./; \
elif test -f "$$f"; then dir=; \ elif test -f "$$f"; then dir=; \
else dir="$(srcdir)/"; fi; \ else dir="$(srcdir)/"; fi; \
tst=$$dir$$f; log='$@'; \ 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 \ if test -n '$(DISABLE_HARD_ERRORS)'; then \
am__enable_hard_errors=no; \ am__enable_hard_errors=no; \
else \ else \
@@ -620,8 +627,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@ am__tar = @am__tar@
am__untar = @am__untar@ am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
@@ -757,13 +766,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps): $(am__aclocal_m4_deps):
clean-checkPROGRAMS: clean-checkPROGRAMS:
@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ $(am__rm_f) $(check_PROGRAMS)
echo " rm -f" $$list; \ test -z "$(EXEEXT)" || $(am__rm_f) $(check_PROGRAMS:$(EXEEXT)=)
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
runtests$(EXEEXT): $(runtests_OBJECTS) $(runtests_DEPENDENCIES) $(EXTRA_runtests_DEPENDENCIES) runtests$(EXEEXT): $(runtests_OBJECTS) $(runtests_DEPENDENCIES) $(EXTRA_runtests_DEPENDENCIES)
@rm -f runtests$(EXEEXT) @rm -f runtests$(EXEEXT)
@@ -810,7 +814,7 @@ distclean-compile:
$(am__depfiles_remade): $(am__depfiles_remade):
@$(MKDIR_P) $(@D) @$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@ @: >>$@
am--depfiles: $(am__depfiles_remade) am--depfiles: $(am__depfiles_remade)
@@ -974,7 +978,6 @@ distclean-tags:
am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
am--force-recheck: am--force-recheck:
@: @:
$(TEST_SUITE_LOG): $(TEST_LOGS) $(TEST_SUITE_LOG): $(TEST_LOGS)
@$(am__set_TESTS_bases); \ @$(am__set_TESTS_bases); \
am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ 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 "XPASS:" $$xpass "$$red"; \
result_count $$1 "ERROR:" $$error "$$mgn"; \ 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)" | \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
$(am__rst_title); \ $(am__rst_title); \
create_testsuite_report --no-color; \ create_testsuite_report --no-color; \
output_system_information; \
echo; \ echo; \
echo ".. contents:: :depth: 2"; \ echo ".. contents:: :depth: 2"; \
echo; \ echo; \
@@ -1073,26 +1103,25 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
create_testsuite_report --maybe-color; \ create_testsuite_report --maybe-color; \
echo "$$col$$br$$std"; \ echo "$$col$$br$$std"; \
if $$success; then :; else \ 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 \ if test -n "$(PACKAGE_BUGREPORT)"; then \
echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ please_report | sed -e "s/^/$${col}/" -e s/'$$'/"$${std}"/; \
fi; \ fi; \
echo "$$col$$br$$std"; \ echo "$$col$$br$$std"; \
fi; \ fi; \
$$success || exit 1 $$success || exit 1
check-TESTS: $(check_PROGRAMS) check-TESTS: $(check_PROGRAMS)
@list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @$(am__rm_f) $(RECHECK_LOGS)
@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @$(am__rm_f) $(RECHECK_LOGS:.log=.trs)
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @$(am__rm_f) $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \ @set +e; $(am__set_TESTS_bases); \
log_list=`for i in $$bases; do echo $$i.log; done`; \ 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`; \
log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
exit $$?; exit $$?;
recheck: all $(check_PROGRAMS) 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); \ @set +e; $(am__set_TESTS_bases); \
bases=`for i in $$bases; do echo $$i; done \ bases=`for i in $$bases; do echo $$i; done \
| $(am__list_recheck_tests)` || exit 1; \ | $(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@ --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@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
distdir: $(BUILT_SOURCES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am $(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -1215,15 +1245,15 @@ install-strip:
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi fi
mostlyclean-generic: mostlyclean-generic:
-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -$(am__rm_f) $(TEST_LOGS)
-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -$(am__rm_f) $(TEST_LOGS:.log=.trs)
-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) -$(am__rm_f) $(TEST_SUITE_LOG)
clean-generic: clean-generic:
distclean-generic: distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@@ -1376,3 +1406,10 @@ uninstall-am:
# Tell versions [3.59,3.63) of GNU make to not export all variables. # 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. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+217 -3
View File
@@ -10,7 +10,7 @@
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> 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-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com> Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.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 */ # undef NDEBUG /* because test suite relies on assert(...) at the moment */
#endif #endif
#include <math.h> /* NAN, INFINITY */
#include <stdbool.h>
#include <stdint.h> /* for SIZE_MAX */
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include "expat_config.h"
#include "expat.h" #include "expat.h"
#include "internal.h"
#include "common.h" #include "common.h"
#include "minicheck.h" #include "minicheck.h"
#include "dummy.h" #include "dummy.h"
@@ -323,7 +329,7 @@ START_TEST(test_alloc_run_external_parser) {
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
XML_SetUserData(g_parser, foo_text); XML_SetUserData(g_parser, foo_text);
XML_SetExternalEntityRefHandler(g_parser, external_entity_null_loader); 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) if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
!= XML_STATUS_ERROR) != XML_STATUS_ERROR)
break; break;
@@ -434,7 +440,7 @@ START_TEST(test_alloc_internal_entity) {
const unsigned int max_alloc_count = 20; const unsigned int max_alloc_count = 20;
for (i = 0; i < max_alloc_count; i++) { 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, XML_SetUnknownEncodingHandler(g_parser, unknown_released_encoding_handler,
NULL); NULL);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
@@ -2085,6 +2091,203 @@ START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) {
} }
END_TEST 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 void
make_alloc_test_case(Suite *s) { make_alloc_test_case(Suite *s) {
TCase *tc_alloc = tcase_create("allocation tests"); TCase *tc_alloc = tcase_create("allocation tests");
@@ -2151,4 +2354,15 @@ make_alloc_test_case(Suite *s) {
tcase_add_test__ifdef_xml_dtd( tcase_add_test__ifdef_xml_dtd(
tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail); 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);
} }
+6 -2
View File
@@ -412,13 +412,13 @@ START_TEST(test_utf16_le_epilog_newline) {
if (first_chunk_bytes >= sizeof(text) - 1) if (first_chunk_bytes >= sizeof(text) - 1)
fail("bad value of first_chunk_bytes"); 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_STATUS_ERROR)
xml_failure(g_parser); xml_failure(g_parser);
else { else {
enum XML_Status rc; enum XML_Status rc;
rc = _XML_Parse_SINGLE_BYTES(g_parser, text + first_chunk_bytes, 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); XML_TRUE);
if (rc == XML_STATUS_ERROR) if (rc == XML_STATUS_ERROR)
xml_failure(g_parser); xml_failure(g_parser);
@@ -3123,6 +3123,10 @@ START_TEST(test_buffer_can_grow_to_max) {
for (int i = 0; i < num_prefixes; ++i) { for (int i = 0; i < num_prefixes; ++i) {
set_subtest("\"%s\"", prefixes[i]); set_subtest("\"%s\"", prefixes[i]);
XML_Parser parser = XML_ParserCreate(NULL); 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 int prefix_len = (int)strlen(prefixes[i]);
const enum XML_Status s const enum XML_Status s
= _XML_Parse_SINGLE_BYTES(parser, prefixes[i], prefix_len, XML_FALSE); = _XML_Parse_SINGLE_BYTES(parser, prefixes[i], prefix_len, XML_FALSE);
+19 -12
View File
@@ -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@ # @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 # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@@ -101,6 +101,8 @@ am__make_running_with_option = \
test $$has_opt = yes test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(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@ pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@
@@ -320,8 +322,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@ am__tar = @am__tar@
am__untar = @am__untar@ am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
@@ -403,13 +407,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps): $(am__aclocal_m4_deps):
clean-noinstPROGRAMS: clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ $(am__rm_f) $(noinst_PROGRAMS)
echo " rm -f" $$list; \ test -z "$(EXEEXT)" || $(am__rm_f) $(noinst_PROGRAMS:$(EXEEXT)=)
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
benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) $(EXTRA_benchmark_DEPENDENCIES) benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) $(EXTRA_benchmark_DEPENDENCIES)
@rm -f benchmark$(EXEEXT) @rm -f benchmark$(EXEEXT)
@@ -425,7 +424,7 @@ distclean-compile:
$(am__depfiles_remade): $(am__depfiles_remade):
@$(MKDIR_P) $(@D) @$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@ @: >>$@
am--depfiles: $(am__depfiles_remade) am--depfiles: $(am__depfiles_remade)
@@ -507,6 +506,7 @@ cscopelist-am: $(am__tagged_files)
distclean-tags: distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am $(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -568,8 +568,8 @@ mostlyclean-generic:
clean-generic: clean-generic:
distclean-generic: distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@@ -667,3 +667,10 @@ uninstall-am:
# Tell versions [3.59,3.63) of GNU make to not export all variables. # 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. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+10 -1
View File
@@ -303,7 +303,14 @@ duff_reallocator(void *ptr, size_t size) {
return realloc(ptr, 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 * char *
portable_strndup(const char *s, size_t n) { portable_strndup(const char *s, size_t n) {
if ((s == NULL) || (n == SIZE_MAX)) { if ((s == NULL) || (n == SIZE_MAX)) {
@@ -311,6 +318,8 @@ portable_strndup(const char *s, size_t n) {
return NULL; return NULL;
} }
n = portable_strnlen(s, n);
char *const buffer = (char *)malloc(n + 1); char *const buffer = (char *)malloc(n + 1);
if (buffer == NULL) { if (buffer == NULL) {
errno = ENOMEM; errno = ENOMEM;
+15 -14
View File
@@ -10,7 +10,7 @@
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> 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-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com> Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
@@ -89,15 +89,15 @@ start_element_event_handler2(void *userData, const XML_Char *name,
const XML_Char **attr) { const XML_Char **attr) {
StructData *storage = (StructData *)userData; StructData *storage = (StructData *)userData;
UNUSED_P(attr); UNUSED_P(attr);
StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser), StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG); (int)XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG);
} }
void XMLCALL void XMLCALL
end_element_event_handler2(void *userData, const XML_Char *name) { end_element_event_handler2(void *userData, const XML_Char *name) {
StructData *storage = (StructData *)userData; StructData *storage = (StructData *)userData;
StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser), StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG); (int)XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG);
} }
void XMLCALL void XMLCALL
@@ -132,7 +132,7 @@ counting_start_element_handler(void *userData, const XML_Char *name,
fail("ID not present"); fail("ID not present");
return; 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"); fail("ID does not have the correct name");
return; return;
} }
@@ -147,7 +147,7 @@ counting_start_element_handler(void *userData, const XML_Char *name,
fail("Attribute not recognised"); fail("Attribute not recognised");
return; return;
} }
if (xcstrcmp(atts[1], attr->value)) { if (xcstrcmp(atts[1], attr->value) != 0) {
fail("Attribute has wrong value"); fail("Attribute has wrong value");
return; return;
} }
@@ -1110,7 +1110,7 @@ external_entity_devaluer(XML_Parser parser, const XML_Char *context,
UNUSED_P(publicId); UNUSED_P(publicId);
if (systemId == NULL || ! xcstrcmp(systemId, XCS("bar"))) if (systemId == NULL || ! xcstrcmp(systemId, XCS("bar")))
return XML_STATUS_OK; return XML_STATUS_OK;
if (xcstrcmp(systemId, XCS("foo"))) if (xcstrcmp(systemId, XCS("foo")) != 0)
fail("Unexpected system ID"); fail("Unexpected system ID");
ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL); ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
if (ext_parser == NULL) if (ext_parser == NULL)
@@ -1276,7 +1276,7 @@ external_entity_duff_loader(XML_Parser parser, const XML_Char *context,
UNUSED_P(publicId); UNUSED_P(publicId);
/* Try a few different allocation levels */ /* Try a few different allocation levels */
for (i = 0; i < max_alloc_count; i++) { for (i = 0; i < max_alloc_count; i++) {
g_allocation_count = i; g_allocation_count = (int)i;
new_parser = XML_ExternalEntityParserCreate(parser, context, NULL); new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
if (new_parser != NULL) { if (new_parser != NULL) {
XML_ParserFree(new_parser); XML_ParserFree(new_parser);
@@ -1552,15 +1552,16 @@ verify_attlist_decl_handler(void *userData, const XML_Char *element_name,
const XML_Char *default_value, int is_required) { const XML_Char *default_value, int is_required) {
AttTest *at = (AttTest *)userData; 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"); 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"); 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"); fail("Unexpected attribute type in attribute declaration");
if ((default_value == NULL && at->default_value != NULL) if ((default_value == NULL && at->default_value != NULL)
|| (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"); fail("Unexpected default value in attribute declaration");
if (is_required != at->is_required) if (is_required != at->is_required)
fail("Requirement mismatch in attribute declaration"); fail("Requirement mismatch in attribute declaration");
@@ -1751,7 +1752,7 @@ param_entity_match_handler(void *userData, const XML_Char *entityName,
* going to overflow an int. * going to overflow an int.
*/ */
if (value_length != (int)xcstrlen(entity_value_to_match) 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; entity_match_flag = ENTITY_MATCH_FAIL;
} else { } else {
entity_match_flag = ENTITY_MATCH_SUCCESS; entity_match_flag = ENTITY_MATCH_SUCCESS;
+1 -2
View File
@@ -134,8 +134,7 @@ void _check_set_test_info(char const *function, char const *filename,
__attribute__((noreturn)) __attribute__((noreturn))
# endif # endif
# endif # endif
void void _fail(const char *file, int line, const char *msg);
_fail(const char *file, int line, const char *msg);
Suite *suite_create(const char *name); Suite *suite_create(const char *name);
TCase *tcase_create(const char *name); TCase *tcase_create(const char *name);
void suite_add_tcase(Suite *suite, TCase *tc); void suite_add_tcase(Suite *suite, TCase *tc);
+4 -3
View File
@@ -70,7 +70,7 @@ START_TEST(test_misc_alloc_create_parser) {
/* Something this simple shouldn't need more than 10 allocations */ /* Something this simple shouldn't need more than 10 allocations */
for (i = 0; i < max_alloc_count; i++) { 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); g_parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
if (g_parser != NULL) if (g_parser != NULL)
break; break;
@@ -90,7 +90,7 @@ START_TEST(test_misc_alloc_create_parser_with_encoding) {
/* Try several levels of allocation */ /* Try several levels of allocation */
for (i = 0; i < max_alloc_count; i++) { 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); g_parser = XML_ParserCreate_MM(XCS("us-ascii"), &memsuite, NULL);
if (g_parser != NULL) if (g_parser != NULL)
break; break;
@@ -211,7 +211,8 @@ START_TEST(test_misc_version) {
if (! versions_equal(&read_version, &parsed_version)) if (! versions_equal(&read_version, &parsed_version))
fail("Version mismatch"); 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"); fail("XML_*_VERSION in expat.h out of sync?\n");
} }
END_TEST END_TEST
+8 -3
View File
@@ -10,7 +10,7 @@
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> 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-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com> Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.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; const unsigned int max_alloc_count = 30;
for (i = 0; i < max_alloc_count; i++) { 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 */ /* Exercise more code paths with a default handler */
XML_SetDefaultHandler(g_parser, dummy_default_handler); XML_SetDefaultHandler(g_parser, dummy_default_handler);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
@@ -454,10 +454,15 @@ START_TEST(test_nsalloc_realloc_attributes) {
nsalloc_teardown(); nsalloc_teardown();
nsalloc_setup(); nsalloc_setup();
} }
#if XML_GE == 1
assert_true(
i == 0); // because expat_realloc relies on expat_malloc to some extent
#else
if (i == 0) if (i == 0)
fail("Parsing worked despite failing reallocations"); fail("Parsing worked despite failing reallocations");
else if (i == max_realloc_count) else if (i == max_realloc_count)
fail("Parsing failed at max reallocation count"); fail("Parsing failed at max reallocation count");
#endif
} }
END_TEST END_TEST
@@ -523,7 +528,7 @@ START_TEST(test_nsalloc_realloc_binding_uri) {
/* Now repeat with a longer URI and a duff reallocator */ /* Now repeat with a longer URI and a duff reallocator */
for (i = 0; i < max_realloc_count; i++) { for (i = 0; i < max_realloc_count; i++) {
XML_ParserReset(g_parser, NULL); 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) if (_XML_Parse_SINGLE_BYTES(g_parser, second, (int)strlen(second), XML_TRUE)
!= XML_STATUS_ERROR) != XML_STATUS_ERROR)
break; break;
+20 -13
View File
@@ -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@ # @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 # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@@ -100,6 +100,8 @@ am__make_running_with_option = \
test $$has_opt = yes test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(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@ pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@
@@ -328,8 +330,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@ am__include = @am__include@
am__leading_dot = @am__leading_dot@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@ am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@ am__tar = @am__tar@
am__untar = @am__untar@ am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@ bindir = @bindir@
build = @build@ build = @build@
build_alias = @build_alias@ build_alias = @build_alias@
@@ -464,16 +468,11 @@ uninstall-binPROGRAMS:
`; \ `; \
test -n "$$list" || exit 0; \ test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files
clean-binPROGRAMS: clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ $(am__rm_f) $(bin_PROGRAMS)
echo " rm -f" $$list; \ test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=)
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
xmlwf$(EXEEXT): $(xmlwf_OBJECTS) $(xmlwf_DEPENDENCIES) $(EXTRA_xmlwf_DEPENDENCIES) xmlwf$(EXEEXT): $(xmlwf_OBJECTS) $(xmlwf_DEPENDENCIES) $(EXTRA_xmlwf_DEPENDENCIES)
@rm -f xmlwf$(EXEEXT) @rm -f xmlwf$(EXEEXT)
@@ -492,7 +491,7 @@ distclean-compile:
$(am__depfiles_remade): $(am__depfiles_remade):
@$(MKDIR_P) $(@D) @$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@ @: >>$@
am--depfiles: $(am__depfiles_remade) am--depfiles: $(am__depfiles_remade)
@@ -630,6 +629,7 @@ cscopelist-am: $(am__tagged_files)
distclean-tags: distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am $(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -694,8 +694,8 @@ mostlyclean-generic:
clean-generic: clean-generic:
distclean-generic: distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic: maintainer-clean-generic:
@echo "This command is intended for maintainers to use" @echo "This command is intended for maintainers to use"
@@ -798,3 +798,10 @@ uninstall-am: uninstall-binPROGRAMS
# Tell versions [3.59,3.63) of GNU make to not export all variables. # 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. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+3 -3
View File
@@ -10,7 +10,7 @@
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2001-2002 Fred L. Drake, Jr. <fdrake@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) 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> Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Licensed under the MIT license: Licensed under the MIT license:
@@ -41,6 +41,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> // NULL
#include <unistd.h> #include <unistd.h>
#ifndef MAP_FILE #ifndef MAP_FILE
@@ -93,8 +94,7 @@ filemap(const tchar *name,
close(fd); close(fd);
return 1; return 1;
} }
p = (void *)mmap((void *)0, (size_t)nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE, p = mmap(NULL, nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, (off_t)0);
fd, (off_t)0);
if (p == (void *)-1) { if (p == (void *)-1) {
tperror(name); tperror(name);
close(fd); close(fd);
+14 -7
View File
@@ -11,7 +11,7 @@
Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net> Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> 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) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com> Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.org> Copyright (c) 2021 Donghee Na <donghee.na@python.org>
@@ -56,12 +56,19 @@
#include "xmltchar.h" #include "xmltchar.h"
#include "filemap.h" #include "filemap.h"
/* Function "read": */
#if defined(_MSC_VER) #if defined(_MSC_VER)
# include <io.h> # include <io.h>
#endif /* https://msdn.microsoft.com/en-us/library/wyssk1bs(v=vs.100).aspx */
# define EXPAT_read _read
#ifdef HAVE_UNISTD_H # define EXPAT_read_count_t int
# define EXPAT_read_req_t unsigned int
#else /* POSIX */
# include <unistd.h> # 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 #endif
#ifndef O_BINARY #ifndef O_BINARY
@@ -192,7 +199,7 @@ processStream(const XML_Char *filename, XML_Parser parser) {
} }
} }
for (;;) { for (;;) {
int nread; EXPAT_read_count_t nread;
char *buf = (char *)XML_GetBuffer(parser, g_read_size_bytes); char *buf = (char *)XML_GetBuffer(parser, g_read_size_bytes);
if (! buf) { if (! buf) {
if (filename != NULL) if (filename != NULL)
@@ -201,14 +208,14 @@ processStream(const XML_Char *filename, XML_Parser parser) {
filename != NULL ? filename : T("xmlwf")); filename != NULL ? filename : T("xmlwf"));
return 0; 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) { if (nread < 0) {
tperror(filename != NULL ? filename : T("STDIN")); tperror(filename != NULL ? filename : T("STDIN"));
if (filename != NULL) if (filename != NULL)
close(fd); close(fd);
return 0; 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")); reportError(parser, filename != NULL ? filename : T("STDIN"));
if (filename != NULL) if (filename != NULL)
close(fd); close(fd);
+17 -4
View File
@@ -11,7 +11,7 @@
Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2004-2009 Karl Waclawek <karl@waclawek.net> Copyright (c) 2004-2009 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> 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) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com> Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Joe Orton <jorton@redhat.com> Copyright (c) 2020 Joe Orton <jorton@redhat.com>
@@ -305,7 +305,7 @@ static XML_Char *
xcsdup(const XML_Char *s) { xcsdup(const XML_Char *s) {
XML_Char *result; XML_Char *result;
int count = 0; int count = 0;
int numBytes; size_t numBytes;
/* Get the length of the string, including terminator */ /* Get the length of the string, including terminator */
while (s[count++] != 0) { 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(" -t write no XML output for [t]iming of plain parsing\n")
T(" -N enable adding doctype and [n]otation declarations\n") T(" -N enable adding doctype and [n]otation declarations\n")
T("\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(" NOTE: If you ever need to increase these values for non-attack payload, please file a bug report.\n")
T("\n") T("\n")
T(" -a FACTOR set maximum tolerated [a]mplification factor (default: 100.0)\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("\n")
T("reparse deferral:\n") T("reparse deferral:\n")
T(" -q disable reparse deferral, and allow [q]uadratic parse runtime with large tokens\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(" -h, --help show this [h]elp message and exit\n")
T(" -v, --version show program's [v]ersion number and exit\n") T(" -v, --version show program's [v]ersion number and exit\n")
T("\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("exit status:\n")
T(" 0 the input files are well-formed and the output (if requested) was written successfully\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") 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 #if XML_GE == 1
XML_SetBillionLaughsAttackProtectionMaximumAmplification( XML_SetBillionLaughsAttackProtectionMaximumAmplification(
parser, attackMaximumAmplification); parser, attackMaximumAmplification);
XML_SetAllocTrackerMaximumAmplification(parser,
attackMaximumAmplification);
#endif #endif
} }
if (attackThresholdGiven) { if (attackThresholdGiven) {
#if XML_GE == 1 #if XML_GE == 1
XML_SetBillionLaughsAttackProtectionActivationThreshold( XML_SetBillionLaughsAttackProtectionActivationThreshold(
parser, attackThresholdBytes); parser, attackThresholdBytes);
XML_SetAllocTrackerActivationThreshold(parser, attackThresholdBytes);
#else #else
(void)attackThresholdBytes; // silence -Wunused-but-set-variable (void)attackThresholdBytes; // silence -Wunused-but-set-variable
#endif #endif
+14 -4
View File
@@ -6,7 +6,7 @@
# \___/_/\_\ .__/ \__,_|\__| # \___/_/\_\ .__/ \__,_|\__|
# |_| XML parser # |_| 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> # Copyright (c) 2021 Tim Bray <tbray@textuality.com>
# Licensed under the MIT license: # Licensed under the MIT license:
# #
@@ -32,6 +32,16 @@
import argparse import argparse
epilog = """ 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: exit status:
0 the input files are well-formed and the output (if requested) was written successfully 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 1 could not allocate data structures, signals a serious problem with execution environment
@@ -74,16 +84,16 @@
output_mode.add_argument('-t', action='store_true', help='write no XML output for [t]iming of plain parsing') 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') 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: ' description='NOTE: '
'If you ever need to increase these values ' 'If you ever need to increase these values '
'for non-attack payload, please file a bug report.') 'for non-attack payload, please file a bug report.')
billion_laughs.add_argument('-a', metavar='FACTOR', billion_laughs.add_argument('-a', metavar='FACTOR',
help='set maximum tolerated [a]mplification factor (default: 100.0)') 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 = 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') 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)') parser.add_argument('files', metavar='FILE', nargs='*', help='file to process (default: STDIN)')