@@ -319,7 +319,7 @@ directions in the next section. Otherwise if you have Microsoft's
Developer Studio installed,
you can use CMake to generate a
.sln file, e.g.
-cmake -G"Visual Studio 15 2017" -DCMAKE_BUILD_TYPE=RelWithDebInfo .
+cmake -G"Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=RelWithDebInfo .
, and build Expat using
msbuild /m expat.sln after.
Alternatively, you may download the Win32 binary package that
@@ -356,10 +356,7 @@ library and header would get installed in
Configuring Expat Using the Pre-Processor
Expat's feature set can be configured using a small number of
-pre-processor definitions. The definition of this symbols does not
-affect the set of entry points for Expat, only the behavior of the API
-and the definition of character types in the case of
-XML_UNICODE_WCHAR_T. The symbols are:
+pre-processor definitions. The symbols are:
- XML_GE
@@ -1138,7 +1135,9 @@ containing part (or perhaps all) of the document. The number of bytes of s
that are part of the document is indicated by len. This means
that s doesn't have to be null-terminated. It also means that
if len is larger than the number of bytes in the block of
-memory that s points at, then a memory fault is likely. The
+memory that s points at, then a memory fault is likely.
+Negative values for len are rejected since Expat 2.2.1.
+The
isFinal parameter informs the parser that this is the last
piece of the document. Frequently, the last piece is empty (i.e.
len is zero.)
@@ -1186,11 +1185,17 @@ XML_ParseBuffer(XML_Parser p,
int isFinal);
+
This is just like XML_Parse,
except in this case Expat provides the buffer. By obtaining the
buffer from Expat with the XML_GetBuffer function, the application can avoid double
copying of the input.
+
+
+
+Negative values for len are rejected since Expat 2.6.3.
+
XML_GetBuffer
diff --git a/contrib/expat/doc/xmlwf.1 b/contrib/expat/doc/xmlwf.1
index ac5ce21e6b8..347c36f0610 100644
--- a/contrib/expat/doc/xmlwf.1
+++ b/contrib/expat/doc/xmlwf.1
@@ -5,7 +5,7 @@
\\$2 \(la\\$1\(ra\\$3
..
.if \n(.g .mso www.tmac
-.TH XMLWF 1 "February 6, 2024" "" ""
+.TH XMLWF 1 "September 4, 2024" "" ""
.SH NAME
xmlwf \- Determines if an XML document is well-formed
.SH SYNOPSIS
diff --git a/contrib/expat/doc/xmlwf.xml b/contrib/expat/doc/xmlwf.xml
index 2b3f1ccd74a..10b29782b19 100644
--- a/contrib/expat/doc/xmlwf.xml
+++ b/contrib/expat/doc/xmlwf.xml
@@ -21,7 +21,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
Scott">
Bronson">
- February 6, 2024">
+ September 4, 2024">
1">
bronson@rinspin.com">
diff --git a/contrib/expat/examples/Makefile.in b/contrib/expat/examples/Makefile.in
index 0ccc020dd94..044c9089c56 100644
--- a/contrib/expat/examples/Makefile.in
+++ b/contrib/expat/examples/Makefile.in
@@ -313,6 +313,7 @@ RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
+SIZEOF_VOID_P = @SIZEOF_VOID_P@
SO_MAJOR = @SO_MAJOR@
SO_MINOR = @SO_MINOR@
SO_PATCH = @SO_PATCH@
@@ -326,7 +327,6 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_cv_sizeof_void_p = @ac_cv_sizeof_void_p@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
diff --git a/contrib/expat/expat_config.h.in b/contrib/expat/expat_config.h.in
index 91c32340868..67ef89c7171 100644
--- a/contrib/expat/expat_config.h.in
+++ b/contrib/expat/expat_config.h.in
@@ -139,7 +139,4 @@
/* Define to `long int' if does not define. */
#undef off_t
-/* Define to `unsigned int' if does not define. */
-#undef size_t
-
#endif // ndef EXPAT_CONFIG_H
diff --git a/contrib/expat/fix-xmltest-log.sh b/contrib/expat/fix-xmltest-log.sh
index 7981cf3b00c..4739acab6b0 100755
--- a/contrib/expat/fix-xmltest-log.sh
+++ b/contrib/expat/fix-xmltest-log.sh
@@ -7,6 +7,7 @@
# |_| XML parser
#
# Copyright (c) 2019-2022 Sebastian Pipping
+# Copyright (c) 2024 Dag-Erling Smørgrav
# Licensed under the MIT license:
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -32,10 +33,10 @@ set -e
filename="${1:-tests/xmltest.log}"
-dos2unix "${filename}"
-
-tempfile="$(mktemp)"
-sed \
+sed -i.bak \
+ -e '# convert DOS line endings to Unix without resorting to dos2unix' \
+ -e $'s/\r//' \
+ \
-e 's/^wine: Call .* msvcrt\.dll\._wperror, aborting$/ibm49i02.dtd: No such file or directory/' \
\
-e '/^wine: /d' \
@@ -46,5 +47,4 @@ sed \
-e '/^wine client error:/d' \
-e '/^In ibm\/invalid\/P49\/: Unhandled exception: unimplemented .\+/d' \
\
- "${filename}" > "${tempfile}"
-mv "${tempfile}" "${filename}"
+ "${filename}"
diff --git a/contrib/expat/lib/Makefile.am b/contrib/expat/lib/Makefile.am
index 0e0185b5912..1958f322f31 100644
--- a/contrib/expat/lib/Makefile.am
+++ b/contrib/expat/lib/Makefile.am
@@ -6,7 +6,7 @@
# \___/_/\_\ .__/ \__,_|\__|
# |_| XML parser
#
-# Copyright (c) 2017-2022 Sebastian Pipping
+# Copyright (c) 2017-2024 Sebastian Pipping
# Copyright (c) 2017 Tomasz Kłoczko
# Copyright (c) 2019 David Loffredo
# Licensed under the MIT license:
@@ -36,7 +36,9 @@ include_HEADERS = \
expat_external.h
lib_LTLIBRARIES = libexpat.la
-noinst_LTLIBRARIES = libexpatinternal.la
+if WITH_TESTS
+noinst_LTLIBRARIES = libtestpat.la
+endif
libexpat_la_LDFLAGS = \
@AM_LDFLAGS@ \
@@ -44,17 +46,16 @@ libexpat_la_LDFLAGS = \
-no-undefined \
-version-info @LIBCURRENT@:@LIBREVISION@:@LIBAGE@
-libexpat_la_SOURCES =
-
-# This layer of indirection allows
-# the test suite to access internal symbols
-# despite compiling with -fvisibility=hidden
-libexpatinternal_la_SOURCES = \
+libexpat_la_SOURCES = \
xmlparse.c \
xmltok.c \
xmlrole.c
-libexpat_la_LIBADD = libexpatinternal.la
+if WITH_TESTS
+libtestpat_la_CPPFLAGS = -DXML_TESTING
+
+libtestpat_la_SOURCES = $(libexpat_la_SOURCES)
+endif
doc_DATA = \
../AUTHORS \
diff --git a/contrib/expat/lib/Makefile.in b/contrib/expat/lib/Makefile.in
index 29584d8bbe7..1a97e85fc41 100644
--- a/contrib/expat/lib/Makefile.in
+++ b/contrib/expat/lib/Makefile.in
@@ -22,7 +22,7 @@
# \___/_/\_\ .__/ \__,_|\__|
# |_| XML parser
#
-# Copyright (c) 2017-2022 Sebastian Pipping
+# Copyright (c) 2017-2024 Sebastian Pipping
# Copyright (c) 2017 Tomasz Kłoczko
# Copyright (c) 2019 David Loffredo
# Licensed under the MIT license:
@@ -176,8 +176,8 @@ am__uninstall_files_from_dir = { \
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" \
"$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
-libexpat_la_DEPENDENCIES = libexpatinternal.la
-am_libexpat_la_OBJECTS =
+libexpat_la_LIBADD =
+am_libexpat_la_OBJECTS = xmlparse.lo xmltok.lo xmlrole.lo
libexpat_la_OBJECTS = $(am_libexpat_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -186,9 +186,13 @@ am__v_lt_1 =
libexpat_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libexpat_la_LDFLAGS) $(LDFLAGS) -o $@
-libexpatinternal_la_LIBADD =
-am_libexpatinternal_la_OBJECTS = xmlparse.lo xmltok.lo xmlrole.lo
-libexpatinternal_la_OBJECTS = $(am_libexpatinternal_la_OBJECTS)
+libtestpat_la_LIBADD =
+am__libtestpat_la_SOURCES_DIST = xmlparse.c xmltok.c xmlrole.c
+am__objects_1 = libtestpat_la-xmlparse.lo libtestpat_la-xmltok.lo \
+ libtestpat_la-xmlrole.lo
+@WITH_TESTS_TRUE@am_libtestpat_la_OBJECTS = $(am__objects_1)
+libtestpat_la_OBJECTS = $(am_libtestpat_la_OBJECTS)
+@WITH_TESTS_TRUE@am_libtestpat_la_rpath =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@@ -204,8 +208,10 @@ am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/conftools/depcomp
am__maybe_remake_depfiles = depfiles
-am__depfiles_remade = ./$(DEPDIR)/xmlparse.Plo ./$(DEPDIR)/xmlrole.Plo \
- ./$(DEPDIR)/xmltok.Plo
+am__depfiles_remade = ./$(DEPDIR)/libtestpat_la-xmlparse.Plo \
+ ./$(DEPDIR)/libtestpat_la-xmlrole.Plo \
+ ./$(DEPDIR)/libtestpat_la-xmltok.Plo ./$(DEPDIR)/xmlparse.Plo \
+ ./$(DEPDIR)/xmlrole.Plo ./$(DEPDIR)/xmltok.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -225,8 +231,9 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
-SOURCES = $(libexpat_la_SOURCES) $(libexpatinternal_la_SOURCES)
-DIST_SOURCES = $(libexpat_la_SOURCES) $(libexpatinternal_la_SOURCES)
+SOURCES = $(libexpat_la_SOURCES) $(libtestpat_la_SOURCES)
+DIST_SOURCES = $(libexpat_la_SOURCES) \
+ $(am__libtestpat_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -344,6 +351,7 @@ RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
+SIZEOF_VOID_P = @SIZEOF_VOID_P@
SO_MAJOR = @SO_MAJOR@
SO_MINOR = @SO_MINOR@
SO_PATCH = @SO_PATCH@
@@ -357,7 +365,6 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_cv_sizeof_void_p = @ac_cv_sizeof_void_p@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -410,24 +417,20 @@ include_HEADERS = \
expat_external.h
lib_LTLIBRARIES = libexpat.la
-noinst_LTLIBRARIES = libexpatinternal.la
+@WITH_TESTS_TRUE@noinst_LTLIBRARIES = libtestpat.la
libexpat_la_LDFLAGS = \
@AM_LDFLAGS@ \
@LIBM@ \
-no-undefined \
-version-info @LIBCURRENT@:@LIBREVISION@:@LIBAGE@
-libexpat_la_SOURCES =
-
-# This layer of indirection allows
-# the test suite to access internal symbols
-# despite compiling with -fvisibility=hidden
-libexpatinternal_la_SOURCES = \
+libexpat_la_SOURCES = \
xmlparse.c \
xmltok.c \
xmlrole.c
-libexpat_la_LIBADD = libexpatinternal.la
+@WITH_TESTS_TRUE@libtestpat_la_CPPFLAGS = -DXML_TESTING
+@WITH_TESTS_TRUE@libtestpat_la_SOURCES = $(libexpat_la_SOURCES)
doc_DATA = \
../AUTHORS \
../Changes
@@ -534,8 +537,8 @@ clean-noinstLTLIBRARIES:
libexpat.la: $(libexpat_la_OBJECTS) $(libexpat_la_DEPENDENCIES) $(EXTRA_libexpat_la_DEPENDENCIES)
$(AM_V_CCLD)$(libexpat_la_LINK) -rpath $(libdir) $(libexpat_la_OBJECTS) $(libexpat_la_LIBADD) $(LIBS)
-libexpatinternal.la: $(libexpatinternal_la_OBJECTS) $(libexpatinternal_la_DEPENDENCIES) $(EXTRA_libexpatinternal_la_DEPENDENCIES)
- $(AM_V_CCLD)$(LINK) $(libexpatinternal_la_OBJECTS) $(libexpatinternal_la_LIBADD) $(LIBS)
+libtestpat.la: $(libtestpat_la_OBJECTS) $(libtestpat_la_DEPENDENCIES) $(EXTRA_libtestpat_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(am_libtestpat_la_rpath) $(libtestpat_la_OBJECTS) $(libtestpat_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -543,6 +546,9 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-xmlparse.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-xmlrole.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-xmltok.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlparse.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlrole.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltok.Plo@am__quote@ # am--include-marker
@@ -574,6 +580,27 @@ am--depfiles: $(am__depfiles_remade)
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+libtestpat_la-xmlparse.lo: xmlparse.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestpat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtestpat_la-xmlparse.lo -MD -MP -MF $(DEPDIR)/libtestpat_la-xmlparse.Tpo -c -o libtestpat_la-xmlparse.lo `test -f 'xmlparse.c' || echo '$(srcdir)/'`xmlparse.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtestpat_la-xmlparse.Tpo $(DEPDIR)/libtestpat_la-xmlparse.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xmlparse.c' object='libtestpat_la-xmlparse.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestpat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtestpat_la-xmlparse.lo `test -f 'xmlparse.c' || echo '$(srcdir)/'`xmlparse.c
+
+libtestpat_la-xmltok.lo: xmltok.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestpat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtestpat_la-xmltok.lo -MD -MP -MF $(DEPDIR)/libtestpat_la-xmltok.Tpo -c -o libtestpat_la-xmltok.lo `test -f 'xmltok.c' || echo '$(srcdir)/'`xmltok.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtestpat_la-xmltok.Tpo $(DEPDIR)/libtestpat_la-xmltok.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xmltok.c' object='libtestpat_la-xmltok.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestpat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtestpat_la-xmltok.lo `test -f 'xmltok.c' || echo '$(srcdir)/'`xmltok.c
+
+libtestpat_la-xmlrole.lo: xmlrole.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestpat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtestpat_la-xmlrole.lo -MD -MP -MF $(DEPDIR)/libtestpat_la-xmlrole.Tpo -c -o libtestpat_la-xmlrole.lo `test -f 'xmlrole.c' || echo '$(srcdir)/'`xmlrole.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtestpat_la-xmlrole.Tpo $(DEPDIR)/libtestpat_la-xmlrole.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xmlrole.c' object='libtestpat_la-xmlrole.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestpat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtestpat_la-xmlrole.lo `test -f 'xmlrole.c' || echo '$(srcdir)/'`xmlrole.c
+
mostlyclean-libtool:
-rm -f *.lo
@@ -749,7 +776,10 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
clean-noinstLTLIBRARIES mostlyclean-am
distclean: distclean-am
- -rm -f ./$(DEPDIR)/xmlparse.Plo
+ -rm -f ./$(DEPDIR)/libtestpat_la-xmlparse.Plo
+ -rm -f ./$(DEPDIR)/libtestpat_la-xmlrole.Plo
+ -rm -f ./$(DEPDIR)/libtestpat_la-xmltok.Plo
+ -rm -f ./$(DEPDIR)/xmlparse.Plo
-rm -f ./$(DEPDIR)/xmlrole.Plo
-rm -f ./$(DEPDIR)/xmltok.Plo
-rm -f Makefile
@@ -798,7 +828,10 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
- -rm -f ./$(DEPDIR)/xmlparse.Plo
+ -rm -f ./$(DEPDIR)/libtestpat_la-xmlparse.Plo
+ -rm -f ./$(DEPDIR)/libtestpat_la-xmlrole.Plo
+ -rm -f ./$(DEPDIR)/libtestpat_la-xmltok.Plo
+ -rm -f ./$(DEPDIR)/xmlparse.Plo
-rm -f ./$(DEPDIR)/xmlrole.Plo
-rm -f ./$(DEPDIR)/xmltok.Plo
-rm -f Makefile
diff --git a/contrib/expat/lib/expat.h b/contrib/expat/lib/expat.h
index 95464b0dd17..d0d6015a662 100644
--- a/contrib/expat/lib/expat.h
+++ b/contrib/expat/lib/expat.h
@@ -18,6 +18,7 @@
Copyright (c) 2022 Thijs Schreijer
Copyright (c) 2023 Hanno Böck
Copyright (c) 2023 Sony Corporation / Snild Dolkow
+ Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -1042,7 +1043,7 @@ typedef struct {
XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void);
-#if XML_GE == 1
+#if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1)
/* Added in Expat 2.4.0 for XML_DTD defined and
* added in Expat 2.6.0 for XML_GE == 1. */
XMLPARSEAPI(XML_Bool)
@@ -1065,7 +1066,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 6
-#define XML_MICRO_VERSION 0
+#define XML_MICRO_VERSION 3
#ifdef __cplusplus
}
diff --git a/contrib/expat/lib/internal.h b/contrib/expat/lib/internal.h
index cce71e4c516..167ec36804a 100644
--- a/contrib/expat/lib/internal.h
+++ b/contrib/expat/lib/internal.h
@@ -28,10 +28,11 @@
Copyright (c) 2002-2003 Fred L. Drake, Jr.
Copyright (c) 2002-2006 Karl Waclawek
Copyright (c) 2003 Greg Stein
- Copyright (c) 2016-2023 Sebastian Pipping
+ Copyright (c) 2016-2024 Sebastian Pipping
Copyright (c) 2018 Yury Gribov
Copyright (c) 2019 David Loffredo
- Copyright (c) 2023 Sony Corporation / Snild Dolkow
+ Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow
+ Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -155,14 +156,20 @@ extern "C" {
void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
const char **fromLimRef);
-#if 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
-extern XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
-extern unsigned int g_parseAttempts; // used for testing only
+extern
+#if ! defined(XML_TESTING)
+ const
+#endif
+ XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
+#if defined(XML_TESTING)
+extern unsigned int g_bytesScanned; // used for testing only
+#endif
#ifdef __cplusplus
}
diff --git a/contrib/expat/lib/siphash.h b/contrib/expat/lib/siphash.h
index a1ed99e687b..04f6f74585b 100644
--- a/contrib/expat/lib/siphash.h
+++ b/contrib/expat/lib/siphash.h
@@ -126,8 +126,7 @@
| ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \
| ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
-#define SIPHASH_INITIALIZER \
- { 0, 0, 0, 0, {0}, 0, 0 }
+#define SIPHASH_INITIALIZER {0, 0, 0, 0, {0}, 0, 0}
struct siphash {
uint64_t v0, v1, v2, v3;
diff --git a/contrib/expat/lib/xmlparse.c b/contrib/expat/lib/xmlparse.c
index aaf0fa9c8f9..d9285b213b3 100644
--- a/contrib/expat/lib/xmlparse.c
+++ b/contrib/expat/lib/xmlparse.c
@@ -1,4 +1,4 @@
-/* 628e24d4966bedbd4800f6ed128d06d29703765b4bce12d3b7f099f90f842fc9 (2.6.0+)
+/* ba4cdf9bdb534f355a9def4c9e25d20ee8e72f95b0a4d930be52e563f5080196 (2.6.3+)
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
@@ -38,7 +38,8 @@
Copyright (c) 2022 Jann Horn
Copyright (c) 2022 Sean McBride
Copyright (c) 2023 Owain Davies
- Copyright (c) 2023 Sony Corporation / Snild Dolkow
+ Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow
+ Copyright (c) 2024 Berkay Eren Ürün
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@@ -210,7 +211,7 @@ typedef char ICHAR;
#endif
/* Round up n to be a multiple of sz, where sz is a power of 2. */
-#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1))
+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
/* Do safe (NULL-aware) pointer arithmetic */
#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
@@ -248,7 +249,7 @@ static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
it odd, since odd numbers are always relative prime to a power of 2.
*/
#define SECOND_HASH(hash, mask, power) \
- ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
+ ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
#define PROBE_STEP(hash, mask, power) \
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
@@ -294,7 +295,7 @@ typedef struct {
The name of the element is stored in both the document and API
encodings. The memory buffer 'buf' is a separately-allocated
memory area which stores the name. During the XML_Parse()/
- XMLParseBuffer() when the element is open, the memory for the 'raw'
+ XML_ParseBuffer() when the element is open, the memory for the 'raw'
version of the name (in the document encoding) is shared with the
document buffer. If the element is open across calls to
XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
@@ -629,8 +630,14 @@ static unsigned long getDebugLevel(const char *variableName,
? 0 \
: ((*((pool)->ptr)++ = c), 1))
-XML_Bool g_reparseDeferralEnabledDefault = XML_TRUE; // write ONLY in runtests.c
-unsigned int g_parseAttempts = 0; // used for testing only
+#if ! defined(XML_TESTING)
+const
+#endif
+ XML_Bool g_reparseDeferralEnabledDefault
+ = XML_TRUE; // write ONLY in runtests.c
+#if defined(XML_TESTING)
+unsigned int g_bytesScanned = 0; // used for testing only
+#endif
struct XML_ParserStruct {
/* The first member must be m_userData so that the XML_GetUserData
@@ -1017,7 +1024,9 @@ callProcessor(XML_Parser parser, const char *start, const char *end,
return XML_ERROR_NONE;
}
}
- g_parseAttempts += 1;
+#if defined(XML_TESTING)
+ g_bytesScanned += (unsigned)have_now;
+#endif
const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr);
if (ret == XML_ERROR_NONE) {
// if we consumed nothing, remember what we had on this parse attempt.
@@ -2030,6 +2039,12 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
if (parser == NULL)
return XML_STATUS_ERROR;
+
+ if (len < 0) {
+ parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
+ return XML_STATUS_ERROR;
+ }
+
switch (parser->m_parsingStatus.parsing) {
case XML_SUSPENDED:
parser->m_errorCode = XML_ERROR_SUSPENDED;
@@ -5838,18 +5853,17 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
/* Set a safe default value in case 'next' does not get set */
next = textStart;
-#ifdef XML_DTD
if (entity->is_param) {
int tok
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
tok, next, &next, XML_FALSE, XML_FALSE,
XML_ACCOUNT_ENTITY_EXPANSION);
- } else
-#endif /* XML_DTD */
+ } else {
result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
textStart, textEnd, &next, XML_FALSE,
XML_ACCOUNT_ENTITY_EXPANSION);
+ }
if (result == XML_ERROR_NONE) {
if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
@@ -5886,18 +5900,17 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
/* Set a safe default value in case 'next' does not get set */
next = textStart;
-#ifdef XML_DTD
if (entity->is_param) {
int tok
= XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
tok, next, &next, XML_FALSE, XML_TRUE,
XML_ACCOUNT_ENTITY_EXPANSION);
- } else
-#endif /* XML_DTD */
+ } else {
result = doContent(parser, openEntity->startTagLevel,
parser->m_internalEncoding, textStart, textEnd, &next,
XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
+ }
if (result != XML_ERROR_NONE)
return result;
@@ -5924,7 +5937,6 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
return XML_ERROR_NONE;
}
-#ifdef XML_DTD
if (entity->is_param) {
int tok;
parser->m_processor = prologProcessor;
@@ -5932,9 +5944,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
(XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
XML_ACCOUNT_DIRECT);
- } else
-#endif /* XML_DTD */
- {
+ } else {
parser->m_processor = contentProcessor;
/* see externalEntityContentProcessor vs contentProcessor */
result = doContent(parser, parser->m_parentParser ? 1 : 0,
@@ -6232,7 +6242,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
dtd->keepProcessing = dtd->standalone;
goto endEntityValue;
}
- if (entity->open) {
+ if (entity->open || (entity == parser->m_declEntity)) {
if (enc == parser->m_encoding)
parser->m_eventPtr = entityTextPtr;
result = XML_ERROR_RECURSIVE_ENTITY_REF;
@@ -7008,6 +7018,16 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
if (! newE)
return 0;
if (oldE->nDefaultAtts) {
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((size_t)oldE->nDefaultAtts
+ > ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) {
+ return 0;
+ }
+#endif
newE->defaultAtts
= ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
if (! newE->defaultAtts) {
@@ -7550,6 +7570,15 @@ nextScaffoldPart(XML_Parser parser) {
int next;
if (! dtd->scaffIndex) {
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if (parser->m_groupSize > ((size_t)(-1) / sizeof(int))) {
+ return -1;
+ }
+#endif
dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
if (! dtd->scaffIndex)
return -1;
@@ -7779,6 +7808,8 @@ copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
static float
accountingGetCurrentAmplification(XML_Parser rootParser) {
+ // 1.........1.........12 => 22
+ const size_t lenOfShortestInclude = sizeof("") - 1;
const XmlBigCount countBytesOutput
= rootParser->m_accounting.countBytesDirect
+ rootParser->m_accounting.countBytesIndirect;
@@ -7786,7 +7817,9 @@ accountingGetCurrentAmplification(XML_Parser rootParser) {
= rootParser->m_accounting.countBytesDirect
? (countBytesOutput
/ (float)(rootParser->m_accounting.countBytesDirect))
- : 1.0f;
+ : ((lenOfShortestInclude
+ + rootParser->m_accounting.countBytesIndirect)
+ / (float)lenOfShortestInclude);
assert(! rootParser->m_parentParser);
return amplificationFactor;
}
diff --git a/contrib/expat/tests/Makefile.am b/contrib/expat/tests/Makefile.am
index f949fe7f1ab..d25376be541 100644
--- a/contrib/expat/tests/Makefile.am
+++ b/contrib/expat/tests/Makefile.am
@@ -6,9 +6,10 @@
# \___/_/\_\ .__/ \__,_|\__|
# |_| XML parser
#
-# Copyright (c) 2017-2023 Sebastian Pipping
+# Copyright (c) 2017-2024 Sebastian Pipping
# Copyright (c) 2017-2022 Rhodri James
# Copyright (c) 2020 Jeffrey Walton
+# Copyright (c) 2024 Dag-Erling Smørgrav
# Licensed under the MIT license:
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -32,7 +33,7 @@
SUBDIRS = . benchmark
-AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(srcdir)/../lib
+AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(srcdir)/../lib -DXML_TESTING
check_PROGRAMS = runtests runtests_cxx
TESTS = runtests runtests_cxx
@@ -72,8 +73,8 @@ runtests_cxx_SOURCES = \
runtests_cxx.cpp \
structdata_cxx.cpp
-runtests_LDADD = ../lib/libexpatinternal.la
-runtests_cxx_LDADD = ../lib/libexpatinternal.la
+runtests_LDADD = ../lib/libtestpat.la
+runtests_cxx_LDADD = ../lib/libtestpat.la
runtests_LDFLAGS = @AM_LDFLAGS@ @LIBM@
runtests_cxx_LDFLAGS = @AM_LDFLAGS@ @LIBM@
@@ -92,7 +93,7 @@ EXTRA_DIST = \
structdata.h \
minicheck.h \
memcheck.h \
- README.txt \
+ README.md \
udiffer.py \
xmltest.log.expected \
xmltest.sh
diff --git a/contrib/expat/tests/Makefile.in b/contrib/expat/tests/Makefile.in
index 4c4fd928e3c..eb00a068cbd 100644
--- a/contrib/expat/tests/Makefile.in
+++ b/contrib/expat/tests/Makefile.in
@@ -22,9 +22,10 @@
# \___/_/\_\ .__/ \__,_|\__|
# |_| XML parser
#
-# Copyright (c) 2017-2023 Sebastian Pipping
+# Copyright (c) 2017-2024 Sebastian Pipping
# Copyright (c) 2017-2022 Rhodri James
# Copyright (c) 2020 Jeffrey Walton
+# Copyright (c) 2024 Dag-Erling Smørgrav
# Licensed under the MIT license:
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -151,7 +152,7 @@ am_runtests_OBJECTS = acc_tests.$(OBJEXT) alloc_tests.$(OBJEXT) \
nsalloc_tests.$(OBJEXT) runtests.$(OBJEXT) \
structdata.$(OBJEXT)
runtests_OBJECTS = $(am_runtests_OBJECTS)
-runtests_DEPENDENCIES = ../lib/libexpatinternal.la
+runtests_DEPENDENCIES = ../lib/libtestpat.la
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
@@ -168,7 +169,7 @@ am_runtests_cxx_OBJECTS = acc_tests_cxx.$(OBJEXT) \
ns_tests_cxx.$(OBJEXT) runtests_cxx.$(OBJEXT) \
structdata_cxx.$(OBJEXT)
runtests_cxx_OBJECTS = $(am_runtests_cxx_OBJECTS)
-runtests_cxx_DEPENDENCIES = ../lib/libexpatinternal.la
+runtests_cxx_DEPENDENCIES = ../lib/libtestpat.la
runtests_cxx_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(runtests_cxx_LDFLAGS) $(LDFLAGS) -o $@
@@ -485,7 +486,7 @@ TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in \
$(top_srcdir)/conftools/depcomp \
- $(top_srcdir)/conftools/test-driver
+ $(top_srcdir)/conftools/test-driver README.md
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -515,7 +516,7 @@ am__relativize = \
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@
-AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(srcdir)/../lib
+AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(srcdir)/../lib -DXML_TESTING
AM_CXXFLAGS = @AM_CXXFLAGS@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AM_LDFLAGS = @AM_LDFLAGS@
@@ -602,6 +603,7 @@ RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
+SIZEOF_VOID_P = @SIZEOF_VOID_P@
SO_MAJOR = @SO_MAJOR@
SO_MINOR = @SO_MINOR@
SO_PATCH = @SO_PATCH@
@@ -615,7 +617,6 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_cv_sizeof_void_p = @ac_cv_sizeof_void_p@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -698,8 +699,8 @@ runtests_cxx_SOURCES = \
runtests_cxx.cpp \
structdata_cxx.cpp
-runtests_LDADD = ../lib/libexpatinternal.la
-runtests_cxx_LDADD = ../lib/libexpatinternal.la
+runtests_LDADD = ../lib/libtestpat.la
+runtests_cxx_LDADD = ../lib/libtestpat.la
runtests_LDFLAGS = @AM_LDFLAGS@ @LIBM@
runtests_cxx_LDFLAGS = @AM_LDFLAGS@ @LIBM@
EXTRA_DIST = \
@@ -716,7 +717,7 @@ EXTRA_DIST = \
structdata.h \
minicheck.h \
memcheck.h \
- README.txt \
+ README.md \
udiffer.py \
xmltest.log.expected \
xmltest.sh
diff --git a/contrib/expat/tests/README.md b/contrib/expat/tests/README.md
new file mode 100644
index 00000000000..010ca95e9e2
--- /dev/null
+++ b/contrib/expat/tests/README.md
@@ -0,0 +1,11 @@
+This directory contains the test suite for Expat. The tests provide
+general unit testing and regression coverage. The tests are not
+expected to be useful examples of Expat usage; see the
+[examples](../examples) directory for that.
+
+The Expat tests use a partial internal implementation of the
+[Check](https://libcheck.github.io/check/) unit testing framework for
+C.
+
+Expat must be built and, on some platforms, installed, before the
+tests can be run.
diff --git a/contrib/expat/tests/README.txt b/contrib/expat/tests/README.txt
deleted file mode 100644
index 30e1d4dabe8..00000000000
--- a/contrib/expat/tests/README.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This directory contains the (fledgling) test suite for Expat. The
-tests provide general unit testing and regression coverage. The tests
-are not expected to be useful examples of Expat usage; see the
-examples/ directory for that.
-
-The Expat tests use a partial internal implementation of the "Check"
-unit testing framework for C. More information on Check can be found at:
-
- http://check.sourceforge.net/
-
-Expat must be built and, depending on platform, must be installed, before "make check" can be executed.
-
-This test suite can all change in a later version.
diff --git a/contrib/expat/tests/acc_tests.c b/contrib/expat/tests/acc_tests.c
index e1c4b7f7eb5..f193aa58a49 100644
--- a/contrib/expat/tests/acc_tests.c
+++ b/contrib/expat/tests/acc_tests.c
@@ -378,6 +378,63 @@ START_TEST(test_helper_unsigned_char_to_printable) {
fail("unsignedCharToPrintable result mistaken");
}
END_TEST
+
+START_TEST(test_amplification_isolated_external_parser) {
+ // NOTE: Length 44 is precisely twice the length of ""
+ // (22) that is used in function accountingGetCurrentAmplification in
+ // xmlparse.c.
+ // 1.........1.........1.........1.........1..4 => 44
+ const char doc[] = "";
+ const int docLen = (int)sizeof(doc) - 1;
+ const float maximumToleratedAmplification = 2.0f;
+
+ struct TestCase {
+ int offsetOfThreshold;
+ enum XML_Status expectedStatus;
+ };
+
+ struct TestCase cases[] = {
+ {-2, XML_STATUS_ERROR}, {-1, XML_STATUS_ERROR}, {0, XML_STATUS_ERROR},
+ {+1, XML_STATUS_OK}, {+2, XML_STATUS_OK},
+ };
+
+ for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
+ const int offsetOfThreshold = cases[i].offsetOfThreshold;
+ const enum XML_Status expectedStatus = cases[i].expectedStatus;
+ const unsigned long long activationThresholdBytes
+ = docLen + offsetOfThreshold;
+
+ set_subtest("offsetOfThreshold=%d, expectedStatus=%d", offsetOfThreshold,
+ expectedStatus);
+
+ XML_Parser parser = XML_ParserCreate(NULL);
+ assert_true(parser != NULL);
+
+ assert_true(XML_SetBillionLaughsAttackProtectionMaximumAmplification(
+ parser, maximumToleratedAmplification)
+ == XML_TRUE);
+ assert_true(XML_SetBillionLaughsAttackProtectionActivationThreshold(
+ parser, activationThresholdBytes)
+ == XML_TRUE);
+
+ XML_Parser ext_parser = XML_ExternalEntityParserCreate(parser, NULL, NULL);
+ assert_true(ext_parser != NULL);
+
+ const enum XML_Status actualStatus
+ = _XML_Parse_SINGLE_BYTES(ext_parser, doc, docLen, XML_TRUE);
+
+ assert_true(actualStatus == expectedStatus);
+ if (actualStatus != XML_STATUS_OK) {
+ assert_true(XML_GetErrorCode(ext_parser)
+ == XML_ERROR_AMPLIFICATION_LIMIT_BREACH);
+ }
+
+ XML_ParserFree(ext_parser);
+ XML_ParserFree(parser);
+ }
+}
+END_TEST
+
#endif // XML_GE == 1
void
@@ -390,6 +447,8 @@ make_accounting_test_case(Suite *s) {
tcase_add_test(tc_accounting, test_accounting_precision);
tcase_add_test(tc_accounting, test_billion_laughs_attack_protection_api);
tcase_add_test(tc_accounting, test_helper_unsigned_char_to_printable);
+ tcase_add_test__ifdef_xml_dtd(tc_accounting,
+ test_amplification_isolated_external_parser);
#else
UNUSED_P(s);
#endif /* XML_GE == 1 */
diff --git a/contrib/expat/tests/basic_tests.c b/contrib/expat/tests/basic_tests.c
index 7112a440187..0d97b1090c7 100644
--- a/contrib/expat/tests/basic_tests.c
+++ b/contrib/expat/tests/basic_tests.c
@@ -1202,6 +1202,49 @@ START_TEST(test_wfc_no_recursive_entity_refs) {
}
END_TEST
+START_TEST(test_recursive_external_parameter_entity_2) {
+ struct TestCase {
+ const char *doc;
+ enum XML_Status expectedStatus;
+ };
+
+ struct TestCase cases[] = {
+ {"", XML_STATUS_ERROR},
+ {""
+ "",
+ XML_STATUS_ERROR},
+ {""
+ "",
+ XML_STATUS_OK},
+ {"", XML_STATUS_OK},
+ };
+
+ for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
+ const char *const doc = cases[i].doc;
+ const enum XML_Status expectedStatus = cases[i].expectedStatus;
+ set_subtest("%s", doc);
+
+ XML_Parser parser = XML_ParserCreate(NULL);
+ assert_true(parser != NULL);
+
+ XML_Parser ext_parser = XML_ExternalEntityParserCreate(parser, NULL, NULL);
+ assert_true(ext_parser != NULL);
+
+ const enum XML_Status actualStatus
+ = _XML_Parse_SINGLE_BYTES(ext_parser, doc, (int)strlen(doc), XML_TRUE);
+
+ assert_true(actualStatus == expectedStatus);
+ if (actualStatus != XML_STATUS_OK) {
+ assert_true(XML_GetErrorCode(ext_parser)
+ == XML_ERROR_RECURSIVE_ENTITY_REF);
+ }
+
+ XML_ParserFree(ext_parser);
+ XML_ParserFree(parser);
+ }
+}
+END_TEST
+
/* Test incomplete external entities are faulted */
START_TEST(test_ext_entity_invalid_parse) {
const char *text = "";
+ for (int isFinal = 0; isFinal < 2; isFinal++) {
+ set_subtest("isFinal=%d", isFinal);
+
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
+ fail("There was not supposed to be any initial parse error.");
+
+ const enum XML_Status status = XML_Parse(parser, doc, -1, isFinal);
+
+ if (status != XML_STATUS_ERROR)
+ fail("Negative len was expected to fail the parse but did not.");
+
+ if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
+ fail("Parse error does not match XML_ERROR_INVALID_ARGUMENT.");
+
+ XML_ParserFree(parser);
+ }
+}
+END_TEST
+
+/* Test XML_ParseBuffer for len < 0 */
+START_TEST(test_negative_len_parse_buffer) {
+ const char *const doc = "";
+ for (int isFinal = 0; isFinal < 2; isFinal++) {
+ set_subtest("isFinal=%d", isFinal);
+
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
+ fail("There was not supposed to be any initial parse error.");
+
+ void *const buffer = XML_GetBuffer(parser, (int)strlen(doc));
+
+ if (buffer == NULL)
+ fail("XML_GetBuffer failed.");
+
+ memcpy(buffer, doc, strlen(doc));
+
+ const enum XML_Status status = XML_ParseBuffer(parser, -1, isFinal);
+
+ if (status != XML_STATUS_ERROR)
+ fail("Negative len was expected to fail the parse but did not.");
+
+ if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
+ fail("Parse error does not match XML_ERROR_INVALID_ARGUMENT.");
+
+ XML_ParserFree(parser);
+ }
+}
+END_TEST
+
/* Test odd corners of the XML_GetBuffer interface */
static enum XML_Status
get_feature(enum XML_FeatureEnum feature_id, long *presult) {
@@ -5202,13 +5300,7 @@ START_TEST(test_nested_entity_suspend) {
END_TEST
/* Regression test for quadratic parsing on large tokens */
-START_TEST(test_big_tokens_take_linear_time) {
- const char *const too_slow_failure_message
- = "Compared to the baseline runtime of the first test, this test has a "
- "slowdown of more than . "
- "Please keep increasing the value by 1 until it reliably passes the "
- "test on your hardware and open a bug sharing that number with us. "
- "Thanks in advance!";
+START_TEST(test_big_tokens_scale_linearly) {
const struct {
const char *pre;
const char *post;
@@ -5220,65 +5312,57 @@ START_TEST(test_big_tokens_take_linear_time) {
{"<", "/>"}, // big elem name, used to be O(N²)
};
const int num_cases = sizeof(text) / sizeof(text[0]);
- // For the test we need a value that is:
- // (1) big enough that the test passes reliably (avoiding flaky tests), and
- // (2) small enough that the test actually catches regressions.
- const int max_slowdown = 15;
char aaaaaa[4096];
const int fillsize = (int)sizeof(aaaaaa);
const int fillcount = 100;
+ const unsigned approx_bytes = fillsize * fillcount; // ignore pre/post.
+ const unsigned max_factor = 4;
+ const unsigned max_scanned = max_factor * approx_bytes;
memset(aaaaaa, 'a', fillsize);
if (! g_reparseDeferralEnabledDefault) {
return; // heuristic is disabled; we would get O(n^2) and fail.
}
-#if ! defined(__linux__)
- if (CLOCKS_PER_SEC < 100000) {
- // Skip this test if clock() doesn't have reasonably good resolution.
- // This workaround is primarily targeting Windows and FreeBSD, since
- // XSI requires the value to be 1.000.000 (10x the condition here), and
- // we want to be very sure that at least one platform in CI can catch
- // regressions (through a failing test).
- return;
- }
-#endif
- clock_t baseline = 0;
for (int i = 0; i < num_cases; ++i) {
XML_Parser parser = XML_ParserCreate(NULL);
assert_true(parser != NULL);
enum XML_Status status;
- set_subtest("max_slowdown=%d text=\"%saaaaaa%s\"", max_slowdown,
- text[i].pre, text[i].post);
- const clock_t start = clock();
+ set_subtest("text=\"%saaaaaa%s\"", text[i].pre, text[i].post);
// parse the start text
+ g_bytesScanned = 0;
status = _XML_Parse_SINGLE_BYTES(parser, text[i].pre,
(int)strlen(text[i].pre), XML_FALSE);
if (status != XML_STATUS_OK) {
xml_failure(parser);
}
+
// parse lots of 'a', failing the test early if it takes too long
+ unsigned past_max_count = 0;
for (int f = 0; f < fillcount; ++f) {
status = _XML_Parse_SINGLE_BYTES(parser, aaaaaa, fillsize, XML_FALSE);
if (status != XML_STATUS_OK) {
xml_failure(parser);
}
- // i == 0 means we're still calculating the baseline value
- if (i > 0) {
- const clock_t now = clock();
- const clock_t clocks_so_far = now - start;
- const int slowdown = clocks_so_far / baseline;
- if (slowdown >= max_slowdown) {
- fprintf(
- stderr,
- "fill#%d: clocks_so_far=%d baseline=%d slowdown=%d max_slowdown=%d\n",
- f, (int)clocks_so_far, (int)baseline, slowdown, max_slowdown);
- fail(too_slow_failure_message);
- }
+ if (g_bytesScanned > max_scanned) {
+ // We're not done, and have already passed the limit -- the test will
+ // definitely fail. This block allows us to save time by failing early.
+ const unsigned pushed
+ = (unsigned)strlen(text[i].pre) + (f + 1) * fillsize;
+ fprintf(
+ stderr,
+ "after %d/%d loops: pushed=%u scanned=%u (factor ~%.2f) max_scanned: %u (factor ~%u)\n",
+ f + 1, fillcount, pushed, g_bytesScanned,
+ g_bytesScanned / (double)pushed, max_scanned, max_factor);
+ past_max_count++;
+ // We are failing, but allow a few log prints first. If we don't reach
+ // a count of five, the test will fail after the loop instead.
+ assert_true(past_max_count < 5);
}
}
+
// parse the end text
status = _XML_Parse_SINGLE_BYTES(parser, text[i].post,
(int)strlen(text[i].post), XML_TRUE);
@@ -5286,18 +5370,14 @@ START_TEST(test_big_tokens_take_linear_time) {
xml_failure(parser);
}
- // how long did it take in total?
- const clock_t end = clock();
- const clock_t taken = end - start;
- if (i == 0) {
- assert_true(taken > 0); // just to make sure we don't div-by-0 later
- baseline = taken;
- }
- const int slowdown = taken / baseline;
- if (slowdown >= max_slowdown) {
- fprintf(stderr, "taken=%d baseline=%d slowdown=%d max_slowdown=%d\n",
- (int)taken, (int)baseline, slowdown, max_slowdown);
- fail(too_slow_failure_message);
+ assert_true(g_bytesScanned > approx_bytes); // or the counter isn't working
+ if (g_bytesScanned > max_scanned) {
+ fprintf(
+ stderr,
+ "after all input: scanned=%u (factor ~%.2f) max_scanned: %u (factor ~%u)\n",
+ g_bytesScanned, g_bytesScanned / (double)approx_bytes, max_scanned,
+ max_factor);
+ fail("scanned too many bytes");
}
XML_ParserFree(parser);
@@ -5774,19 +5854,17 @@ START_TEST(test_varying_buffer_fills) {
fillsize[2], fillsize[3]);
XML_Parser parser = XML_ParserCreate(NULL);
assert_true(parser != NULL);
- g_parseAttempts = 0;
CharData storage;
CharData_Init(&storage);
XML_SetUserData(parser, &storage);
XML_SetStartElementHandler(parser, start_element_event_handler);
+ g_bytesScanned = 0;
int worstcase_bytes = 0; // sum of (buffered bytes at each XML_Parse call)
- int scanned_bytes = 0; // sum of (buffered bytes at each actual parse)
int offset = 0;
while (*fillsize >= 0) {
assert_true(offset + *fillsize <= document_length); // or test is invalid
- const unsigned attempts_before = g_parseAttempts;
const enum XML_Status status
= XML_Parse(parser, &document[offset], *fillsize, XML_FALSE);
if (status != XML_STATUS_OK) {
@@ -5796,28 +5874,20 @@ START_TEST(test_varying_buffer_fills) {
fillsize++;
assert_true(offset <= INT_MAX - worstcase_bytes); // avoid overflow
worstcase_bytes += offset; // we might've tried to parse all pending bytes
- if (g_parseAttempts != attempts_before) {
- assert_true(g_parseAttempts == attempts_before + 1); // max 1/XML_Parse
- assert_true(offset <= INT_MAX - scanned_bytes); // avoid overflow
- scanned_bytes += offset; // we *did* try to parse all pending bytes
- }
}
assert_true(storage.count == 1); // the big token should've been parsed
- assert_true(scanned_bytes > 0); // test-the-test: does our counter work?
+ assert_true(g_bytesScanned > 0); // test-the-test: does our counter work?
if (g_reparseDeferralEnabledDefault) {
// heuristic is enabled; some XML_Parse calls may have deferred reparsing
- const int max_bytes_scanned = -*fillsize;
- if (scanned_bytes > max_bytes_scanned) {
+ const unsigned max_bytes_scanned = -*fillsize;
+ if (g_bytesScanned > max_bytes_scanned) {
fprintf(stderr,
- "bytes scanned in parse attempts: actual=%d limit=%d \n",
- scanned_bytes, max_bytes_scanned);
+ "bytes scanned in parse attempts: actual=%u limit=%u \n",
+ g_bytesScanned, max_bytes_scanned);
fail("too many bytes scanned in parse attempts");
}
- assert_true(scanned_bytes <= worstcase_bytes);
- } else {
- // heuristic is disabled; every XML_Parse() will have reparsed
- assert_true(scanned_bytes == worstcase_bytes);
}
+ assert_true(g_bytesScanned <= (unsigned)worstcase_bytes);
XML_ParserFree(parser);
}
@@ -5940,6 +6010,8 @@ make_basic_test_case(Suite *s) {
tcase_add_test__ifdef_xml_dtd(tc_basic, test_user_parameters);
tcase_add_test__ifdef_xml_dtd(tc_basic, test_ext_entity_ref_parameter);
tcase_add_test(tc_basic, test_empty_parse);
+ tcase_add_test(tc_basic, test_negative_len_parse);
+ tcase_add_test(tc_basic, test_negative_len_parse_buffer);
tcase_add_test(tc_basic, test_get_buffer_1);
tcase_add_test(tc_basic, test_get_buffer_2);
#if XML_CONTEXT_BYTES > 0
@@ -5972,6 +6044,8 @@ make_basic_test_case(Suite *s) {
tcase_add_test__ifdef_xml_dtd(tc_basic, test_skipped_parameter_entity);
tcase_add_test__ifdef_xml_dtd(tc_basic,
test_recursive_external_parameter_entity);
+ tcase_add_test__ifdef_xml_dtd(tc_basic,
+ test_recursive_external_parameter_entity_2);
tcase_add_test(tc_basic, test_undefined_ext_entity_in_external_dtd);
tcase_add_test(tc_basic, test_suspend_xdecl);
tcase_add_test(tc_basic, test_abort_epilog);
@@ -6065,7 +6139,7 @@ make_basic_test_case(Suite *s) {
tcase_add_test__ifdef_xml_dtd(tc_basic,
test_pool_integrity_with_unfinished_attr);
tcase_add_test__if_xml_ge(tc_basic, test_nested_entity_suspend);
- tcase_add_test(tc_basic, test_big_tokens_take_linear_time);
+ tcase_add_test(tc_basic, test_big_tokens_scale_linearly);
tcase_add_test(tc_basic, test_set_reparse_deferral);
tcase_add_test(tc_basic, test_reparse_deferral_is_inherited);
tcase_add_test(tc_basic, test_set_reparse_deferral_on_null_parser);
diff --git a/contrib/expat/tests/benchmark/Makefile.in b/contrib/expat/tests/benchmark/Makefile.in
index 18f3b7bf7bf..d0e6d0769db 100644
--- a/contrib/expat/tests/benchmark/Makefile.in
+++ b/contrib/expat/tests/benchmark/Makefile.in
@@ -303,6 +303,7 @@ RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
+SIZEOF_VOID_P = @SIZEOF_VOID_P@
SO_MAJOR = @SO_MAJOR@
SO_MINOR = @SO_MINOR@
SO_PATCH = @SO_PATCH@
@@ -316,7 +317,6 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_cv_sizeof_void_p = @ac_cv_sizeof_void_p@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
diff --git a/contrib/expat/tests/misc_tests.c b/contrib/expat/tests/misc_tests.c
index b5212f58a5b..2ee9320b139 100644
--- a/contrib/expat/tests/misc_tests.c
+++ b/contrib/expat/tests/misc_tests.c
@@ -208,7 +208,7 @@ START_TEST(test_misc_version) {
if (! versions_equal(&read_version, &parsed_version))
fail("Version mismatch");
- if (xcstrcmp(version_text, XCS("expat_2.6.0"))) /* needs bump on releases */
+ if (xcstrcmp(version_text, XCS("expat_2.6.3"))) /* needs bump on releases */
fail("XML_*_VERSION in expat.h out of sync?\n");
}
END_TEST
diff --git a/contrib/expat/xmlwf/Makefile.in b/contrib/expat/xmlwf/Makefile.in
index a8a84dc4e6d..480fd3e0410 100644
--- a/contrib/expat/xmlwf/Makefile.in
+++ b/contrib/expat/xmlwf/Makefile.in
@@ -311,6 +311,7 @@ RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
+SIZEOF_VOID_P = @SIZEOF_VOID_P@
SO_MAJOR = @SO_MAJOR@
SO_MINOR = @SO_MINOR@
SO_PATCH = @SO_PATCH@
@@ -324,7 +325,6 @@ ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-ac_cv_sizeof_void_p = @ac_cv_sizeof_void_p@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@