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 !!
!! in order to (1) have a sound fix ready before the end of a 90 days !!
!! grace period and (2) in a sustainable manner, !!
!! - helping CPython Expat bindings with supporting Expat's billion laughs !!
!! - helping CPython Expat bindings with supporting Expat's amplification !!
!! attack protection API (https://github.com/python/cpython/issues/90949): !!
!! - XML_SetAllocTrackerActivationThreshold !!
!! - XML_SetAllocTrackerMaximumAmplification !!
!! - XML_SetBillionLaughsAttackProtectionActivationThreshold !!
!! - XML_SetBillionLaughsAttackProtectionMaximumAmplification !!
!! - helping Perl's XML::Parser Expat bindings with supporting Expat's !!
!! security API (https://github.com/cpan-authors/XML-Parser/issues/102): !!
!! - XML_SetAllocTrackerActivationThreshold !!
!! - XML_SetAllocTrackerMaximumAmplification !!
!! - XML_SetBillionLaughsAttackProtectionActivationThreshold !!
!! - XML_SetBillionLaughsAttackProtectionMaximumAmplification !!
!! - XML_SetReparseDeferralEnabled !!
@@ -37,6 +41,79 @@
!! THANK YOU! Sebastian Pipping -- Berlin, 2024-03-09 !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Release 2.7.2 Tue September 16 2025
Security fixes:
#1018 #1034 CVE-2025-59375 -- Disallow use of disproportional amounts of
dynamic memory from within an Expat parser (e.g. previously
a ~250 KiB sized document was able to cause allocation of
~800 MiB from the heap, i.e. an "amplification" of factor
~3,300); once a threshold (that defaults to 64 MiB) is
reached, a maximum amplification factor (that defaults to
100.0) is enforced, and violating documents are rejected
with an out-of-memory error.
There are two new API functions to fine-tune this new
behavior:
- XML_SetAllocTrackerActivationThreshold
- XML_SetAllocTrackerMaximumAmplification .
If you ever need to increase these defaults for non-attack
XML payload, please file a bug report with libexpat.
There is also a new environment variable
EXPAT_MALLOC_DEBUG=(0|1|2) to control the verbosity
of allocations debugging at runtime, disabled by default.
Known impact is (reliable and easy) denial of service:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H/E:H/RL:O/RC:C
(Base Score: 7.5, Temporal Score: 7.2)
Please note that a layer of compression around XML can
significantly reduce the minimum attack payload size.
Distributors intending to backport (or cherry-pick) the
fix need to copy 99% of the related pull request, not just
the "lib: Implement tracking of dynamic memory allocations"
commit, to not end up with a state that literally does both
too much and too little at the same time. Appending ".diff"
to the pull request URL could be of help.
Other changes:
#1008 #1017 Autotools: Sync CMake templates with CMake 3.31 for macOS
#1007 CMake: Drop support for CMake <3.15
#1004 CMake: Fix off_t detection for -Werror
#1007 CMake|Windows: Fix -DEXPAT_MSVC_STATIC_CRT=ON
#1013 Windows: Drop support for Visual Studio <=16.0/2019
#1026 xmlwf: Mention supported environment variables in
--help output
#1024 xmlwf: Fix (internal) help generator
#1034 docs: Promote the contract to call function
XML_FreeContentModel when registering a custom
element declaration handler (via a call to function
XML_SetElementDeclHandler)
#1027 docs: Add missing <p>..</p> wrap
#994 docs: Drop AppVeyor badge
#1000 tests: Fix portable_strndup
#1036 Drop casts around malloc/free/realloc that C99 does not need
#1010 Replace empty for-loops with while loops
#1011 Add const with internal XmlInitUnknownEncodingNS
#14 #1037 Drop an OpenVMS support leftover
#999 #1001 Address more clang-tidy warnings
#1030 #1038 Version info bumped from 11:2:10 (libexpat*.so.1.10.2)
to 12:0:11 (libexpat*.so.1.11.0); see https://verbump.de/
for what these numbers do
Infrastructure:
#1003 CI: Cover compilation on FreeBSD
#1009 #1035 CI: Upgrade Clang from 19 to 21
#1031 CI: Make calling Cppcheck without --suppress=objectIndex
and --suppress=unknownMacro possible
#1013 CI|Windows: Get off of deprecated image "windows-2019"
#1008 #1017 ..
#1023 #1025 CI: Adapt to breaking changes in GitHub Actions
Special thanks to:
Alexander Bluhm
Neil Pang
Theo Buehler
and
OSS-Fuzz / ClusterFuzz
Perl XML::Parser
Release 2.7.1 Thu March 27 2025
Bug fixes:
#980 #989 Restore event pointer behavior from Expat 2.6.4
@@ -54,7 +131,7 @@ Release 2.7.1 Thu March 27 2025
#983 #984 Fix printf format specifiers for 32bit Emscripten
#992 docs: Promote OpenSSF Best Practices self-certification
#978 tests/benchmark: Resolve mistaken double close
#986 Address compiler warnings
#986 Address Frama-C warnings
#990 #993 Version info bumped from 11:1:10 (libexpat*.so.1.10.1)
to 11:2:10 (libexpat*.so.1.10.2); see https://verbump.de/
for what these numbers do
+4 -3
View File
@@ -58,10 +58,8 @@ pkgconfig_DATA = expat.pc
pkgconfigdir = $(libdir)/pkgconfig
dist_cmake_DATA = \
cmake/autotools/expat.cmake
nodist_cmake_DATA = \
cmake/autotools/expat.cmake \
cmake/autotools/expat-config-version.cmake \
cmake/autotools/expat-noconfig.cmake \
cmake/expat-config.cmake
@@ -70,6 +68,9 @@ cmakedir = $(libdir)/cmake/expat-@PACKAGE_VERSION@
_EXTRA_DIST_CMAKE = \
cmake/autotools/expat__linux.cmake.in \
cmake/autotools/expat__macos.cmake.in \
cmake/autotools/expat__windows.cmake.in \
cmake/autotools/expat-noconfig__linux.cmake.in \
cmake/autotools/expat-noconfig__macos.cmake.in \
cmake/autotools/expat-noconfig__windows.cmake.in \
+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@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -105,6 +105,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
am__rm_f = rm -f $(am__rm_f_notfound)
am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -145,12 +147,13 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(dist_cmake_DATA) $(am__DIST_COMMON)
$(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = expat_config.h
CONFIG_CLEAN_FILES = expat.pc cmake/expat-config.cmake \
cmake/autotools/expat.cmake \
cmake/autotools/expat-config-version.cmake \
cmake/autotools/expat-noconfig.cmake run.sh
CONFIG_CLEAN_VPATH_FILES =
@@ -203,14 +206,12 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { 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)" \
"$(DESTDIR)$(pkgconfigdir)"
DATA = $(dist_cmake_DATA) $(nodist_cmake_DATA) $(pkgconfig_DATA)
am__installdirs = "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(pkgconfigdir)"
DATA = $(nodist_cmake_DATA) $(pkgconfig_DATA)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
@@ -256,8 +257,8 @@ distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -rf "$(distdir)" \
find "$(distdir)" -type d ! -perm -700 -exec chmod u+rwx {} ';' \
; rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
@@ -288,14 +289,16 @@ am__relativize = \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).tar.lz \
$(distdir).tar.xz
GZIP_ENV = --best
GZIP_ENV = -9
DIST_TARGETS = dist-lzip dist-xz dist-bzip2 dist-gzip
# Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
distcleancheck_listfiles = \
find . \( -type f -a \! \
\( -name .nfs* -o -name .smb* -o -name .__afs* \) \) -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@
@@ -403,8 +406,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -458,16 +463,17 @@ LIBTOOLFLAGS = --verbose
SUBDIRS = lib $(am__append_1) $(am__append_2) $(am__append_3)
pkgconfig_DATA = expat.pc
pkgconfigdir = $(libdir)/pkgconfig
dist_cmake_DATA = \
cmake/autotools/expat.cmake
nodist_cmake_DATA = \
cmake/autotools/expat.cmake \
cmake/autotools/expat-config-version.cmake \
cmake/autotools/expat-noconfig.cmake \
cmake/expat-config.cmake
cmakedir = $(libdir)/cmake/expat-@PACKAGE_VERSION@
_EXTRA_DIST_CMAKE = \
cmake/autotools/expat__linux.cmake.in \
cmake/autotools/expat__macos.cmake.in \
cmake/autotools/expat__windows.cmake.in \
cmake/autotools/expat-noconfig__linux.cmake.in \
cmake/autotools/expat-noconfig__macos.cmake.in \
cmake/autotools/expat-noconfig__windows.cmake.in \
@@ -552,12 +558,12 @@ expat_config.h: stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/expat_config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status expat_config.h
$(AM_V_at)rm -f stamp-h1
$(AM_V_GEN)cd $(top_builddir) && $(SHELL) ./config.status expat_config.h
$(srcdir)/expat_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
$(AM_V_GEN)($(am__cd) $(top_srcdir) && $(AUTOHEADER))
$(AM_V_at)rm -f stamp-h1
$(AM_V_at)touch $@
distclean-hdr:
-rm -f expat_config.h stamp-h1
@@ -565,6 +571,8 @@ expat.pc: $(top_builddir)/config.status $(srcdir)/expat.pc.in
cd $(top_builddir) && $(SHELL) ./config.status $@
cmake/expat-config.cmake: $(top_builddir)/config.status $(top_srcdir)/cmake/expat-config.cmake.in
cd $(top_builddir) && $(SHELL) ./config.status $@
cmake/autotools/expat.cmake: $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $@
cmake/autotools/expat-config-version.cmake: $(top_builddir)/config.status $(top_srcdir)/cmake/autotools/expat-config-version.cmake.in
cd $(top_builddir) && $(SHELL) ./config.status $@
cmake/autotools/expat-noconfig.cmake: $(top_builddir)/config.status
@@ -580,27 +588,6 @@ clean-libtool:
distclean-libtool:
-rm -f libtool config.lt
install-dist_cmakeDATA: $(dist_cmake_DATA)
@$(NORMAL_INSTALL)
@list='$(dist_cmake_DATA)'; test -n "$(cmakedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(cmakedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(cmakedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(cmakedir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(cmakedir)" || exit $$?; \
done
uninstall-dist_cmakeDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_cmake_DATA)'; test -n "$(cmakedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(cmakedir)'; $(am__uninstall_files_from_dir)
install-nodist_cmakeDATA: $(nodist_cmake_DATA)
@$(NORMAL_INSTALL)
@list='$(nodist_cmake_DATA)'; test -n "$(cmakedir)" || list=; \
@@ -749,12 +736,13 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
$(AM_V_at)$(MKDIR_P) "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@@ -822,6 +810,10 @@ dist-gzip: distdir
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__post_remove_distdir)
dist-bzip3: distdir
tardir=$(distdir) && $(am__tar) | bzip3 -c >$(distdir).tar.bz3
$(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__post_remove_distdir)
@@ -862,9 +854,11 @@ dist dist-all:
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.bz3*) \
bzip3 -dc $(distdir).tar.bz3 | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
@@ -872,7 +866,7 @@ distcheck: dist
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
eval GZIP= gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
*.tar.zst*) \
@@ -948,7 +942,7 @@ check: check-recursive
all-am: Makefile $(DATA) expat_config.h
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(pkgconfigdir)"; do \
for dir in "$(DESTDIR)$(cmakedir)" "$(DESTDIR)$(pkgconfigdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
@@ -975,8 +969,8 @@ mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -1003,8 +997,7 @@ info: info-recursive
info-am:
install-data-am: install-dist_cmakeDATA install-nodist_cmakeDATA \
install-pkgconfigDATA
install-data-am: install-nodist_cmakeDATA install-pkgconfigDATA
install-dvi: install-dvi-recursive
@@ -1050,29 +1043,27 @@ ps: ps-recursive
ps-am:
uninstall-am: uninstall-dist_cmakeDATA uninstall-nodist_cmakeDATA \
uninstall-pkgconfigDATA
uninstall-am: uninstall-nodist_cmakeDATA uninstall-pkgconfigDATA
.MAKE: $(am__recursive_targets) all install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--refresh check check-am clean clean-cscope clean-generic \
clean-libtool cscope cscopelist-am ctags ctags-am dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
dist-xz dist-zip dist-zstd distcheck distclean \
dist-all dist-bzip2 dist-bzip3 dist-gzip dist-lzip dist-shar \
dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \
distclean-generic distclean-hdr distclean-libtool \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dist_cmakeDATA \
install-dvi install-dvi-am install-exec install-exec-am \
install-html install-html-am install-info install-info-am \
install-man install-nodist_cmakeDATA install-pdf \
install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am \
uninstall-dist_cmakeDATA uninstall-nodist_cmakeDATA \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man \
install-nodist_cmakeDATA install-pdf install-pdf-am \
install-pkgconfigDATA install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs installdirs-am \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-nodist_cmakeDATA \
uninstall-pkgconfigDATA
.PRECIOUS: Makefile
@@ -1149,3 +1140,10 @@ qa:
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+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)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/libexpat/libexpat?svg=true)](https://ci.appveyor.com/project/libexpat/libexpat)
[![Packaging status](https://repology.org/badge/tiny-repos/expat.svg)](https://repology.org/metapackage/expat/versions)
[![Downloads SourceForge](https://img.shields.io/sourceforge/dt/expat?label=Downloads%20SourceForge)](https://sourceforge.net/projects/expat/files/)
[![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
@@ -12,7 +11,7 @@
> at the top of the `Changes` file.
# Expat, Release 2.7.1
# Expat, Release 2.7.2
This is Expat, a C99 library for parsing
[XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by
@@ -27,7 +26,8 @@ Expat supports the following C99 compilers:
- GNU GCC >=4.5 (for use from C) or GNU GCC >=4.8.1 (for use from C++)
- LLVM Clang >=3.5
- Microsoft Visual Studio >=16.0/2019 (rolling `${today} minus 5 years`)
- Microsoft Visual Studio >=17.0/2022
(the oldest version supported by the [official GitHub Actions Windows images](https://github.com/actions/runner-images))
Windows users can use the
[`expat-win32bin-*.*.*.{exe,zip}` download](https://github.com/libexpat/libexpat/releases),
+16 -6
View File
@@ -84,9 +84,9 @@ dnl
dnl If the API changes incompatibly set LIBAGE back to 0
dnl
LIBCURRENT=11 # sync
LIBREVISION=2 # with
LIBAGE=10 # CMakeLists.txt!
LIBCURRENT=12 # sync
LIBREVISION=0 # with
LIBAGE=11 # CMakeLists.txt!
AC_CONFIG_HEADERS([expat_config.h])
AH_TOP([#ifndef EXPAT_CONFIG_H
@@ -440,12 +440,22 @@ AC_MSG_RESULT([${CMAKE_SHARED_LIBRARY_PREFIX}])
AC_SUBST([CMAKE_SHARED_LIBRARY_PREFIX])
AS_CASE("${host_os}",
[darwin*], [CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__macos.cmake.in],
[mingw*|cygwin*], [CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__windows.cmake.in],
[CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__linux.cmake.in])
[darwin*], [
CMAKE_SOURCE=cmake/autotools/expat__macos.cmake.in
CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__macos.cmake.in
],
[mingw*|cygwin*], [
CMAKE_SOURCE=cmake/autotools/expat__windows.cmake.in
CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__windows.cmake.in
],
[
CMAKE_SOURCE=cmake/autotools/expat__linux.cmake.in
CMAKE_NOCONFIG_SOURCE=cmake/autotools/expat-noconfig__linux.cmake.in
])
AC_CONFIG_FILES([Makefile]
[expat.pc]
[cmake/expat-config.cmake]
[cmake/autotools/expat.cmake:${CMAKE_SOURCE}]
[cmake/autotools/expat-config-version.cmake]
[cmake/autotools/expat-noconfig.cmake:${CMAKE_NOCONFIG_SOURCE}]
[doc/Makefile]
+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@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -102,6 +102,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
am__rm_f = rm -f $(am__rm_f_notfound)
am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -184,10 +186,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { 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
am__installdirs = "$(DESTDIR)$(man1dir)"
@@ -303,8 +304,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -442,6 +445,7 @@ ctags CTAGS:
cscope cscopelist:
@WITH_DISTRIBUTABLE_MANPAGE_TRUE@dist-hook:
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -507,11 +511,11 @@ install-strip:
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-$(am__rm_f) $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -616,3 +620,10 @@ uninstall-man: uninstall-man1
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+123 -7
View File
@@ -52,7 +52,7 @@
<div>
<h1>
The Expat XML Parser
<small>Release 2.7.1</small>
<small>Release 2.7.2</small>
</h1>
</div>
<div class="content">
@@ -157,6 +157,8 @@ interface.</p>
<ul>
<li><a href="#XML_SetBillionLaughsAttackProtectionMaximumAmplification">XML_SetBillionLaughsAttackProtectionMaximumAmplification</a></li>
<li><a href="#XML_SetBillionLaughsAttackProtectionActivationThreshold">XML_SetBillionLaughsAttackProtectionActivationThreshold</a></li>
<li><a href="#XML_SetAllocTrackerMaximumAmplification">XML_SetAllocTrackerMaximumAmplification</a></li>
<li><a href="#XML_SetAllocTrackerActivationThreshold">XML_SetAllocTrackerActivationThreshold</a></li>
<li><a href="#XML_SetReparseDeferralEnabled">XML_SetReparseDeferralEnabled</a></li>
</ul>
</li>
@@ -319,7 +321,7 @@ directions in the next section. Otherwise if you have Microsoft's
Developer Studio installed,
you can use CMake to generate a <code>.sln</code> file, e.g.
<code>
cmake -G"Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=RelWithDebInfo .
cmake -G"Visual Studio 17 2022" -DCMAKE_BUILD_TYPE=RelWithDebInfo .
</code>, and build Expat using <code>msbuild /m expat.sln</code> after.</p>
<p>Alternatively, you may download the Win32 binary package that
@@ -1905,7 +1907,7 @@ struct XML_cp {
<p>Sets a handler for element declarations in a DTD. The handler gets
called with the name of the element in the declaration and a pointer
to a structure that contains the element model. It's the user code's
responsibility to free model when finished with it. See <code>
responsibility to free model when finished with via a call to <code>
<a href="#XML_FreeContentModel">XML_FreeContentModel</a></code>.
There is no need to free the model from the handler, it can be kept
around and freed at a later stage.</p>
@@ -2198,13 +2200,13 @@ XML_SetBillionLaughsAttackProtectionMaximumAmplification(XML_Parser p,
returns <code>XML_TRUE</code> upon success and <code>XML_FALSE</code> upon error.
</p>
The amplification factor is calculated as ..
<pre>
amplification := (direct + indirect) / direct
</pre>
<p>The amplification factor is calculated as ..</p>
<pre>amplification := (direct + indirect) / direct</pre>
<p>
.. while parsing, whereas
<code>direct</code> is the number of bytes read from the primary document in parsing and
<code>indirect</code> is the number of bytes added by expanding entities and reading of external DTD files, combined.
</p>
<p>For a call to <code>XML_SetBillionLaughsAttackProtectionMaximumAmplification</code> to succeed:</p>
<ul>
@@ -2267,6 +2269,120 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(XML_Parser p,
</p>
</div>
<h4 id="XML_SetAllocTrackerMaximumAmplification">XML_SetAllocTrackerMaximumAmplification</h4>
<pre class="fcndec">
/* Added in Expat 2.7.2. */
XML_Bool
XML_SetAllocTrackerMaximumAmplification(XML_Parser p,
float maximumAmplificationFactor);
</pre>
<div class="fcndef">
<p>
Sets the maximum tolerated amplification factor
between direct input and bytes of dynamic memory allocated
(default: <code>100.0</code>)
of parser <code>p</code> to <code>maximumAmplificationFactor</code>, and
returns <code>XML_TRUE</code> upon success and <code>XML_FALSE</code> upon error.
</p>
<p>
<strong>Note:</strong>
There are three types of allocations that intentionally bypass tracking and limiting:
</p>
<ul>
<li>
application calls to functions
<code><a href="#XML_MemMalloc">XML_MemMalloc</a></code>
and
<code><a href="#XML_MemRealloc">XML_MemRealloc</a></code>
&mdash;
<em>healthy</em> use of these two functions continues to be a responsibility
of the application using Expat
&mdash;,
</li>
<li>
the main character buffer used by functions
<code><a href="#XML_GetBuffer">XML_GetBuffer</a></code>
and
<code><a href="#XML_ParseBuffer">XML_ParseBuffer</a></code>
(and thus also by plain
<code><a href="#XML_Parse">XML_Parse</a></code>), and
</li>
<li>
the <a href="#XML_SetElementDeclHandler">content model memory</a>
(that is passed to the
<a href="#XML_SetElementDeclHandler">element declaration handler</a>
and freed by a call to
<code><a href="#XML_FreeContentModel">XML_FreeContentModel</a></code>).
</li>
</ul>
<p>The amplification factor is calculated as ..</p>
<pre>amplification := allocated / direct</pre>
<p>
.. while parsing, whereas
<code>direct</code> is the number of bytes read from the primary document in parsing and
<code>allocated</code> is the number of bytes of dynamic memory allocated in the parser hierarchy.
</p>
<p>For a call to <code>XML_SetAllocTrackerMaximumAmplification</code> to succeed:</p>
<ul>
<li>parser <code>p</code> must be a non-<code>NULL</code> root parser (without any parent parsers) and</li>
<li><code>maximumAmplificationFactor</code> must be non-<code>NaN</code> and greater than or equal to <code>1.0</code>.</li>
</ul>
<p>
<strong>Note:</strong>
If you ever need to increase this value for non-attack payload,
please <a href="https://github.com/libexpat/libexpat/issues">file a bug report</a>.
</p>
<p>
<strong>Note:</strong>
Amplifications factors greater than 100 can been observed near the start of parsing
even with benign files in practice.
So if you do reduce the maximum allowed amplification,
please make sure that the activation threshold is still big enough
to not end up with undesired false positives (i.e. benign files being rejected).
</p>
</div>
<h4 id="XML_SetAllocTrackerActivationThreshold">XML_SetAllocTrackerActivationThreshold</h4>
<pre class="fcndec">
/* Added in Expat 2.7.2. */
XML_Bool
XML_SetAllocTrackerActivationThreshold(XML_Parser p,
unsigned long long activationThresholdBytes);
</pre>
<div class="fcndef">
<p>
Sets number of allocated bytes of dynamic memory
needed to activate protection against disproportionate use of RAM
(default: <code>64 MiB</code>)
of parser <code>p</code> to <code>activationThresholdBytes</code>, and
returns <code>XML_TRUE</code> upon success and <code>XML_FALSE</code> upon error.
</p>
<p>
<strong>Note:</strong>
For types of allocations that intentionally bypass tracking and limiting, please see
<code><a href="#XML_SetAllocTrackerMaximumAmplification">XML_SetAllocTrackerMaximumAmplification</a></code>
above.
</p>
<p>For a call to <code>XML_SetAllocTrackerActivationThreshold</code> to succeed:</p>
<ul>
<li>parser <code>p</code> must be a non-<code>NULL</code> root parser (without any parent parsers).</li>
</ul>
<p>
<strong>Note:</strong>
If you ever need to increase this value for non-attack payload,
please <a href="https://github.com/libexpat/libexpat/issues">file a bug report</a>.
</p>
</div>
<h4 id="XML_SetReparseDeferralEnabled">XML_SetReparseDeferralEnabled</h4>
<pre class="fcndec">
/* Added in Expat 2.6.0. */
+23 -7
View File
@@ -5,7 +5,7 @@
\\$2 \(la\\$1\(ra\\$3
..
.if \n(.g .mso www.tmac
.TH XMLWF 1 "March 27, 2025" "" ""
.TH XMLWF 1 "September 16, 2025" "" ""
.SH NAME
xmlwf \- Determines if an XML document is well-formed
.SH SYNOPSIS
@@ -88,7 +88,11 @@ supports both.
.TP
\*(T<\fB\-a\fR\*(T> \fIfactor\fR
Sets the maximum tolerated amplification factor
for protection against billion laughs attacks (default: 100.0).
for protection against amplification attacks
like the billion laughs attack
(default: 100.0
for the sum of direct and indirect output and also
for allocations of dynamic memory).
The amplification factor is calculated as ..
.nf
@@ -97,12 +101,22 @@ The amplification factor is calculated as ..
.fi
\&.. while parsing, whereas
\&.. with regard to use of entities and ..
.nf
amplification := allocated / direct
.fi
\&.. with regard to dynamic memory while parsing.
<direct> is the number of bytes read
from the primary document in parsing and
from the primary document in parsing,
<indirect> is the number of bytes
added by expanding entities and reading of external DTD files,
combined.
combined, and
<allocated> is the total number of bytes of dynamic memory
allocated (and not freed) per hierarchy of parsers.
\fINOTE\fR:
If you ever need to increase this value for non-attack payload,
@@ -110,8 +124,10 @@ please file a bug report.
.TP
\*(T<\fB\-b\fR\*(T> \fIbytes\fR
Sets the number of output bytes (including amplification)
needed to activate protection against billion laughs attacks
(default: 8 MiB).
needed to activate protection against amplification attacks
like billion laughs
(default: 8 MiB for the sum of direct and indirect output,
and 64 MiB for allocations of dynamic memory).
This can be thought of as an "activation threshold".
\fINOTE\fR:
+21 -7
View File
@@ -21,7 +21,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY dhfirstname "<firstname>Scott</firstname>">
<!ENTITY dhsurname "<surname>Bronson</surname>">
<!ENTITY dhdate "<date>March 27, 2025</date>">
<!ENTITY dhdate "<date>September 16, 2025</date>">
<!-- Please adjust this^^ date whenever cutting a new release. -->
<!ENTITY dhsection "<manvolnum>1</manvolnum>">
<!ENTITY dhemail "<email>bronson@rinspin.com</email>">
@@ -158,19 +158,31 @@ supports both.
<listitem>
<para>
Sets the maximum tolerated amplification factor
for protection against billion laughs attacks (default: 100.0).
for protection against amplification attacks
like the billion laughs attack
(default: 100.0
for the sum of direct and indirect output and also
for allocations of dynamic memory).
The amplification factor is calculated as ..
</para>
<literallayout>
amplification := (direct + indirect) / direct
</literallayout>
<para>
.. while parsing, whereas
.. with regard to use of entities and ..
</para>
<literallayout>
amplification := allocated / direct
</literallayout>
<para>
.. with regard to dynamic memory while parsing.
&lt;direct&gt; is the number of bytes read
from the primary document in parsing and
from the primary document in parsing,
&lt;indirect&gt; is the number of bytes
added by expanding entities and reading of external DTD files,
combined.
combined, and
&lt;allocated&gt; is the total number of bytes of dynamic memory
allocated (and not freed) per hierarchy of parsers.
</para>
<para>
<emphasis>NOTE</emphasis>:
@@ -185,8 +197,10 @@ supports both.
<listitem>
<para>
Sets the number of output bytes (including amplification)
needed to activate protection against billion laughs attacks
(default: 8 MiB).
needed to activate protection against amplification attacks
like billion laughs
(default: 8 MiB for the sum of direct and indirect output,
and 64 MiB for allocations of dynamic memory).
This can be thought of as an &quot;activation threshold&quot;.
</para>
<para>
+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@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -101,6 +101,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
am__rm_f = rm -f $(am__rm_f_notfound)
am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -330,8 +332,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -414,13 +418,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
$(am__rm_f) $(noinst_PROGRAMS)
test -z "$(EXEEXT)" || $(am__rm_f) $(noinst_PROGRAMS:$(EXEEXT)=)
element_declarations$(EXEEXT): $(element_declarations_OBJECTS) $(element_declarations_DEPENDENCIES) $(EXTRA_element_declarations_DEPENDENCIES)
@rm -f element_declarations$(EXEEXT)
@@ -446,7 +445,7 @@ distclean-compile:
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
@: >>$@
am--depfiles: $(am__depfiles_remade)
@@ -528,6 +527,7 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -589,8 +589,8 @@ mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -692,3 +692,10 @@ uninstall-am:
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+6 -6
View File
@@ -24,7 +24,7 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#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
/* Define to 1 if you have the `getrandom' function. */
@@ -33,10 +33,10 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#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
/* 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
/* Define to 1 if you have the <stdint.h> header file. */
@@ -93,7 +93,7 @@
/* Define to the version of this package. */
#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
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
@@ -133,10 +133,10 @@
/* Define to make XML Namespaces functionality available. */
#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
/* 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
#endif // ndef EXPAT_CONFIG_H
+2
View File
@@ -354,9 +354,11 @@ ExternalEntityRefHandler(XML_Parser parser, const XML_Char *context,
if (g_external_entity) {
XML_Parser ext_parser
= XML_ExternalEntityParserCreate(parser, context, g_encoding);
if (ext_parser != NULL) {
rc = Parse(ext_parser, g_external_entity, g_external_entity_size, 1);
XML_ParserFree(ext_parser);
}
}
return rc;
}
+8 -4
View File
@@ -15,6 +15,7 @@
*/
#include <assert.h>
#include <limits.h> // for INT_MAX
#include <stdint.h>
#include "expat.h"
@@ -65,8 +66,9 @@ ParseOneInput(XML_Parser p, const uint8_t *data, size_t size) {
XML_SetUserData(p, p);
XML_SetElementHandler(p, start, end);
XML_SetCharacterDataHandler(p, may_stop_character_handler);
XML_Parse(p, (const XML_Char *)data, size, 0);
if (XML_Parse(p, (const XML_Char *)data, size, 1) == XML_STATUS_ERROR) {
assert(size <= INT_MAX);
XML_Parse(p, (const XML_Char *)data, (int)size, 0);
if (XML_Parse(p, (const XML_Char *)data, (int)size, 1) == XML_STATUS_ERROR) {
XML_ErrorString(XML_GetErrorCode(p));
}
XML_GetCurrentLineNumber(p);
@@ -89,15 +91,17 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
XML_Parser externalEntityParser
= XML_ExternalEntityParserCreate(parentParser, "e1", NULL);
assert(externalEntityParser);
if (externalEntityParser != NULL) {
ParseOneInput(externalEntityParser, data, size);
XML_ParserFree(externalEntityParser);
}
XML_Parser externalDtdParser
= XML_ExternalEntityParserCreate(parentParser, NULL, NULL);
assert(externalDtdParser);
if (externalDtdParser != NULL) {
ParseOneInput(externalDtdParser, data, size);
XML_ParserFree(externalDtdParser);
}
// finally frees this parser which served as parent
XML_ParserFree(parentParser);
+10 -6
View File
@@ -15,6 +15,7 @@
*/
#include <assert.h>
#include <limits.h> // for INT_MAX
#include <stdint.h>
#include <string.h>
@@ -66,16 +67,17 @@ ParseOneInput(XML_Parser p, const uint8_t *data, size_t size) {
XML_SetUserData(p, p);
XML_SetElementHandler(p, start, end);
XML_SetCharacterDataHandler(p, may_stop_character_handler);
void *buf = XML_GetBuffer(p, size);
assert(size <= INT_MAX);
void *buf = XML_GetBuffer(p, (int)size);
assert(buf);
memcpy(buf, data, size);
XML_ParseBuffer(p, size, 0);
buf = XML_GetBuffer(p, size);
XML_ParseBuffer(p, (int)size, 0);
buf = XML_GetBuffer(p, (int)size);
if (buf == NULL) {
return;
}
memcpy(buf, data, size);
if (XML_ParseBuffer(p, size, 1) == XML_STATUS_ERROR) {
if (XML_ParseBuffer(p, (int)size, 1) == XML_STATUS_ERROR) {
XML_ErrorString(XML_GetErrorCode(p));
}
XML_GetCurrentLineNumber(p);
@@ -101,15 +103,17 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
XML_Parser externalEntityParser
= XML_ExternalEntityParserCreate(parentParser, "e1", NULL);
assert(externalEntityParser);
if (externalEntityParser != NULL) {
ParseOneInput(externalEntityParser, data, size);
XML_ParserFree(externalEntityParser);
}
XML_Parser externalDtdParser
= XML_ExternalEntityParserCreate(parentParser, NULL, NULL);
assert(externalDtdParser);
if (externalDtdParser != NULL) {
ParseOneInput(externalDtdParser, data, size);
XML_ParserFree(externalDtdParser);
}
// finally frees this parser which served as parent
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@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -104,6 +104,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
am__rm_f = rm -f $(am__rm_f_notfound)
am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -168,10 +170,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { 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)" \
"$(DESTDIR)$(includedir)"
@@ -368,8 +369,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -513,26 +516,22 @@ uninstall-libLTLIBRARIES:
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-$(am__rm_f) $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
$(am__rm_f) $${locs}
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-$(am__rm_f) $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
$(am__rm_f) $${locs}
libexpat.la: $(libexpat_la_OBJECTS) $(libexpat_la_DEPENDENCIES) $(EXTRA_libexpat_la_DEPENDENCIES)
$(AM_V_CCLD)$(libexpat_la_LINK) -rpath $(libdir) $(libexpat_la_OBJECTS) $(libexpat_la_LIBADD) $(LIBS)
@@ -555,7 +554,7 @@ distclean-compile:
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
@: >>$@
am--depfiles: $(am__depfiles_remade)
@@ -700,6 +699,7 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -764,8 +764,8 @@ mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -885,3 +885,10 @@ uninstall-local:
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+37 -24
View File
@@ -42,21 +42,21 @@
*/
#ifndef Expat_INCLUDED
#define Expat_INCLUDED 1
# define Expat_INCLUDED 1
#include <stdlib.h>
#include "expat_external.h"
# include <stdlib.h>
# include "expat_external.h"
#ifdef __cplusplus
# ifdef __cplusplus
extern "C" {
#endif
# endif
struct XML_ParserStruct;
typedef struct XML_ParserStruct *XML_Parser;
typedef unsigned char XML_Bool;
#define XML_TRUE ((XML_Bool)1)
#define XML_FALSE ((XML_Bool)0)
# define XML_TRUE ((XML_Bool)1)
# define XML_FALSE ((XML_Bool)0)
/* The XML_Status enum gives the possible return values for several
API functions. The preprocessor #defines are included so this
@@ -73,11 +73,11 @@ typedef unsigned char XML_Bool;
*/
enum XML_Status {
XML_STATUS_ERROR = 0,
#define XML_STATUS_ERROR XML_STATUS_ERROR
# define XML_STATUS_ERROR XML_STATUS_ERROR
XML_STATUS_OK = 1,
#define XML_STATUS_OK XML_STATUS_OK
# define XML_STATUS_OK XML_STATUS_OK
XML_STATUS_SUSPENDED = 2
#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
# define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
};
enum XML_Error {
@@ -680,7 +680,7 @@ XMLPARSEAPI(void)
XML_SetUserData(XML_Parser parser, void *userData);
/* Returns the last value set by XML_SetUserData or NULL. */
#define XML_GetUserData(parser) (*(void **)(parser))
# define XML_GetUserData(parser) (*(void **)(parser))
/* This is equivalent to supplying an encoding argument to
XML_ParserCreate. On success XML_SetEncoding returns non-zero,
@@ -752,7 +752,7 @@ XML_GetSpecifiedAttributeCount(XML_Parser parser);
XMLPARSEAPI(int)
XML_GetIdAttributeIndex(XML_Parser parser);
#ifdef XML_ATTR_INFO
# ifdef XML_ATTR_INFO
/* Source file byte offsets for the start and end of attribute names and values.
The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
file an attribute value of "blah" will yield:
@@ -773,7 +773,7 @@ typedef struct {
*/
XMLPARSEAPI(const XML_AttrInfo *)
XML_GetAttributeInfo(XML_Parser parser);
#endif
# endif
/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
detected. The last call to XML_Parse must have isFinal true; len
@@ -970,9 +970,9 @@ XMLPARSEAPI(const char *)
XML_GetInputContext(XML_Parser parser, int *offset, int *size);
/* For backwards compatibility with previous versions. */
#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
# define XML_GetErrorLineNumber XML_GetCurrentLineNumber
# define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
# define XML_GetErrorByteIndex XML_GetCurrentByteIndex
/* Frees the content model passed to the element declaration handler */
XMLPARSEAPI(void)
@@ -1032,7 +1032,10 @@ enum XML_FeatureEnum {
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
/* Added in Expat 2.6.0. */
XML_FEATURE_GE
XML_FEATURE_GE,
/* Added in Expat 2.7.2. */
XML_FEATURE_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT,
XML_FEATURE_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT,
/* Additional features must be added to the end of this enum. */
};
@@ -1045,7 +1048,7 @@ typedef struct {
XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void);
#if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1)
# if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1)
/* Added in Expat 2.4.0 for XML_DTD defined and
* added in Expat 2.6.0 for XML_GE == 1. */
XMLPARSEAPI(XML_Bool)
@@ -1057,7 +1060,17 @@ XML_SetBillionLaughsAttackProtectionMaximumAmplification(
XMLPARSEAPI(XML_Bool)
XML_SetBillionLaughsAttackProtectionActivationThreshold(
XML_Parser parser, unsigned long long activationThresholdBytes);
#endif
/* Added in Expat 2.7.2. */
XMLPARSEAPI(XML_Bool)
XML_SetAllocTrackerMaximumAmplification(XML_Parser parser,
float maximumAmplificationFactor);
/* Added in Expat 2.7.2. */
XMLPARSEAPI(XML_Bool)
XML_SetAllocTrackerActivationThreshold(
XML_Parser parser, unsigned long long activationThresholdBytes);
# endif
/* Added in Expat 2.6.0. */
XMLPARSEAPI(XML_Bool)
@@ -1066,12 +1079,12 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
/* Expat follows the semantic versioning convention.
See https://semver.org
*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 7
#define XML_MICRO_VERSION 1
# define XML_MAJOR_VERSION 2
# define XML_MINOR_VERSION 7
# define XML_MICRO_VERSION 2
#ifdef __cplusplus
# ifdef __cplusplus
}
#endif
# endif
#endif /* not Expat_INCLUDED */
+32 -31
View File
@@ -38,7 +38,7 @@
*/
#ifndef Expat_External_INCLUDED
#define Expat_External_INCLUDED 1
# define Expat_External_INCLUDED 1
/* External API definitions */
@@ -64,7 +64,7 @@
compiled with the cdecl calling convention as the default since
system headers may assume the cdecl convention.
*/
#ifndef XMLCALL
# ifndef XMLCALL
# if defined(_MSC_VER)
# define XMLCALL __cdecl
# elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER)
@@ -82,62 +82,63 @@
*/
# define XMLCALL
# endif
#endif /* not defined XMLCALL */
# endif /* not defined XMLCALL */
#if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
# if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
# ifndef XML_BUILDING_EXPAT
/* 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)
# endif
# endif
#endif /* not defined XML_STATIC */
# endif /* not defined XML_STATIC */
#ifndef XML_ENABLE_VISIBILITY
# ifndef XML_ENABLE_VISIBILITY
# define XML_ENABLE_VISIBILITY 0
#endif
# endif
#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
# if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
# define XMLIMPORT __attribute__((visibility("default")))
#endif
# endif
/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
# ifndef XMLIMPORT
# define XMLIMPORT
#endif
# endif
#if defined(__GNUC__) \
# if defined(__GNUC__) \
&& (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
# define XML_ATTR_MALLOC __attribute__((__malloc__))
#else
# else
# define XML_ATTR_MALLOC
#endif
# endif
#if defined(__GNUC__) \
# if defined(__GNUC__) \
&& ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
#else
# else
# define XML_ATTR_ALLOC_SIZE(x)
#endif
# endif
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
# define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
#ifdef __cplusplus
# ifdef __cplusplus
extern "C" {
#endif
# endif
#ifdef XML_UNICODE_WCHAR_T
# ifdef XML_UNICODE_WCHAR_T
# ifndef XML_UNICODE
# define XML_UNICODE
# endif
# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
# endif
#endif
# endif
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
# ifdef XML_UNICODE /* Information is UTF-16 encoded. */
# ifdef XML_UNICODE_WCHAR_T
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
@@ -145,21 +146,21 @@ typedef wchar_t XML_LChar;
typedef unsigned short XML_Char;
typedef char XML_LChar;
# endif /* XML_UNICODE_WCHAR_T */
#else /* Information is UTF-8 encoded. */
# else /* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE */
# endif /* XML_UNICODE */
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
# ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
typedef long long XML_Index;
typedef unsigned long long XML_Size;
#else
# else
typedef long XML_Index;
typedef unsigned long XML_Size;
#endif /* XML_LARGE_SIZE */
# endif /* XML_LARGE_SIZE */
#ifdef __cplusplus
# ifdef __cplusplus
}
#endif
# endif
#endif /* not Expat_External_INCLUDED */
+8
View File
@@ -148,6 +148,11 @@
100.0f
#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \
8388608 // 8 MiB, 2^23
#define EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT 100.0f
#define EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT \
67108864 // 64 MiB, 2^26
/* NOTE END */
#include "expat.h" // so we can use type XML_Parser below
@@ -171,6 +176,9 @@ extern
#endif
XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
#if defined(XML_TESTING)
void *expat_malloc(XML_Parser parser, size_t size, int sourceLine);
void expat_free(XML_Parser parser, void *ptr, int sourceLine);
void *expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine);
extern unsigned int g_bytesScanned; // used for testing only
#endif
+505 -145
View File
File diff suppressed because it is too large Load Diff
+13 -19
View File
@@ -34,19 +34,13 @@
*/
#ifndef XmlRole_INCLUDED
#define XmlRole_INCLUDED 1
# define XmlRole_INCLUDED 1
#ifdef __VMS
/* 0 1 2 3 0 1 2 3
1234567890123456789012345678901 1234567890123456789012345678901 */
# define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
#endif
# include "xmltok.h"
#include "xmltok.h"
#ifdef __cplusplus
# ifdef __cplusplus
extern "C" {
#endif
# endif
enum {
XML_ROLE_ERROR = -1,
@@ -107,11 +101,11 @@ enum {
XML_ROLE_CONTENT_ELEMENT_PLUS,
XML_ROLE_PI,
XML_ROLE_COMMENT,
#ifdef XML_DTD
# ifdef XML_DTD
XML_ROLE_TEXT_DECL,
XML_ROLE_IGNORE_SECT,
XML_ROLE_INNER_PARAM_ENTITY_REF,
#endif /* XML_DTD */
# endif /* XML_DTD */
XML_ROLE_PARAM_ENTITY_REF
};
@@ -120,23 +114,23 @@ typedef struct prolog_state {
const char *end, const ENCODING *enc);
unsigned level;
int role_none;
#ifdef XML_DTD
# ifdef XML_DTD
unsigned includeLevel;
int documentEntity;
int inEntityValue;
#endif /* XML_DTD */
# endif /* XML_DTD */
} PROLOG_STATE;
void XmlPrologStateInit(PROLOG_STATE *state);
#ifdef XML_DTD
# ifdef XML_DTD
void XmlPrologStateInitExternalEntity(PROLOG_STATE *state);
#endif /* XML_DTD */
# endif /* XML_DTD */
#define XmlTokenRole(state, tok, ptr, end, enc) \
# define XmlTokenRole(state, tok, ptr, end, enc) \
(((state)->handler)(state, tok, ptr, end, enc))
#ifdef __cplusplus
# ifdef __cplusplus
}
#endif
# endif
#endif /* not XmlRole_INCLUDED */
+2 -2
View File
@@ -1398,7 +1398,7 @@ unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
}
ENCODING *
XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert,
void *userData) {
int i;
struct unknown_encoding *e = (struct unknown_encoding *)mem;
@@ -1661,7 +1661,7 @@ initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc,
# undef ns
ENCODING *
XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
XmlInitUnknownEncodingNS(void *mem, const int *table, CONVERTER convert,
void *userData) {
ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
if (enc)
+89 -89
View File
@@ -35,113 +35,113 @@
*/
#ifndef XmlTok_INCLUDED
#define XmlTok_INCLUDED 1
# define XmlTok_INCLUDED 1
#ifdef __cplusplus
# ifdef __cplusplus
extern "C" {
#endif
# endif
/* The following token may be returned by XmlContentTok */
#define XML_TOK_TRAILING_RSQB \
# define XML_TOK_TRAILING_RSQB \
-5 /* ] or ]] at the end of the scan; might be \
start of illegal ]]> sequence */
/* The following tokens may be returned by both XmlPrologTok and
XmlContentTok.
*/
#define XML_TOK_NONE -4 /* The string to be scanned is empty */
#define XML_TOK_TRAILING_CR \
# define XML_TOK_NONE -4 /* The string to be scanned is empty */
# define XML_TOK_TRAILING_CR \
-3 /* A CR at the end of the scan; \
might be part of CRLF sequence */
#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
#define XML_TOK_PARTIAL -1 /* only part of a token */
#define XML_TOK_INVALID 0
# define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
# define XML_TOK_PARTIAL -1 /* only part of a token */
# define XML_TOK_INVALID 0
/* The following tokens are returned by XmlContentTok; some are also
returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
*/
#define XML_TOK_START_TAG_WITH_ATTS 1
#define XML_TOK_START_TAG_NO_ATTS 2
#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
#define XML_TOK_END_TAG 5
#define XML_TOK_DATA_CHARS 6
#define XML_TOK_DATA_NEWLINE 7
#define XML_TOK_CDATA_SECT_OPEN 8
#define XML_TOK_ENTITY_REF 9
#define XML_TOK_CHAR_REF 10 /* numeric character reference */
# define XML_TOK_START_TAG_WITH_ATTS 1
# define XML_TOK_START_TAG_NO_ATTS 2
# define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
# define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
# define XML_TOK_END_TAG 5
# define XML_TOK_DATA_CHARS 6
# define XML_TOK_DATA_NEWLINE 7
# define XML_TOK_CDATA_SECT_OPEN 8
# define XML_TOK_ENTITY_REF 9
# define XML_TOK_CHAR_REF 10 /* numeric character reference */
/* The following tokens may be returned by both XmlPrologTok and
XmlContentTok.
*/
#define XML_TOK_PI 11 /* processing instruction */
#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
#define XML_TOK_COMMENT 13
#define XML_TOK_BOM 14 /* Byte order mark */
# define XML_TOK_PI 11 /* processing instruction */
# define XML_TOK_XML_DECL 12 /* XML decl or text decl */
# define XML_TOK_COMMENT 13
# define XML_TOK_BOM 14 /* Byte order mark */
/* The following tokens are returned only by XmlPrologTok */
#define XML_TOK_PROLOG_S 15
#define XML_TOK_DECL_OPEN 16 /* <!foo */
#define XML_TOK_DECL_CLOSE 17 /* > */
#define XML_TOK_NAME 18
#define XML_TOK_NMTOKEN 19
#define XML_TOK_POUND_NAME 20 /* #name */
#define XML_TOK_OR 21 /* | */
#define XML_TOK_PERCENT 22
#define XML_TOK_OPEN_PAREN 23
#define XML_TOK_CLOSE_PAREN 24
#define XML_TOK_OPEN_BRACKET 25
#define XML_TOK_CLOSE_BRACKET 26
#define XML_TOK_LITERAL 27
#define XML_TOK_PARAM_ENTITY_REF 28
#define XML_TOK_INSTANCE_START 29
# define XML_TOK_PROLOG_S 15
# define XML_TOK_DECL_OPEN 16 /* <!foo */
# define XML_TOK_DECL_CLOSE 17 /* > */
# define XML_TOK_NAME 18
# define XML_TOK_NMTOKEN 19
# define XML_TOK_POUND_NAME 20 /* #name */
# define XML_TOK_OR 21 /* | */
# define XML_TOK_PERCENT 22
# define XML_TOK_OPEN_PAREN 23
# define XML_TOK_CLOSE_PAREN 24
# define XML_TOK_OPEN_BRACKET 25
# define XML_TOK_CLOSE_BRACKET 26
# define XML_TOK_LITERAL 27
# define XML_TOK_PARAM_ENTITY_REF 28
# define XML_TOK_INSTANCE_START 29
/* The following occur only in element type declarations */
#define XML_TOK_NAME_QUESTION 30 /* name? */
#define XML_TOK_NAME_ASTERISK 31 /* name* */
#define XML_TOK_NAME_PLUS 32 /* name+ */
#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
#define XML_TOK_COMMA 38
# define XML_TOK_NAME_QUESTION 30 /* name? */
# define XML_TOK_NAME_ASTERISK 31 /* name* */
# define XML_TOK_NAME_PLUS 32 /* name+ */
# define XML_TOK_COND_SECT_OPEN 33 /* <![ */
# define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
# define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
# define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
# define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
# define XML_TOK_COMMA 38
/* The following token is returned only by XmlAttributeValueTok */
#define XML_TOK_ATTRIBUTE_VALUE_S 39
# define XML_TOK_ATTRIBUTE_VALUE_S 39
/* The following token is returned only by XmlCdataSectionTok */
#define XML_TOK_CDATA_SECT_CLOSE 40
# define XML_TOK_CDATA_SECT_CLOSE 40
/* With namespace processing this is returned by XmlPrologTok for a
name with a colon.
*/
#define XML_TOK_PREFIXED_NAME 41
# define XML_TOK_PREFIXED_NAME 41
#ifdef XML_DTD
# ifdef XML_DTD
# define XML_TOK_IGNORE_SECT 42
#endif /* XML_DTD */
# endif /* XML_DTD */
#ifdef XML_DTD
# ifdef XML_DTD
# define XML_N_STATES 4
#else /* not XML_DTD */
# else /* not XML_DTD */
# define XML_N_STATES 3
#endif /* not XML_DTD */
# endif /* not XML_DTD */
#define XML_PROLOG_STATE 0
#define XML_CONTENT_STATE 1
#define XML_CDATA_SECTION_STATE 2
#ifdef XML_DTD
# define XML_PROLOG_STATE 0
# define XML_CONTENT_STATE 1
# define XML_CDATA_SECTION_STATE 2
# ifdef XML_DTD
# define XML_IGNORE_SECTION_STATE 3
#endif /* XML_DTD */
# endif /* XML_DTD */
#define XML_N_LITERAL_TYPES 2
#define XML_ATTRIBUTE_VALUE_LITERAL 0
#define XML_ENTITY_VALUE_LITERAL 1
# define XML_N_LITERAL_TYPES 2
# define XML_ATTRIBUTE_VALUE_LITERAL 0
# define XML_ENTITY_VALUE_LITERAL 1
/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
#define XML_UTF8_ENCODE_MAX 4
# define XML_UTF8_ENCODE_MAX 4
/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
#define XML_UTF16_ENCODE_MAX 2
# define XML_UTF16_ENCODE_MAX 2
typedef struct position {
/* first line and first column are 0 not 1 */
@@ -220,62 +220,62 @@ struct encoding {
the prolog outside literals, comments and processing instructions.
*/
#define XmlTok(enc, state, ptr, end, nextTokPtr) \
# define XmlTok(enc, state, ptr, end, nextTokPtr) \
(((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
# define XmlPrologTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
#define XmlContentTok(enc, ptr, end, nextTokPtr) \
# define XmlContentTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
# define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
#ifdef XML_DTD
# ifdef XML_DTD
# define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
#endif /* XML_DTD */
# endif /* XML_DTD */
/* This is used for performing a 2nd-level tokenization on the content
of a literal that has already been returned by XmlTok.
*/
#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
# define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
(((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
# define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
# define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
# define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
(((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
#define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr))
# define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr))
#define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr))
# define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr))
#define XmlGetAttributes(enc, ptr, attsMax, atts) \
# define XmlGetAttributes(enc, ptr, attsMax, atts) \
(((enc)->getAtts)(enc, ptr, attsMax, atts))
#define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr))
# define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr))
#define XmlPredefinedEntityName(enc, ptr, end) \
# define XmlPredefinedEntityName(enc, ptr, end) \
(((enc)->predefinedEntityName)(enc, ptr, end))
#define XmlUpdatePosition(enc, ptr, end, pos) \
# define XmlUpdatePosition(enc, ptr, end, pos) \
(((enc)->updatePosition)(enc, ptr, end, pos))
#define XmlIsPublicId(enc, ptr, end, badPtr) \
# define XmlIsPublicId(enc, ptr, end, badPtr) \
(((enc)->isPublicId)(enc, ptr, end, badPtr))
#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
# define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
# define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
typedef struct {
@@ -299,7 +299,7 @@ int XmlSizeOfUnknownEncoding(void);
typedef int(XMLCALL *CONVERTER)(void *userData, const char *p);
ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
ENCODING *XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert,
void *userData);
int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc,
@@ -312,10 +312,10 @@ int XmlInitEncodingNS(INIT_ENCODING *p, const ENCODING **encPtr,
const char *name);
const ENCODING *XmlGetUtf8InternalEncodingNS(void);
const ENCODING *XmlGetUtf16InternalEncodingNS(void);
ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
void *userData);
#ifdef __cplusplus
ENCODING *XmlInitUnknownEncodingNS(void *mem, const int *table,
CONVERTER convert, void *userData);
# ifdef __cplusplus
}
#endif
# endif
#endif /* not XmlTok_INCLUDED */
+65 -28
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@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -102,6 +102,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
am__rm_f = rm -f $(am__rm_f_notfound)
am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -324,10 +326,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { 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__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
@@ -415,12 +416,13 @@ am__sh_e_setup = case $$- in *e*) set +e;; esac
# Default flags passed to test drivers.
am__common_driver_flags = \
--color-tests "$$am__color_tests" \
$$am__collect_skipped_logs \
--enable-hard-errors "$$am__enable_hard_errors" \
--expect-failure "$$am__expect_failure"
# To be inserted before the command running the test. Creates the
# directory for the log if needed. Stores in $dir the directory
# containing $f, in $tst the test, in $log the log. Executes the
# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
# developer-defined test setup AM_TESTS_ENVIRONMENT (if any), and
# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
# will run the test scripts (or their associated LOG_COMPILER, if
# thy have one).
@@ -439,6 +441,11 @@ if test -f "./$$f"; then dir=./; \
elif test -f "$$f"; then dir=; \
else dir="$(srcdir)/"; fi; \
tst=$$dir$$f; log='$@'; \
if test -n '$(IGNORE_SKIPPED_LOGS)'; then \
am__collect_skipped_logs='--collect-skipped-logs no'; \
else \
am__collect_skipped_logs=''; \
fi; \
if test -n '$(DISABLE_HARD_ERRORS)'; then \
am__enable_hard_errors=no; \
else \
@@ -620,8 +627,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -757,13 +766,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
clean-checkPROGRAMS:
@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
$(am__rm_f) $(check_PROGRAMS)
test -z "$(EXEEXT)" || $(am__rm_f) $(check_PROGRAMS:$(EXEEXT)=)
runtests$(EXEEXT): $(runtests_OBJECTS) $(runtests_DEPENDENCIES) $(EXTRA_runtests_DEPENDENCIES)
@rm -f runtests$(EXEEXT)
@@ -810,7 +814,7 @@ distclean-compile:
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
@: >>$@
am--depfiles: $(am__depfiles_remade)
@@ -974,7 +978,6 @@ distclean-tags:
am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
am--force-recheck:
@:
$(TEST_SUITE_LOG): $(TEST_LOGS)
@$(am__set_TESTS_bases); \
am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
@@ -1050,10 +1053,37 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
result_count $$1 "XPASS:" $$xpass "$$red"; \
result_count $$1 "ERROR:" $$error "$$mgn"; \
}; \
output_system_information () \
{ \
echo; \
{ uname -a | $(AWK) '{ \
printf "System information (uname -a):"; \
for (i = 1; i < NF; ++i) \
{ \
if (i != 2) \
printf " %s", $$i; \
} \
printf "\n"; \
}'; } 2>&1; \
if test -r /etc/os-release; then \
echo "Distribution information (/etc/os-release):"; \
sed 8q /etc/os-release; \
elif test -r /etc/issue; then \
echo "Distribution information (/etc/issue):"; \
cat /etc/issue; \
fi; \
}; \
please_report () \
{ \
echo "Some test(s) failed. Please report this to $(PACKAGE_BUGREPORT),"; \
echo "together with the test-suite.log file (gzipped) and your system"; \
echo "information. Thanks."; \
}; \
{ \
echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
$(am__rst_title); \
create_testsuite_report --no-color; \
output_system_information; \
echo; \
echo ".. contents:: :depth: 2"; \
echo; \
@@ -1073,26 +1103,25 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
create_testsuite_report --maybe-color; \
echo "$$col$$br$$std"; \
if $$success; then :; else \
echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
echo "$${col}See $(subdir)/$(TEST_SUITE_LOG) for debugging.$${std}";\
if test -n "$(PACKAGE_BUGREPORT)"; then \
echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
please_report | sed -e "s/^/$${col}/" -e s/'$$'/"$${std}"/; \
fi; \
echo "$$col$$br$$std"; \
fi; \
$$success || exit 1
check-TESTS: $(check_PROGRAMS)
@list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@$(am__rm_f) $(RECHECK_LOGS)
@$(am__rm_f) $(RECHECK_LOGS:.log=.trs)
@$(am__rm_f) $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
log_list=`for i in $$bases; do echo $$i.log; done`; \
trs_list=`for i in $$bases; do echo $$i.trs; done`; \
log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
log_list=`echo $$log_list`; \
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
exit $$?;
recheck: all $(check_PROGRAMS)
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@$(am__rm_f) $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
bases=`for i in $$bases; do echo $$i; done \
| $(am__list_recheck_tests)` || exit 1; \
@@ -1130,6 +1159,7 @@ runtests_cxx.log: runtests_cxx$(EXEEXT)
@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -1215,15 +1245,15 @@ install-strip:
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
-$(am__rm_f) $(TEST_LOGS)
-$(am__rm_f) $(TEST_LOGS:.log=.trs)
-$(am__rm_f) $(TEST_SUITE_LOG)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -1376,3 +1406,10 @@ uninstall-am:
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+217 -3
View File
@@ -10,7 +10,7 @@
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
@@ -46,10 +46,16 @@
# undef NDEBUG /* because test suite relies on assert(...) at the moment */
#endif
#include <math.h> /* NAN, INFINITY */
#include <stdbool.h>
#include <stdint.h> /* for SIZE_MAX */
#include <string.h>
#include <assert.h>
#include "expat_config.h"
#include "expat.h"
#include "internal.h"
#include "common.h"
#include "minicheck.h"
#include "dummy.h"
@@ -323,7 +329,7 @@ START_TEST(test_alloc_run_external_parser) {
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
XML_SetUserData(g_parser, foo_text);
XML_SetExternalEntityRefHandler(g_parser, external_entity_null_loader);
g_allocation_count = i;
g_allocation_count = (int)i;
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
!= XML_STATUS_ERROR)
break;
@@ -434,7 +440,7 @@ START_TEST(test_alloc_internal_entity) {
const unsigned int max_alloc_count = 20;
for (i = 0; i < max_alloc_count; i++) {
g_allocation_count = i;
g_allocation_count = (int)i;
XML_SetUnknownEncodingHandler(g_parser, unknown_released_encoding_handler,
NULL);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
@@ -2085,6 +2091,203 @@ START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) {
}
END_TEST
START_TEST(test_alloc_tracker_size_recorded) {
XML_Memory_Handling_Suite memsuite = {malloc, realloc, free};
bool values[] = {true, false};
for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
const bool useMemSuite = values[i];
set_subtest("useMemSuite=%d", (int)useMemSuite);
XML_Parser parser = useMemSuite
? XML_ParserCreate_MM(NULL, &memsuite, XCS("|"))
: XML_ParserCreate(NULL);
#if XML_GE == 1
void *ptr = expat_malloc(parser, 10, -1);
assert_true(ptr != NULL);
assert_true(*((size_t *)ptr - 1) == 10);
assert_true(expat_realloc(parser, ptr, SIZE_MAX / 2, -1) == NULL);
assert_true(*((size_t *)ptr - 1) == 10); // i.e. unchanged
ptr = expat_realloc(parser, ptr, 20, -1);
assert_true(ptr != NULL);
assert_true(*((size_t *)ptr - 1) == 20);
expat_free(parser, ptr, -1);
#endif
XML_ParserFree(parser);
}
}
END_TEST
START_TEST(test_alloc_tracker_maximum_amplification) {
if (g_reparseDeferralEnabledDefault == XML_TRUE) {
return;
}
XML_Parser parser = XML_ParserCreate(NULL);
// Get .m_accounting.countBytesDirect from 0 to 3
const char *const chunk = "<e>";
assert_true(_XML_Parse_SINGLE_BYTES(parser, chunk, (int)strlen(chunk),
/*isFinal=*/XML_FALSE)
== XML_STATUS_OK);
#if XML_GE == 1
// Stop activation threshold from interfering
assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE);
// Exceed maximum amplification: should be rejected.
assert_true(expat_malloc(parser, 1000, -1) == NULL);
// Increase maximum amplification, and try the same amount once more: should
// work.
assert_true(XML_SetAllocTrackerMaximumAmplification(parser, 3000.0f)
== XML_TRUE);
void *const ptr = expat_malloc(parser, 1000, -1);
assert_true(ptr != NULL);
expat_free(parser, ptr, -1);
#endif
XML_ParserFree(parser);
}
END_TEST
START_TEST(test_alloc_tracker_threshold) {
XML_Parser parser = XML_ParserCreate(NULL);
#if XML_GE == 1
// Exceed maximum amplification *before* (default) threshold: should work.
void *const ptr = expat_malloc(parser, 1000, -1);
assert_true(ptr != NULL);
expat_free(parser, ptr, -1);
// Exceed maximum amplification *after* threshold: should be rejected.
assert_true(XML_SetAllocTrackerActivationThreshold(parser, 999) == XML_TRUE);
assert_true(expat_malloc(parser, 1000, -1) == NULL);
#endif
XML_ParserFree(parser);
}
END_TEST
START_TEST(test_alloc_tracker_getbuffer_unlimited) {
XML_Parser parser = XML_ParserCreate(NULL);
#if XML_GE == 1
// Artificially lower threshold
assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE);
// Self-test: Prove that threshold is as rejecting as expected
assert_true(expat_malloc(parser, 1000, -1) == NULL);
#endif
// XML_GetBuffer should be allowed to pass, though
assert_true(XML_GetBuffer(parser, 1000) != NULL);
XML_ParserFree(parser);
}
END_TEST
START_TEST(test_alloc_tracker_api) {
XML_Parser parserWithoutParent = XML_ParserCreate(NULL);
XML_Parser parserWithParent = XML_ExternalEntityParserCreate(
parserWithoutParent, XCS("entity123"), NULL);
if (parserWithoutParent == NULL)
fail("parserWithoutParent is NULL");
if (parserWithParent == NULL)
fail("parserWithParent is NULL");
#if XML_GE == 1
// XML_SetAllocTrackerMaximumAmplification, error cases
if (XML_SetAllocTrackerMaximumAmplification(NULL, 123.0f) == XML_TRUE)
fail("Call with NULL parser is NOT supposed to succeed");
if (XML_SetAllocTrackerMaximumAmplification(parserWithParent, 123.0f)
== XML_TRUE)
fail("Call with non-root parser is NOT supposed to succeed");
if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, NAN)
== XML_TRUE)
fail("Call with NaN limit is NOT supposed to succeed");
if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, -1.0f)
== XML_TRUE)
fail("Call with negative limit is NOT supposed to succeed");
if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 0.9f)
== XML_TRUE)
fail("Call with positive limit <1.0 is NOT supposed to succeed");
// XML_SetAllocTrackerMaximumAmplification, success cases
if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 1.0f)
== XML_FALSE)
fail("Call with positive limit >=1.0 is supposed to succeed");
if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 123456.789f)
== XML_FALSE)
fail("Call with positive limit >=1.0 is supposed to succeed");
if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, INFINITY)
== XML_FALSE)
fail("Call with positive limit >=1.0 is supposed to succeed");
// XML_SetAllocTrackerActivationThreshold, error cases
if (XML_SetAllocTrackerActivationThreshold(NULL, 123) == XML_TRUE)
fail("Call with NULL parser is NOT supposed to succeed");
if (XML_SetAllocTrackerActivationThreshold(parserWithParent, 123) == XML_TRUE)
fail("Call with non-root parser is NOT supposed to succeed");
// XML_SetAllocTrackerActivationThreshold, success cases
if (XML_SetAllocTrackerActivationThreshold(parserWithoutParent, 123)
== XML_FALSE)
fail("Call with non-NULL parentless parser is supposed to succeed");
#endif // XML_GE == 1
XML_ParserFree(parserWithParent);
XML_ParserFree(parserWithoutParent);
}
END_TEST
START_TEST(test_mem_api_cycle) {
XML_Parser parser = XML_ParserCreate(NULL);
void *ptr = XML_MemMalloc(parser, 10);
assert_true(ptr != NULL);
memset(ptr, 'x', 10); // assert writability, with ASan in mind
ptr = XML_MemRealloc(parser, ptr, 20);
assert_true(ptr != NULL);
memset(ptr, 'y', 20); // assert writability, with ASan in mind
XML_MemFree(parser, ptr);
XML_ParserFree(parser);
}
END_TEST
START_TEST(test_mem_api_unlimited) {
XML_Parser parser = XML_ParserCreate(NULL);
#if XML_GE == 1
assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE);
#endif
void *ptr = XML_MemMalloc(parser, 1000);
assert_true(ptr != NULL);
ptr = XML_MemRealloc(parser, ptr, 2000);
assert_true(ptr != NULL);
XML_MemFree(parser, ptr);
XML_ParserFree(parser);
}
END_TEST
void
make_alloc_test_case(Suite *s) {
TCase *tc_alloc = tcase_create("allocation tests");
@@ -2151,4 +2354,15 @@ make_alloc_test_case(Suite *s) {
tcase_add_test__ifdef_xml_dtd(
tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail);
tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_tracker_size_recorded);
tcase_add_test__ifdef_xml_dtd(tc_alloc,
test_alloc_tracker_maximum_amplification);
tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_tracker_threshold);
tcase_add_test__ifdef_xml_dtd(tc_alloc,
test_alloc_tracker_getbuffer_unlimited);
tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_tracker_api);
tcase_add_test(tc_alloc, test_mem_api_cycle);
tcase_add_test__ifdef_xml_dtd(tc_alloc, test_mem_api_unlimited);
}
+6 -2
View File
@@ -412,13 +412,13 @@ START_TEST(test_utf16_le_epilog_newline) {
if (first_chunk_bytes >= sizeof(text) - 1)
fail("bad value of first_chunk_bytes");
if (_XML_Parse_SINGLE_BYTES(g_parser, text, first_chunk_bytes, XML_FALSE)
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)first_chunk_bytes, XML_FALSE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
else {
enum XML_Status rc;
rc = _XML_Parse_SINGLE_BYTES(g_parser, text + first_chunk_bytes,
sizeof(text) - first_chunk_bytes - 1,
(int)(sizeof(text) - first_chunk_bytes - 1),
XML_TRUE);
if (rc == XML_STATUS_ERROR)
xml_failure(g_parser);
@@ -3123,6 +3123,10 @@ START_TEST(test_buffer_can_grow_to_max) {
for (int i = 0; i < num_prefixes; ++i) {
set_subtest("\"%s\"", prefixes[i]);
XML_Parser parser = XML_ParserCreate(NULL);
#if XML_GE == 1
assert_true(XML_SetAllocTrackerActivationThreshold(parser, (size_t)-1)
== XML_TRUE); // i.e. deactivate
#endif
const int prefix_len = (int)strlen(prefixes[i]);
const enum XML_Status s
= _XML_Parse_SINGLE_BYTES(parser, prefixes[i], prefix_len, XML_FALSE);
+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@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -101,6 +101,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
am__rm_f = rm -f $(am__rm_f_notfound)
am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -320,8 +322,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -403,13 +407,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
$(am__rm_f) $(noinst_PROGRAMS)
test -z "$(EXEEXT)" || $(am__rm_f) $(noinst_PROGRAMS:$(EXEEXT)=)
benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) $(EXTRA_benchmark_DEPENDENCIES)
@rm -f benchmark$(EXEEXT)
@@ -425,7 +424,7 @@ distclean-compile:
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
@: >>$@
am--depfiles: $(am__depfiles_remade)
@@ -507,6 +506,7 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -568,8 +568,8 @@ mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -667,3 +667,10 @@ uninstall-am:
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+10 -1
View File
@@ -303,7 +303,14 @@ duff_reallocator(void *ptr, size_t size) {
return realloc(ptr, size);
}
// Portable remake of strndup(3) for C99; does not care about space efficiency
// Portable remake of strnlen(3) for C99
static size_t
portable_strnlen(const char *s, size_t maxlen) {
const char *const end = (const char *)memchr(s, '\0', maxlen);
return (end == NULL) ? maxlen : (size_t)(end - s);
}
// Portable remake of strndup(3) for C99
char *
portable_strndup(const char *s, size_t n) {
if ((s == NULL) || (n == SIZE_MAX)) {
@@ -311,6 +318,8 @@ portable_strndup(const char *s, size_t n) {
return NULL;
}
n = portable_strnlen(s, n);
char *const buffer = (char *)malloc(n + 1);
if (buffer == NULL) {
errno = ENOMEM;
+15 -14
View File
@@ -10,7 +10,7 @@
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
@@ -89,15 +89,15 @@ start_element_event_handler2(void *userData, const XML_Char *name,
const XML_Char **attr) {
StructData *storage = (StructData *)userData;
UNUSED_P(attr);
StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser),
XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG);
StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
(int)XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG);
}
void XMLCALL
end_element_event_handler2(void *userData, const XML_Char *name) {
StructData *storage = (StructData *)userData;
StructData_AddItem(storage, name, XML_GetCurrentColumnNumber(g_parser),
XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG);
StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
(int)XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG);
}
void XMLCALL
@@ -132,7 +132,7 @@ counting_start_element_handler(void *userData, const XML_Char *name,
fail("ID not present");
return;
}
if (id != -1 && xcstrcmp(atts[id], info->id_name)) {
if (id != -1 && xcstrcmp(atts[id], info->id_name) != 0) {
fail("ID does not have the correct name");
return;
}
@@ -147,7 +147,7 @@ counting_start_element_handler(void *userData, const XML_Char *name,
fail("Attribute not recognised");
return;
}
if (xcstrcmp(atts[1], attr->value)) {
if (xcstrcmp(atts[1], attr->value) != 0) {
fail("Attribute has wrong value");
return;
}
@@ -1110,7 +1110,7 @@ external_entity_devaluer(XML_Parser parser, const XML_Char *context,
UNUSED_P(publicId);
if (systemId == NULL || ! xcstrcmp(systemId, XCS("bar")))
return XML_STATUS_OK;
if (xcstrcmp(systemId, XCS("foo")))
if (xcstrcmp(systemId, XCS("foo")) != 0)
fail("Unexpected system ID");
ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
if (ext_parser == NULL)
@@ -1276,7 +1276,7 @@ external_entity_duff_loader(XML_Parser parser, const XML_Char *context,
UNUSED_P(publicId);
/* Try a few different allocation levels */
for (i = 0; i < max_alloc_count; i++) {
g_allocation_count = i;
g_allocation_count = (int)i;
new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
if (new_parser != NULL) {
XML_ParserFree(new_parser);
@@ -1552,15 +1552,16 @@ verify_attlist_decl_handler(void *userData, const XML_Char *element_name,
const XML_Char *default_value, int is_required) {
AttTest *at = (AttTest *)userData;
if (xcstrcmp(element_name, at->element_name))
if (xcstrcmp(element_name, at->element_name) != 0)
fail("Unexpected element name in attribute declaration");
if (xcstrcmp(attr_name, at->attr_name))
if (xcstrcmp(attr_name, at->attr_name) != 0)
fail("Unexpected attribute name in attribute declaration");
if (xcstrcmp(attr_type, at->attr_type))
if (xcstrcmp(attr_type, at->attr_type) != 0)
fail("Unexpected attribute type in attribute declaration");
if ((default_value == NULL && at->default_value != NULL)
|| (default_value != NULL && at->default_value == NULL)
|| (default_value != NULL && xcstrcmp(default_value, at->default_value)))
|| (default_value != NULL
&& xcstrcmp(default_value, at->default_value) != 0))
fail("Unexpected default value in attribute declaration");
if (is_required != at->is_required)
fail("Requirement mismatch in attribute declaration");
@@ -1751,7 +1752,7 @@ param_entity_match_handler(void *userData, const XML_Char *entityName,
* going to overflow an int.
*/
if (value_length != (int)xcstrlen(entity_value_to_match)
|| xcstrncmp(value, entity_value_to_match, value_length)) {
|| xcstrncmp(value, entity_value_to_match, value_length) != 0) {
entity_match_flag = ENTITY_MATCH_FAIL;
} else {
entity_match_flag = ENTITY_MATCH_SUCCESS;
+1 -2
View File
@@ -134,8 +134,7 @@ void _check_set_test_info(char const *function, char const *filename,
__attribute__((noreturn))
# endif
# endif
void
_fail(const char *file, int line, const char *msg);
void _fail(const char *file, int line, const char *msg);
Suite *suite_create(const char *name);
TCase *tcase_create(const char *name);
void suite_add_tcase(Suite *suite, TCase *tc);
+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 */
for (i = 0; i < max_alloc_count; i++) {
g_allocation_count = i;
g_allocation_count = (int)i;
g_parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
if (g_parser != NULL)
break;
@@ -90,7 +90,7 @@ START_TEST(test_misc_alloc_create_parser_with_encoding) {
/* Try several levels of allocation */
for (i = 0; i < max_alloc_count; i++) {
g_allocation_count = i;
g_allocation_count = (int)i;
g_parser = XML_ParserCreate_MM(XCS("us-ascii"), &memsuite, NULL);
if (g_parser != NULL)
break;
@@ -211,7 +211,8 @@ START_TEST(test_misc_version) {
if (! versions_equal(&read_version, &parsed_version))
fail("Version mismatch");
if (xcstrcmp(version_text, XCS("expat_2.7.1"))) /* needs bump on releases */
if (xcstrcmp(version_text, XCS("expat_2.7.2"))
!= 0) /* needs bump on releases */
fail("XML_*_VERSION in expat.h out of sync?\n");
}
END_TEST
+8 -3
View File
@@ -10,7 +10,7 @@
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
@@ -83,7 +83,7 @@ START_TEST(test_nsalloc_xmlns) {
const unsigned int max_alloc_count = 30;
for (i = 0; i < max_alloc_count; i++) {
g_allocation_count = i;
g_allocation_count = (int)i;
/* Exercise more code paths with a default handler */
XML_SetDefaultHandler(g_parser, dummy_default_handler);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
@@ -454,10 +454,15 @@ START_TEST(test_nsalloc_realloc_attributes) {
nsalloc_teardown();
nsalloc_setup();
}
#if XML_GE == 1
assert_true(
i == 0); // because expat_realloc relies on expat_malloc to some extent
#else
if (i == 0)
fail("Parsing worked despite failing reallocations");
else if (i == max_realloc_count)
fail("Parsing failed at max reallocation count");
#endif
}
END_TEST
@@ -523,7 +528,7 @@ START_TEST(test_nsalloc_realloc_binding_uri) {
/* Now repeat with a longer URI and a duff reallocator */
for (i = 0; i < max_realloc_count; i++) {
XML_ParserReset(g_parser, NULL);
g_reallocation_count = i;
g_reallocation_count = (int)i;
if (_XML_Parse_SINGLE_BYTES(g_parser, second, (int)strlen(second), XML_TRUE)
!= XML_STATUS_ERROR)
break;
+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@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -100,6 +100,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
am__rm_f = rm -f $(am__rm_f_notfound)
am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -328,8 +330,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -464,16 +468,11 @@ uninstall-binPROGRAMS:
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files
clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
$(am__rm_f) $(bin_PROGRAMS)
test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=)
xmlwf$(EXEEXT): $(xmlwf_OBJECTS) $(xmlwf_DEPENDENCIES) $(EXTRA_xmlwf_DEPENDENCIES)
@rm -f xmlwf$(EXEEXT)
@@ -492,7 +491,7 @@ distclean-compile:
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
@: >>$@
am--depfiles: $(am__depfiles_remade)
@@ -630,6 +629,7 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -694,8 +694,8 @@ mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -798,3 +798,10 @@ uninstall-am: uninstall-binPROGRAMS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
+3 -3
View File
@@ -10,7 +10,7 @@
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2001-2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Licensed under the MIT license:
@@ -41,6 +41,7 @@
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h> // NULL
#include <unistd.h>
#ifndef MAP_FILE
@@ -93,8 +94,7 @@ filemap(const tchar *name,
close(fd);
return 1;
}
p = (void *)mmap((void *)0, (size_t)nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE,
fd, (off_t)0);
p = mmap(NULL, nbytes, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, (off_t)0);
if (p == (void *)-1) {
tperror(name);
close(fd);
+14 -7
View File
@@ -11,7 +11,7 @@
Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
@@ -56,12 +56,19 @@
#include "xmltchar.h"
#include "filemap.h"
/* Function "read": */
#if defined(_MSC_VER)
# include <io.h>
#endif
#ifdef HAVE_UNISTD_H
/* https://msdn.microsoft.com/en-us/library/wyssk1bs(v=vs.100).aspx */
# define EXPAT_read _read
# define EXPAT_read_count_t int
# define EXPAT_read_req_t unsigned int
#else /* POSIX */
# include <unistd.h>
/* https://pubs.opengroup.org/onlinepubs/009695399/functions/read.html */
# define EXPAT_read read
# define EXPAT_read_count_t ssize_t
# define EXPAT_read_req_t size_t
#endif
#ifndef O_BINARY
@@ -192,7 +199,7 @@ processStream(const XML_Char *filename, XML_Parser parser) {
}
}
for (;;) {
int nread;
EXPAT_read_count_t nread;
char *buf = (char *)XML_GetBuffer(parser, g_read_size_bytes);
if (! buf) {
if (filename != NULL)
@@ -201,14 +208,14 @@ processStream(const XML_Char *filename, XML_Parser parser) {
filename != NULL ? filename : T("xmlwf"));
return 0;
}
nread = read(fd, buf, g_read_size_bytes);
nread = EXPAT_read(fd, buf, (EXPAT_read_req_t)g_read_size_bytes);
if (nread < 0) {
tperror(filename != NULL ? filename : T("STDIN"));
if (filename != NULL)
close(fd);
return 0;
}
if (XML_ParseBuffer(parser, nread, nread == 0) == XML_STATUS_ERROR) {
if (XML_ParseBuffer(parser, (int)nread, nread == 0) == XML_STATUS_ERROR) {
reportError(parser, filename != NULL ? filename : T("STDIN"));
if (filename != NULL)
close(fd);
+17 -4
View File
@@ -11,7 +11,7 @@
Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2004-2009 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Joe Orton <jorton@redhat.com>
@@ -305,7 +305,7 @@ static XML_Char *
xcsdup(const XML_Char *s) {
XML_Char *result;
int count = 0;
int numBytes;
size_t numBytes;
/* Get the length of the string, including terminator */
while (s[count++] != 0) {
@@ -913,11 +913,11 @@ usage(const XML_Char *prog, int rc) {
T(" -t write no XML output for [t]iming of plain parsing\n")
T(" -N enable adding doctype and [n]otation declarations\n")
T("\n")
T("billion laughs attack protection:\n")
T("amplification attack protection (e.g. billion laughs):\n")
T(" NOTE: If you ever need to increase these values for non-attack payload, please file a bug report.\n")
T("\n")
T(" -a FACTOR set maximum tolerated [a]mplification factor (default: 100.0)\n")
T(" -b BYTES set number of output [b]ytes needed to activate (default: 8 MiB)\n")
T(" -b BYTES set number of output [b]ytes needed to activate (default: 8 MiB/64 MiB)\n")
T("\n")
T("reparse deferral:\n")
T(" -q disable reparse deferral, and allow [q]uadratic parse runtime with large tokens\n")
@@ -926,6 +926,16 @@ usage(const XML_Char *prog, int rc) {
T(" -h, --help show this [h]elp message and exit\n")
T(" -v, --version show program's [v]ersion number and exit\n")
T("\n")
T("environment variables:\n")
T(" EXPAT_ACCOUNTING_DEBUG=(0|1|2|3)\n")
T(" Control verbosity of accounting debugging (default: 0)\n")
T(" EXPAT_ENTITY_DEBUG=(0|1)\n")
T(" Control verbosity of entity debugging (default: 0)\n")
T(" EXPAT_ENTROPY_DEBUG=(0|1)\n")
T(" Control verbosity of entropy debugging (default: 0)\n")
T(" EXPAT_MALLOC_DEBUG=(0|1|2)\n")
T(" Control verbosity of allocation tracker (default: 0)\n")
T("\n")
T("exit status:\n")
T(" 0 the input files are well-formed and the output (if requested) was written successfully\n")
T(" 1 could not allocate data structures, signals a serious problem with execution environment\n")
@@ -1171,12 +1181,15 @@ tmain(int argc, XML_Char **argv) {
#if XML_GE == 1
XML_SetBillionLaughsAttackProtectionMaximumAmplification(
parser, attackMaximumAmplification);
XML_SetAllocTrackerMaximumAmplification(parser,
attackMaximumAmplification);
#endif
}
if (attackThresholdGiven) {
#if XML_GE == 1
XML_SetBillionLaughsAttackProtectionActivationThreshold(
parser, attackThresholdBytes);
XML_SetAllocTrackerActivationThreshold(parser, attackThresholdBytes);
#else
(void)attackThresholdBytes; // silence -Wunused-but-set-variable
#endif
+14 -4
View File
@@ -6,7 +6,7 @@
# \___/_/\_\ .__/ \__,_|\__|
# |_| XML parser
#
# Copyright (c) 2019-2023 Sebastian Pipping <sebastian@pipping.org>
# Copyright (c) 2019-2025 Sebastian Pipping <sebastian@pipping.org>
# Copyright (c) 2021 Tim Bray <tbray@textuality.com>
# Licensed under the MIT license:
#
@@ -32,6 +32,16 @@
import argparse
epilog = """
environment variables:
EXPAT_ACCOUNTING_DEBUG=(0|1|2|3)
Control verbosity of accounting debugging (default: 0)
EXPAT_ENTITY_DEBUG=(0|1)
Control verbosity of entity debugging (default: 0)
EXPAT_ENTROPY_DEBUG=(0|1)
Control verbosity of entropy debugging (default: 0)
EXPAT_MALLOC_DEBUG=(0|1|2)
Control verbosity of allocation tracker (default: 0)
exit status:
0 the input files are well-formed and the output (if requested) was written successfully
1 could not allocate data structures, signals a serious problem with execution environment
@@ -74,16 +84,16 @@
output_mode.add_argument('-t', action='store_true', help='write no XML output for [t]iming of plain parsing')
output_related.add_argument('-N', action='store_true', help='enable adding doctype and [n]otation declarations')
billion_laughs = parser.add_argument_group('billion laughs attack protection',
billion_laughs = parser.add_argument_group('amplification attack protection (e.g. billion laughs)',
description='NOTE: '
'If you ever need to increase these values '
'for non-attack payload, please file a bug report.')
billion_laughs.add_argument('-a', metavar='FACTOR',
help='set maximum tolerated [a]mplification factor (default: 100.0)')
billion_laughs.add_argument('-b', metavar='BYTES', help='set number of output [b]ytes needed to activate (default: 8 MiB)')
billion_laughs.add_argument('-b', metavar='BYTES', help='set number of output [b]ytes needed to activate (default: 8 MiB/64 MiB)')
reparse_deferral = parser.add_argument_group('reparse deferral')
reparse_deferral.add_argument('-q', metavar='FACTOR',
reparse_deferral.add_argument('-q', action='store_true',
help='disable reparse deferral, and allow [q]uadratic parse runtime with large tokens')
parser.add_argument('files', metavar='FILE', nargs='*', help='file to process (default: STDIN)')