Vendor import of expat 2.8.5

This commit is contained in:
Philip Paeps committed 2026-09-22 22:37:02 +09:00
1 parent 698f424711
commit ad0a85f5d5
58 files changed
+1609 -854

No files matched your search

+86 -1
View File
@@ -13,9 +13,94 @@
!! will be funded by the City of Munich as part of their !!
!! Open Source Sabbatical (https://opensource.muenchen.de/sabbatical.html) !!
!! — thank you! !!
!! Sebastian Pipping -- Berlin, 2026-08-03 !!
!! !!
!! If your business relies on Expat beyond January 2027, please consider !!
!! funding the maintenance of Expat to ensure its health and security for !!
!! you and others. Thank you! !!
!! !!
!! Sebastian Pipping -- Berlin, 2026-09-22 !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Release 2.8.5 Tue September 22 2026
Security fixes:
#1282 CVE-2026-93990 -- Reject high surrogates not followed by a
low surrogate during UTF-16 decoding; previously, malformed
UTF-16 could be smuggled into the application using Expat
and could cause arbitrary damage there, depending on how
malformed UTF-16 was handled inside the application;
validation was not their job but Expat's. This is similar
to past vulnerability CVE-2022-25235.
Upstream CVSS 3.1 vector:
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (CVSS score: 9.8)
///////////////////////////////////////////////////////////////////////////////
// The next release will drop two (disabled-by-default) features: //
// //
// - ATTR_INFO (-DXML_ATTR_INFO, -DEXPAT_ATTR_INFO, --enable-xml-attr-info, //
// function XML_GetAttributeInfo, struct XML_AttrInfo) //
// - MIN_SIZE (-DXML_MIN_SIZE, -DEXPAT_MIN_SIZE) //
// //
// If you need them in 2026 and beyond, please share your scenario at //
// GitHub issues #1370 (for ATTR_INFO) and/or #1379 (for MIN_SIZE). Thanks! //
///////////////////////////////////////////////////////////////////////////////
Bug fixes:
#1346 lib: Fix OOM-related memory leak on a failed overflow check
#1371 lib: Fix memory alignment for architectures with 128bit
pointers like CHERI-RISC-V
#1367 xmlwf: Handle errors when closing output files
Other changes:
#1354 lib: Reject an XML declaration version other than `1.[0-9]+`
(which is less strict than XML 1.0r4 (fourth edition)
and matches XML 1.0r5 (fifth edition))
#1362 lib: Make Clang, GCC and MSVC warn about use of function
XML_SetHashSalt that is deprecated since Expat 2.8.0
#1357 lib: Drop internal macros FASTCALL, PTRCALL, PTRFASTCALL
#1367 xmlwf: Document that with `-k` the last error determines the
xmlwf exit code in `--help` output
#1367 xmlwf: Make exit code 3 documentation match exit code 2 more
closely in `--help` output
#1352 #1353 CMake|Windows: Refrain from adding `/source-charset:utf-8`
for MSVC
#1366 #1374 Autotools: Be explicit about the minimum required version of
GNU Automake, currently version 1.13 of 2012-12-28
#1351 Autotools|macOS: Sync CMake templates with CMake 4.4.3
#1349 Replace some internal use of XML_Bool with standard bool
#1364 tests: Propagate xmltest.sh failures via exit status
#1360 tests|xmlwf: Add `#include "expat_config.h"` where missing
#1355 tests: Start covering hash table operation
#1350 #1369 tests: Drop __cplusplus leftovers
#1378 tests: Fix tail pointer when unlinking the last tracked
allocation
#1376 docs: Emphasize that XML_StopParser is not immediate
#1381 docs: Sync XML_FeatureEnum value list in doc/reference.html
#1356 #1361 Version info bumped from 13:4:12 (libexpat*.so.1.12.4)
to 13:5:12 (libexpat*.so.1.12.5); see https://verbump.de/
for what these numbers do
Infrastructure:
#1347 Add missing .gitignore entries
#1360 CI: Detect missing `#include "expat_config.h"`
#1368 CI: Bump MinGW Clang from 23.0.1 to 23.1.1
#1377 CI: Bump Fil-C from 0.684 to 0.685
#1380 CI: Bump Cppcheck from 2.21.0 to 2.22.0
#1372 CI: Extract helper script `apply-htmltidy.sh`
#1366 #1374 Autotools: Start to also produce .tar.bz3 release tarballs
Special thanks to:
Afonso Januário
Braian Plaku
Florian Schmaus
Huang Wenbin
Kamila Szewczyk
Kartik Kenchi
Leo Camus
Matthew Fernandez
Stan Ulbrych
and
City of Munich Open Source Sabbatical
Release 2.8.4 Mon August 31 2026
Security fixes:
#1321 #1331 CVE-2026-66046, CVE-2026-76641 -- Fix quadratic runtime from
-7
View File
@@ -33,13 +33,6 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
# USE OR OTHER DEALINGS IN THE SOFTWARE.
AUTOMAKE_OPTIONS = \
dist-bzip2 \
dist-lzip \
dist-xz \
foreign \
subdir-objects
ACLOCAL_AMFLAGS = -I m4
LIBTOOLFLAGS = --verbose
+105 -56
View File
@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.18.1 from Makefile.am.
# Makefile.in generated by automake 1.19 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# Copyright (C) 1994-2026 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -261,7 +261,13 @@ am__remove_distdir = \
; rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
am__post_remove_distdir = \
$(am__is_gnu_make) || rm -f am__distdir.tar; \
$(am__remove_distdir)
am__ensure_distdir_tar = \
test -f am__distdir.tar || $(MAKE) $(AM_MAKEFLAGS) am__distdir.tar
am__dist_compress_failed = \
am__rc=$$?; rm -f $$am__archive am__distdir.tar; exit $$am__rc
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
@@ -287,10 +293,13 @@ am__relativize = \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).tar.lz \
$(distdir).tar.xz
# Exists only to be overridden by the user if desired.
AM_DIST_TAR_IGNORE_STDERR = $(am__tar_ignore_stderr)
DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 \
$(distdir).tar.bz3 $(distdir).tar.lz $(distdir).tar.xz
GZIP_ENV = -9
DIST_TARGETS = dist-lzip dist-xz dist-bzip2 dist-gzip
DIST_TARGETS = am--dist-lzip am--dist-xz am--dist-bzip2 am--dist-bzip3 \
am--dist-gzip
# Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
@@ -411,6 +420,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__tar_ignore_stderr = @am__tar_ignore_stderr@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
@@ -454,13 +464,6 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = \
dist-bzip2 \
dist-lzip \
dist-xz \
foreign \
subdir-objects
ACLOCAL_AMFLAGS = -I m4
LIBTOOLFLAGS = --verbose
SUBDIRS = lib $(am__append_1) $(am__append_2) $(am__append_3)
@@ -748,13 +751,14 @@ distdir-am: $(DISTFILES)
$(AM_V_at)$(MKDIR_P) "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
am__distdir="$(distdir)"; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sed "/\//!d;s|^|$$am__distdir/|;s,/[^/]*$$,," | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
@@ -807,55 +811,96 @@ distdir-am: $(DISTFILES)
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_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)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)
am__distdir.tar: distdir
am__distdir="$(distdir)"; \
am__tar_msg=`tardir=$$am__distdir && $(am__tar) 2>&1 >am__distdir.tar`; \
am__tar_rc=$$?; \
test -z "$$am__tar_msg" || { printf '%s\n' "$$am__tar_msg" >&2; \
test x"$(AM_DIST_TAR_IGNORE_STDERR)" = xyes || am__tar_rc=1; }; \
test $$am__tar_rc -eq 0 || { rm -f am__distdir.tar; \
echo "$(distdir).tar: cannot create the distribution archive" >&2; exit 1; }
dist-zstd: distdir
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
.INTERMEDIATE: am__distdir.tar
dist-gzip: am--dist-gzip
$(am__post_remove_distdir)
am--dist-gzip: am__distdir.tar
@$(am__ensure_distdir_tar)
am__archive=$(distdir).tar.gz; \
eval GZIP= gzip $(GZIP_ENV) -c <am__distdir.tar >$$am__archive \
|| { $(am__dist_compress_failed); }
dist-bzip2: am--dist-bzip2
$(am__post_remove_distdir)
am--dist-bzip2: am__distdir.tar
@$(am__ensure_distdir_tar)
am__archive=$(distdir).tar.bz2; \
BZIP2=$${BZIP2--9} bzip2 -c <am__distdir.tar >$$am__archive \
|| { $(am__dist_compress_failed); }
dist-bzip3: am--dist-bzip3
$(am__post_remove_distdir)
am--dist-bzip3: am__distdir.tar
@$(am__ensure_distdir_tar)
am__archive=$(distdir).tar.bz3; \
bzip3 -c <am__distdir.tar >$$am__archive \
|| { $(am__dist_compress_failed); }
dist-lzip: am--dist-lzip
$(am__post_remove_distdir)
am--dist-lzip: am__distdir.tar
@$(am__ensure_distdir_tar)
am__archive=$(distdir).tar.lz; \
lzip -c $${LZIP_OPT--9} <am__distdir.tar >$$am__archive \
|| { $(am__dist_compress_failed); }
dist-xz: am--dist-xz
$(am__post_remove_distdir)
am--dist-xz: am__distdir.tar
@$(am__ensure_distdir_tar)
am__archive=$(distdir).tar.xz; \
XZ_OPT=$${XZ_OPT--e} xz -c <am__distdir.tar >$$am__archive \
|| { $(am__dist_compress_failed); }
dist-tarZ: distdir
dist-zstd: am--dist-zstd
$(am__post_remove_distdir)
am--dist-zstd: am__distdir.tar
@$(am__ensure_distdir_tar)
am__archive=$(distdir).tar.zst; \
zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} <am__distdir.tar >$$am__archive \
|| { $(am__dist_compress_failed); }
dist-tarZ: am--dist-tarZ
$(am__post_remove_distdir)
am--dist-tarZ: am__distdir.tar
@$(am__ensure_distdir_tar)
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
am__archive=$(distdir).tar.Z; \
compress -c <am__distdir.tar >$$am__archive \
|| { $(am__dist_compress_failed); }
dist-shar: distdir
dist-shar: am--dist-shar
$(am__post_remove_distdir)
am--dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
shar $(distdir) >$(distdir).shar || { rm -f $(distdir).shar; exit 1; }
eval GZIP= gzip $(GZIP_ENV) -f $(distdir).shar
dist-zip: distdir
dist-zip: am--dist-zip
$(am__post_remove_distdir)
am--dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__post_remove_distdir)
dist dist-all:
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS)
$(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
case "$(DIST_ARCHIVES)" in \
*.tar.gz*) \
eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
@@ -879,11 +924,13 @@ distcheck: dist
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
am__distdir="$(distdir)"; \
am__distarchives="$(DIST_ARCHIVES)"; \
test -d "$$am__distdir/_build" || exit 0; \
dc_install_base=`$(am__cd) "$$am__distdir/_inst" && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build/sub \
&& $(am__cd) "$$am__distdir/_build/sub" \
&& ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
@@ -906,13 +953,13 @@ distcheck: dist
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& rm -rf $$am__distarchives \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
list="$(DIST_ARCHIVES)"; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@test -n '$(distuninstallcheck_dir)' || { \
@@ -1051,16 +1098,18 @@ 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-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-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man \
am--dist-bzip2 am--dist-bzip3 am--dist-gzip am--dist-lzip \
am--dist-shar am--dist-tarZ am--dist-xz am--dist-zip \
am--dist-zstd am--refresh check check-am clean clean-cscope \
clean-generic clean-libtool cscope cscopelist-am ctags \
ctags-am dist 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-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 \
+1 -1
View File
@@ -17,7 +17,7 @@
> Thank you! :heart: :pray:
# Expat, Release 2.8.4
# Expat, Release 2.8.5
This is Expat, a C99 library for parsing
[XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by
+16 -2
View File
@@ -74,7 +74,21 @@ AC_CONFIG_SRCDIR([Makefile.in])
AC_CONFIG_AUX_DIR([conftools])
AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE
dnl NOTE: Macro `AM_OPTIONAL_AUTOMAKE` is available with Automake >=1.19
dnl and serves as a proxy for robust Automake >=1.19 detection here.
dnl `dist-bzip3` was introduced with Automake 1.18 already but there
dnl is no robust way of checking precisely for Automake >=1.18.
dnl Automake >=1.13 is needed for (1) our use of LOG_DRIVER and
dnl (2) making it work without asking for parallel tests, explicitly.
m4_ifdef([AM_OPTIONAL_AUTOMAKE], [
AM_INIT_AUTOMAKE([1.19 dist-bzip2 dist-bzip3 dist-lzip dist-xz foreign subdir-objects])
dnl NOTE: Without this dummy call in the file the `m4_ifdef` above never hits true.
AM_OPTIONAL_AUTOMAKE([])
], [
AM_INIT_AUTOMAKE([1.13 dist-bzip2 dist-lzip dist-xz foreign subdir-objects])
])
AM_MAINTAINER_MODE([enable]) # to allow argument --disable-maintainer-mode
@@ -90,7 +104,7 @@ dnl If the API changes incompatibly set LIBAGE back to 0
dnl
LIBCURRENT=13 # sync
LIBREVISION=4 # with
LIBREVISION=5 # with
LIBAGE=12 # CMakeLists.txt!
AC_CONFIG_HEADERS([expat_config.h])
+7 -5
View File
@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.18.1 from Makefile.am.
# Makefile.in generated by automake 1.19 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# Copyright (C) 1994-2026 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -309,6 +309,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__tar_ignore_stderr = @am__tar_ignore_stderr@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
@@ -372,9 +373,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu doc/Makefile
$(AUTOMAKE) --foreign doc/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -455,13 +456,14 @@ distdir: $(BUILT_SOURCES)
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
am__distdir="$(distdir)"; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sed "/\//!d;s|^|$$am__distdir/|;s,/[^/]*$$,," | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
+24 -8
View File
@@ -53,7 +53,7 @@
<body>
<div>
<h1>
The Expat XML Parser <small>Release 2.8.4</small>
The Expat XML Parser <small>Release 2.8.5</small>
</h1>
</div>
@@ -1763,12 +1763,16 @@ XML_StopParser(XML_Parser p,
</pre>
<div class="fcndef">
<p>
Stops parsing, causing <code><a href="#XML_Parse">XML_Parse</a></code> or
<code><a href="#XML_ParseBuffer">XML_ParseBuffer</a></code> to return. Must be
called from within a call-back handler, except when aborting (when
<code>resumable</code> is <code>XML_FALSE</code>) an already suspended parser.
Some call-backs may still follow because they would otherwise get lost,
including
Stops parsing as soon as possible, causing <code><a href=
"#XML_Parse">XML_Parse</a></code> or <code><a href=
"#XML_ParseBuffer">XML_ParseBuffer</a></code> to return. Must be called from
within a call-back handler, except when aborting (when <code>resumable</code>
is <code>XML_FALSE</code>) an already suspended parser.
</p>
<p>
<strong>Note:</strong> Some call-backs may still follow because they would
otherwise get lost, including
</p>
<ul>
@@ -3709,8 +3713,20 @@ enum XML_FeatureEnum {
XML_FEATURE_MIN_SIZE,
XML_FEATURE_SIZEOF_XML_CHAR,
XML_FEATURE_SIZEOF_XML_LCHAR,
/* Added in Expat 2.0.0. */
XML_FEATURE_NS,
XML_FEATURE_LARGE_SIZE
/* Added in Expat 2.0.1. */
XML_FEATURE_LARGE_SIZE,
/* Added in Expat 2.1.0. */
XML_FEATURE_ATTR_INFO,
/* Added in Expat 2.4.0. */
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
/* Added in Expat 2.6.0. */
XML_FEATURE_GE,
/* Added in Expat 2.7.2. */
XML_FEATURE_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT,
XML_FEATURE_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT,
};
typedef struct {
+1 -1
View File
@@ -5,7 +5,7 @@
\\$2 \(la\\$1\(ra\\$3
..
.if \n(.g .mso www.tmac
.TH XMLWF 1 "August 31, 2026" "" ""
.TH XMLWF 1 "September 22, 2026" "" ""
.SH NAME
xmlwf \- Determines if an XML document is well-formed
.SH SYNOPSIS
+1 -1
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>August 31, 2026</date>">
<!ENTITY dhdate "<date>September 22, 2026</date>">
<!-- Please adjust this^^ date whenever cutting a new release. -->
<!ENTITY dhsection "<manvolnum>1</manvolnum>">
<!ENTITY dhemail "<email>[email protected]</email>">
+16 -11
View File
@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.18.1 from Makefile.am.
# Makefile.in generated by automake 1.19 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# Copyright (C) 1994-2026 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -337,6 +337,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__tar_ignore_stderr = @am__tar_ignore_stderr@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
@@ -399,9 +400,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu examples/Makefile
$(AUTOMAKE) --foreign examples/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -453,22 +454,25 @@ $(am__depfiles_remade):
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
@@ -537,13 +541,14 @@ distdir: $(BUILT_SOURCES)
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
am__distdir="$(distdir)"; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sed "/\//!d;s|^|$$am__distdir/|;s,/[^/]*$$,," | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
+4 -1
View File
@@ -8,6 +8,7 @@
Copyright (c) 2022 Mark Brand <[email protected]>
Copyright (c) 2025 Sebastian Pipping <[email protected]>
Copyright (c) 2026 Braian Plaku <[email protected]>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -383,7 +384,9 @@ UnknownEncodingHandler(void *encodingHandlerData, const XML_Char *name,
void
InitializeParser(XML_Parser parser) {
XML_SetUserData(parser, (void *)parser);
XML_SetHashSalt(parser, 0x41414141);
const uint8_t entropy[16] = {0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41};
XML_SetHashSalt16Bytes(parser, entropy);
XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
XML_SetElementDeclHandler(parser, ElementDeclHandler);
+11 -3
View File
@@ -17,6 +17,7 @@
#include <assert.h>
#include <limits.h> // for INT_MAX
#include <stdint.h>
#include <string.h>
#include "expat.h"
#include "siphash.h"
@@ -34,7 +35,8 @@
#endif
// 16-byte deterministic hash key.
static unsigned char hash_key[16] = "FUZZING IS FUN!";
static unsigned char hash_key_1[16] = "FUZZING IS FUN?";
static unsigned char hash_key_2[16] = "FUZZING IS FUN!";
static void XMLCALL
start(void *userData, const XML_Char *name, const XML_Char **atts) {
@@ -59,8 +61,14 @@ may_stop_character_handler(void *userData, const XML_Char *s, int len) {
static void
ParseOneInput(XML_Parser p, const uint8_t *data, size_t size) {
// Set the hash salt using siphash to generate a deterministic hash.
struct sipkey *key = sip_keyof(hash_key);
XML_SetHashSalt(p, (unsigned long)siphash24(data, size, key));
// The salt is 16 bytes and siphash24 produces 8, so the input is hashed
// under two keys.
const uint64_t first = siphash24(data, size, sip_keyof(hash_key_1));
const uint64_t second = siphash24(data, size, sip_keyof(hash_key_2));
uint8_t entropy[16];
memcpy(entropy, &first, sizeof(first));
memcpy(entropy + sizeof(first), &second, sizeof(second));
XML_SetHashSalt16Bytes(p, entropy);
(void)sip24_valid;
XML_SetUserData(p, p);
+10 -3
View File
@@ -35,7 +35,8 @@
#endif
// 16-byte deterministic hash key.
static unsigned char hash_key[16] = "FUZZING IS FUN!";
static unsigned char hash_key_1[16] = "FUZZING IS FUN?";
static unsigned char hash_key_2[16] = "FUZZING IS FUN!";
static void XMLCALL
start(void *userData, const XML_Char *name, const XML_Char **atts) {
@@ -60,8 +61,14 @@ may_stop_character_handler(void *userData, const XML_Char *s, int len) {
static void
ParseOneInput(XML_Parser p, const uint8_t *data, size_t size) {
// Set the hash salt using siphash to generate a deterministic hash.
struct sipkey *key = sip_keyof(hash_key);
XML_SetHashSalt(p, (unsigned long)siphash24(data, size, key));
// The salt is 16 bytes and siphash24 produces 8, so the input is hashed
// under two keys.
const uint64_t first = siphash24(data, size, sip_keyof(hash_key_1));
const uint64_t second = siphash24(data, size, sip_keyof(hash_key_2));
uint8_t entropy[16];
memcpy(entropy, &first, sizeof(first));
memcpy(entropy + sizeof(first), &second, sizeof(second));
XML_SetHashSalt16Bytes(p, entropy);
(void)sip24_valid;
XML_SetUserData(p, p);
+1
View File
@@ -115,6 +115,7 @@ EXTRA_DIST = \
expat_external.h \
expat.h \
fallthrough.h \
hash_table.h \
iasciitab.h \
internal.h \
latin1tab.h \
+17 -11
View File
@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.18.1 from Makefile.am.
# Makefile.in generated by automake 1.19 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# Copyright (C) 1994-2026 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -444,6 +444,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__tar_ignore_stderr = @am__tar_ignore_stderr@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
@@ -511,6 +512,7 @@ EXTRA_DIST = \
expat_external.h \
expat.h \
fallthrough.h \
hash_table.h \
iasciitab.h \
internal.h \
latin1tab.h \
@@ -540,9 +542,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu lib/Makefile
$(AUTOMAKE) --foreign lib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -643,22 +645,25 @@ $(am__depfiles_remade):
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
@@ -832,13 +837,14 @@ distdir: $(BUILT_SOURCES)
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
am__distdir="$(distdir)"; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sed "/\//!d;s|^|$$am__distdir/|;s,/[^/]*$$,," | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
+7 -1
View File
@@ -20,6 +20,7 @@
Copyright (c) 2023 Sony Corporation / Snild Dolkow <[email protected]>
Copyright (c) 2024 Taichi Haradaguchi <[email protected]>
Copyright (c) 2025 Matthew Fernandez <[email protected]>
Copyright (c) 2026 Braian Plaku <[email protected]>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -921,7 +922,9 @@ XML_SetParamEntityParsing(XML_Parser parser,
Returns 1 if successful, 0 when called after parsing has started.
Note: If parser == NULL, the function will do nothing and return 0.
DEPRECATED since Expat 2.8.0.
Please use XML_SetHashSalt16Bytes instead.
*/
XML_ATTR_DEPRECATED("please use XML_SetHashSalt16Bytes instead")
XMLPARSEAPI(int)
XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt);
@@ -1040,8 +1043,11 @@ enum XML_FeatureEnum {
XML_FEATURE_MIN_SIZE,
XML_FEATURE_SIZEOF_XML_CHAR,
XML_FEATURE_SIZEOF_XML_LCHAR,
/* Added in Expat 2.0.0. */
XML_FEATURE_NS,
/* Added in Expat 2.0.1. */
XML_FEATURE_LARGE_SIZE,
/* Added in Expat 2.1.0. */
XML_FEATURE_ATTR_INFO,
/* Added in Expat 2.4.0. */
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
@@ -1096,7 +1102,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
*/
# define XML_MAJOR_VERSION 2
# define XML_MINOR_VERSION 8
# define XML_MICRO_VERSION 4
# define XML_MICRO_VERSION 5
# ifdef __cplusplus
}
+12
View File
@@ -16,6 +16,7 @@
Copyright (c) 2017 Rhodri James <[email protected]>
Copyright (c) 2018 Yury Gribov <[email protected]>
Copyright (c) 2026 Matthew Fernandez <[email protected]>
Copyright (c) 2026 Braian Plaku <[email protected]>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -125,6 +126,17 @@
# define XML_ATTR_ALLOC_SIZE(x)
# endif
/* Marks a function that Expat still provides but that callers should move off
of. */
# if defined(__clang__) || defined(__GNUC__)
# define XML_ATTR_DEPRECATED(message) \
__attribute__((__deprecated__(message)))
# elif defined(_MSC_VER)
# define XML_ATTR_DEPRECATED(message) __declspec(deprecated(message))
# else
# define XML_ATTR_DEPRECATED(message) // empty i.e. no deprecation
# endif
# define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
# ifdef __cplusplus
+78
View File
@@ -0,0 +1,78 @@
/* Hash table related internal API
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2026 Sebastian Pipping <[email protected]>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
SPDX-License-Identifier: MIT
*/
#if ! defined(HASH_TABLE_H)
# define HASH_TABLE_H 1
# include "expat.h" // for XML_Bool, XML_Parser
# include "internal.h" // for XML_NONTESTING_STATIC
# include <stddef.h> // for size_t
typedef const XML_Char *KEY;
typedef struct {
KEY name;
} NAMED;
typedef struct {
NAMED **v;
unsigned char power;
size_t size;
size_t used;
XML_Parser parser;
} HASH_TABLE;
typedef struct {
NAMED **p;
NAMED **end;
} HASH_TABLE_ITER;
XML_NONTESTING_STATIC NAMED *lookupWithLength(XML_Parser parser,
HASH_TABLE *table, KEY name,
size_t nameLen,
size_t createSize);
XML_NONTESTING_STATIC NAMED *lookup(XML_Parser parser, HASH_TABLE *table,
KEY name, size_t createSize);
XML_NONTESTING_STATIC void hashTableInit(HASH_TABLE *table, XML_Parser parser);
XML_NONTESTING_STATIC void hashTableClear(HASH_TABLE *table);
XML_NONTESTING_STATIC void hashTableDestroy(HASH_TABLE *table);
XML_NONTESTING_STATIC void hashTableIterInit(HASH_TABLE_ITER *iter,
const HASH_TABLE *table);
XML_NONTESTING_STATIC NAMED *hashTableIterNext(HASH_TABLE_ITER *iter);
XML_NONTESTING_STATIC XML_Bool keyeq(KEY s1, size_t s1len, KEY s2);
XML_NONTESTING_STATIC size_t keylen(KEY s);
#endif // ! defined(HASH_TABLE_H)
+67 -100
View File
@@ -6,13 +6,6 @@
The following calling convention macros are defined for frequently
called functions:
FASTCALL - Used for those internal functions that have a simple
body and a low number of arguments and local variables.
PTRCALL - Used for functions called though function pointers.
PTRFASTCALL - Like PTRCALL, but for low number of arguments.
inline - Used for selected internal functions for which inlining
may improve performance on some platforms.
@@ -34,6 +27,8 @@
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <[email protected]>
Copyright (c) 2024 Taichi Haradaguchi <[email protected]>
Copyright (c) 2026 Matthew Wozniczka <[email protected]>
Copyright (c) 2026 Braian Plaku <[email protected]>
Copyright (c) 2026 Florian Schmaus <[email protected]>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -58,132 +53,104 @@
SPDX-License-Identifier: MIT
*/
#if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__)
/* We'll use this version by default only where we know it helps.
#if ! defined(INTERNAL_H)
# define INTERNAL_H 1
regparm() generates warnings on Solaris boxes. See SF bug #692878.
# ifndef XML_MIN_SIZE
# if ! defined(inline)
# ifdef __GNUC__
# define inline __inline
# endif /* __GNUC__ */
# endif
# endif /* XML_MIN_SIZE */
Instability reported with egcs on a RedHat Linux 7.3.
Let's comment out:
#define FASTCALL __attribute__((stdcall, regparm(3)))
and let's try this:
*/
# define FASTCALL __attribute__((regparm(3)))
# define PTRFASTCALL __attribute__((regparm(3)))
#endif
/* Using __fastcall seems to have an unexpected negative effect under
MS VC++, especially for function pointers, so we won't use it for
now on that platform. It may be reconsidered for a future release
if it can be made more effective.
Likely reason: __fastcall on Windows is like stdcall, therefore
the compiler cannot perform stack optimizations for call clusters.
*/
/* Make sure all of these are defined if they aren't already. */
#ifndef FASTCALL
# define FASTCALL
#endif
#ifndef PTRCALL
# define PTRCALL
#endif
#ifndef PTRFASTCALL
# define PTRFASTCALL
#endif
#ifndef XML_MIN_SIZE
# if ! defined(__cplusplus) && ! defined(inline)
# ifdef __GNUC__
# define inline __inline
# endif /* __GNUC__ */
# endif
#endif /* XML_MIN_SIZE */
#ifdef __cplusplus
# define inline inline
#else
# ifndef inline
# define inline
# endif
#endif
#include <limits.h> // ULONG_MAX
#include <stddef.h> // size_t
#if defined(_WIN32) \
&& (! defined(__USE_MINGW_ANSI_STDIO) \
|| (1 - __USE_MINGW_ANSI_STDIO - 1 == 0))
# define EXPAT_FMT_LLX(midpart) "%" midpart "I64x"
# define EXPAT_FMT_ULL(midpart) "%" midpart "I64u"
# if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u"
# else
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
# if ! defined(XML_NONTESTING_STATIC)
# if defined(XML_TESTING)
# define XML_NONTESTING_STATIC // empty i.e. not static
# else
# define XML_NONTESTING_STATIC static
# endif
# endif
#else
# include <inttypes.h> // PRIdPTR, PRIuPTR
# define EXPAT_FMT_LLX(midpart) "%" midpart "llx"
# define EXPAT_FMT_ULL(midpart) "%" midpart "llu"
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart PRIdPTR
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart PRIuPTR
#endif
#ifndef UNUSED_P
# define UNUSED_P(p) (void)p
#endif
# include <limits.h> // ULONG_MAX
# include <stddef.h> // size_t
# if defined(_WIN32) \
&& (! defined(__USE_MINGW_ANSI_STDIO) \
|| (1 - __USE_MINGW_ANSI_STDIO - 1 == 0))
# define EXPAT_FMT_LLX(midpart) "%" midpart "I64x"
# define EXPAT_FMT_ULL(midpart) "%" midpart "I64u"
# if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u"
# else
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
# endif
# else
# include <inttypes.h> // PRIdPTR, PRIuPTR
# define EXPAT_FMT_LLX(midpart) "%" midpart "llx"
# define EXPAT_FMT_ULL(midpart) "%" midpart "llu"
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart PRIdPTR
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart PRIuPTR
# endif
# ifndef UNUSED_P
# define UNUSED_P(p) (void)p
# endif
/* NOTE BEGIN If you ever patch these defaults to greater values
for non-attack XML payload in your environment,
please file a bug report with libexpat. Thank you!
*/
#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT \
100.0f
#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \
8388608 // 8 MiB, 2^23
# define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT \
100.0f
# define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \
8388608 // 8 MiB, 2^23
#define EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT 100.0f
#define EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT \
67108864 // 64 MiB, 2^26
# define EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT 100.0f
# define EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT \
67108864 // 64 MiB, 2^26
// NOTE: If function expat_alloc was user facing, EXPAT_MALLOC_ALIGNMENT would
// have to take sizeof(long double) into account
#define EXPAT_MALLOC_ALIGNMENT sizeof(long long) // largest parser (sub)member
#define EXPAT_MALLOC_PADDING ((EXPAT_MALLOC_ALIGNMENT) - sizeof(size_t))
union expat_align {
long long l;
void *p;
};
# define EXPAT_MALLOC_ALIGNMENT sizeof(union expat_align)
# define EXPAT_MALLOC_PADDING ((EXPAT_MALLOC_ALIGNMENT) - sizeof(size_t))
/* NOTE END */
#include "expat.h" // so we can use type XML_Parser below
#ifdef __cplusplus
extern "C" {
#endif
# include "expat.h" // so we can use type XML_Parser below
void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
const char **fromLimRef);
#if defined(XML_GE) && XML_GE == 1
# if defined(XML_GE) && XML_GE == 1
unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
const char *unsignedCharToPrintable(unsigned char c);
#endif
# endif
extern
#if ! defined(XML_TESTING)
# if ! defined(XML_TESTING)
const
#endif
# endif
XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
#if defined(XML_TESTING)
# if defined(XML_TESTING)
int xmlSetHashSalt(XML_Parser parser, unsigned long hash_salt);
void *expat_malloc(XML_Parser parser, size_t size, int sourceLine);
void expat_free(XML_Parser parser, void *ptr, int sourceLine);
void *expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine);
extern unsigned int g_bytesScanned; // used for testing only
#endif
# endif
#ifdef __cplusplus
}
#endif
#endif // not defined INTERNAL_H
+100 -123
View File
@@ -1,4 +1,4 @@
/* 13c4e8da8fccffb0e8e599684e0d447ad14c1bb0b48792cf5dd77d8712301871 (2.8.4+)
/* 0864fe2d216f47b742263b698bc051c865b342e8b820e42c234717098ea507e3 (2.8.5+)
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
@@ -54,6 +54,8 @@
Copyright (c) 2026 Darren Carreras <carrerasdarren@gmail.com>
Copyright (c) 2026 Alberto Maschietto <albertomaschietto9@gmail.com>
Copyright (c) 2026 Zeyou Liu <zeyouliu@tencent.com>
Copyright (c) 2026 Stan Ulbrych <stan@python.org>
Copyright (c) 2026 Braian Plaku <braianplaku@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -226,25 +228,10 @@ typedef char ICHAR;
#define EXPAT_MIN(a, b) (((a) < (b)) ? (a) : (b))
#include "internal.h"
#include "hash_table.h"
#include "xmltok.h"
#include "xmlrole.h"
typedef const XML_Char *KEY;
typedef struct {
KEY name;
} NAMED;
typedef struct {
NAMED **v;
unsigned char power;
size_t size;
size_t used;
XML_Parser parser;
} HASH_TABLE;
static size_t keylen(KEY s);
static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
/* For probing (after a collision) we need a step size relative prime
@@ -260,11 +247,6 @@ static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
#define PROBE_STEP(hash, mask, power) \
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
typedef struct {
NAMED **p;
NAMED **end;
} HASH_TABLE_ITER;
#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
#define INIT_DATA_BUF_SIZE 1024
#define INIT_ATTS_SIZE 16
@@ -334,12 +316,12 @@ typedef struct {
const XML_Char *publicId;
const XML_Char *notation;
bool open;
XML_Bool hasMore; /* true if entity has not been completely processed */
/* An entity can be open while being already completely processed (hasMore ==
XML_FALSE). The reason is the delayed closing of entities until their inner
bool hasMore; /* true if entity has not been completely processed */
/* An entity can be open while being already completely processed (!hasMore).
The reason is the delayed closing of entities until their inner
entities are processed and closed */
XML_Bool is_param;
XML_Bool is_internal; /* true if declared in internal subset outside PE */
bool is_param;
bool is_internal; /* true if declared in internal subset outside PE */
} ENTITY;
typedef struct {
@@ -374,8 +356,8 @@ typedef struct {
typedef struct attribute_id {
XML_Char *name;
PREFIX *prefix;
XML_Bool maybeTokenized;
XML_Bool xmlns;
bool maybeTokenized;
bool xmlns;
} ATTRIBUTE_ID;
typedef struct {
@@ -431,12 +413,12 @@ typedef struct {
XML_Bool standalone;
#ifdef XML_DTD
/* indicates if external PE has been read */
XML_Bool paramEntityRead;
bool paramEntityRead;
HASH_TABLE paramEntities;
#endif /* XML_DTD */
PREFIX defaultPrefix;
/* === scaffolding for building content model === */
XML_Bool in_eldecl;
bool in_eldecl;
CONTENT_SCAFFOLD *scaffold;
unsigned contentStringLen;
unsigned scaffSize;
@@ -458,7 +440,7 @@ typedef struct open_internal_entity {
struct open_internal_entity *next;
ENTITY *entity;
int startTagLevel;
XML_Bool betweenDecl; /* WFC: PE Between Declarations */
bool betweenDecl; /* WFC: PE Between Declarations */
enum EntityType type;
} OPEN_INTERNAL_ENTITY;
@@ -495,8 +477,8 @@ typedef struct entity_stats {
} ENTITY_STATS;
#endif /* XML_GE == 1 */
typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
const char *end, const char **endPtr);
typedef enum XML_Error Processor(XML_Parser parser, const char *start,
const char *end, const char **endPtr);
static Processor prologProcessor;
static Processor prologInitProcessor;
@@ -528,7 +510,7 @@ static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
XML_Bool haveMore, XML_Bool allowClosingDoctype,
enum XML_Account account);
static enum XML_Error processEntity(XML_Parser parser, ENTITY *entity,
XML_Bool betweenDecl, enum EntityType type);
bool betweenDecl, enum EntityType type);
static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
const ENCODING *enc, const char *start,
const char *end, const char **endPtr,
@@ -588,7 +570,7 @@ static void reportDefault(XML_Parser parser, const ENCODING *enc,
static const XML_Char *getContext(XML_Parser parser);
static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
static void FASTCALL normalizePublicId(XML_Char *s);
static void normalizePublicId(XML_Char *s);
static DTD *dtdCreate(XML_Parser parser);
/* do not call if m_parentParser != NULL */
@@ -598,36 +580,24 @@ static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
XML_Parser parser);
static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
STRING_POOL *newPool, const HASH_TABLE *oldTable);
static NAMED *lookupWithLength(XML_Parser parser, HASH_TABLE *table, KEY name,
size_t nameLen, size_t createSize);
static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
size_t createSize);
static void FASTCALL hashTableInit(HASH_TABLE *table, XML_Parser parser);
static void FASTCALL hashTableClear(HASH_TABLE *table);
static void FASTCALL hashTableDestroy(HASH_TABLE *table);
static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *iter,
const HASH_TABLE *table);
static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *iter);
static void FASTCALL poolInit(STRING_POOL *pool, XML_Parser parser);
static void FASTCALL poolClear(STRING_POOL *pool);
static void FASTCALL poolDestroy(STRING_POOL *pool);
static void poolInit(STRING_POOL *pool, XML_Parser parser);
static void poolClear(STRING_POOL *pool);
static void poolDestroy(STRING_POOL *pool);
static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
const char *ptr, const char *end);
static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
const char *ptr, const char *end);
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
static bool FASTCALL poolGrowUntil(STRING_POOL *pool, size_t needed);
static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
const XML_Char *s);
static const XML_Char *FASTCALL poolCopyStringNoFinish(STRING_POOL *pool,
const XML_Char *s);
static XML_Bool poolGrow(STRING_POOL *pool);
static bool poolGrowUntil(STRING_POOL *pool, size_t needed);
static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
static const XML_Char *poolCopyStringNoFinish(STRING_POOL *pool,
const XML_Char *s);
static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
int n);
static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
const XML_Char *s);
static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
static int FASTCALL nextScaffoldPart(XML_Parser parser);
static int nextScaffoldPart(XML_Parser parser);
static XML_Content *build_model(XML_Parser parser);
static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
const char *ptr, const char *end);
@@ -1596,7 +1566,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
}
/* moves list of bindings to m_freeBindingList */
static void FASTCALL
static void
moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
while (bindings) {
BINDING *b = bindings;
@@ -1869,7 +1839,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
return parser;
}
static void FASTCALL
static void
destroyBindings(BINDING *bindings, XML_Parser parser) {
for (;;) {
BINDING *b = bindings;
@@ -2268,9 +2238,10 @@ XML_SetParamEntityParsing(XML_Parser parser,
#endif
}
// DEPRECATED since Expat 2.8.0.
int XMLCALL
XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
/* The body of XML_SetHashSalt, so that Expat's own tests can reach it
without tripping the deprecation of the public function. */
XML_NONTESTING_STATIC int
xmlSetHashSalt(XML_Parser parser, unsigned long hash_salt) {
if (parser == NULL)
return 0;
@@ -2296,6 +2267,12 @@ XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
return 1;
}
// DEPRECATED since Expat 2.8.0.
int XMLCALL
XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
return xmlSetHashSalt(parser, hash_salt);
}
XML_Bool XMLCALL
XML_SetHashSalt16Bytes(XML_Parser parser, const uint8_t entropy[16]) {
if (parser == NULL)
@@ -3168,7 +3145,7 @@ storeRawNames(XML_Parser parser) {
return XML_TRUE;
}
static enum XML_Error PTRCALL
static enum XML_Error
contentProcessor(XML_Parser parser, const char *start, const char *end,
const char **endPtr) {
enum XML_Error result = doContent(
@@ -3182,7 +3159,7 @@ contentProcessor(XML_Parser parser, const char *start, const char *end,
return result;
}
static enum XML_Error PTRCALL
static enum XML_Error
externalEntityInitProcessor(XML_Parser parser, const char *start,
const char *end, const char **endPtr) {
enum XML_Error result = initializeEncoding(parser);
@@ -3192,7 +3169,7 @@ externalEntityInitProcessor(XML_Parser parser, const char *start,
return externalEntityInitProcessor2(parser, start, end, endPtr);
}
static enum XML_Error PTRCALL
static enum XML_Error
externalEntityInitProcessor2(XML_Parser parser, const char *start,
const char *end, const char **endPtr) {
const char *next = start; /* XmlContentTok doesn't always set the last arg */
@@ -3237,7 +3214,7 @@ externalEntityInitProcessor2(XML_Parser parser, const char *start,
return externalEntityInitProcessor3(parser, start, end, endPtr);
}
static enum XML_Error PTRCALL
static enum XML_Error
externalEntityInitProcessor3(XML_Parser parser, const char *start,
const char *end, const char **endPtr) {
int tok;
@@ -3289,7 +3266,7 @@ externalEntityInitProcessor3(XML_Parser parser, const char *start,
return externalEntityContentProcessor(parser, start, end, endPtr);
}
static enum XML_Error PTRCALL
static enum XML_Error
externalEntityContentProcessor(XML_Parser parser, const char *start,
const char *end, const char **endPtr) {
enum XML_Error result
@@ -4551,6 +4528,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
/* Detect and prevent integer overflow */
if (len > SIZE_MAX - EXPAND_SPARE
|| len + EXPAND_SPARE > SIZE_MAX / sizeof(XML_Char)) {
FREE(parser, b);
return XML_ERROR_NO_MEMORY;
}
@@ -4588,7 +4566,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
/* The idea here is to avoid using stack for each CDATA section when
the whole file is parsed with one call.
*/
static enum XML_Error PTRCALL
static enum XML_Error
cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
const char **endPtr) {
enum XML_Error result = doCdataSection(
@@ -4754,7 +4732,7 @@ doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
/* The idea here is to avoid using stack for each IGNORE section when
the whole file is parsed with one call.
*/
static enum XML_Error PTRCALL
static enum XML_Error
ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
const char **endPtr) {
enum XML_Error result
@@ -5024,7 +5002,7 @@ handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
return XML_ERROR_UNKNOWN_ENCODING;
}
static enum XML_Error PTRCALL
static enum XML_Error
prologInitProcessor(XML_Parser parser, const char *s, const char *end,
const char **nextPtr) {
enum XML_Error result = initializeEncoding(parser);
@@ -5036,7 +5014,7 @@ prologInitProcessor(XML_Parser parser, const char *s, const char *end,
#ifdef XML_DTD
static enum XML_Error PTRCALL
static enum XML_Error
externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
const char **nextPtr) {
enum XML_Error result = initializeEncoding(parser);
@@ -5045,7 +5023,7 @@ externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
/* we know now that XML_Parse(Buffer) has been called,
so we consider the external parameter entity read */
parser->m_dtd->paramEntityRead = XML_TRUE;
parser->m_dtd->paramEntityRead = true;
if (parser->m_prologState.inEntityValue) {
parser->m_processor = entityValueInitProcessor;
@@ -5056,7 +5034,7 @@ externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
}
}
static enum XML_Error PTRCALL
static enum XML_Error
entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
const char **nextPtr) {
int tok;
@@ -5140,7 +5118,7 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
}
}
static enum XML_Error PTRCALL
static enum XML_Error
externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
const char **nextPtr) {
const char *next = s;
@@ -5186,7 +5164,7 @@ externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
XML_ACCOUNT_DIRECT);
}
static enum XML_Error PTRCALL
static enum XML_Error
entityValueProcessor(XML_Parser parser, const char *s, const char *end,
const char **nextPtr) {
const char *start = s;
@@ -5233,7 +5211,7 @@ entityValueProcessor(XML_Parser parser, const char *s, const char *end,
#endif /* XML_DTD */
static enum XML_Error PTRCALL
static enum XML_Error
prologProcessor(XML_Parser parser, const char *s, const char *end,
const char **nextPtr) {
const char *next = s;
@@ -5479,7 +5457,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
}
if (parser->m_useForeignDTD)
entity->base = parser->m_curBase;
dtd->paramEntityRead = XML_FALSE;
dtd->paramEntityRead = false;
beforeHandler(parser);
const int status = parser->m_externalEntityRefHandler(
parser->m_externalEntityRefHandlerArg, 0, entity->base,
@@ -5529,7 +5507,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
if (! entity)
return XML_ERROR_NO_MEMORY;
entity->base = parser->m_curBase;
dtd->paramEntityRead = XML_FALSE;
dtd->paramEntityRead = false;
beforeHandler(parser);
const int status = parser->m_externalEntityRefHandler(
parser->m_externalEntityRefHandlerArg, 0, entity->base,
@@ -5872,7 +5850,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
} else {
poolFinish(&dtd->pool);
parser->m_declEntity->publicId = NULL;
parser->m_declEntity->is_param = XML_FALSE;
parser->m_declEntity->is_param = false;
/* if we have a parent parser or are reading an internal parameter
entity, then the entity declaration is not considered "internal"
*/
@@ -5902,7 +5880,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
} else {
poolFinish(&dtd->pool);
parser->m_declEntity->publicId = NULL;
parser->m_declEntity->is_param = XML_TRUE;
parser->m_declEntity->is_param = true;
/* if we have a parent parser or are reading an internal parameter
entity, then the entity declaration is not considered "internal"
*/
@@ -6137,8 +6115,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
return XML_ERROR_RECURSIVE_ENTITY_REF;
if (entity->textPtr) {
enum XML_Error result;
XML_Bool betweenDecl
= (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
bool betweenDecl = (role == XML_ROLE_PARAM_ENTITY_REF);
result = processEntity(parser, entity, betweenDecl, ENTITY_INTERNAL);
if (result != XML_ERROR_NONE)
return result;
@@ -6146,7 +6123,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
break;
}
if (parser->m_externalEntityRefHandler) {
dtd->paramEntityRead = XML_FALSE;
dtd->paramEntityRead = false;
entity->open = true;
entityTrackingOnOpen(parser, entity, __LINE__);
beforeHandler(parser);
@@ -6190,7 +6167,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
return XML_ERROR_NO_MEMORY;
dtd->scaffLevel = 0;
dtd->scaffCount = 0;
dtd->in_eldecl = XML_TRUE;
dtd->in_eldecl = true;
handleDefault = XML_FALSE;
}
break;
@@ -6219,7 +6196,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
afterHandler(parser);
handleDefault = XML_FALSE;
}
dtd->in_eldecl = XML_FALSE;
dtd->in_eldecl = false;
}
break;
@@ -6301,7 +6278,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
parser->m_handlerArg, parser->m_declElementType->name, model);
afterHandler(parser);
}
dtd->in_eldecl = XML_FALSE;
dtd->in_eldecl = false;
dtd->contentStringLen = 0;
}
}
@@ -6370,7 +6347,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
/* not reached */
}
static enum XML_Error PTRCALL
static enum XML_Error
epilogProcessor(XML_Parser parser, const char *s, const char *end,
const char **nextPtr) {
parser->m_processor = epilogProcessor;
@@ -6449,7 +6426,7 @@ epilogProcessor(XML_Parser parser, const char *s, const char *end,
}
static enum XML_Error
processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl,
processEntity(XML_Parser parser, ENTITY *entity, bool betweenDecl,
enum EntityType type) {
OPEN_INTERNAL_ENTITY *openEntity, **openEntityList;
OPEN_INTERNAL_ENTITY **const freeEntityList = &parser->m_freeEntities;
@@ -6485,7 +6462,7 @@ processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl,
return XML_ERROR_NO_MEMORY;
}
entity->open = true;
entity->hasMore = XML_TRUE;
entity->hasMore = true;
#if XML_GE == 1
entityTrackingOnOpen(parser, entity, __LINE__);
#endif
@@ -6507,7 +6484,7 @@ processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl,
return XML_ERROR_NONE;
}
static enum XML_Error PTRCALL
static enum XML_Error
internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
const char **nextPtr) {
UNUSED_P(s);
@@ -6557,7 +6534,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
// Entity is complete. We cannot close it here since we need to first
// process its possible inner entities (which are added to the
// m_openInternalEntities during doProlog or doContent calls above)
entity->hasMore = XML_FALSE;
entity->hasMore = false;
if (! entity->is_param
&& (openEntity->startTagLevel != parser->m_tagLevel)) {
return XML_ERROR_ASYNC_ENTITY;
@@ -6589,7 +6566,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
return XML_ERROR_NONE;
}
static enum XML_Error PTRCALL
static enum XML_Error
errorProcessor(XML_Parser parser, const char *s, const char *end,
const char **nextPtr) {
UNUSED_P(s);
@@ -6640,7 +6617,7 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
// Entity is complete. We cannot close it here since we need to first
// process its possible inner entities (which are added to the
// m_openAttributeEntities during appendAttributeValue)
entity->hasMore = XML_FALSE;
entity->hasMore = false;
continue;
} // End of entity processing, "if" block skips the rest
@@ -6948,7 +6925,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
}
if (entity->systemId) {
if (parser->m_externalEntityRefHandler) {
dtd->paramEntityRead = XML_FALSE;
dtd->paramEntityRead = false;
entity->open = true;
entityTrackingOnOpen(parser, entity, __LINE__);
beforeHandler(parser);
@@ -7100,7 +7077,7 @@ callStoreEntityValue(XML_Parser parser, const ENCODING *enc,
// Entity is complete. We cannot close it here since we need to first
// process its possible inner entities (which are added to the
// m_openValueEntities during storeEntityValue)
entity->hasMore = XML_FALSE;
entity->hasMore = false;
continue;
} // End of entity processing, "if" block skips the rest
@@ -7162,7 +7139,7 @@ storeSelfEntityValue(XML_Parser parser, ENTITY *entity) {
#endif /* XML_GE == 0 */
static void FASTCALL
static void
normalizeLines(XML_Char *s) {
XML_Char *p;
for (;; s++) {
@@ -7328,7 +7305,7 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
att->value = value;
att->isCdata = isCdata;
if (! isCdata)
attId->maybeTokenized = XML_TRUE;
attId->maybeTokenized = true;
NAME_AND_DEFAULT_ATTRIBUTE *const nameAndDefaultAttribute
= (NAME_AND_DEFAULT_ATTRIBUTE *)lookup(
@@ -7413,7 +7390,7 @@ getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
else
id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
sizeof(PREFIX));
id->xmlns = XML_TRUE;
id->xmlns = true;
} else {
int i;
for (i = 0; name[i]; i++) {
@@ -7603,7 +7580,7 @@ setContext(XML_Parser parser, const XML_Char *context) {
return XML_TRUE;
}
static void FASTCALL
static void
normalizePublicId(XML_Char *publicId) {
XML_Char *p = publicId;
XML_Char *s;
@@ -7636,13 +7613,13 @@ dtdCreate(XML_Parser parser) {
hashTableInit(&(p->attributeIds), parser);
hashTableInit(&(p->prefixes), parser);
#ifdef XML_DTD
p->paramEntityRead = XML_FALSE;
p->paramEntityRead = false;
hashTableInit(&(p->paramEntities), parser);
#endif /* XML_DTD */
p->defaultPrefix.name = NULL;
p->defaultPrefix.binding = NULL;
p->in_eldecl = XML_FALSE;
p->in_eldecl = false;
p->scaffIndex = NULL;
p->scaffIndexSize = 0;
p->scaffold = NULL;
@@ -7670,7 +7647,7 @@ dtdReset(DTD *p, XML_Parser parser) {
}
hashTableClear(&(p->generalEntities));
#ifdef XML_DTD
p->paramEntityRead = XML_FALSE;
p->paramEntityRead = false;
hashTableClear(&(p->paramEntities));
#endif /* XML_DTD */
hashTableClear(&(p->elementTypes));
@@ -7681,7 +7658,7 @@ dtdReset(DTD *p, XML_Parser parser) {
p->defaultPrefix.name = NULL;
p->defaultPrefix.binding = NULL;
p->in_eldecl = XML_FALSE;
p->in_eldecl = false;
FREE(parser, p->scaffIndex);
p->scaffIndex = NULL;
@@ -7949,7 +7926,7 @@ copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
// Compares two strings `s1` and `s2` whereas:
// - `s2` is zero-terminated but
// - `s1` is made up of exactly (not just up to) `s1len` non-zero characters.
static XML_Bool FASTCALL
XML_NONTESTING_STATIC XML_Bool
keyeq(KEY s1, size_t s1len, KEY s2) {
#ifdef XML_UNICODE
# ifdef XML_UNICODE_WCHAR_T
@@ -7966,7 +7943,7 @@ keyeq(KEY s1, size_t s1len, KEY s2) {
#endif
}
static size_t
XML_NONTESTING_STATIC size_t
keylen(KEY s) {
return xcslen(s);
}
@@ -7979,7 +7956,7 @@ copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
*key = rootParser->m_hash_secret_salt_128;
}
static unsigned long FASTCALL
static unsigned long
hash(XML_Parser parser, KEY s, size_t keyLen) {
struct siphash state;
struct sipkey key;
@@ -8009,7 +7986,7 @@ hash(XML_Parser parser, KEY s, size_t keyLen) {
// read-write mode does, because keys can be re-hashed later and the
// hash table does not store key length information.
//
static NAMED *
XML_NONTESTING_STATIC NAMED *
lookupWithLength(XML_Parser parser, HASH_TABLE *table, KEY name, size_t nameLen,
size_t createSize) {
size_t i;
@@ -8116,12 +8093,12 @@ lookupWithLength(XML_Parser parser, HASH_TABLE *table, KEY name, size_t nameLen,
// be used to tell cases "existed and found" and "newly inserted" apart
// with the structure returned.
//
static NAMED *
XML_NONTESTING_STATIC NAMED *
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
return lookupWithLength(parser, table, name, keylen(name), createSize);
}
static void FASTCALL
XML_NONTESTING_STATIC void
hashTableClear(HASH_TABLE *table) {
size_t i;
for (i = 0; i < table->size; i++) {
@@ -8131,7 +8108,7 @@ hashTableClear(HASH_TABLE *table) {
table->used = 0;
}
static void FASTCALL
XML_NONTESTING_STATIC void
hashTableDestroy(HASH_TABLE *table) {
size_t i;
for (i = 0; i < table->size; i++)
@@ -8139,7 +8116,7 @@ hashTableDestroy(HASH_TABLE *table) {
FREE(table->parser, table->v);
}
static void FASTCALL
XML_NONTESTING_STATIC void
hashTableInit(HASH_TABLE *p, XML_Parser parser) {
p->power = 0;
p->size = 0;
@@ -8148,13 +8125,13 @@ hashTableInit(HASH_TABLE *p, XML_Parser parser) {
p->parser = parser;
}
static void FASTCALL
XML_NONTESTING_STATIC void
hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
iter->p = table->v;
iter->end = iter->p ? iter->p + table->size : NULL;
}
static NAMED *FASTCALL
XML_NONTESTING_STATIC NAMED *
hashTableIterNext(HASH_TABLE_ITER *iter) {
while (iter->p != iter->end) {
NAMED *tem = *(iter->p)++;
@@ -8164,7 +8141,7 @@ hashTableIterNext(HASH_TABLE_ITER *iter) {
return NULL;
}
static void FASTCALL
static void
poolInit(STRING_POOL *pool, XML_Parser parser) {
pool->blocks = NULL;
pool->freeBlocks = NULL;
@@ -8174,7 +8151,7 @@ poolInit(STRING_POOL *pool, XML_Parser parser) {
pool->parser = parser;
}
static void FASTCALL
static void
poolClear(STRING_POOL *pool) {
if (! pool->freeBlocks)
pool->freeBlocks = pool->blocks;
@@ -8193,7 +8170,7 @@ poolClear(STRING_POOL *pool) {
pool->end = NULL;
}
static void FASTCALL
static void
poolDestroy(STRING_POOL *pool) {
BLOCK *p = pool->blocks;
while (p) {
@@ -8226,7 +8203,7 @@ poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
return pool->start;
}
static const XML_Char *FASTCALL
static const XML_Char *
poolCopyString(STRING_POOL *pool, const XML_Char *s) {
if (! poolAppendChars(pool, s, xcslen(s) + /*null terminator*/ 1))
return NULL;
@@ -8237,7 +8214,7 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s) {
// A version of `poolCopyString` that does not call `poolFinish`
// and reverts any partial advancement upon failure.
static const XML_Char *FASTCALL
static const XML_Char *
poolCopyStringNoFinish(STRING_POOL *pool, const XML_Char *s) {
const XML_Char *const original = s;
do {
@@ -8275,7 +8252,7 @@ poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
return s;
}
static const XML_Char *FASTCALL
static const XML_Char *
poolAppendString(STRING_POOL *pool, const XML_Char *s) {
if (! poolAppendChars(pool, s, xcslen(s)))
return NULL;
@@ -8320,7 +8297,7 @@ poolBytesToAllocateFor(int blockSize) {
}
}
static XML_Bool FASTCALL
static XML_Bool
poolGrow(STRING_POOL *pool) {
if (pool->freeBlocks) {
if (pool->start == NULL) {
@@ -8425,7 +8402,7 @@ poolGrow(STRING_POOL *pool) {
return XML_TRUE;
}
static bool FASTCALL
static bool
poolGrowUntil(STRING_POOL *pool, size_t needed) {
for (;;) {
const size_t available = pool->end - pool->ptr;
@@ -8438,7 +8415,7 @@ poolGrowUntil(STRING_POOL *pool, size_t needed) {
}
}
static int FASTCALL
static int
nextScaffoldPart(XML_Parser parser) {
DTD *const dtd = parser->m_dtd; /* save one level of indirection */
CONTENT_SCAFFOLD *me;
+56 -57
View File
@@ -12,7 +12,7 @@
Copyright (c) 2002-2006 Karl Waclawek <[email protected]>
Copyright (c) 2002-2003 Fred L. Drake, Jr. <[email protected]>
Copyright (c) 2005-2009 Steven Solie <[email protected]>
Copyright (c) 2016-2023 Sebastian Pipping <[email protected]>
Copyright (c) 2016-2026 Sebastian Pipping <[email protected]>
Copyright (c) 2017 Rhodri James <[email protected]>
Copyright (c) 2019 David Loffredo <[email protected]>
Copyright (c) 2021 Donghee Na <[email protected]>
@@ -121,9 +121,8 @@ static const char KW_SYSTEM[]
# define setTopLevel(state) ((state)->handler = internalSubset)
#endif /* not XML_DTD */
typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok,
const char *ptr, const char *end,
const ENCODING *enc);
typedef int PROLOG_HANDLER(PROLOG_STATE *state, int tok, const char *ptr,
const char *end, const ENCODING *enc);
static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2,
doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2,
@@ -137,9 +136,9 @@ static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2,
#endif /* XML_DTD */
declClose, error;
static int FASTCALL common(PROLOG_STATE *state, int tok);
static int common(PROLOG_STATE *state, int tok);
static int PTRCALL
static int
prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -170,7 +169,7 @@ prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -202,7 +201,7 @@ prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -222,7 +221,7 @@ prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -239,7 +238,7 @@ doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -265,7 +264,7 @@ doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -281,7 +280,7 @@ doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -297,7 +296,7 @@ doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -316,7 +315,7 @@ doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -332,7 +331,7 @@ doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -377,7 +376,7 @@ internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
#ifdef XML_DTD
static int PTRCALL
static int
externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
state->handler = externalSubset1;
@@ -386,7 +385,7 @@ externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return externalSubset1(state, tok, ptr, end, enc);
}
static int PTRCALL
static int
externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -414,7 +413,7 @@ externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
#endif /* XML_DTD */
static int PTRCALL
static int
entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -433,7 +432,7 @@ entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -449,7 +448,7 @@ entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -473,7 +472,7 @@ entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -489,7 +488,7 @@ entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -505,7 +504,7 @@ entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -524,7 +523,7 @@ entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -541,7 +540,7 @@ entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -565,7 +564,7 @@ entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -581,7 +580,7 @@ entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -597,7 +596,7 @@ entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -613,7 +612,7 @@ entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -629,7 +628,7 @@ notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -649,7 +648,7 @@ notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -665,7 +664,7 @@ notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -682,7 +681,7 @@ notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -702,7 +701,7 @@ notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -719,7 +718,7 @@ attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -739,7 +738,7 @@ attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -769,7 +768,7 @@ attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -787,7 +786,7 @@ attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -806,7 +805,7 @@ attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -822,7 +821,7 @@ attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -838,7 +837,7 @@ attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -858,7 +857,7 @@ attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
}
/* default value */
static int PTRCALL
static int
attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -888,7 +887,7 @@ attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -904,7 +903,7 @@ attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -921,7 +920,7 @@ element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -947,7 +946,7 @@ element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -981,7 +980,7 @@ element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -1005,7 +1004,7 @@ element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -1022,7 +1021,7 @@ element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -1042,7 +1041,7 @@ element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -1071,7 +1070,7 @@ element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -1120,7 +1119,7 @@ element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
#ifdef XML_DTD
static int PTRCALL
static int
condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
switch (tok) {
@@ -1140,7 +1139,7 @@ condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -1157,7 +1156,7 @@ condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
return common(state, tok);
}
static int PTRCALL
static int
condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -1175,7 +1174,7 @@ condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
#endif /* XML_DTD */
static int PTRCALL
static int
declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(ptr);
@@ -1211,7 +1210,7 @@ declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
*
* LCOV_EXCL_START
*/
static int PTRCALL
static int
error(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
const ENCODING *enc) {
UNUSED_P(state);
@@ -1223,7 +1222,7 @@ error(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
}
/* LCOV_EXCL_STOP */
static int FASTCALL
static int
common(PROLOG_STATE *state, int tok) {
#ifdef XML_DTD
if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+3 -11
View File
@@ -10,7 +10,7 @@
Copyright (c) 2000 Clark Cooper <[email protected]>
Copyright (c) 2002 Karl Waclawek <[email protected]>
Copyright (c) 2002 Fred L. Drake, Jr. <[email protected]>
Copyright (c) 2017-2025 Sebastian Pipping <[email protected]>
Copyright (c) 2017-2026 Sebastian Pipping <[email protected]>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -40,10 +40,6 @@
# include "xmltok.h"
# ifdef __cplusplus
extern "C" {
# endif
enum {
XML_ROLE_ERROR = -1,
XML_ROLE_NONE = 0,
@@ -112,8 +108,8 @@ enum {
};
typedef struct prolog_state {
int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr,
const char *end, const ENCODING *enc);
int (*handler)(struct prolog_state *state, int tok, const char *ptr,
const char *end, const ENCODING *enc);
unsigned level;
int role_none;
# ifdef XML_DTD
@@ -131,8 +127,4 @@ void XmlPrologStateInitExternalEntity(PROLOG_STATE *state);
# define XmlTokenRole(state, tok, ptr, end, enc) \
(((state)->handler)(state, tok, ptr, end, enc))
# ifdef __cplusplus
}
# endif
#endif /* not XmlRole_INCLUDED */
+139 -64
View File
@@ -27,6 +27,7 @@
Copyright (c) 2025 Alfonso Gregory <[email protected]>
Copyright (c) 2026 Nick Begg <[email protected]>
Copyright (c) 2026 Kartik Kenchi <[email protected]>
Copyright (c) 2026 Afonso Januário <[email protected]>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -136,20 +137,20 @@
: ((p)[1] & 0x80) == 0 \
|| ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
static int PTRFASTCALL
static int
isNever(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
UNUSED_P(p);
return 0;
}
static int PTRFASTCALL
static int
utf8_isName2(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
}
static int PTRFASTCALL
static int
utf8_isName3(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
@@ -157,13 +158,13 @@ utf8_isName3(const ENCODING *enc, const char *p) {
#define utf8_isName4 isNever
static int PTRFASTCALL
static int
utf8_isNmstrt2(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
}
static int PTRFASTCALL
static int
utf8_isNmstrt3(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
@@ -171,19 +172,19 @@ utf8_isNmstrt3(const ENCODING *enc, const char *p) {
#define utf8_isNmstrt4 isNever
static int PTRFASTCALL
static int
utf8_isInvalid2(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return UTF8_INVALID2((const unsigned char *)p);
}
static int PTRFASTCALL
static int
utf8_isInvalid3(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return UTF8_INVALID3((const unsigned char *)p);
}
static int PTRFASTCALL
static int
utf8_isInvalid4(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return UTF8_INVALID4((const unsigned char *)p);
@@ -193,21 +194,21 @@ struct normal_encoding {
ENCODING enc;
unsigned char type[256];
#ifdef XML_MIN_SIZE
int(PTRFASTCALL *byteType)(const ENCODING *, const char *);
int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
int(PTRCALL *charMatches)(const ENCODING *, const char *, int);
int (*byteType)(const ENCODING *, const char *);
int (*isNameMin)(const ENCODING *, const char *);
int (*isNmstrtMin)(const ENCODING *, const char *);
int (*byteToAscii)(const ENCODING *, const char *);
int (*charMatches)(const ENCODING *, const char *, int);
#endif /* XML_MIN_SIZE */
int(PTRFASTCALL *isName2)(const ENCODING *, const char *);
int(PTRFASTCALL *isName3)(const ENCODING *, const char *);
int(PTRFASTCALL *isName4)(const ENCODING *, const char *);
int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
int (*isName2)(const ENCODING *, const char *);
int (*isName3)(const ENCODING *, const char *);
int (*isName4)(const ENCODING *, const char *);
int (*isNmstrt2)(const ENCODING *, const char *);
int (*isNmstrt3)(const ENCODING *, const char *);
int (*isNmstrt4)(const ENCODING *, const char *);
int (*isInvalid2)(const ENCODING *, const char *);
int (*isInvalid3)(const ENCODING *, const char *);
int (*isInvalid4)(const ENCODING *, const char *);
};
#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc))
@@ -232,7 +233,20 @@ struct normal_encoding {
/* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \
/* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL
static int FASTCALL checkCharRefNumber(int result);
/* Like NULL_VTABLE but with a real isInvalid4 so the UTF-16 encodings reject a
high surrogate that is not followed by a low surrogate. Only needed for the
XML_MIN_SIZE build, where the shared tokenizer dispatches through the vtable;
the regular build inlines the same check via IS_INVALID_CHAR. */
#ifdef XML_MIN_SIZE
# define UTF16_NULL_VTABLE(E) \
/* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \
/* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \
/* isInvalid2 */ NULL, /* isInvalid3 */ NULL, E##isInvalid4
#else
# define UTF16_NULL_VTABLE(E) NULL_VTABLE
#endif
static int checkCharRefNumber(int result);
#include "xmltok_impl.h"
#include "ascii.h"
@@ -253,7 +267,7 @@ static int FASTCALL checkCharRefNumber(int result);
(((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
#ifdef XML_MIN_SIZE
static int PTRFASTCALL
static int
sb_byteType(const ENCODING *enc, const char *p) {
return SB_BYTE_TYPE(enc, p);
}
@@ -264,7 +278,7 @@ sb_byteType(const ENCODING *enc, const char *p) {
#ifdef XML_MIN_SIZE
# define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
static int PTRFASTCALL
static int
sb_byteToAscii(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return *p;
@@ -297,7 +311,7 @@ sb_byteToAscii(const ENCODING *enc, const char *p) {
#ifdef XML_MIN_SIZE
# define CHAR_MATCHES(enc, p, c) \
(AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
static int PTRCALL
static int
sb_charMatches(const ENCODING *enc, const char *p, int c) {
UNUSED_P(enc);
return *p == c;
@@ -368,7 +382,7 @@ _INTERNAL_trim_to_complete_utf8_characters(const char *from,
*fromLimRef = fromLim;
}
static enum XML_Convert_Result PTRCALL
static enum XML_Convert_Result
utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
char **toP, const char *toLim) {
bool input_incomplete = false;
@@ -407,7 +421,7 @@ utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
return XML_CONVERT_COMPLETED;
}
static enum XML_Convert_Result PTRCALL
static enum XML_Convert_Result
utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim) {
enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
@@ -505,7 +519,7 @@ static const struct normal_encoding internal_utf8_encoding
},
STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
static enum XML_Convert_Result PTRCALL
static enum XML_Convert_Result
latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
char **toP, const char *toLim) {
UNUSED_P(enc);
@@ -528,7 +542,7 @@ latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
}
}
static enum XML_Convert_Result PTRCALL
static enum XML_Convert_Result
latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim) {
UNUSED_P(enc);
@@ -563,7 +577,7 @@ static const struct normal_encoding latin1_encoding
},
STANDARD_VTABLE(sb_) NULL_VTABLE};
static enum XML_Convert_Result PTRCALL
static enum XML_Convert_Result
ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
char **toP, const char *toLim) {
UNUSED_P(enc);
@@ -598,7 +612,7 @@ static const struct normal_encoding ascii_encoding
},
STANDARD_VTABLE(sb_) NULL_VTABLE};
static int PTRFASTCALL
static int
unicode_byte_type(char hi, char lo) {
switch ((unsigned char)hi) {
/* 0xD800-0xDBFF first 16-bit code unit or high surrogate (W1) */
@@ -625,7 +639,7 @@ unicode_byte_type(char hi, char lo) {
}
#define DEFINE_UTF16_TO_UTF8(E) \
static enum XML_Convert_Result PTRCALL E##toUtf8( \
static enum XML_Convert_Result E##toUtf8( \
const ENCODING *enc, const char **fromP, const char *fromLim, \
char **toP, const char *toLim) { \
const char *from = *fromP; \
@@ -702,7 +716,7 @@ unicode_byte_type(char hi, char lo) {
}
#define DEFINE_UTF16_TO_UTF16(E) \
static enum XML_Convert_Result PTRCALL E##toUtf16( \
static enum XML_Convert_Result E##toUtf16( \
const ENCODING *enc, const char **fromP, const char *fromLim, \
unsigned short **toP, const unsigned short *toLim) { \
enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
@@ -749,38 +763,49 @@ DEFINE_UTF16_TO_UTF16(big2_)
UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \
UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
/* A 4-byte UTF-16 character is a surrogate pair; byteType only reports BT_LEAD4
for a high surrogate, so the pair is invalid unless the second unit is a low
surrogate (U+DC00..U+DFFF, i.e. high byte 0xDC..0xDF). */
#define LITTLE2_IS_INVALID_CHAR(p, n) \
((n) == 4 && ((unsigned char)(p)[3] & 0xFC) != 0xDC)
#ifdef XML_MIN_SIZE
static int PTRFASTCALL
static int
little2_byteType(const ENCODING *enc, const char *p) {
return LITTLE2_BYTE_TYPE(enc, p);
}
static int PTRFASTCALL
static int
little2_byteToAscii(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return LITTLE2_BYTE_TO_ASCII(p);
}
static int PTRCALL
static int
little2_charMatches(const ENCODING *enc, const char *p, int c) {
UNUSED_P(enc);
return LITTLE2_CHAR_MATCHES(p, c);
}
static int PTRFASTCALL
static int
little2_isNameMin(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return LITTLE2_IS_NAME_CHAR_MINBPC(p);
}
static int PTRFASTCALL
static int
little2_isNmstrtMin(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p);
}
static int
little2_isInvalid4(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return LITTLE2_IS_INVALID_CHAR(p, 4);
}
# undef VTABLE
# define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
@@ -797,6 +822,7 @@ little2_isNmstrtMin(const ENCODING *enc, const char *p) {
# define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p)
# define IS_NMSTRT_CHAR(enc, p, n) (0)
# define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)
# define IS_INVALID_CHAR(enc, p, n) LITTLE2_IS_INVALID_CHAR(p, n)
# define XML_TOK_IMPL_C
# include "xmltok_impl.c"
@@ -828,7 +854,7 @@ static const struct normal_encoding little2_encoding_ns
# include "asciitab.h"
# include "latin1tab.h"
},
STANDARD_VTABLE(little2_) NULL_VTABLE};
STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)};
#endif
@@ -846,7 +872,7 @@ static const struct normal_encoding little2_encoding
#undef BT_COLON
#include "latin1tab.h"
},
STANDARD_VTABLE(little2_) NULL_VTABLE};
STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)};
#if BYTEORDER != 4321
@@ -858,7 +884,7 @@ static const struct normal_encoding internal_little2_encoding_ns
# include "iasciitab.h"
# include "latin1tab.h"
},
STANDARD_VTABLE(little2_) NULL_VTABLE};
STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)};
# endif
@@ -870,7 +896,7 @@ static const struct normal_encoding internal_little2_encoding
# undef BT_COLON
# include "latin1tab.h"
},
STANDARD_VTABLE(little2_) NULL_VTABLE};
STANDARD_VTABLE(little2_) UTF16_NULL_VTABLE(little2_)};
#endif
@@ -882,38 +908,49 @@ static const struct normal_encoding internal_little2_encoding
UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
#define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \
UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
/* A 4-byte UTF-16 character is a surrogate pair; byteType only reports BT_LEAD4
for a high surrogate, so the pair is invalid unless the second unit is a low
surrogate (U+DC00..U+DFFF, i.e. high byte 0xDC..0xDF). */
#define BIG2_IS_INVALID_CHAR(p, n) \
((n) == 4 && ((unsigned char)(p)[2] & 0xFC) != 0xDC)
#ifdef XML_MIN_SIZE
static int PTRFASTCALL
static int
big2_byteType(const ENCODING *enc, const char *p) {
return BIG2_BYTE_TYPE(enc, p);
}
static int PTRFASTCALL
static int
big2_byteToAscii(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return BIG2_BYTE_TO_ASCII(p);
}
static int PTRCALL
static int
big2_charMatches(const ENCODING *enc, const char *p, int c) {
UNUSED_P(enc);
return BIG2_CHAR_MATCHES(p, c);
}
static int PTRFASTCALL
static int
big2_isNameMin(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return BIG2_IS_NAME_CHAR_MINBPC(p);
}
static int PTRFASTCALL
static int
big2_isNmstrtMin(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return BIG2_IS_NMSTRT_CHAR_MINBPC(p);
}
static int
big2_isInvalid4(const ENCODING *enc, const char *p) {
UNUSED_P(enc);
return BIG2_IS_INVALID_CHAR(p, 4);
}
# undef VTABLE
# define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
@@ -930,6 +967,7 @@ big2_isNmstrtMin(const ENCODING *enc, const char *p) {
# define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p)
# define IS_NMSTRT_CHAR(enc, p, n) (0)
# define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p)
# define IS_INVALID_CHAR(enc, p, n) BIG2_IS_INVALID_CHAR(p, n)
# define XML_TOK_IMPL_C
# include "xmltok_impl.c"
@@ -961,7 +999,7 @@ static const struct normal_encoding big2_encoding_ns
# include "asciitab.h"
# include "latin1tab.h"
},
STANDARD_VTABLE(big2_) NULL_VTABLE};
STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)};
#endif
@@ -979,7 +1017,7 @@ static const struct normal_encoding big2_encoding
#undef BT_COLON
#include "latin1tab.h"
},
STANDARD_VTABLE(big2_) NULL_VTABLE};
STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)};
#if BYTEORDER != 1234
@@ -991,7 +1029,7 @@ static const struct normal_encoding internal_big2_encoding_ns
# include "iasciitab.h"
# include "latin1tab.h"
},
STANDARD_VTABLE(big2_) NULL_VTABLE};
STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)};
# endif
@@ -1003,13 +1041,13 @@ static const struct normal_encoding internal_big2_encoding
# undef BT_COLON
# include "latin1tab.h"
},
STANDARD_VTABLE(big2_) NULL_VTABLE};
STANDARD_VTABLE(big2_) UTF16_NULL_VTABLE(big2_)};
#endif
#undef PREFIX
static int FASTCALL
static int
streqci(const char *s1, const char *s2) {
for (;;) {
char c1 = *s1++;
@@ -1030,7 +1068,7 @@ streqci(const char *s1, const char *s2) {
return 1;
}
static void PTRCALL
static void
initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end,
POSITION *pos) {
UNUSED_P(enc);
@@ -1048,7 +1086,7 @@ toAscii(const ENCODING *enc, const char *ptr, const char *end) {
return buf[0];
}
static int FASTCALL
static int
isSpace(int c) {
switch (c) {
case 0x20:
@@ -1154,6 +1192,34 @@ static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'};
static const char KW_no[] = {ASCII_n, ASCII_o, '\0'};
static const char KW_1_dot[] = {ASCII_1, ASCII_PERIOD, '\0'};
/* Checks a version pseudo-attribute value against the VersionNum production.
XML 1.0 Fourth Edition only allows the literal "1.0", but the Fifth
Edition relaxed this to "1." followed by one or more digits, since Expat
only implements 1.0 itself but plans to track the Fifth Edition's laxer
grammar here so that "1.1" and similar aren't rejected only to have that
rejection reverted later. Returns true for a value matching "1.[0-9]+".
val/valEnd bound the value itself; valEnd is the upper bound used when
decoding the individual characters between them. */
static bool
checkXmlDeclVersionNum(const ENCODING *enc, const char *val,
const char *valEnd) {
if (valEnd - val < 2 * enc->minBytesPerChar
|| ! XmlNameMatchesAscii(enc, val, val + 2 * enc->minBytesPerChar,
KW_1_dot))
return false;
val += 2 * enc->minBytesPerChar;
if (val == valEnd)
return false;
for (; val != valEnd; val += enc->minBytesPerChar) {
int c = toAscii(enc, val, valEnd);
if (c < ASCII_0 || c > ASCII_9)
return false;
}
return true;
}
static int
doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *,
const char *),
@@ -1188,6 +1254,15 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *,
*badPtr = val;
return 0;
}
/* Expat implements XML 1.0 only, so any version outside the "1.0"/"1.x"
family is rejected. Following the Fifth Edition's VersionNum
production (rather than the Fourth Edition's exact "1.0") avoids
rejecting "1.1" now only to have to revert that once Expat tracks
the newer edition. */
if (! checkXmlDeclVersionNum(enc, val, ptr - enc->minBytesPerChar)) {
*badPtr = val;
return 0;
}
if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
*badPtr = ptr;
return 0;
@@ -1242,7 +1317,7 @@ doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *,
return 1;
}
static int FASTCALL
static int
checkCharRefNumber(int result) {
switch (result >> 8) {
case 0xD8:
@@ -1266,7 +1341,7 @@ checkCharRefNumber(int result) {
return result;
}
int FASTCALL
int
XmlUtf8Encode(int c, char *buf) {
enum {
/* minN is minimum legal resulting value for N byte sequence */
@@ -1302,7 +1377,7 @@ XmlUtf8Encode(int c, char *buf) {
return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
}
int FASTCALL
int
XmlUtf16Encode(int charNum, unsigned short *buf) {
if (charNum < 0)
return 0;
@@ -1334,7 +1409,7 @@ XmlSizeOfUnknownEncoding(void) {
return sizeof(struct unknown_encoding);
}
static int PTRFASTCALL
static int
unknown_isName(const ENCODING *enc, const char *p) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
int c = uenc->convert(uenc->userData, p);
@@ -1343,7 +1418,7 @@ unknown_isName(const ENCODING *enc, const char *p) {
return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
}
static int PTRFASTCALL
static int
unknown_isNmstrt(const ENCODING *enc, const char *p) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
int c = uenc->convert(uenc->userData, p);
@@ -1352,14 +1427,14 @@ unknown_isNmstrt(const ENCODING *enc, const char *p) {
return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
}
static int PTRFASTCALL
static int
unknown_isInvalid(const ENCODING *enc, const char *p) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
int c = uenc->convert(uenc->userData, p);
return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
}
static enum XML_Convert_Result PTRCALL
static enum XML_Convert_Result
unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
char **toP, const char *toLim) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
@@ -1389,7 +1464,7 @@ unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
}
}
static enum XML_Convert_Result PTRCALL
static enum XML_Convert_Result
unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim) {
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
@@ -1513,7 +1588,7 @@ static const char KW_UTF_16LE[]
= {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
ASCII_6, ASCII_L, ASCII_E, '\0'};
static int FASTCALL
static int
getEncodingIndex(const char *name) {
static const char *const encodingNames[] = {
KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE,
+25 -33
View File
@@ -41,10 +41,6 @@
# include <stdint.h> // uint64_t
# ifdef __cplusplus
extern "C" {
# endif
/* The following token may be returned by XmlContentTok */
# define XML_TOK_TRAILING_RSQB \
-5 /* ] or ]] at the end of the scan; might be \
@@ -163,8 +159,8 @@ typedef struct {
struct encoding;
typedef struct encoding ENCODING;
typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *,
const char **);
typedef int (*SCANNER)(const ENCODING *, const char *, const char *,
const char **);
enum XML_Convert_Result {
XML_CONVERT_COMPLETED = 0,
@@ -176,28 +172,27 @@ enum XML_Convert_Result {
struct encoding {
SCANNER scanners[XML_N_STATES];
SCANNER literalScanners[XML_N_LITERAL_TYPES];
int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *,
const char *);
int(PTRFASTCALL *nameLength)(const ENCODING *, const char *);
const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
ATTRIBUTE *atts);
int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *,
const char *);
void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr,
const char *end, POSITION *);
int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr,
const char *end, const char **badPtr);
enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim, char **toP,
const char *toLim);
enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
unsigned short **toP,
const unsigned short *toLim);
int (*nameMatchesAscii)(const ENCODING *, const char *, const char *,
const char *);
int (*nameLength)(const ENCODING *, const char *);
const char *(*skipS)(const ENCODING *, const char *);
int (*getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
ATTRIBUTE *atts);
int (*charRefNumber)(const ENCODING *enc, const char *ptr);
int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
void (*updatePosition)(const ENCODING *, const char *ptr, const char *end,
POSITION *);
int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
const char **badPtr);
enum XML_Convert_Result (*utf8Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim, char **toP,
const char *toLim);
enum XML_Convert_Result (*utf16Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
unsigned short **toP,
const unsigned short *toLim);
int minBytesPerChar;
char isUtf8;
char isUtf16;
@@ -297,8 +292,8 @@ int XmlInitEncoding(INIT_ENCODING *p, const ENCODING **encPtr,
const char *name);
const ENCODING *XmlGetUtf8InternalEncoding(void);
const ENCODING *XmlGetUtf16InternalEncoding(void);
int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
int XmlUtf8Encode(int charNumber, char *buf);
int XmlUtf16Encode(int charNumber, unsigned short *buf);
int XmlSizeOfUnknownEncoding(void);
typedef int(XMLCALL *CONVERTER)(void *userData, const char *p);
@@ -318,8 +313,5 @@ const ENCODING *XmlGetUtf8InternalEncodingNS(void);
const ENCODING *XmlGetUtf16InternalEncodingNS(void);
ENCODING *XmlInitUnknownEncodingNS(void *mem, const int *table,
CONVERTER convert, void *userData);
# ifdef __cplusplus
}
# endif
#endif /* not XmlTok_INCLUDED */
+30 -33
View File
@@ -10,7 +10,7 @@
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2018 Benjamin Peterson <benjamin@python.org>
Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com>
@@ -18,6 +18,7 @@
Copyright (c) 2020 Boris Kolpackov <boris@codesynthesis.com>
Copyright (c) 2022 Martin Ettl <ettl.martin78@googlemail.com>
Copyright (c) 2026 Nick Begg <nick@stunttruck.net>
Copyright (c) 2026 Kartik Kenchi <netliomax25@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -44,10 +45,6 @@
#ifdef XML_TOK_IMPL_C
# ifndef IS_INVALID_CHAR // i.e. for UTF-16 and XML_MIN_SIZE not defined
# define IS_INVALID_CHAR(enc, ptr, n) (0)
# endif
# define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
case BT_LEAD##n: \
if (end - ptr < n) \
@@ -144,7 +141,7 @@
/* ptr points to character following "<!-" */
static int PTRCALL
static int
PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
if (HAS_CHAR(enc, ptr, end)) {
@@ -181,7 +178,7 @@ PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
/* ptr points to character following "<!" */
static int PTRCALL
static int
PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
@@ -230,7 +227,7 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
return XML_TOK_PARTIAL;
}
static int PTRCALL
static int
PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end,
int *tokPtr) {
int upper = 0;
@@ -275,7 +272,7 @@ PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end,
/* ptr points to character following "<?" */
static int PTRCALL
static int
PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
int tok;
@@ -335,7 +332,7 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
return XML_TOK_PARTIAL;
}
static int PTRCALL
static int
PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
static const char CDATA_LSQB[]
@@ -354,7 +351,7 @@ PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
return XML_TOK_CDATA_SECT_OPEN;
}
static int PTRCALL
static int
PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
if (ptr >= end)
@@ -430,7 +427,7 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
/* ptr points to character following "</" */
static int PTRCALL
static int
PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
@@ -481,7 +478,7 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
/* ptr points to character following "&#X" */
static int PTRCALL
static int
PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
if (HAS_CHAR(enc, ptr, end)) {
@@ -512,7 +509,7 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
/* ptr points to character following "&#" */
static int PTRCALL
static int
PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
if (HAS_CHAR(enc, ptr, end)) {
@@ -543,7 +540,7 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
/* ptr points to character following "&" */
static int PTRCALL
static int
PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
@@ -571,7 +568,7 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
/* ptr points to character following first character of attribute name */
static int PTRCALL
static int
PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
# ifdef XML_NS
@@ -724,7 +721,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
/* ptr points to character following "<" */
static int PTRCALL
static int
PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
# ifdef XML_NS
@@ -822,7 +819,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
return XML_TOK_PARTIAL;
}
static int PTRCALL
static int
PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
if (ptr >= end)
@@ -922,7 +919,7 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
/* ptr points to character following "%" */
static int PTRCALL
static int
PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
@@ -952,7 +949,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
return XML_TOK_PARTIAL;
}
static int PTRCALL
static int
PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
REQUIRE_CHAR(enc, ptr, end);
@@ -982,7 +979,7 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
return -XML_TOK_POUND_NAME;
}
static int PTRCALL
static int
PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
while (HAS_CHAR(enc, ptr, end)) {
@@ -1016,7 +1013,7 @@ PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end,
return XML_TOK_PARTIAL;
}
static int PTRCALL
static int
PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
int tok;
@@ -1260,7 +1257,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
return -tok;
}
static int PTRCALL
static int
PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
const char *start;
@@ -1329,7 +1326,7 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
return XML_TOK_DATA_CHARS;
}
static int PTRCALL
static int
PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
const char *start;
@@ -1396,7 +1393,7 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
# ifdef XML_DTD
static int PTRCALL
static int
PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
int level = 0;
@@ -1448,7 +1445,7 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
# endif /* XML_DTD */
static int PTRCALL
static int
PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
const char **badPtr) {
ptr += MINBPC(enc);
@@ -1508,7 +1505,7 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
first attsMax attributes are stored in atts.
*/
static int PTRCALL
static int
PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
ATTRIBUTE *atts) {
enum { other, inName, inValue } state = inName;
@@ -1601,7 +1598,7 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
/* not reached */
}
static int PTRFASTCALL
static int
PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) {
int result = 0;
/* skip &# */
@@ -1659,7 +1656,7 @@ PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) {
return checkCharRefNumber(result);
}
static int PTRCALL
static int
PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
const char *end) {
UNUSED_P(enc);
@@ -1713,7 +1710,7 @@ PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
return 0;
}
static int PTRCALL
static int
PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
const char *end1, const char *ptr2) {
UNUSED_P(enc);
@@ -1732,7 +1729,7 @@ PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
return ptr1 == end1;
}
static int PTRFASTCALL
static int
PREFIX(nameLength)(const ENCODING *enc, const char *ptr) {
const char *start = ptr;
for (;;) {
@@ -1762,7 +1759,7 @@ PREFIX(nameLength)(const ENCODING *enc, const char *ptr) {
}
}
static const char *PTRFASTCALL
static const char *
PREFIX(skipS)(const ENCODING *enc, const char *ptr) {
for (;;) {
switch (BYTE_TYPE(enc, ptr)) {
@@ -1777,7 +1774,7 @@ PREFIX(skipS)(const ENCODING *enc, const char *ptr) {
}
}
static void PTRCALL
static void
PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end,
POSITION *pos) {
while (HAS_CHAR(enc, ptr, end)) {
+3 -3
View File
@@ -11,7 +11,7 @@
Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2026 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2025 Alfonso Gregory <gfunni234@gmail.com>
Licensed under the MIT license:
@@ -64,14 +64,14 @@ static const ENCODING *const NS(encodings)[] = {
&ns(utf8_encoding).enc /* NO_ENC */
};
static int PTRCALL
static int
NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE,
ptr, end, nextTokPtr);
}
static int PTRCALL
static int
NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE,
+5 -3
View File
@@ -49,6 +49,7 @@ runtests_SOURCES = \
common.c \
dummy.c \
handlers.c \
hash_tests.c \
memcheck.c \
minicheck.c \
misc_tests.c \
@@ -69,13 +70,14 @@ EXTRA_DIST = \
common.h \
dummy.h \
handlers.h \
hash_tests.h \
memcheck.h \
minicheck.h \
misc_tests.h \
ns_tests.h \
nsalloc_tests.h \
structdata.h \
minicheck.h \
memcheck.h \
README.md \
structdata.h \
udiffer.py \
xmltest.log.expected \
xmltest.sh
+31 -21
View File
@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.18.1 from Makefile.am.
# Makefile.in generated by automake 1.19 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# Copyright (C) 1994-2026 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -149,9 +149,9 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am_runtests_OBJECTS = acc_tests.$(OBJEXT) alloc_tests.$(OBJEXT) \
basic_tests.$(OBJEXT) chardata.$(OBJEXT) common.$(OBJEXT) \
dummy.$(OBJEXT) handlers.$(OBJEXT) memcheck.$(OBJEXT) \
minicheck.$(OBJEXT) misc_tests.$(OBJEXT) ns_tests.$(OBJEXT) \
nsalloc_tests.$(OBJEXT) runtests.$(OBJEXT) \
dummy.$(OBJEXT) handlers.$(OBJEXT) hash_tests.$(OBJEXT) \
memcheck.$(OBJEXT) minicheck.$(OBJEXT) misc_tests.$(OBJEXT) \
ns_tests.$(OBJEXT) nsalloc_tests.$(OBJEXT) runtests.$(OBJEXT) \
structdata.$(OBJEXT)
runtests_OBJECTS = $(am_runtests_OBJECTS)
runtests_DEPENDENCIES = ../lib/libtestpat.la
@@ -181,10 +181,10 @@ am__depfiles_remade = ./$(DEPDIR)/acc_tests.Po \
./$(DEPDIR)/alloc_tests.Po ./$(DEPDIR)/basic_tests.Po \
./$(DEPDIR)/chardata.Po ./$(DEPDIR)/common.Po \
./$(DEPDIR)/dummy.Po ./$(DEPDIR)/handlers.Po \
./$(DEPDIR)/memcheck.Po ./$(DEPDIR)/minicheck.Po \
./$(DEPDIR)/misc_tests.Po ./$(DEPDIR)/ns_tests.Po \
./$(DEPDIR)/nsalloc_tests.Po ./$(DEPDIR)/runtests.Po \
./$(DEPDIR)/structdata.Po
./$(DEPDIR)/hash_tests.Po ./$(DEPDIR)/memcheck.Po \
./$(DEPDIR)/minicheck.Po ./$(DEPDIR)/misc_tests.Po \
./$(DEPDIR)/ns_tests.Po ./$(DEPDIR)/nsalloc_tests.Po \
./$(DEPDIR)/runtests.Po ./$(DEPDIR)/structdata.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -594,6 +594,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__tar_ignore_stderr = @am__tar_ignore_stderr@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
@@ -649,6 +650,7 @@ runtests_SOURCES = \
common.c \
dummy.c \
handlers.c \
hash_tests.c \
memcheck.c \
minicheck.c \
misc_tests.c \
@@ -667,13 +669,14 @@ EXTRA_DIST = \
common.h \
dummy.h \
handlers.h \
hash_tests.h \
memcheck.h \
minicheck.h \
misc_tests.h \
ns_tests.h \
nsalloc_tests.h \
structdata.h \
minicheck.h \
memcheck.h \
README.md \
structdata.h \
udiffer.py \
xmltest.log.expected \
xmltest.sh
@@ -691,9 +694,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu tests/Makefile
$(AUTOMAKE) --foreign tests/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -733,6 +736,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/handlers.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash_tests.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcheck.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minicheck.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc_tests.Po@am__quote@ # am--include-marker
@@ -748,22 +752,25 @@ $(am__depfiles_remade):
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
@@ -1067,13 +1074,14 @@ distdir: $(BUILT_SOURCES)
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
am__distdir="$(distdir)"; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sed "/\//!d;s|^|$$am__distdir/|;s,/[^/]*$$,," | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
@@ -1172,6 +1180,7 @@ distclean: distclean-recursive
-rm -f ./$(DEPDIR)/common.Po
-rm -f ./$(DEPDIR)/dummy.Po
-rm -f ./$(DEPDIR)/handlers.Po
-rm -f ./$(DEPDIR)/hash_tests.Po
-rm -f ./$(DEPDIR)/memcheck.Po
-rm -f ./$(DEPDIR)/minicheck.Po
-rm -f ./$(DEPDIR)/misc_tests.Po
@@ -1231,6 +1240,7 @@ maintainer-clean: maintainer-clean-recursive
-rm -f ./$(DEPDIR)/common.Po
-rm -f ./$(DEPDIR)/dummy.Po
-rm -f ./$(DEPDIR)/handlers.Po
-rm -f ./$(DEPDIR)/hash_tests.Po
-rm -f ./$(DEPDIR)/memcheck.Po
-rm -f ./$(DEPDIR)/minicheck.Po
-rm -f ./$(DEPDIR)/misc_tests.Po
+2 -10
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-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 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>
@@ -42,17 +42,9 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_ACC_TESTS_H
# define XML_ACC_TESTS_H
#define XML_ACC_TESTS_H
extern void make_accounting_test_case(Suite *s);
#endif /* XML_ACC_TESTS_H */
#ifdef __cplusplus
}
#endif
+2 -10
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-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 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>
@@ -42,17 +42,9 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_ALLOC_TESTS_H
# define XML_ALLOC_TESTS_H
#define XML_ALLOC_TESTS_H
extern void make_alloc_test_case(Suite *s);
#endif /* XML_ALLOC_TESTS_H */
#ifdef __cplusplus
}
#endif
+349 -5
View File
@@ -24,6 +24,8 @@
Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com>
Copyright (c) 2026 Kartik Kenchi <netliomax25@gmail.com>
Copyright (c) 2026 Zeyou Liu <zeyouliu@tencent.com>
Copyright (c) 2026 Afonso Januário <afonso-januario@hotmail.com>
Copyright (c) 2026 Braian Plaku <braianplaku@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -214,7 +216,7 @@ START_TEST(test_hash_collision) {
"<d8>This triggers the table growth and collides with b2</d8>\n"
"</doc>\n";
XML_SetHashSalt(g_parser, COLLIDING_HASH_SALT);
xmlSetHashSalt(g_parser, COLLIDING_HASH_SALT);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
@@ -998,6 +1000,50 @@ START_TEST(test_xmldecl_empty_version) {
}
END_TEST
/* Regression test for GH #967: Expat only implements XML 1.0 Fourth
Edition, so a declared version outside the "1.x" family must be
rejected rather than silently accepted. A version matching the Fifth
Edition's VersionNum production ("1." followed by one or more digits)
is accepted even though Expat itself only implements 1.0 Fourth
Edition, per GH #967's review thread: rejecting "1.1" now would just
have to be reverted once Expat tracks the Fifth Edition, so it's let
through rather than blocked twice. */
START_TEST(test_xmldecl_wrong_version_number) {
const char *const badVersions[] = {"2.3", "0.9", "10", "1.", "1", " 1.0 "};
for (size_t i = 0; i < sizeof(badVersions) / sizeof(badVersions[0]); i++) {
char doc[64];
snprintf(doc, sizeof(doc), "<?xml version='%s'?>\n<doc/>", badVersions[i]);
set_subtest("version='%s'", badVersions[i]);
XML_Parser parser = XML_ParserCreate(NULL);
assert_true(_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), XML_TRUE)
== XML_STATUS_ERROR);
assert_true(XML_GetErrorCode(parser) == XML_ERROR_XML_DECL);
XML_ParserFree(parser);
}
}
END_TEST
/* GH #967's review pointed out that XML 1.0 Fifth Edition relaxed
VersionNum to "1." followed by one or more digits, so versions like
"1.1" and "1.123" should parse rather than being rejected. */
START_TEST(test_xmldecl_accepts_1_x_version) {
const char *const goodVersions[] = {"1.1", "1.123"};
for (size_t i = 0; i < sizeof(goodVersions) / sizeof(goodVersions[0]); i++) {
char doc[64];
snprintf(doc, sizeof(doc), "<?xml version='%s'?>\n<doc/>", goodVersions[i]);
set_subtest("version='%s'", goodVersions[i]);
XML_Parser parser = XML_ParserCreate(NULL);
assert_true(_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), XML_TRUE)
== XML_STATUS_OK);
XML_ParserFree(parser);
}
}
END_TEST
/* Regression test for SF bug #584832. */
START_TEST(test_unknown_encoding_internal_entity) {
const char *text = "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
@@ -1846,6 +1892,301 @@ START_TEST(test_utf16_bad_surrogate_pair) {
}
END_TEST
// Helper that creates a UTF-16LE copy of UTF-16BE literal input and vice versa
static char *
utf16_dup_flipped(const char *text, size_t lenBytes) {
assert_true(lenBytes < SIZE_MAX);
assert_true(lenBytes % 2 == 0);
char *const buffer = malloc(lenBytes + 1);
assert_true(buffer != NULL);
for (size_t i = 0; i < lenBytes; i++) {
// This maps 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2, 4 -> 5, ..
size_t j = i + ((i % 2 == 0) ? +1 : -1);
assert_true(j < lenBytes);
buffer[j] = text[i];
}
buffer[lenBytes] = '\0';
return buffer;
}
/* Tests that invalid combinations of surrogates are detected when decoding
UTF-16, both little-endian and big-endian.
Previously, a high surrogate not followed by a low surrogate slipped
through. Without validation the high would consume the next
code unit as a fake low, hiding e.g. a following '<' from the
tokenizer. */
START_TEST(test_utf16_surrogate_pairs) {
struct TestCase {
const char *idea;
const char *content;
bool expectedSuccess;
};
struct TestCase testCases[] = {
// Group {smallest high - 1}{*}
{"{smallest high - 1}{smallest high - 1}",
"\0<\0a\0>"
"\xD7\xFF"
"\xD7\xFF"
"\0<\0/\0a\0>",
true},
{"{smallest high - 1}{smallest high}",
"\0<\0a\0>"
"\xD7\xFF"
"\xD8\x00"
"\0<\0/\0a\0>",
false},
{"{smallest high - 1}{largest high}",
"\0<\0a\0>"
"\xD7\xFF"
"\xDB\xFF"
"\0<\0/\0a\0>",
false},
{"{smallest high - 1}{smallest low}",
"\0<\0a\0>"
"\xD7\xFF"
"\xDC\x00"
"\0<\0/\0a\0>",
false},
{"{smallest high - 1}{largest low}",
"\0<\0a\0>"
"\xD7\xFF"
"\xDF\xFF"
"\0<\0/\0a\0>",
false},
{"{smallest high - 1}{largest low + 1}",
"\0<\0a\0>"
"\xD7\xFF"
"\xE0\x00"
"\0<\0/\0a\0>",
true},
// Group {smallest high}{*}
{"{smallest high}{smallest high - 1}",
"\0<\0a\0>"
"\xD8\x00"
"\xD7\xFF"
"\0<\0/\0a\0>",
false},
{"{smallest high}{smallest high}",
"\0<\0a\0>"
"\xD8\x00"
"\xD8\x00"
"\0<\0/\0a\0>",
false},
{"{smallest high}{largest high}",
"\0<\0a\0>"
"\xD8\x00"
"\xDB\xFF"
"\0<\0/\0a\0>",
false},
{"{smallest high}{smallest low}",
"\0<\0a\0>"
"\xD8\x00"
"\xDC\x00"
"\0<\0/\0a\0>",
true},
{"{smallest high}{largest low}",
"\0<\0a\0>"
"\xD8\x00"
"\xDF\xFF"
"\0<\0/\0a\0>",
true},
{"{smallest high}{largest low + 1}",
"\0<\0a\0>"
"\xD8\x00"
"\xE0\x00"
"\0<\0/\0a\0>",
false},
// Group {largest high}{*}
{"{largest high}{smallest high - 1}",
"\0<\0a\0>"
"\xDB\xFF"
"\xD7\xFF"
"\0<\0/\0a\0>",
false},
{"{largest high}{smallest high}",
"\0<\0a\0>"
"\xDB\xFF"
"\xD8\x00"
"\0<\0/\0a\0>",
false},
{"{largest high}{largest high}",
"\0<\0a\0>"
"\xDB\xFF"
"\xDB\xFF"
"\0<\0/\0a\0>",
false},
{"{largest high}{smallest low}",
"\0<\0a\0>"
"\xDB\xFF"
"\xDC\x00"
"\0<\0/\0a\0>",
true},
{"{largest high}{largest low}",
"\0<\0a\0>"
"\xDB\xFF"
"\xDF\xFF"
"\0<\0/\0a\0>",
true},
{"{largest high}{largest low + 1}",
"\0<\0a\0>"
"\xDB\xFF"
"\xE0\x00"
"\0<\0/\0a\0>",
false},
// Group {smallest low}{*}
{"{smallest low}{smallest high - 1}",
"\0<\0a\0>"
"\xDC\x00"
"\xD7\xFF"
"\0<\0/\0a\0>",
false},
{"{smallest low}{smallest high}",
"\0<\0a\0>"
"\xDC\x00"
"\xD8\x00"
"\0<\0/\0a\0>",
false},
{"{smallest low}{largest high}",
"\0<\0a\0>"
"\xDC\x00"
"\xDB\xFF"
"\0<\0/\0a\0>",
false},
{"{smallest low}{smallest low}",
"\0<\0a\0>"
"\xDC\x00"
"\xDC\x00"
"\0<\0/\0a\0>",
false},
{"{smallest low}{largest low}",
"\0<\0a\0>"
"\xDC\x00"
"\xDF\xFF"
"\0<\0/\0a\0>",
false},
{"{smallest low}{largest low + 1}",
"\0<\0a\0>"
"\xDC\x00"
"\xE0\x00"
"\0<\0/\0a\0>",
false},
// Group {largest low}{*}
{"{largest low}{smallest high - 1}",
"\0<\0a\0>"
"\xDF\xFF"
"\xD7\xFF"
"\0<\0/\0a\0>",
false},
{"{largest low}{smallest high}",
"\0<\0a\0>"
"\xDF\xFF"
"\xD8\x00"
"\0<\0/\0a\0>",
false},
{"{largest low}{largest high}",
"\0<\0a\0>"
"\xDF\xFF"
"\xDB\xFF"
"\0<\0/\0a\0>",
false},
{"{largest low}{smallest low}",
"\0<\0a\0>"
"\xDF\xFF"
"\xDC\x00"
"\0<\0/\0a\0>",
false},
{"{largest low}{largest low}",
"\0<\0a\0>"
"\xDF\xFF"
"\xDF\xFF"
"\0<\0/\0a\0>",
false},
{"{largest low}{largest low + 1}",
"\0<\0a\0>"
"\xDF\xFF"
"\xE0\x00"
"\0<\0/\0a\0>",
false},
// Group {largest low + 1}{*}
{"{largest low + 1}{smallest high - 1}",
"\0<\0a\0>"
"\xE0\x00"
"\xD7\xFF"
"\0<\0/\0a\0>",
true},
{"{largest low + 1}{smallest high}",
"\0<\0a\0>"
"\xE0\x00"
"\xD8\x00"
"\0<\0/\0a\0>",
false},
{"{largest low + 1}{largest high}",
"\0<\0a\0>"
"\xE0\x00"
"\xDB\xFF"
"\0<\0/\0a\0>",
false},
{"{largest low + 1}{smallest low}",
"\0<\0a\0>"
"\xE0\x00"
"\xDC\x00"
"\0<\0/\0a\0>",
false},
{"{largest low + 1}{largest low}",
"\0<\0a\0>"
"\xE0\x00"
"\xDF\xFF"
"\0<\0/\0a\0>",
false},
{"{largest low + 1}{largest low + 1}",
"\0<\0a\0>"
"\xE0\x00"
"\xE0\x00"
"\0<\0/\0a\0>",
true},
};
for (size_t i = 0; i < sizeof(testCases) / sizeof(testCases[0]); i++) {
set_subtest("%s", testCases[i].idea);
const int lenBytes = /*<a>*/ 6 + /*first*/ 2 + /*second*/ 2 + /*</a>*/ 8;
const bool expectedSuccess = testCases[i].expectedSuccess;
const enum XML_Status expectedStatus
= (expectedSuccess ? XML_STATUS_OK : XML_STATUS_ERROR);
const char *const bigEndian = testCases[i].content;
char *const littleEndian = utf16_dup_flipped(bigEndian, lenBytes);
assert_true(littleEndian != NULL);
const char *endianCases[] = {bigEndian, littleEndian};
for (size_t j = 0; j < sizeof(endianCases) / sizeof(endianCases[0]); j++) {
const char *text = endianCases[j];
assert_true(text[lenBytes] == '\0'); // self-test
assert_true((text[0] == '\0')
!= (text[lenBytes - 1] == '\0')); // self-test
XML_Parser parser = XML_ParserCreate(NULL);
assert_true(parser != NULL);
assert_true(_XML_Parse_SINGLE_BYTES(parser, text, lenBytes, XML_TRUE)
== expectedStatus);
if (! expectedSuccess) {
assert_true(XML_GetErrorCode(parser) == XML_ERROR_INVALID_TOKEN);
}
XML_ParserFree(parser);
}
free(littleEndian);
}
}
END_TEST
START_TEST(test_bad_cdata) {
struct CaseData {
const char *text;
@@ -2358,7 +2699,7 @@ START_TEST(test_set_foreign_dtd) {
ExtTest test_data = {"<!ELEMENT doc (#PCDATA)*>", NULL, NULL};
/* Check hash salt is passed through too */
XML_SetHashSalt(g_parser, 0x12345678);
xmlSetHashSalt(g_parser, 0x12345678);
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
XML_SetUserData(g_parser, &test_data);
XML_SetExternalEntityRefHandler(g_parser, external_entity_loader);
@@ -2377,7 +2718,7 @@ START_TEST(test_set_foreign_dtd) {
!= XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING)
fail("Failed to reject late foreign DTD setting");
/* Ditto for the hash salt */
if (XML_SetHashSalt(g_parser, 0x23456789))
if (xmlSetHashSalt(g_parser, 0x23456789))
fail("Failed to reject late hash salt change");
/* Now finish the parse */
@@ -2428,7 +2769,7 @@ START_TEST(test_foreign_dtd_with_doctype) {
ExtTest test_data = {"<!ELEMENT doc (#PCDATA)*>", NULL, NULL};
/* Check hash salt is passed through too */
XML_SetHashSalt(g_parser, 0x12345678);
xmlSetHashSalt(g_parser, 0x12345678);
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
XML_SetUserData(g_parser, &test_data);
XML_SetExternalEntityRefHandler(g_parser, external_entity_loader);
@@ -2447,7 +2788,7 @@ START_TEST(test_foreign_dtd_with_doctype) {
!= XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING)
fail("Failed to reject late foreign DTD setting");
/* Ditto for the hash salt */
if (XML_SetHashSalt(g_parser, 0x23456789))
if (xmlSetHashSalt(g_parser, 0x23456789))
fail("Failed to reject late hash salt change");
/* Now finish the parse */
@@ -6756,6 +7097,8 @@ make_basic_test_case(Suite *s) {
tcase_add_test(tc_basic, test_xmldecl_missing_attr);
tcase_add_test(tc_basic, test_xmldecl_missing_value);
tcase_add_test(tc_basic, test_xmldecl_empty_version);
tcase_add_test(tc_basic, test_xmldecl_wrong_version_number);
tcase_add_test(tc_basic, test_xmldecl_accepts_1_x_version);
tcase_add_test__if_xml_ge(tc_basic, test_unknown_encoding_internal_entity);
tcase_add_test(tc_basic, test_unrecognised_encoding_internal_entity);
tcase_add_test__ifdef_xml_dtd(tc_basic, test_ext_entity_set_encoding);
@@ -6789,6 +7132,7 @@ make_basic_test_case(Suite *s) {
tcase_add_test(tc_basic, test_long_cdata_utf16);
tcase_add_test(tc_basic, test_multichar_cdata_utf16);
tcase_add_test(tc_basic, test_utf16_bad_surrogate_pair);
tcase_add_test(tc_basic, test_utf16_surrogate_pairs);
tcase_add_test(tc_basic, test_bad_cdata);
tcase_add_test(tc_basic, test_bad_cdata_utf16);
tcase_add_test(tc_basic, test_stop_parser_between_cdata_calls);
+2 -10
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-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 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>
@@ -42,17 +42,9 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_BASIC_TESTS_H
# define XML_BASIC_TESTS_H
#define XML_BASIC_TESTS_H
extern void make_basic_test_case(Suite *s);
#endif /* XML_BASIC_TESTS_H */
#ifdef __cplusplus
}
#endif
+16 -11
View File
@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.18.1 from Makefile.am.
# Makefile.in generated by automake 1.19 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# Copyright (C) 1994-2026 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -327,6 +327,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__tar_ignore_stderr = @am__tar_ignore_stderr@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
@@ -388,9 +389,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/benchmark/Makefile'; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/benchmark/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu tests/benchmark/Makefile
$(AUTOMAKE) --foreign tests/benchmark/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -432,22 +433,25 @@ $(am__depfiles_remade):
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
@@ -516,13 +520,14 @@ distdir: $(BUILT_SOURCES)
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
am__distdir="$(distdir)"; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sed "/\//!d;s|^|$$am__distdir/|;s,/[^/]*$$,," | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
+1 -9
View File
@@ -9,7 +9,7 @@
Copyright (c) 2002-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2026 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -34,10 +34,6 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_CHARDATA_H
# define XML_CHARDATA_H 1
@@ -57,7 +53,3 @@ void CharData_AppendXMLChars(CharData *storage, const XML_Char *s, int len);
int CharData_CheckXMLChars(CharData *storage, const XML_Char *s);
#endif /* XML_CHARDATA_H */
#ifdef __cplusplus
}
#endif
+41 -49
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-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 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>
@@ -43,42 +43,38 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#ifndef XML_COMMON_H
#define XML_COMMON_H
#include "expat_config.h"
#include "minicheck.h"
#include "chardata.h"
#ifdef XML_LARGE_SIZE
# define XML_FMT_INT_MOD "ll"
#else
# define XML_FMT_INT_MOD "l"
#endif
#ifndef XML_COMMON_H
# define XML_COMMON_H
# include "expat_config.h"
# include "minicheck.h"
# include "chardata.h"
# ifdef XML_LARGE_SIZE
# define XML_FMT_INT_MOD "ll"
#ifdef XML_UNICODE_WCHAR_T
# define XML_FMT_STR "ls"
# include <wchar.h>
# define xcstrlen(s) wcslen(s)
# define xcstrcmp(s, t) wcscmp((s), (t))
# define xcstrncmp(s, t, n) wcsncmp((s), (t), (n))
# define XCS(s) _XCS(s)
# define _XCS(s) L##s
#else
# ifdef XML_UNICODE
# error "No support for UTF-16 character without wchar_t in tests"
# else
# define XML_FMT_INT_MOD "l"
# endif
# ifdef XML_UNICODE_WCHAR_T
# define XML_FMT_STR "ls"
# include <wchar.h>
# define xcstrlen(s) wcslen(s)
# define xcstrcmp(s, t) wcscmp((s), (t))
# define xcstrncmp(s, t, n) wcsncmp((s), (t), (n))
# define XCS(s) _XCS(s)
# define _XCS(s) L##s
# else
# ifdef XML_UNICODE
# error "No support for UTF-16 character without wchar_t in tests"
# else
# define XML_FMT_STR "s"
# define xcstrlen(s) strlen(s)
# define xcstrcmp(s, t) strcmp((s), (t))
# define xcstrncmp(s, t, n) strncmp((s), (t), (n))
# define XCS(s) s
# endif /* XML_UNICODE */
# endif /* XML_UNICODE_WCHAR_T */
# define XML_FMT_STR "s"
# define xcstrlen(s) strlen(s)
# define xcstrcmp(s, t) strcmp((s), (t))
# define xcstrncmp(s, t, n) strncmp((s), (t), (n))
# define XCS(s) s
# endif /* XML_UNICODE */
#endif /* XML_UNICODE_WCHAR_T */
extern XML_Parser g_parser;
@@ -98,7 +94,7 @@ extern void basic_teardown(void);
extern void _xml_failure(XML_Parser parser, const char *file, int line);
# define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
#define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
extern enum XML_Status _XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s,
int len, int isFinal);
@@ -107,8 +103,8 @@ extern void _expect_failure(const char *text, enum XML_Error errorCode,
const char *errorMessage, const char *file,
int lineno);
# define expect_failure(text, errorCode, errorMessage) \
_expect_failure((text), (errorCode), (errorMessage), __FILE__, __LINE__)
#define expect_failure(text, errorCode, errorMessage) \
_expect_failure((text), (errorCode), (errorMessage), __FILE__, __LINE__)
/* Support functions for handlers to collect up character and attribute data.
*/
@@ -116,14 +112,14 @@ extern void _expect_failure(const char *text, enum XML_Error errorCode,
extern void _run_character_check(const char *text, const XML_Char *expected,
const char *file, int line);
# define run_character_check(text, expected) \
_run_character_check(text, expected, __FILE__, __LINE__)
#define run_character_check(text, expected) \
_run_character_check(text, expected, __FILE__, __LINE__)
extern void _run_attribute_check(const char *text, const XML_Char *expected,
const char *file, int line);
# define run_attribute_check(text, expected) \
_run_attribute_check(text, expected, __FILE__, __LINE__)
#define run_attribute_check(text, expected) \
_run_attribute_check(text, expected, __FILE__, __LINE__)
typedef struct ExtTest {
const char *parse_text;
@@ -135,11 +131,11 @@ extern void _run_ext_character_check(const char *text, ExtTest *test_data,
const XML_Char *expected, const char *file,
int line);
# define run_ext_character_check(text, test_data, expected) \
_run_ext_character_check(text, test_data, expected, __FILE__, __LINE__)
#define run_ext_character_check(text, test_data, expected) \
_run_ext_character_check(text, test_data, expected, __FILE__, __LINE__)
# define ALLOC_ALWAYS_SUCCEED (-1)
# define REALLOC_ALWAYS_SUCCEED (-1)
#define ALLOC_ALWAYS_SUCCEED (-1)
#define REALLOC_ALWAYS_SUCCEED (-1)
extern int g_allocation_count;
extern int g_reallocation_count;
@@ -151,7 +147,3 @@ extern void *duff_reallocator(void *ptr, size_t size);
extern char *portable_strndup(const char *s, size_t n);
#endif /* XML_COMMON_H */
#ifdef __cplusplus
}
#endif
+20 -28
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-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 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>
@@ -42,31 +42,27 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_DUMMY_H
# define XML_DUMMY_H
#define XML_DUMMY_H
# define DUMMY_START_DOCTYPE_HANDLER_FLAG (1UL << 0)
# define DUMMY_END_DOCTYPE_HANDLER_FLAG (1UL << 1)
# define DUMMY_ENTITY_DECL_HANDLER_FLAG (1UL << 2)
# define DUMMY_NOTATION_DECL_HANDLER_FLAG (1UL << 3)
# define DUMMY_ELEMENT_DECL_HANDLER_FLAG (1UL << 4)
# define DUMMY_ATTLIST_DECL_HANDLER_FLAG (1UL << 5)
# define DUMMY_COMMENT_HANDLER_FLAG (1UL << 6)
# define DUMMY_PI_HANDLER_FLAG (1UL << 7)
# define DUMMY_START_ELEMENT_HANDLER_FLAG (1UL << 8)
# define DUMMY_START_CDATA_HANDLER_FLAG (1UL << 9)
# define DUMMY_END_CDATA_HANDLER_FLAG (1UL << 10)
# define DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG (1UL << 11)
# define DUMMY_START_NS_DECL_HANDLER_FLAG (1UL << 12)
# define DUMMY_END_NS_DECL_HANDLER_FLAG (1UL << 13)
# define DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG (1UL << 14)
# define DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG (1UL << 15)
# define DUMMY_SKIP_HANDLER_FLAG (1UL << 16)
# define DUMMY_DEFAULT_HANDLER_FLAG (1UL << 17)
#define DUMMY_START_DOCTYPE_HANDLER_FLAG (1UL << 0)
#define DUMMY_END_DOCTYPE_HANDLER_FLAG (1UL << 1)
#define DUMMY_ENTITY_DECL_HANDLER_FLAG (1UL << 2)
#define DUMMY_NOTATION_DECL_HANDLER_FLAG (1UL << 3)
#define DUMMY_ELEMENT_DECL_HANDLER_FLAG (1UL << 4)
#define DUMMY_ATTLIST_DECL_HANDLER_FLAG (1UL << 5)
#define DUMMY_COMMENT_HANDLER_FLAG (1UL << 6)
#define DUMMY_PI_HANDLER_FLAG (1UL << 7)
#define DUMMY_START_ELEMENT_HANDLER_FLAG (1UL << 8)
#define DUMMY_START_CDATA_HANDLER_FLAG (1UL << 9)
#define DUMMY_END_CDATA_HANDLER_FLAG (1UL << 10)
#define DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG (1UL << 11)
#define DUMMY_START_NS_DECL_HANDLER_FLAG (1UL << 12)
#define DUMMY_END_NS_DECL_HANDLER_FLAG (1UL << 13)
#define DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG (1UL << 14)
#define DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG (1UL << 15)
#define DUMMY_SKIP_HANDLER_FLAG (1UL << 16)
#define DUMMY_DEFAULT_HANDLER_FLAG (1UL << 17)
extern void init_dummy_handlers(void);
extern unsigned long get_dummy_handler_flags(void);
@@ -146,7 +142,3 @@ extern void XMLCALL dummy_skip_handler(void *userData,
int is_parameter_entity);
#endif /* XML_DUMMY_H */
#ifdef __cplusplus
}
#endif
+17 -26
View File
@@ -45,16 +45,12 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_HANDLERS_H
# define XML_HANDLERS_H
#define XML_HANDLERS_H
# include "expat_config.h"
#include "expat_config.h"
# include "expat.h"
#include "expat.h"
/* Variable holding the expected handler userData */
extern const void *g_handler_data;
@@ -74,8 +70,8 @@ extern void XMLCALL start_element_event_handler(void *userData,
extern void XMLCALL end_element_event_handler(void *userData,
const XML_Char *name);
# define STRUCT_START_TAG 0
# define STRUCT_END_TAG 1
#define STRUCT_START_TAG 0
#define STRUCT_END_TAG 1
extern void XMLCALL start_element_event_handler2(void *userData,
const XML_Char *name,
@@ -516,22 +512,21 @@ extern const struct handler_record_entry *
_handler_record_get(const struct handler_record_list *storage, int index,
const char *file, int line);
# define handler_record_get(storage, index) \
_handler_record_get((storage), (index), __FILE__, __LINE__)
#define handler_record_get(storage, index) \
_handler_record_get((storage), (index), __FILE__, __LINE__)
# define assert_record_handler_called(storage, index, expected_name, \
expected_arg) \
do { \
const struct handler_record_entry *e \
= handler_record_get(storage, index); \
assert_true(strcmp(e->name, expected_name) == 0); \
assert_true(e->arg == (expected_arg)); \
} while (0)
#define assert_record_handler_called(storage, index, expected_name, \
expected_arg) \
do { \
const struct handler_record_entry *e = handler_record_get(storage, index); \
assert_true(strcmp(e->name, expected_name) == 0); \
assert_true(e->arg == (expected_arg)); \
} while (0)
/* Entity Declaration Handlers */
# define ENTITY_MATCH_FAIL (-1)
# define ENTITY_MATCH_NOT_FOUND (0)
# define ENTITY_MATCH_SUCCESS (1)
#define ENTITY_MATCH_FAIL (-1)
#define ENTITY_MATCH_NOT_FOUND (0)
#define ENTITY_MATCH_SUCCESS (1)
extern void XMLCALL param_entity_match_handler(
void *userData, const XML_Char *entityName, int is_parameter_entity,
@@ -630,7 +625,3 @@ extern void XMLCALL suspend_then_resume_character_handler(void *userData,
int len);
#endif /* XML_HANDLERS_H */
#ifdef __cplusplus
}
#endif
+157
View File
@@ -0,0 +1,157 @@
/* Tests related to the hash tables used inside Expat
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
SPDX-License-Identifier: MIT
*/
#include "hash_tests.h"
#include "common.h" // for XCS
#include "expat.h"
#include "hash_table.h"
#include "minicheck.h"
#include <stdbool.h>
#include <string.h> // for memcmp
START_TEST(test_hash_table) {
// The test is not doing any parsing, so a single run
// (with `g_chunkSize == 0`) is enough
if (g_chunkSize != 0)
return;
typedef struct {
const XML_Char *name;
bool initialized;
} NAME_AND_FLAG;
HASH_TABLE table;
XML_Parser parser = XML_ParserCreate(NULL);
hashTableInit(&table, parser);
const XML_Char *const key1 = XCS("key1");
const XML_Char *const key2 = XCS("key2");
const XML_Char *const key3 = XCS("key1overlap");
// Self-test: `key3` starts with `key1` but is different from it
assert_true(memcmp(key1, key3, keylen(key1)) == 0);
assert_true(keyeq(key1, keylen(key1), key3) == XML_FALSE);
// Test: Look up false for all keys because the table is empty
assert_true(lookup(parser, &table, key1, 0) == NULL);
assert_true(lookup(parser, &table, key2, 0) == NULL);
assert_true(lookup(parser, &table, key3, 0) == NULL);
// Test: Iteration yields 0 items initially
{
HASH_TABLE_ITER iter1;
hashTableIterInit(&iter1, &table);
assert_true(hashTableIterNext(&iter1) == NULL);
}
// Test: Insertion works (including initialization to zero)
NAME_AND_FLAG *const inserted1
= (NAME_AND_FLAG *)lookup(parser, &table, key1, sizeof(NAME_AND_FLAG));
assert_true(inserted1 != NULL);
assert_true(inserted1->name == key1);
assert_true(! inserted1->initialized);
// Make it possible to tell the struct apart from a freshly inserted version
inserted1->initialized = true;
// Test: Only present keys can be looked up
assert_true(lookup(parser, &table, key1, 0) != NULL);
assert_true(lookup(parser, &table, key2, 0) == NULL);
assert_true(lookup(parser, &table, key3, 0) == NULL);
// Test: Key length works without false positives
assert_true(lookupWithLength(parser, &table, key3, /*nameLen=*/3, 0) == NULL);
assert_true(lookupWithLength(parser, &table, key3, /*nameLen=*/4, 0) != NULL);
assert_true(lookupWithLength(parser, &table, key3, /*nameLen=*/5, 0) == NULL);
// TEST: Lookup does not reset existing entries to zeros
NAME_AND_FLAG *const found
= (NAME_AND_FLAG *)lookup(parser, &table, key1, sizeof(NAME_AND_FLAG));
assert_true(found != NULL);
assert_true(found->name == key1);
assert_true(found->initialized); // this is key
// Test: Insertion of a second item works
assert_true(lookup(parser, &table, key2, 0) == NULL);
assert_true(lookup(parser, &table, key2, sizeof(NAME_AND_FLAG)) != NULL);
assert_true(lookup(parser, &table, key2, 0) != NULL);
// Test: Iteration yields nothing but the two expected items
{
HASH_TABLE_ITER iter2;
hashTableIterInit(&iter2, &table);
size_t itemCount = 0;
while (true) {
const NAME_AND_FLAG *const item
= (const NAME_AND_FLAG *)hashTableIterNext(&iter2);
if (item == NULL)
break;
itemCount++;
if (keyeq(key1, keylen(key1), item->name) == XML_TRUE)
assert_true(item->initialized);
else if (keyeq(key2, keylen(key2), item->name) == XML_TRUE)
assert_true(! item->initialized);
else
fail("unexpected item .name");
}
assert_true(itemCount == 2);
}
// Test: After clearing all lookups fail
hashTableClear(&table);
assert_true(lookup(parser, &table, key1, 0) == NULL);
assert_true(lookup(parser, &table, key2, 0) == NULL);
assert_true(lookup(parser, &table, key3, 0) == NULL);
// Test: After clearing iteration yields 0 items again
{
HASH_TABLE_ITER iter3;
hashTableIterInit(&iter3, &table);
assert_true(hashTableIterNext(&iter3) == NULL);
}
hashTableDestroy(&table);
XML_ParserFree(parser);
}
END_TEST
void
make_hash_test_case(Suite *s) {
TCase *const tc_hash = tcase_create("hash tests");
suite_add_tcase(s, tc_hash);
tcase_add_test(tc_hash, test_hash_table);
}
+41
View File
@@ -0,0 +1,41 @@
/* Tests related to the hash tables used inside Expat
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
SPDX-License-Identifier: MIT
*/
#ifndef XML_HASH_TESTS_H
#define XML_HASH_TESTS_H
#include "minicheck.h"
extern void make_hash_test_case(Suite *s);
#endif /* XML_HASH_TESTS_H */
+2 -1
View File
@@ -10,6 +10,7 @@
Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com>
Copyright (c) 2026 Leo Camus <leo.camus23@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -117,7 +118,7 @@ tracking_free(void *ptr) {
if (entry->next != NULL)
entry->next->prev = entry->prev;
else
alloc_tail = entry->next;
alloc_tail = entry->prev;
free(entry);
} else {
printf("Attempting to free unallocated memory at %p\n", ptr);
+2 -10
View File
@@ -7,8 +7,8 @@
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017-2026 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -33,10 +33,6 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_MEMCHECK_H
# define XML_MEMCHECK_H 1
@@ -53,7 +49,3 @@ void *tracking_realloc(void *ptr, size_t size);
int tracking_report(void);
#endif /* XML_MEMCHECK_H */
#ifdef __cplusplus
}
#endif
+30 -46
View File
@@ -14,7 +14,7 @@
Copyright (c) 2004-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2006-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
Licensed under the MIT license:
@@ -41,27 +41,15 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_MINICHECK_H
# define XML_MINICHECK_H
#define XML_MINICHECK_H
# define CK_NOFORK 0
# define CK_FORK 1
#define CK_NOFORK 0
#define CK_FORK 1
# define CK_SILENT 0
# define CK_NORMAL 1
# define CK_VERBOSE 2
/* Workaround for Microsoft's compiler and Tru64 Unix systems where the
C compiler has a working __func__, but the C++ compiler only has a
working __FUNCTION__. This could be fixed in configure.in, but it's
not worth it right now. */
# if defined(_MSC_VER) || (defined(__osf__) && defined(__cplusplus))
# define __func__ __FUNCTION__
# endif
#define CK_SILENT 0
#define CK_NORMAL 1
#define CK_VERBOSE 2
/* PRINTF_LIKE has two effects:
1. Make clang's -Wformat-nonliteral stop warning about non-literal format
@@ -69,30 +57,30 @@ extern "C" {
2. Make both clang and gcc's -Wformat-nonliteral warn about *callers* of
the annotated function that use a non-literal format string.
*/
# if defined(__GNUC__)
# define PRINTF_LIKE(fmtpos, argspos) \
__attribute__((format(printf, fmtpos, argspos)))
# else
# define PRINTF_LIKE(fmtpos, argspos)
# endif
#if defined(__GNUC__)
# define PRINTF_LIKE(fmtpos, argspos) \
__attribute__((format(printf, fmtpos, argspos)))
#else
# define PRINTF_LIKE(fmtpos, argspos)
#endif
# define START_TEST(testname) \
static void testname(void) { \
_check_set_test_info(__func__, __FILE__, __LINE__); \
{
# define END_TEST \
} \
}
#define START_TEST(testname) \
static void testname(void) { \
_check_set_test_info(__func__, __FILE__, __LINE__); \
{
#define END_TEST \
} \
}
void PRINTF_LIKE(1, 2) set_subtest(char const *fmt, ...);
# define fail(msg) _fail(__FILE__, __LINE__, msg)
# define assert_true(cond) \
do { \
if (! (cond)) { \
_fail(__FILE__, __LINE__, "check failed: " #cond); \
} \
} while (0)
#define fail(msg) _fail(__FILE__, __LINE__, msg)
#define assert_true(cond) \
do { \
if (! (cond)) { \
_fail(__FILE__, __LINE__, "check failed: " #cond); \
} \
} while (0)
typedef void (*tcase_setup_function)(void);
typedef void (*tcase_teardown_function)(void);
@@ -131,11 +119,11 @@ void _check_set_test_info(char const *function, char const *filename,
* Prototypes for the actual implementation.
*/
# if defined(__has_attribute)
# if __has_attribute(noreturn)
#if defined(__has_attribute)
# if __has_attribute(noreturn)
__attribute__((noreturn))
# endif
# endif
#endif
void _fail(const char *file, int line, const char *msg);
Suite *suite_create(const char *name);
TCase *tcase_create(const char *name);
@@ -150,7 +138,3 @@ int srunner_ntests_failed(SRunner *runner);
void srunner_free(SRunner *runner);
#endif /* XML_MINICHECK_H */
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -218,7 +218,7 @@ START_TEST(test_misc_version) {
if (! versions_equal(&read_version, &parsed_version))
fail("Version mismatch");
if (xcstrcmp(version_text, XCS("expat_2.8.4"))
if (xcstrcmp(version_text, XCS("expat_2.8.5"))
!= 0) /* needs bump on releases */
fail("XML_*_VERSION in expat.h out of sync?\n");
}
+2 -10
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-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 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>
@@ -42,17 +42,9 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_MISC_TESTS_H
# define XML_MISC_TESTS_H
#define XML_MISC_TESTS_H
extern void make_miscellaneous_test_case(Suite *s);
#endif /* XML_MISC_TESTS_H */
#ifdef __cplusplus
}
#endif
+2 -10
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-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 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>
@@ -42,17 +42,9 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_NS_TESTS_H
# define XML_NS_TESTS_H
#define XML_NS_TESTS_H
extern void make_namespace_test_case(Suite *s);
#endif /* XML_NS_TESTS_H */
#ifdef __cplusplus
}
#endif
+2
View File
@@ -43,6 +43,8 @@
SPDX-License-Identifier: MIT
*/
#include "expat_config.h"
#if defined(NDEBUG)
# undef NDEBUG /* because test suite relies on assert(...) at the moment */
#endif
+2 -10
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-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 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>
@@ -42,17 +42,9 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_NSALLOC_TESTS_H
# define XML_NSALLOC_TESTS_H
#define XML_NSALLOC_TESTS_H
extern void make_nsalloc_test_case(Suite *s);
#endif /* XML_NSALLOC_TESTS_H */
#ifdef __cplusplus
}
#endif
+3 -1
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-2026 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>
@@ -55,6 +55,7 @@
#include "common.h"
#include "basic_tests.h"
#include "hash_tests.h"
#include "ns_tests.h"
#include "misc_tests.h"
#include "alloc_tests.h"
@@ -68,6 +69,7 @@ make_suite(void) {
Suite *s = suite_create("basic");
make_basic_test_case(s);
make_hash_test_case(s);
make_namespace_test_case(s);
make_miscellaneous_test_case(s);
make_alloc_test_case(s);
+1 -8
View File
@@ -8,6 +8,7 @@
|_| XML parser
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -32,10 +33,6 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_STRUCTDATA_H
# define XML_STRUCTDATA_H 1
@@ -65,7 +62,3 @@ void StructData_CheckItems(StructData *storage, const StructDataEntry *expected,
void StructData_Dispose(StructData *storage);
#endif /* XML_STRUCTDATA_H */
#ifdef __cplusplus
}
#endif
+2
View File
@@ -31,6 +31,7 @@
# Copyright (c) 2008-2019 Sebastian Pipping <[email protected]>
# Copyright (c) 2017 Rhodri James <[email protected]>
# Copyright (c) 2025 Hanno Böck <[email protected]>
# Copyright (c) 2026 Huang Wenbin <[email protected]>
# Licensed under the MIT license:
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -172,3 +173,4 @@ done
echo "Passed: $SUCCESS"
echo "Failed: $ERROR"
test "$ERROR" -eq 0
+16 -11
View File
@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.18.1 from Makefile.am.
# Makefile.in generated by automake 1.19 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2025 Free Software Foundation, Inc.
# Copyright (C) 1994-2026 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -335,6 +335,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__tar_ignore_stderr = @am__tar_ignore_stderr@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
@@ -412,9 +413,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu xmlwf/Makefile'; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xmlwf/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu xmlwf/Makefile
$(AUTOMAKE) --foreign xmlwf/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -499,22 +500,25 @@ $(am__depfiles_remade):
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
@@ -639,13 +643,14 @@ distdir: $(BUILT_SOURCES)
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
am__distdir="$(distdir)"; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sed "/\//!d;s|^|$$am__distdir/|;s,/[^/]*$$,," | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
+3 -1
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-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com>
Licensed under the MIT license:
@@ -37,6 +37,8 @@
SPDX-License-Identifier: MIT
*/
#include "expat_config.h" // for off_t
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
+3 -3
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-2025 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 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>
@@ -266,7 +266,7 @@ externalEntityRefStream(XML_Parser parser, const XML_Char *context,
return ret;
}
int
bool
XML_ProcessFile(XML_Parser parser, const XML_Char *filename, unsigned flags) {
int result;
@@ -299,5 +299,5 @@ XML_ProcessFile(XML_Parser parser, const XML_Char *filename, unsigned flags) {
}
} else
result = processStream(filename, parser);
return result;
return (bool)result;
}
+5 -3
View File
@@ -10,7 +10,7 @@
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2005 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -35,6 +35,8 @@
SPDX-License-Identifier: MIT
*/
#include <stdbool.h>
#define XML_MAP_FILE 01
#define XML_EXTERNAL_ENTITIES 02
@@ -46,5 +48,5 @@
extern int g_read_size_bytes;
extern int XML_ProcessFile(XML_Parser parser, const XML_Char *filename,
unsigned flags);
extern bool XML_ProcessFile(XML_Parser parser, const XML_Char *filename,
unsigned flags);
+1 -9
View File
@@ -8,7 +8,7 @@
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -33,10 +33,6 @@
SPDX-License-Identifier: MIT
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Registered charset names are at most 40 characters long. */
#define CHARSET_MAX 41
@@ -48,7 +44,3 @@ extern "C" {
*/
void getXMLCharset(const char *buf, char *charset);
#ifdef __cplusplus
}
#endif
+17 -8
View File
@@ -933,7 +933,7 @@ usage(const XML_Char *prog, int rc) {
T(" -w enable support for [W]indows code pages\n")
T(" -r disable memory-mapping and use [r]ead calls instead\n")
T(" -g BYTES buffer size to request per call pair to XML_[G]etBuffer and read (default: 8 KiB)\n")
T(" -k when processing multiple files, [k]eep processing after first file with error\n")
T(" -k when processing multiple files, [k]eep processing after first file with error, and make the last error determine the exit code.\n")
T("\n")
T("output control arguments:\n")
T(" -d DIRECTORY output [d]estination directory\n")
@@ -969,7 +969,7 @@ usage(const XML_Char *prog, int rc) {
T(" 0 the input files are well-formed and the output (if requested) was written successfully\n")
T(" 1 could not allocate data structures, signals a serious problem with execution environment\n")
T(" 2 one or more input files were not well-formed\n")
T(" 3 could not create an output file\n")
T(" 3 one or more output files could not be written\n")
T(" 4 command-line argument error\n")
T("\n")
T("xmlwf of libexpat is software libre, licensed under the MIT license.\n")
@@ -1194,7 +1194,6 @@ tmain(int argc, XML_Char **argv) {
}
for (; i < argc; i++) {
XML_Char *outName = 0;
int result;
XML_Parser parser;
if (useNamespaces)
parser = XML_ParserCreateNS(encoding, NSSEP);
@@ -1350,19 +1349,29 @@ tmain(int argc, XML_Char **argv) {
}
if (windowsCodePages)
XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0);
result = XML_ProcessFile(parser, useStdin ? NULL : argv[i], processFlags);
const bool processingSuccess
= XML_ProcessFile(parser, useStdin ? NULL : argv[i], processFlags);
bool closingSuccess = true;
if (outputDir) {
if (outputType == 'm')
metaEndDocument(parser);
fclose(userData.fp);
if (! result) {
closingSuccess = (fclose(userData.fp) == 0);
if (! closingSuccess)
tperror(outName);
if (! processingSuccess || ! closingSuccess) {
tremove(outName);
}
free(outName);
}
XML_ParserFree(parser);
if (! result) {
exitCode = XMLWF_EXIT_NOT_WELLFORMED;
if (! processingSuccess || ! closingSuccess) {
// NOTE: If both failed, the last error should determine the exit code.
// Failure to close happened after failure to process.
if (! closingSuccess)
exitCode = XMLWF_EXIT_OUTPUT_ERROR;
else if (! processingSuccess)
exitCode = XMLWF_EXIT_NOT_WELLFORMED;
cleanupUserData(&userData);
if (! continueOnError) {
break;
+5 -2
View File
@@ -50,7 +50,7 @@ epilog = dedent(
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
2 one or more input files were not well-formed
3 could not create an output file
3 one or more output files could not be written
4 command-line argument error
xmlwf of libexpat is software libre, licensed under the MIT license.
@@ -116,7 +116,10 @@ input_related.add_argument(
input_related.add_argument(
"-k",
action="store_true",
help="when processing multiple files, [k]eep processing after first file with error",
help=(
"when processing multiple files, [k]eep processing after first file with error"
", and make the last error determine the exit code."
),
)
output_related = parser.add_argument_group("output control arguments")
+6 -2
View File
@@ -6,7 +6,7 @@
# \___/_/\_\ .__/ \__,_|\__|
# |_| XML parser
#
# Copyright (c) 2019-2021 Sebastian Pipping <[email protected]>
# Copyright (c) 2019-2026 Sebastian Pipping <[email protected]>
# Licensed under the MIT license:
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -30,7 +30,11 @@
#
# SPDX-License-Identifier: MIT
./xmlwf/xmlwf_helpgen.py | sed \
set -e
cd "$(dirname "$(type -P "$0")")"
./xmlwf_helpgen.py | sed \
-e 's,usage: ,usage:,' \
-e 's, xmlwf, %s,' \
-e 's, \[-h | -v\],,' \