This is an automated email from the ASF dual-hosted git repository.
mseidel pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/openoffice.git
The following commit(s) were added to refs/heads/trunk by this push:
new e288e1255e Remove unused patch
e288e1255e is described below
commit e288e1255ead18ac4791577314bdb194e6de74ce
Author: mseidel <[email protected]>
AuthorDate: Mon Apr 10 20:12:54 2023 +0200
Remove unused patch
---
main/expat/expat-2.2.10.patch | 3688 -----------------------------------------
1 file changed, 3688 deletions(-)
diff --git a/main/expat/expat-2.2.10.patch b/main/expat/expat-2.2.10.patch
deleted file mode 100644
index 2690f58c52..0000000000
--- a/main/expat/expat-2.2.10.patch
+++ /dev/null
@@ -1,3688 +0,0 @@
---- misc/expat-2.2.10/lib/makefile.mk Wed Aug 20 14:33:55 2008
-+++ misc/build/expat-2.2.10/lib/makefile.mk Wed Aug 20 14:26:42 2008
-@@ -1 +1,79 @@
--dummy
-+#**************************************************************
-+#
-+# Licensed to the Apache Software Foundation (ASF) under one
-+# or more contributor license agreements. See the NOTICE file
-+# distributed with this work for additional information
-+# regarding copyright ownership. The ASF licenses this file
-+# to you under the Apache License, Version 2.0 (the
-+# "License"); you may not use this file except in compliance
-+# with the License. You may obtain a copy of the License at
-+#
-+# http://www.apache.org/licenses/LICENSE-2.0
-+#
-+# Unless required by applicable law or agreed to in writing,
-+# software distributed under the License is distributed on an
-+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-+# KIND, either express or implied. See the License for the
-+# specific language governing permissions and limitations
-+# under the License.
-+#
-+#**************************************************************
-+PRJ=..$/..$/..$/..$/..
-+
-+PRJNAME=expat
-+TARGET=expat
-+LIBTARGET=NO
-+EXTERNAL_WARNINGS_NOT_ERRORS=TRUE
-+
-+# --- Settings -----------------------------------------------------
-+.INCLUDE : settings.mk
-+# --- Files --------------------------------------------------------
-+
-+CFLAGS+=-I..
-+
-+.IF "$(OS)"=="WNT"
-+CDEFS+=-DWIN32
-+.ELSE
-+CDEFS+=-DHAVE_EXPAT_CONFIG_H
-+.ENDIF
-+
-+.IF "$(OS)"=="MACOSX" && "$(SYSBASE)"!=""
-+CDEFS+=-DHAVE_MEMMOVE -DHAVE_BCOPY
-+.ENDIF # "$(OS)"=="MACOSX"
-+
-+SECOND_BUILD=UNICODE
-+UNICODE_SLOFILES=$(SLO)$/xmlparse.obj
-+UNICODECDEFS+=-DXML_UNICODE
-+
-+LIB1ARCHIV=$(LB)$/libascii_$(TARGET)_xmlparse.a
-+LIB1TARGET=$(SLB)$/ascii_$(TARGET)_xmlparse.lib
-+LIB1OBJFILES=$(SLO)$/xmlparse.obj
-+
-+LIB2ARCHIV=$(LB)$/lib$(TARGET)_xmlparse.a
-+LIB2TARGET=$(SLB)$/$(TARGET)_xmlparse.lib
-+LIB2OBJFILES =$(REAL_UNICODE_SLOFILES)
-+
-+LIB3ARCHIV=$(LB)$/lib$(TARGET)_xmltok.a
-+LIB3TARGET=$(SLB)$/$(TARGET)_xmltok.lib
-+LIB3OBJFILES=$(SLO)$/xmlrole.obj $(SLO)$/xmltok.obj
-+
-+.IF "$(BUILD_X64)"!=""
-+# ---------------- X64 stuff special ---------------------
-+# use UNICODE only because shell/shlxthandler
-+# doesn't link against ascii_expat_xmlparse
-+#---------------------------------------------------------
-+SLOFILES_X64=$(SLO_X64)$/xmlparse.obj \
-+ $(SLO_X64)$/xmlrole.obj \
-+ $(SLO_X64)$/xmltok.obj
-+CDEFS_X64+=-DXML_UNICODE -DWIN32
-+CFLAGS_X64+=-I..
-+LIB1TARGET_X64=$(SLB_X64)$/$(TARGET)_xmlparse.lib
-+LIB1OBJFILES_X64=$(SLO_X64)$/xmlparse.obj
-+LIB2TARGET_X64=$(SLB_X64)$/$(TARGET)_xmltok.lib
-+LIB2OBJFILES_X64=$(SLO_X64)$/xmlrole.obj $(SLO_X64)$/xmltok.obj
-+.ENDIF # "$(BUILD_X64)"!=""
-+
-+# --- Targets ------------------------------------------------------
-+.INCLUDE : set_wntx64.mk
-+.INCLUDE : target.mk
-+.INCLUDE : tg_wntx64.mk
-diff -ru expat-2.2.10/Changes misc/build/expat-2.2.10/Changes
---- misc/expat-2.2.10/Changes 2020-10-03 11:14:57.000000000 -0400
-+++ misc/build/expat-2.2.10/Changes 2022-10-11 18:20:29.490872000 -0400
-@@ -2,6 +2,49 @@
- https://github.com/libexpat/libexpat/labels/help%20wanted
- If you can help, please get in touch. Thanks!
-
-+Release 2.2.13 XXX XXXXX XX XXXX
-+ Security fixes:
-+ #629 #640 CVE-2022-40674 -- Heap use-after-free vulnerability in
-+ function doContent. Expected impact is denial of service
-+ or potentially arbitrary code execution.
-+
-+
-+Release 2.2.11 XXX XXXXX XX XXXX
-+ Security fixes:
-+ #34 #466 CVE-2013-0340/CWE-776 -- Protect against billion laughs
attacks
-+ (denial-of-service; flavors targeting CPU time or RAM or
both,
-+ leveraging general entities or parameter entities or both)
-+ by tracking and limiting the input amplification factor
-+ (<amplification> := (<direct> + <indirect>) / <direct>).
-+ By conservative default, amplification up to a factor of
100.0
-+ is tolerated and rejection only starts after 8 MiB of
output bytes
-+ (=<direct> + <indirect>) have been processed.
-+ A new error code XML_ERROR_AMPLIFICATION_LIMIT_BREACH
signals
-+ this condition.
-+ New features:
-+ #34 #466 Add two new API functions to further tighten billion laughs
-+ protection parameters when desired.
-+ - XML_SetBillionLaughsAttackProtectionMaximumAmplification
-+ - XML_SetBillionLaughsAttackProtectionActivationThreshold
-+ Please see file "doc/reference.html" for more details.
-+ If you ever need to increase the defaults for non-attack
XML
-+ payload, please file a bug report with libexpat.
-+ #34 #466 Introduce environment switches
EXPAT_ACCOUNTING_DEBUG=(0|1|2|3)
-+ and EXPAT_ENTITY_DEBUG=(0|1) for runtime debugging of
accounting
-+ and entity processing; specific behavior of these values
may
-+ change in the future.
-+ #34 #466 xmlwf: Add arguments "-a FACTOR" and "-b BYTES" to further
tighten
-+ billion laughs protection parameters when desired.
-+ If you ever need to increase the defaults for non-attack
XML
-+ payload, please file a bug report with libexpat.
-+
-+ Special thanks to:
-+ Nick Wellnhofer
-+ Yury Gribov
-+ and
-+ Clang LeakSan
-+ JetBrains
-+
- Release 2.2.10 Sat October 3 2020
- Bug fixes:
- #390 #395 #398 Fix undefined behavior during parsing caused by
-diff -ru expat-2.2.10/CMakeLists.txt misc/build/expat-2.2.10/CMakeLists.txt
---- expat-2.2.10/CMakeLists.txt 2020-10-03 11:14:57.000000000 -0400
-+++ misc/build/expat-2.2.10/CMakeLists.txt 2021-08-25 18:35:36.883146000
-0400
-@@ -448,14 +448,12 @@
- endif()
- endfunction()
-
-- add_executable(runtests tests/runtests.c ${test_SRCS})
-+ add_executable(runtests tests/runtests.c ${test_SRCS} ${expat_SRCS})
- set_property(TARGET runtests PROPERTY RUNTIME_OUTPUT_DIRECTORY tests)
-- target_link_libraries(runtests expat)
- expat_add_test(runtests $<TARGET_FILE:runtests>)
-
-- add_executable(runtestspp tests/runtestspp.cpp ${test_SRCS})
-+ add_executable(runtestspp tests/runtestspp.cpp ${test_SRCS} ${expat_SRCS})
- set_property(TARGET runtestspp PROPERTY RUNTIME_OUTPUT_DIRECTORY tests)
-- target_link_libraries(runtestspp expat)
- expat_add_test(runtestspp $<TARGET_FILE:runtestspp>)
- endif()
-
-diff -ru expat-2.2.10/doc/Makefile.in misc/build/expat-2.2.10/doc/Makefile.in
---- expat-2.2.10/doc/Makefile.in 2020-10-03 11:37:06.000000000 -0400
-+++ misc/build/expat-2.2.10/doc/Makefile.in 2021-07-18 18:17:02.628168000
-0400
-@@ -1,7 +1,7 @@
--# Makefile.in generated by automake 1.16.2 from Makefile.am.
-+# Makefile.in generated by automake 1.16.1 from Makefile.am.
- # @configure_input@
-
--# Copyright (C) 1994-2020 Free Software Foundation, Inc.
-+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
-
- # This Makefile.in is free software; the Free Software Foundation
- # gives unlimited permission to copy and/or distribute it,
-@@ -314,7 +314,6 @@
- prefix = @prefix@
- program_transform_name = @program_transform_name@
- psdir = @psdir@
--runstatedir = @runstatedir@
- sbindir = @sbindir@
- sharedstatedir = @sharedstatedir@
- srcdir = @srcdir@
-diff -ru expat-2.2.10/doc/reference.html
misc/build/expat-2.2.10/doc/reference.html
---- expat-2.2.10/doc/reference.html 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/doc/reference.html 2021-07-18 17:21:48.691559000
-0400
-@@ -120,6 +120,13 @@
- <li><a href="#XML_GetInputContext">XML_GetInputContext</a></li>
- </ul>
- </li>
-+ <li>
-+ <a href="#billion-laughs">Billion Laughs Attack Protection</a>
-+ <ul>
-+ <li><a
href="#XML_SetBillionLaughsAttackProtectionMaximumAmplification">XML_SetBillionLaughsAttackProtectionMaximumAmplification</a></li>
-+ <li><a
href="#XML_SetBillionLaughsAttackProtectionActivationThreshold">XML_SetBillionLaughsAttackProtectionActivationThreshold</a></li>
-+ </ul>
-+ </li>
- <li><a href="#miscellaneous">Miscellaneous Functions</a>
- <ul>
- <li><a href="#XML_SetUserData">XML_SetUserData</a></li>
-@@ -1998,6 +2005,98 @@
- return NULL.</p>
- </div>
-
-+
-+
-+<h3><a name="billion-laughs">Billion Laughs Attack Protection</a></h3>
-+
-+<p>The functions in this section configure the built-in
-+ protection against various forms of
-+ <a href="https://en.wikipedia.org/wiki/Billion_laughs_attack">billion
laughs attacks</a>.</p>
-+
-+<pre class="fcndec"
id="XML_SetBillionLaughsAttackProtectionMaximumAmplification">
-+/* Added in Expat 2.2.11. */
-+XML_Bool XMLCALL
-+XML_SetBillionLaughsAttackProtectionMaximumAmplification(XML_Parser p,
-+ float
maximumAmplificationFactor);
-+</pre>
-+<div class="fcndef">
-+ <p>
-+ Sets the maximum tolerated amplification factor
-+ for protection against
-+ <a href="https://en.wikipedia.org/wiki/Billion_laughs_attack">billion
laughs attacks</a>
-+ (default: <code>100.0</code>)
-+ of parser <code>p</code> to <code>maximumAmplificationFactor</code>, and
-+ returns <code>XML_TRUE</code> upon success and <code>XML_TRUE</code> upon
error.
-+ </p>
-+
-+ The amplification factor is calculated as ..
-+ <pre>
-+ amplification := (direct + indirect) / direct
-+ </pre>
-+ .. while parsing, whereas
-+ <code>direct</code> is the number of bytes read from the primary document
in parsing and
-+ <code>indirect</code> is the number of bytes added by expanding entities
and reading of external DTD files, combined.
-+
-+ <p>For a call to
<code>XML_SetBillionLaughsAttackProtectionMaximumAmplification</code> to
succeed:</p>
-+ <ul>
-+ <li>parser <code>p</code> must be a non-<code>NULL</code> root parser
(without any parent parsers) and</li>
-+ <li><code>maximumAmplificationFactor</code> must be non-<code>NaN</code>
and greater than or equal to <code>1.0</code>.</li>
-+ </ul>
-+
-+ <p>
-+ <strong>Note:</strong>
-+ If you ever need to increase this value for non-attack payload,
-+ please <a href="https://github.com/libexpat/libexpat/issues">file a bug
report</a>.
-+ </p>
-+
-+ <p>
-+ <strong>Note:</strong>
-+ Peak amplifications
-+ of factor 15,000 for the entire payload and
-+ of factor 30,000 in the middle of parsing
-+ have been observed with small benign files in practice.
-+
-+ So if you do reduce the maximum allowed amplification,
-+ please make sure that the activation threshold is still big enough
-+ to not end up with undesired false positives (i.e. benign files being
rejected).
-+ </p>
-+</div>
-+
-+<pre class="fcndec"
id="XML_SetBillionLaughsAttackProtectionActivationThreshold">
-+/* Added in Expat 2.2.11. */
-+XML_Bool XMLCALL
-+XML_SetBillionLaughsAttackProtectionActivationThreshold(XML_Parser p,
-+ unsigned long long
activationThresholdBytes);
-+</pre>
-+<div class="fcndef">
-+ <p>
-+ Sets number of output bytes (including amplification from entity
expansion and reading DTD files)
-+ needed to activate protection against
-+ <a href="https://en.wikipedia.org/wiki/Billion_laughs_attack">billion
laughs attacks</a>
-+ (default: <code>8 MiB</code>)
-+ of parser <code>p</code> to <code>activationThresholdBytes</code>, and
-+ returns <code>XML_TRUE</code> upon success and <code>XML_TRUE</code> upon
error.
-+ </p>
-+
-+ <p>For a call to
<code>XML_SetBillionLaughsAttackProtectionActivationThreshold</code> to
succeed:</p>
-+ <ul>
-+ <li>parser <code>p</code> must be a non-<code>NULL</code> root parser
(without any parent parsers).</li>
-+ </ul>
-+
-+ <p>
-+ <strong>Note:</strong>
-+ If you ever need to increase this value for non-attack payload,
-+ please <a href="https://github.com/libexpat/libexpat/issues">file a bug
report</a>.
-+ </p>
-+
-+ <p>
-+ <strong>Note:</strong>
-+ Activation thresholds below 4 MiB are known to break support for
-+ <a
href="https://en.wikipedia.org/wiki/Darwin_Information_Typing_Architecture">DITA</a>
1.3 payload
-+ and are hence not recommended.
-+ </p>
-+</div>
-+
- <h3><a name="miscellaneous">Miscellaneous functions</a></h3>
-
- <p>The functions in this section either obtain state information from
-diff -ru expat-2.2.10/doc/xmlwf.xml misc/build/expat-2.2.10/doc/xmlwf.xml
---- expat-2.2.10/doc/xmlwf.xml 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/doc/xmlwf.xml 2021-07-18 17:21:48.692559000
-0400
-@@ -3,7 +3,7 @@
- <!ENTITY dhfirstname "<firstname>Scott</firstname>">
- <!ENTITY dhsurname "<surname>Bronson</surname>">
- <!-- Please adjust the date whenever revising the manpage. -->
-- <!ENTITY dhdate "<date>March 11, 2016</date>">
-+ <!ENTITY dhdate "<date>July 18, 2021</date>">
- <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
- allowed: see man(7), man(1). -->
- <!ENTITY dhsection "<manvolnum>1</manvolnum>">
-@@ -138,6 +138,52 @@
- </para>
-
- <variablelist>
-+
-+ <variablelist>
-+
-+ <varlistentry>
-+ <term><option>-a</option> <replaceable>factor</replaceable></term>
-+ <listitem>
-+ <para>
-+ Sets the maximum tolerated amplification factor
-+ for protection against billion laughs attacks (default: 100.0).
-+ The amplification factor is calculated as ..
-+ </para>
-+ <literallayout>
-+ amplification := (direct + indirect) / direct
-+ </literallayout>
-+ <para>
-+ .. while parsing, whereas
-+ <direct> is the number of bytes read
-+ from the primary document in parsing and
-+ <indirect> is the number of bytes
-+ added by expanding entities and reading of external DTD files,
-+ combined.
-+ </para>
-+ <para>
-+ <emphasis>NOTE</emphasis>:
-+ If you ever need to increase this value for non-attack payload,
-+ please file a bug report.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+
-+ <varlistentry>
-+ <term><option>-b</option> <replaceable>bytes</replaceable></term>
-+ <listitem>
-+ <para>
-+ Sets the number of output bytes (including amplification)
-+ needed to activate protection against billion laughs attacks
-+ (default: 8 MiB).
-+ This can be thought of as an "activation threshold".
-+ </para>
-+ <para>
-+ <emphasis>NOTE</emphasis>:
-+ If you ever need to increase this value for non-attack payload,
-+ please file a bug report.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-
- <varlistentry>
- <term><option>-c</option></term>
-@@ -455,6 +501,7 @@
- <literallayout>
- The Expat home page: http://www.libexpat.org/
- The W3 XML specification: http://www.w3.org/TR/REC-xml
-+Billion laughs attack:
https://en.wikipedia.org/wiki/Billion_laughs_attack
- </literallayout>
-
- </para>
-diff -ru expat-2.2.10/lib/expat.h misc/build/expat-2.2.10/lib/expat.h
---- expat-2.2.10/lib/expat.h 2020-10-03 11:14:57.000000000 -0400
-+++ misc/build/expat-2.2.10/lib/expat.h 2022-10-11 18:20:29.490872000
-0400
-@@ -115,7 +115,10 @@
- XML_ERROR_RESERVED_PREFIX_XMLNS,
- XML_ERROR_RESERVED_NAMESPACE_URI,
- /* Added in 2.2.1. */
-- XML_ERROR_INVALID_ARGUMENT
-+ XML_ERROR_INVALID_ARGUMENT,
-+ /* Added in 2.2.11 */
-+ XML_ERROR_NO_BUFFER,
-+ XML_ERROR_AMPLIFICATION_LIMIT_BREACH
- };
-
- enum XML_Content_Type {
-@@ -997,7 +1000,10 @@
- XML_FEATURE_SIZEOF_XML_LCHAR,
- XML_FEATURE_NS,
- XML_FEATURE_LARGE_SIZE,
-- XML_FEATURE_ATTR_INFO
-+ XML_FEATURE_ATTR_INFO,
-+ /* added in Expat 2.2.11 */
-+ XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
-+ XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT
- /* Additional features must be added to the end of this enum. */
- };
-
-@@ -1010,12 +1016,25 @@
- XMLPARSEAPI(const XML_Feature *)
- XML_GetFeatureList(void);
-
-+
-+#ifdef XML_DTD
-+/* Added in Expat 2.2.11 */
-+XMLPARSEAPI(XML_Bool)
-+XML_SetBillionLaughsAttackProtectionMaximumAmplification(
-+ XML_Parser parser, float maximumAmplificationFactor);
-+
-+/* Added in Expat 2.2.11 */
-+XMLPARSEAPI(XML_Bool)
-+XML_SetBillionLaughsAttackProtectionActivationThreshold(
-+ XML_Parser parser, unsigned long long activationThresholdBytes);
-+#endif
-+
- /* Expat follows the semantic versioning convention.
- See http://semver.org.
- */
- #define XML_MAJOR_VERSION 2
- #define XML_MINOR_VERSION 2
--#define XML_MICRO_VERSION 10
-+#define XML_MICRO_VERSION 13
-
- #ifdef __cplusplus
- }
-diff -ru expat-2.2.10/lib/internal.h misc/build/expat-2.2.10/lib/internal.h
---- expat-2.2.10/lib/internal.h 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/lib/internal.h 2021-07-18 17:21:48.692559000
-0400
-@@ -101,10 +101,47 @@
- # endif
- #endif
-
-+#include <limits.h> // ULONG_MAX
-+
-+#if defined(_WIN32) && ! defined(__USE_MINGW_ANSI_STDIO)
-+# 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
-+# define EXPAT_FMT_ULL(midpart) "%" midpart "llu"
-+# if ! defined(ULONG_MAX)
-+# error Compiler did not define ULONG_MAX for us
-+# elif ULONG_MAX == 18446744073709551615u // 2^64-1
-+# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld"
-+# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu"
-+# else
-+# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
-+# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
-+# endif
-+#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
-+/* NOTE END */
-+
-+#include "expat.h" // so we can use type XML_Parser below
-+
- #ifdef __cplusplus
- extern "C" {
- #endif
-@@ -117,6 +154,11 @@
- void
- _INTERNAL_trim_to_complete_utf8_characters(const char *from,
- const char **fromLimRef);
-+#if defined(XML_DTD)
-+unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
-+unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
-+const char *unsignedCharToPrintable(unsigned char c);
-+#endif
-
- #ifdef __cplusplus
- }
-diff -ru expat-2.2.10/lib/libexpat.def misc/build/expat-2.2.10/lib/libexpat.def
---- expat-2.2.10/lib/libexpat.def 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/lib/libexpat.def 2021-07-18 17:21:48.692559000
-0400
-@@ -76,3 +76,6 @@
- XML_SetHashSalt @67
- ; added with version 2.2.5
- _INTERNAL_trim_to_complete_utf8_characters @68
-+; added with version 2.2.11
-+ XML_SetBillionLaughsAttackProtectionActivationThreshold @69
-+ XML_SetBillionLaughsAttackProtectionMaximumAmplification @70
-\ No newline at end of file
-diff -ru expat-2.2.10/lib/libexpatw.def
misc/build/expat-2.2.10/lib/libexpatw.def
---- expat-2.2.10/lib/libexpatw.def 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/lib/libexpatw.def 2021-07-18 17:21:48.692559000
-0400
-@@ -76,3 +76,6 @@
- XML_SetHashSalt @67
- ; added with version 2.2.5
- _INTERNAL_trim_to_complete_utf8_characters @68
-+; added with version 2.2.11
-+ XML_SetBillionLaughsAttackProtectionActivationThreshold @69
-+ XML_SetBillionLaughsAttackProtectionMaximumAmplification @70
-\ No newline at end of file
-diff -ru expat-2.2.10/lib/Makefile.in misc/build/expat-2.2.10/lib/Makefile.in
---- expat-2.2.10/lib/Makefile.in 2020-10-03 11:37:06.000000000 -0400
-+++ misc/build/expat-2.2.10/lib/Makefile.in 2021-07-18 18:17:02.702168000
-0400
-@@ -1,7 +1,7 @@
--# Makefile.in generated by automake 1.16.2 from Makefile.am.
-+# Makefile.in generated by automake 1.16.1 from Makefile.am.
- # @configure_input@
-
--# Copyright (C) 1994-2020 Free Software Foundation, Inc.
-+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
-
- # This Makefile.in is free software; the Free Software Foundation
- # gives unlimited permission to copy and/or distribute it,
-@@ -372,7 +372,6 @@
- prefix = @prefix@
- program_transform_name = @program_transform_name@
- psdir = @psdir@
--runstatedir = @runstatedir@
- sbindir = @sbindir@
- sharedstatedir = @sharedstatedir@
- srcdir = @srcdir@
-diff -ru expat-2.2.10/lib/xmlparse.c misc/build/expat-2.2.10/lib/xmlparse.c
---- expat-2.2.10/lib/xmlparse.c 2020-10-03 11:14:57.000000000 -0400
-+++ misc/build/expat-2.2.10/lib/xmlparse.c 2022-10-11 18:20:29.491872000
-0400
-@@ -47,6 +47,7 @@
- #include <limits.h> /* UINT_MAX */
- #include <stdio.h> /* fprintf */
- #include <stdlib.h> /* getenv, rand_s */
-+#include <math.h> /* isnan */
-
- #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600)
- /* vs2008/9.0 and earlier lack stdint.h; _MSC_VER 1600 is vs2010/10.0 */
-@@ -73,6 +74,10 @@
-
- #ifdef _WIN32
- # include "winconfig.h"
-+#include <float.h>
-+#ifndef isnan
-+#define isnan _isnan
-+#endif
- #elif defined(HAVE_EXPAT_CONFIG_H)
- # include <expat_config.h>
- #endif /* ndef _WIN32 */
-@@ -382,6 +387,31 @@
- XML_Bool betweenDecl; /* WFC: PE Between Declarations */
- } OPEN_INTERNAL_ENTITY;
-
-+enum XML_Account {
-+ XML_ACCOUNT_DIRECT, /* bytes directly passed to the Expat parser
*/
-+ XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity
-+ expansion */
-+ XML_ACCOUNT_NONE /* i.e. do not account, was accounted already
*/
-+};
-+
-+#ifdef XML_DTD
-+typedef unsigned long long XmlBigCount;
-+typedef struct accounting {
-+ XmlBigCount countBytesDirect;
-+ XmlBigCount countBytesIndirect;
-+ int debugLevel;
-+ float maximumAmplificationFactor; // >=1.0
-+ unsigned long long activationThresholdBytes;
-+} ACCOUNTING;
-+
-+typedef struct entity_stats {
-+ unsigned int countEverOpened;
-+ unsigned int currentDepth;
-+ unsigned int maximumDepthSeen;
-+ int debugLevel;
-+} ENTITY_STATS;
-+#endif /* XML_DTD */
-+
- typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
- const char *end, const char
**endPtr);
-
-@@ -412,16 +442,18 @@
- static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
- const char *s, const char *end, int tok,
- const char *next, const char **nextPtr,
-- XML_Bool haveMore, XML_Bool
allowClosingDoctype);
-+ XML_Bool haveMore,
XML_Bool allowClosingDoctype,
-+ enum XML_Account
account);
- static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
- XML_Bool betweenDecl);
- static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
- const ENCODING *enc, const char *start,
- const char *end, const char **endPtr,
-- XML_Bool haveMore);
-+ XML_Bool
haveMore, enum XML_Account account);
- static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,
- const char **startPtr, const char *end,
-- const char **nextPtr, XML_Bool haveMore);
-+ const char **nextPtr, XML_Bool haveMore,
-+ enum XML_Account account);
- #ifdef XML_DTD
- static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
- const char **startPtr, const char *end,
-@@ -431,7 +463,8 @@
- static void freeBindings(XML_Parser parser, BINDING *bindings);
- static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,
- const char *s, TAG_NAME *tagNamePtr,
-- BINDING **bindingsPtr);
-+ BINDING
**bindingsPtr,
-+ enum
XML_Account account);
- static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
- const ATTRIBUTE_ID *attId, const XML_Char
*uri,
- BINDING **bindingsPtr);
-@@ -440,15 +473,18 @@
- XML_Parser parser);
- static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,
- XML_Bool isCdata, const char *,
-- const char *, STRING_POOL *);
-+ const char *, STRING_POOL *,
-+ enum XML_Account account);
- static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING
*,
- XML_Bool isCdata, const char *,
-- const char *, STRING_POOL *);
-+ const char *, STRING_POOL *,
-+ enum XML_Account account);
- static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end);
- static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
- static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
-- const char *start, const char *end);
-+ const char *start, const char *end,
-+ enum XML_Account account);
- static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end);
- static int reportComment(XML_Parser parser, const ENCODING *enc,
-@@ -512,6 +548,34 @@
-
- static void parserInit(XML_Parser parser, const XML_Char *encodingName);
-
-+#ifdef XML_DTD
-+static float accountingGetCurrentAmplification(XML_Parser rootParser);
-+static void accountingReportStats(XML_Parser originParser, const char
*epilog);
-+static void accountingOnAbort(XML_Parser originParser);
-+static void accountingReportDiff(XML_Parser rootParser,
-+ unsigned int levelsAwayFromRootParser,
-+ const char *before, const char *after,
-+ ptrdiff_t bytesMore, int source_line,
-+ enum XML_Account account);
-+static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok,
-+ const char *before, const char *after,
-+ int source_line,
-+ enum XML_Account account);
-+
-+static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity,
-+ const char *action, int sourceLine);
-+static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity,
-+ int sourceLine);
-+static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity,
-+ int sourceLine);
-+
-+static XML_Parser getRootParserOf(XML_Parser parser,
-+ unsigned int *outLevelDiff);
-+#endif /* XML_DTD */
-+
-+static unsigned long getDebugLevel(const char *variableName,
-+ unsigned long defaultDebugLevel);
-+
- #define poolStart(pool) ((pool)->start)
- #define poolEnd(pool) ((pool)->ptr)
- #define poolLength(pool) ((pool)->ptr - (pool)->start)
-@@ -625,6 +689,10 @@
- enum XML_ParamEntityParsing m_paramEntityParsing;
- #endif
- unsigned long m_hash_secret_salt;
-+#ifdef XML_DTD
-+ ACCOUNTING m_accounting;
-+ ENTITY_STATS m_entity_stats;
-+#endif
- };
-
- #define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
-@@ -640,6 +708,7 @@
- XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
- XML_Char tmp[2];
- *tmp = nsSep;
-+ tmp[1] = 0;
- return XML_ParserCreate_MM(encodingName, NULL, tmp);
- }
-
-@@ -809,9 +878,8 @@
-
- static unsigned long
- ENTROPY_DEBUG(const char *label, unsigned long entropy) {
-- const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
-- if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
-- fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
-+ if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) {
-+ fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n",
label,
- (int)sizeof(entropy) * 2, entropy, (unsigned
long)sizeof(entropy));
- }
- return entropy;
-@@ -855,7 +923,7 @@
- return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
- } else {
- return ENTROPY_DEBUG("fallback(8)",
-- entropy * (unsigned long)2305843009213693951ULL);
-+ entropy * (unsigned long
long)2305843009213693951ULL);
- }
- #endif
- }
-@@ -1073,6 +1141,18 @@
- parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
- #endif
- parser->m_hash_secret_salt = 0;
-+
-+#ifdef XML_DTD
-+ memset(&parser->m_accounting, 0, sizeof(ACCOUNTING));
-+ parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG",
0u);
-+ parser->m_accounting.maximumAmplificationFactor
-+ = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT;
-+ parser->m_accounting.activationThresholdBytes
-+ = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT;
-+
-+ memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS));
-+ parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u);
-+#endif
- }
-
- /* moves list of bindings to m_freeBindingList */
-@@ -1255,6 +1335,7 @@
- if (parser->m_ns) {
- XML_Char tmp[2];
- *tmp = parser->m_namespaceSeparator;
-+ tmp[1] = 0;
- parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
- } else {
- parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
-@@ -1893,6 +1974,12 @@
- parser->m_errorCode = XML_ERROR_FINISHED;
- return XML_STATUS_ERROR;
- case XML_INITIALIZED:
-+ /* Has someone called XML_GetBuffer successfully before? */
-+ if (! parser->m_bufferPtr) {
-+ parser->m_errorCode = XML_ERROR_NO_BUFFER;
-+ return XML_STATUS_ERROR;
-+ }
-+
- if (parser->m_parentParser == NULL && ! startParsing(parser)) {
- parser->m_errorCode = XML_ERROR_NO_MEMORY;
- return XML_STATUS_ERROR;
-@@ -1971,6 +2058,11 @@
- keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
- if (keep > XML_CONTEXT_BYTES)
- keep = XML_CONTEXT_BYTES;
-+ /* Detect and prevent integer overflow */
-+ if (keep > INT_MAX - neededSize) {
-+ parser->m_errorCode = XML_ERROR_NO_MEMORY;
-+ return NULL;
-+ }
- neededSize += keep;
- #endif /* defined XML_CONTEXT_BYTES */
- if (neededSize
-@@ -2337,6 +2429,13 @@
- /* Added in 2.2.5. */
- case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
- return XML_L("invalid argument");
-+ /* Added in 2.2.11. */
-+ case XML_ERROR_NO_BUFFER:
-+ return XML_L(
-+ "a successful prior call to function XML_GetBuffer is required");
-+ case XML_ERROR_AMPLIFICATION_LIMIT_BREACH:
-+ return XML_L(
-+ "limit on input amplification factor (from DTD and entities)
breached");
- }
- return NULL;
- }
-@@ -2373,41 +2472,75 @@
-
- const XML_Feature *XMLCALL
- XML_GetFeatureList(void) {
-- static const XML_Feature features[]
-- = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
-- sizeof(XML_Char)},
-- {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
-- sizeof(XML_LChar)},
-+ static const XML_Feature features[] = {
-+ {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
-+ sizeof(XML_Char)},
-+ {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
-+ sizeof(XML_LChar)},
- #ifdef XML_UNICODE
-- {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
-+ {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
- #endif
- #ifdef XML_UNICODE_WCHAR_T
-- {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
-+ {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
- #endif
- #ifdef XML_DTD
-- {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
-+ {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
- #endif
- #ifdef XML_CONTEXT_BYTES
-- {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
-- XML_CONTEXT_BYTES},
-+ {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
-+ XML_CONTEXT_BYTES},
- #endif
- #ifdef XML_MIN_SIZE
-- {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
-+ {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
- #endif
- #ifdef XML_NS
-- {XML_FEATURE_NS, XML_L("XML_NS"), 0},
-+ {XML_FEATURE_NS, XML_L("XML_NS"), 0},
- #endif
- #ifdef XML_LARGE_SIZE
-- {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
-+ {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
- #endif
- #ifdef XML_ATTR_INFO
-- {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
-+ {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
-+#endif
-+#ifdef XML_DTD
-+ /* Added in Expat 2.2.11. */
-+
{XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
-+ XML_L("XML_BLAP_MAX_AMP"),
-+ (long int)
-+
EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT},
-+
{XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
-+ XML_L("XML_BLAP_ACT_THRES"),
-+ EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT},
- #endif
-- {XML_FEATURE_END, NULL, 0}};
-+ {XML_FEATURE_END, NULL, 0}};
-
- return features;
- }
-
-+#ifdef XML_DTD
-+XML_Bool XMLCALL
-+XML_SetBillionLaughsAttackProtectionMaximumAmplification(
-+ XML_Parser parser, float maximumAmplificationFactor) {
-+ if ((parser == NULL) || (parser->m_parentParser != NULL)
-+ || isnan(maximumAmplificationFactor)
-+ || (maximumAmplificationFactor < 1.0f)) {
-+ return XML_FALSE;
-+ }
-+ parser->m_accounting.maximumAmplificationFactor =
maximumAmplificationFactor;
-+ return XML_TRUE;
-+}
-+
-+XML_Bool XMLCALL
-+XML_SetBillionLaughsAttackProtectionActivationThreshold(
-+ XML_Parser parser, unsigned long long activationThresholdBytes) {
-+ if ((parser == NULL) || (parser->m_parentParser != NULL)) {
-+ return XML_FALSE;
-+ }
-+ parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
-+ return XML_TRUE;
-+}
-+#endif /* XML_DTD */
-+
- /* Initially tag->rawName always points into the parse buffer;
- for those TAG instances opened while the current parse buffer was
- processed, and not yet closed, we need to store tag->rawName in a more
-@@ -2419,6 +2552,7 @@
- while (tag) {
- int bufSize;
- int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
-+ size_t rawNameLen;
- char *rawNameBuf = tag->buf + nameLen;
- /* Stop if already stored. Since m_tagStack is a stack, we can stop
- at the first entry that has already been copied; everything
-@@ -2430,7 +2564,11 @@
- /* For re-use purposes we need to ensure that the
- size of tag->buf is a multiple of sizeof(XML_Char).
- */
-- bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
-+ rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
-+ /* Detect and prevent integer overflow. */
-+ if (rawNameLen > (size_t)INT_MAX - nameLen)
-+ return XML_FALSE;
-+ bufSize = nameLen + (int)rawNameLen;
- if (bufSize > tag->bufEnd - tag->buf) {
- char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
- if (temp == NULL)
-@@ -2460,9 +2598,9 @@
- static enum XML_Error PTRCALL
- contentProcessor(XML_Parser parser, const char *start, const char *end,
- const char **endPtr) {
-- enum XML_Error result
-- = doContent(parser, 0, parser->m_encoding, start, end, endPtr,
-- (XML_Bool)! parser->m_parsingStatus.finalBuffer);
-+ enum XML_Error result = doContent(
-+ parser, 0, parser->m_encoding, start, end, endPtr,
-+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
- if (result == XML_ERROR_NONE) {
- if (! storeRawNames(parser))
- return XML_ERROR_NO_MEMORY;
-@@ -2487,6 +2625,14 @@
- int tok = XmlContentTok(parser->m_encoding, start, end, &next);
- switch (tok) {
- case XML_TOK_BOM:
-+#ifdef XML_DTD
-+ if (! accountingDiffTolerated(parser, tok, start, next, __LINE__,
-+ XML_ACCOUNT_DIRECT)) {
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+#endif /* XML_DTD */
-+
- /* If we are at the end of the buffer, this would cause the next stage,
- i.e. externalEntityInitProcessor3, to pass control directly to
- doContent (by detecting XML_TOK_NONE) without processing any xml text
-@@ -2524,6 +2670,10 @@
- const char *next = start; /* XmlContentTok doesn't always set the last arg
*/
- parser->m_eventPtr = start;
- tok = XmlContentTok(parser->m_encoding, start, end, &next);
-+ /* Note: These bytes are accounted later in:
-+ - processXmlDecl
-+ - externalEntityContentProcessor
-+ */
- parser->m_eventEndPtr = next;
-
- switch (tok) {
-@@ -2565,7 +2715,8 @@
- const char *end, const char **endPtr) {
- enum XML_Error result
- = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
-- (XML_Bool)! parser->m_parsingStatus.finalBuffer);
-+ (XML_Bool)! parser->m_parsingStatus.finalBuffer,
-+ XML_ACCOUNT_ENTITY_EXPANSION);
- if (result == XML_ERROR_NONE) {
- if (! storeRawNames(parser))
- return XML_ERROR_NO_MEMORY;
-@@ -2576,7 +2727,7 @@
- static enum XML_Error
- doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
- const char *s, const char *end, const char **nextPtr,
-- XML_Bool haveMore) {
-+ XML_Bool haveMore, enum XML_Account account) {
- /* save one level of indirection */
- DTD *const dtd = parser->m_dtd;
-
-@@ -2594,6 +2745,17 @@
- for (;;) {
- const char *next = s; /* XmlContentTok doesn't always set the last arg */
- int tok = XmlContentTok(enc, s, end, &next);
-+#ifdef XML_DTD
-+ const char *accountAfter
-+ = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR))
-+ ? (haveMore ? s /* i.e. 0 bytes */ : end)
-+ : next;
-+ if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__,
-+ account)) {
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+#endif
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_TRAILING_CR:
-@@ -2649,6 +2811,14 @@
- XML_Char ch = (XML_Char)XmlPredefinedEntityName(
- enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
- if (ch) {
-+#ifdef XML_DTD
-+ /* NOTE: We are replacing 4-6 characters original input for 1
character
-+ * so there is no amplification and hence recording without
-+ * protection. */
-+ accountingDiffTolerated(parser, tok, (char *)&ch,
-+ ((char *)&ch) + sizeof(XML_Char), __LINE__,
-+ XML_ACCOUNT_ENTITY_EXPANSION);
-+#endif /* XML_DTD */
- if (parser->m_characterDataHandler)
- parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
- else if (parser->m_defaultHandler)
-@@ -2767,7 +2937,7 @@
- }
- tag->name.str = (XML_Char *)tag->buf;
- *toPtr = XML_T('\0');
-- result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
-+ result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings),
account);
- if (result)
- return result;
- if (parser->m_startElementHandler)
-@@ -2791,7 +2961,8 @@
- if (! name.str)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&parser->m_tempPool);
-- result = storeAtts(parser, enc, s, &name, &bindings);
-+ result = storeAtts(parser, enc, s, &name, &bindings,
-+ XML_ACCOUNT_NONE /* token spans whole start tag */);
- if (result != XML_ERROR_NONE) {
- freeBindings(parser, bindings);
- return result;
-@@ -2926,7 +3097,7 @@
- /* END disabled code */
- else if (parser->m_defaultHandler)
- reportDefault(parser, enc, s, next);
-- result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
-+ result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore,
account);
- if (result != XML_ERROR_NONE)
- return result;
- else if (! next) {
-@@ -3055,7 +3226,8 @@
- */
- static enum XML_Error
- storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
-- TAG_NAME *tagNamePtr, BINDING **bindingsPtr) {
-+ TAG_NAME *tagNamePtr, BINDING **bindingsPtr,
-+ enum XML_Account account) {
- DTD *const dtd = parser->m_dtd; /* save one level of indirection */
- ELEMENT_TYPE *elementType;
- int nDefaultAtts;
-@@ -3087,13 +3259,38 @@
-
- /* get the attributes from the tokenizer */
- n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
-+
-+ /* Detect and prevent integer overflow */
-+ if (n > INT_MAX - nDefaultAtts) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+
- if (n + nDefaultAtts > parser->m_attsSize) {
- int oldAttsSize = parser->m_attsSize;
- ATTRIBUTE *temp;
- #ifdef XML_ATTR_INFO
- XML_AttrInfo *temp2;
- #endif
-+
-+ /* Detect and prevent integer overflow */
-+ if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
-+ || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+
- parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
-+
-+ /* 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 ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
-+ parser->m_attsSize = oldAttsSize;
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+#endif
-+
- temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
- parser->m_attsSize * sizeof(ATTRIBUTE));
- if (temp == NULL) {
-@@ -3102,6 +3299,17 @@
- }
- parser->m_atts = temp;
- #ifdef XML_ATTR_INFO
-+ /* 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 ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) {
-+ parser->m_attsSize = oldAttsSize;
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+# endif
-+
- temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
- parser->m_attsSize *
sizeof(XML_AttrInfo));
- if (temp2 == NULL) {
-@@ -3165,7 +3373,7 @@
- /* normalize the attribute value */
- result = storeAttributeValue(
- parser, enc, isCdata, parser->m_atts[i].valuePtr,
-- parser->m_atts[i].valueEnd, &parser->m_tempPool);
-+ parser->m_atts[i].valueEnd, &parser->m_tempPool, account);
- if (result)
- return result;
- appAtts[attIndex] = poolStart(&parser->m_tempPool);
-@@ -3240,8 +3448,16 @@
- if (nPrefixes) {
- int j; /* hash table index */
- unsigned long version = parser->m_nsAttsVersion;
-- int nsAttsSize = (int)1 << parser->m_nsAttsPower;
-- unsigned char oldNsAttsPower = parser->m_nsAttsPower;
-+ unsigned int nsAttsSize;
-+ unsigned char oldNsAttsPower;
-+
-+ /* Detect and prevent invalid shift */
-+ if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte
*/) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+
-+ nsAttsSize = 1u << parser->m_nsAttsPower;
-+ oldNsAttsPower = parser->m_nsAttsPower;
- /* size of hash table must be at least 2 * (# of prefixed attributes) */
- if ((nPrefixes << 1)
- >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
-@@ -3251,7 +3467,28 @@
- ;
- if (parser->m_nsAttsPower < 3)
- parser->m_nsAttsPower = 3;
-- nsAttsSize = (int)1 << parser->m_nsAttsPower;
-+
-+ /* Detect and prevent invalid shift */
-+ if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte
*/) {
-+ /* Restore actual size of memory in m_nsAtts */
-+ parser->m_nsAttsPower = oldNsAttsPower;
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+
-+ nsAttsSize = 1u << parser->m_nsAttsPower;
-+
-+ /* 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 (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) {
-+ /* Restore actual size of memory in m_nsAtts */
-+ parser->m_nsAttsPower = oldNsAttsPower;
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+#endif
-+
- temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
- nsAttsSize * sizeof(NS_ATT));
- if (! temp) {
-@@ -3409,9 +3646,31 @@
- tagNamePtr->prefixLen = prefixLen;
- for (i = 0; localPart[i++];)
- ; /* i includes null terminator */
-+
-+ /* Detect and prevent integer overflow */
-+ if (binding->uriLen > INT_MAX - prefixLen
-+ || i > INT_MAX - (binding->uriLen + prefixLen)) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+
- n = i + binding->uriLen + prefixLen;
- if (n > binding->uriAlloc) {
- TAG *p;
-+
-+ /* Detect and prevent integer overflow */
-+ if (n > INT_MAX - EXPAND_SPARE) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+ /* 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 ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+#endif
-+
- uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
- if (! uri)
- return XML_ERROR_NO_MEMORY;
-@@ -3491,6 +3750,17 @@
- if (! mustBeXML && isXMLNS
- && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
- isXMLNS = XML_FALSE;
-+
-+ // NOTE: While Expat does not validate namespace URIs against RFC 3986,
-+ // we have to at least make sure that the XML processor on top of
-+ // Expat (that is splitting tag names by namespace separator into
-+ // 2- or 3-tuples (uri-local or uri-local-prefix)) cannot be
confused
-+ // by an attacker putting additional namespace separator characters
-+ // into namespace declarations. That would be ambiguous and not to
-+ // be expected.
-+ if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)) {
-+ return XML_ERROR_SYNTAX;
-+ }
- }
- isXML = isXML && len == xmlLen;
- isXMLNS = isXMLNS && len == xmlnsLen;
-@@ -3507,7 +3777,24 @@
- if (parser->m_freeBindingList) {
- b = parser->m_freeBindingList;
- if (len > b->uriAlloc) {
-- XML_Char *temp = (XML_Char *)REALLOC(
-+
-+ XML_Char *temp;
-+ /* Detect and prevent integer overflow */
-+ if (len > INT_MAX - EXPAND_SPARE) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+
-+ /* 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 ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+#endif
-+
-+ temp = (XML_Char *)REALLOC(
- parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
-@@ -3519,6 +3806,21 @@
- b = (BINDING *)MALLOC(parser, sizeof(BINDING));
- if (! b)
- return XML_ERROR_NO_MEMORY;
-+
-+ /* Detect and prevent integer overflow */
-+ if (len > INT_MAX - EXPAND_SPARE) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+ /* 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 ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+#endif
-+
- b->uri
- = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (! b->uri) {
-@@ -3556,7 +3858,7 @@
- const char **endPtr) {
- enum XML_Error result
- = doCdataSection(parser, parser->m_encoding, &start, end, endPtr,
-- (XML_Bool)! parser->m_parsingStatus.finalBuffer);
-+ (XML_Bool)! parser->m_parsingStatus.finalBuffer,
XML_ACCOUNT_DIRECT);
- if (result != XML_ERROR_NONE)
- return result;
- if (start) {
-@@ -3576,7 +3878,8 @@
- */
- static enum XML_Error
- doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
-- const char *end, const char **nextPtr, XML_Bool haveMore) {
-+ const char *end, const char **nextPtr, XML_Bool haveMore,
-+ enum XML_Account account) {
- const char *s = *startPtr;
- const char **eventPP;
- const char **eventEndPP;
-@@ -3594,6 +3897,12 @@
- for (;;) {
- const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
- int tok = XmlCdataSectionTok(enc, s, end, &next);
-+#ifdef XML_DTD
-+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+#endif
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_CDATA_SECT_CLOSE:
-@@ -3738,6 +4047,13 @@
- *eventPP = s;
- *startPtr = NULL;
- tok = XmlIgnoreSectionTok(enc, s, end, &next);
-+# ifdef XML_DTD
-+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
-+ XML_ACCOUNT_DIRECT)) {
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+# endif
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_IGNORE_SECT:
-@@ -3822,6 +4138,15 @@
- const char *versionend;
- const XML_Char *storedversion = NULL;
- int standalone = -1;
-+
-+#ifdef XML_DTD
-+ if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__,
-+ XML_ACCOUNT_DIRECT)) {
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+#endif
-+
- if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
- isGeneralTextEntity, parser->m_encoding, s, next,
&parser->m_eventPtr,
- &version, &versionend, &encodingName, &newEncoding, &standalone)) {
-@@ -3971,6 +4296,10 @@
-
- for (;;) {
- tok = XmlPrologTok(parser->m_encoding, start, end, &next);
-+ /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in:
-+ - storeEntityValue
-+ - processXmlDecl
-+ */
- parser->m_eventEndPtr = next;
- if (tok <= 0) {
- if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
-@@ -3989,7 +4318,8 @@
- break;
- }
- /* found end of entity value - can store it now */
-- return storeEntityValue(parser, parser->m_encoding, s, end);
-+ return storeEntityValue(parser, parser->m_encoding, s, end,
-+ XML_ACCOUNT_DIRECT);
- } else if (tok == XML_TOK_XML_DECL) {
- enum XML_Error result;
- result = processXmlDecl(parser, 0, start, next);
-@@ -4016,6 +4346,14 @@
- */
- else if (tok == XML_TOK_BOM && next == end
- && ! parser->m_parsingStatus.finalBuffer) {
-+# ifdef XML_DTD
-+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
-+ XML_ACCOUNT_DIRECT)) {
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+# endif
-+
- *nextPtr = next;
- return XML_ERROR_NONE;
- }
-@@ -4058,16 +4396,24 @@
- }
- /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
- However, when parsing an external subset, doProlog will not accept a BOM
-- as valid, and report a syntax error, so we have to skip the BOM
-+ as valid, and report a syntax error, so we have to skip the BOM, and
-+ account for the BOM bytes.
- */
- else if (tok == XML_TOK_BOM) {
-+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
-+ XML_ACCOUNT_DIRECT)) {
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+
- s = next;
- tok = XmlPrologTok(parser->m_encoding, s, end, &next);
- }
-
- parser->m_processor = prologProcessor;
- return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
-- (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
-+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
-+ XML_ACCOUNT_DIRECT);
- }
-
- static enum XML_Error PTRCALL
-@@ -4080,6 +4426,9 @@
-
- for (;;) {
- tok = XmlPrologTok(enc, start, end, &next);
-+ /* Note: These bytes are accounted later in:
-+ - storeEntityValue
-+ */
- if (tok <= 0) {
- if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
- *nextPtr = s;
-@@ -4097,7 +4446,7 @@
- break;
- }
- /* found end of entity value - can store it now */
-- return storeEntityValue(parser, enc, s, end);
-+ return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT);
- }
- start = next;
- }
-@@ -4111,13 +4460,14 @@
- const char *next = s;
- int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
- return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
-- (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
-+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
-+ XML_ACCOUNT_DIRECT);
- }
-
- static enum XML_Error
- doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char
*end,
- int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
-- XML_Bool allowClosingDoctype) {
-+ XML_Bool allowClosingDoctype, enum XML_Account account) {
- #ifdef XML_DTD
- static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
- #endif /* XML_DTD */
-@@ -4144,6 +4494,10 @@
- static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
- static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
-
-+#ifndef XML_DTD
-+ UNUSED_P(account);
-+#endif
-+
- /* save one level of indirection */
- DTD *const dtd = parser->m_dtd;
-
-@@ -4208,6 +4562,19 @@
- }
- }
- role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
-+#ifdef XML_DTD
-+ switch (role) {
-+ case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor
-+ case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl
-+ case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl
-+ break;
-+ default:
-+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account))
{
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+ }
-+#endif
- switch (role) {
- case XML_ROLE_XML_DECL: {
- enum XML_Error result = processXmlDecl(parser, 0, s, next);
-@@ -4483,7 +4850,8 @@
- const XML_Char *attVal;
- enum XML_Error result = storeAttributeValue(
- parser, enc, parser->m_declAttributeIsCdata,
-- s + enc->minBytesPerChar, next - enc->minBytesPerChar,
&dtd->pool);
-+ s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool,
-+ XML_ACCOUNT_NONE);
- if (result)
- return result;
- attVal = poolStart(&dtd->pool);
-@@ -4516,8 +4884,9 @@
- break;
- case XML_ROLE_ENTITY_VALUE:
- if (dtd->keepProcessing) {
-- enum XML_Error result = storeEntityValue(
-- parser, enc, s + enc->minBytesPerChar, next -
enc->minBytesPerChar);
-+ enum XML_Error result
-+ = storeEntityValue(parser, enc, s + enc->minBytesPerChar,
-+ next - enc->minBytesPerChar,
XML_ACCOUNT_NONE);
- if (parser->m_declEntity) {
- parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
- parser->m_declEntity->textLen
-@@ -4776,7 +5145,13 @@
- if (parser->m_prologState.level >= parser->m_groupSize) {
- if (parser->m_groupSize) {
- {
-- char *const new_connector = (char *)REALLOC(
-+ char * new_connector;
-+ /* Detect and prevent integer overflow */
-+ if (parser->m_groupSize > (unsigned int)(-1) / 2u) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+
-+ new_connector = (char *)REALLOC(
- parser, parser->m_groupConnector, parser->m_groupSize *= 2);
- if (new_connector == NULL) {
- parser->m_groupSize /= 2;
-@@ -4786,7 +5161,18 @@
- }
-
- if (dtd->scaffIndex) {
-- int *const new_scaff_index = (int *)REALLOC(
-+ int *new_scaff_index;
-+ /* 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 XML_ERROR_NO_MEMORY;
-+ }
-+#endif
-+
-+ new_scaff_index = (int *)REALLOC(
- parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
- if (new_scaff_index == NULL)
- return XML_ERROR_NO_MEMORY;
-@@ -4907,12 +5293,15 @@
- if (parser->m_externalEntityRefHandler) {
- dtd->paramEntityRead = XML_FALSE;
- entity->open = XML_TRUE;
-+ entityTrackingOnOpen(parser, entity, __LINE__);
- if (! parser->m_externalEntityRefHandler(
- parser->m_externalEntityRefHandlerArg, 0, entity->base,
- entity->systemId, entity->publicId)) {
-+ entityTrackingOnClose(parser, entity, __LINE__);
- entity->open = XML_FALSE;
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- }
-+ entityTrackingOnClose(parser, entity, __LINE__);
- entity->open = XML_FALSE;
- handleDefault = XML_FALSE;
- if (! dtd->paramEntityRead) {
-@@ -4991,7 +5380,7 @@
- if (dtd->in_eldecl) {
- ELEMENT_TYPE *el;
- const XML_Char *name;
-- int nameLen;
-+ size_t nameLen;
- const char *nxt
- = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
- int myindex = nextScaffoldPart(parser);
-@@ -5007,7 +5396,13 @@
- nameLen = 0;
- for (; name[nameLen++];)
- ;
-- dtd->contentStringLen += nameLen;
-+
-+ /* Detect and prevent integer overflow */
-+ if (nameLen > UINT_MAX - dtd->contentStringLen) {
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+
-+ dtd->contentStringLen += (unsigned)nameLen;
- if (parser->m_elementDeclHandler)
- handleDefault = XML_FALSE;
- }
-@@ -5110,6 +5505,13 @@
- for (;;) {
- const char *next = NULL;
- int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
-+#ifdef XML_DTD
-+ if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
-+ XML_ACCOUNT_DIRECT)) {
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+#endif
- parser->m_eventEndPtr = next;
- switch (tok) {
- /* report partial linebreak - it might be the last token */
-@@ -5183,6 +5585,9 @@
- return XML_ERROR_NO_MEMORY;
- }
- entity->open = XML_TRUE;
-+#ifdef XML_DTD
-+ entityTrackingOnOpen(parser, entity, __LINE__);
-+#endif
- entity->processed = 0;
- openEntity->next = parser->m_openInternalEntities;
- parser->m_openInternalEntities = openEntity;
-@@ -5201,17 +5606,22 @@
- int tok
- = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
- result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
-- tok, next, &next, XML_FALSE, XML_FALSE);
-+ tok, next, &next, XML_FALSE, XML_FALSE,
-+ XML_ACCOUNT_ENTITY_EXPANSION);
- } else
- #endif /* XML_DTD */
- result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
-- textStart, textEnd, &next, XML_FALSE);
-+ textStart, textEnd, &next, XML_FALSE,
-+ XML_ACCOUNT_ENTITY_EXPANSION);
-
- if (result == XML_ERROR_NONE) {
- if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
- entity->processed = (int)(next - textStart);
- parser->m_processor = internalEntityProcessor;
- } else {
-+#ifdef XML_DTD
-+ entityTrackingOnClose(parser, entity, __LINE__);
-+#endif /* XML_DTD */
- entity->open = XML_FALSE;
- parser->m_openInternalEntities = openEntity->next;
- /* put openEntity back in list of free instances */
-@@ -5244,12 +5654,13 @@
- int tok
- = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
- result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
-- tok, next, &next, XML_FALSE, XML_TRUE);
-+ tok, next, &next, XML_FALSE, XML_TRUE,
-+ XML_ACCOUNT_ENTITY_EXPANSION);
- } else
- #endif /* XML_DTD */
- result = doContent(parser, openEntity->startTagLevel,
- parser->m_internalEncoding, textStart, textEnd, &next,
-- XML_FALSE);
-+ XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
-
- if (result != XML_ERROR_NONE)
- return result;
-@@ -5258,6 +5669,9 @@
- entity->processed = (int)(next - (const char *)entity->textPtr);
- return result;
- } else {
-+#ifdef XML_DTD
-+ entityTrackingOnClose(parser, entity, __LINE__);
-+#endif
- entity->open = XML_FALSE;
- parser->m_openInternalEntities = openEntity->next;
- /* put openEntity back in list of free instances */
-@@ -5271,15 +5685,22 @@
- parser->m_processor = prologProcessor;
- tok = XmlPrologTok(parser->m_encoding, s, end, &next);
- return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
-- (XML_Bool)! parser->m_parsingStatus.finalBuffer,
XML_TRUE);
-+ (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
-+ XML_ACCOUNT_DIRECT);
- } else
- #endif /* XML_DTD */
- {
- parser->m_processor = contentProcessor;
- /* see externalEntityContentProcessor vs contentProcessor */
-- return doContent(parser, parser->m_parentParser ? 1 : 0,
parser->m_encoding,
-- s, end, nextPtr,
-- (XML_Bool)! parser->m_parsingStatus.finalBuffer);
-+ result = doContent(parser, parser->m_parentParser ? 1 : 0,
-+ parser->m_encoding, s, end, nextPtr,
-+ (XML_Bool)! parser->m_parsingStatus.finalBuffer,
-+ XML_ACCOUNT_DIRECT);
-+ if (result == XML_ERROR_NONE) {
-+ if (! storeRawNames(parser))
-+ return XML_ERROR_NO_MEMORY;
-+ }
-+ return result;
- }
- }
-
-@@ -5294,9 +5715,10 @@
-
- static enum XML_Error
- storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
-- const char *ptr, const char *end, STRING_POOL *pool) {
-+ const char *ptr, const char *end, STRING_POOL *pool,
-+ enum XML_Account account) {
- enum XML_Error result
-- = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
-+ = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account);
- if (result)
- return result;
- if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
-@@ -5308,11 +5730,23 @@
-
- static enum XML_Error
- appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
-- const char *ptr, const char *end, STRING_POOL *pool) {
-+ const char *ptr, const char *end, STRING_POOL *pool,
-+ enum XML_Account account) {
- DTD *const dtd = parser->m_dtd; /* save one level of indirection */
-+#ifndef XML_DTD
-+ UNUSED_P(account);
-+#endif
-+
- for (;;) {
-- const char *next;
-+ const char *next
-+ = ptr; /* XmlAttributeValueTok doesn't always set the last arg
*/
- int tok = XmlAttributeValueTok(enc, ptr, end, &next);
-+#ifdef XML_DTD
-+ if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account))
{
-+ accountingOnAbort(parser);
-+ return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ }
-+#endif
- switch (tok) {
- case XML_TOK_NONE:
- return XML_ERROR_NONE;
-@@ -5372,6 +5806,14 @@
- XML_Char ch = (XML_Char)XmlPredefinedEntityName(
- enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
- if (ch) {
-+#ifdef XML_DTD
-+ /* NOTE: We are replacing 4-6 characters original input for 1
character
-+ * so there is no amplification and hence recording without
-+ * protection. */
-+ accountingDiffTolerated(parser, tok, (char *)&ch,
-+ ((char *)&ch) + sizeof(XML_Char), __LINE__,
-+ XML_ACCOUNT_ENTITY_EXPANSION);
-+#endif /* XML_DTD */
- if (! poolAppendChar(pool, ch))
- return XML_ERROR_NO_MEMORY;
- break;
-@@ -5449,9 +5891,16 @@
- enum XML_Error result;
- const XML_Char *textEnd = entity->textPtr + entity->textLen;
- entity->open = XML_TRUE;
-+#ifdef XML_DTD
-+ entityTrackingOnOpen(parser, entity, __LINE__);
-+#endif
- result = appendAttributeValue(parser, parser->m_internalEncoding,
- isCdata, (const char *)entity->textPtr,
-- (const char *)textEnd, pool);
-+ (const char *)textEnd, pool,
-+ XML_ACCOUNT_ENTITY_EXPANSION);
-+#ifdef XML_DTD
-+ entityTrackingOnClose(parser, entity, __LINE__);
-+#endif
- entity->open = XML_FALSE;
- if (result)
- return result;
-@@ -5481,13 +5930,16 @@
-
- static enum XML_Error
- storeEntityValue(XML_Parser parser, const ENCODING *enc,
-- const char *entityTextPtr, const char *entityTextEnd) {
-+ const char *entityTextPtr, const char *entityTextEnd,
-+ enum XML_Account account) {
- DTD *const dtd = parser->m_dtd; /* save one level of indirection */
- STRING_POOL *pool = &(dtd->entityValuePool);
- enum XML_Error result = XML_ERROR_NONE;
- #ifdef XML_DTD
- int oldInEntityValue = parser->m_prologState.inEntityValue;
- parser->m_prologState.inEntityValue = 1;
-+#else
-+ UNUSED_P(account);
- #endif /* XML_DTD */
- /* never return Null for the value argument in EntityDeclHandler,
- since this would indicate an external entity; therefore we
-@@ -5498,8 +5950,19 @@
- }
-
- for (;;) {
-- const char *next;
-+ const char *next
-+ = entityTextPtr; /* XmlEntityValueTok doesn't always set the last
arg */
- int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
-+
-+#ifdef XML_DTD
-+ if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__,
-+ account)) {
-+ accountingOnAbort(parser);
-+ result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
-+ goto endEntityValue;
-+ }
-+#endif
-+
- switch (tok) {
- case XML_TOK_PARAM_ENTITY_REF:
- #ifdef XML_DTD
-@@ -5535,13 +5998,16 @@
- if (parser->m_externalEntityRefHandler) {
- dtd->paramEntityRead = XML_FALSE;
- entity->open = XML_TRUE;
-+ entityTrackingOnOpen(parser, entity, __LINE__);
- if (! parser->m_externalEntityRefHandler(
- parser->m_externalEntityRefHandlerArg, 0, entity->base,
- entity->systemId, entity->publicId)) {
-+ entityTrackingOnClose(parser, entity, __LINE__);
- entity->open = XML_FALSE;
- result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- goto endEntityValue;
- }
-+ entityTrackingOnClose(parser, entity, __LINE__);
- entity->open = XML_FALSE;
- if (! dtd->paramEntityRead)
- dtd->keepProcessing = dtd->standalone;
-@@ -5549,9 +6015,12 @@
- dtd->keepProcessing = dtd->standalone;
- } else {
- entity->open = XML_TRUE;
-+ entityTrackingOnOpen(parser, entity, __LINE__);
- result = storeEntityValue(
- parser, parser->m_internalEncoding, (const char
*)entity->textPtr,
-- (const char *)(entity->textPtr + entity->textLen));
-+ (const char *)(entity->textPtr + entity->textLen),
-+ XML_ACCOUNT_ENTITY_EXPANSION);
-+ entityTrackingOnClose(parser, entity, __LINE__);
- entity->open = XML_FALSE;
- if (result)
- goto endEntityValue;
-@@ -5784,7 +6253,25 @@
- }
- } else {
- DEFAULT_ATTRIBUTE *temp;
-- int count = type->allocDefaultAtts * 2;
-+ int count;
-+
-+ /* Detect and prevent integer overflow */
-+ if (type->allocDefaultAtts > INT_MAX / 2) {
-+ return 0;
-+ }
-+
-+ count = type->allocDefaultAtts * 2;
-+
-+ /* 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 ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) {
-+ return 0;
-+ }
-+#endif
-+
- temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
- (count *
sizeof(DEFAULT_ATTRIBUTE)));
- if (temp == NULL)
-@@ -6435,10 +6922,26 @@
- /* check for overflow (table is half full) */
- if (table->used >> (table->power - 1)) {
- unsigned char newPower = table->power + 1;
-- size_t newSize = (size_t)1 << newPower;
-- unsigned long newMask = (unsigned long)newSize - 1;
-- size_t tsize = newSize * sizeof(NAMED *);
-- NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
-+ size_t newSize;
-+ unsigned long newMask;
-+ size_t tsize;
-+ NAMED **newV;
-+
-+ /* Detect and prevent invalid shift */
-+ if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) {
-+ return NULL;
-+ }
-+
-+ newSize = (size_t)1 << newPower;
-+ newMask = (unsigned long)newSize - 1;
-+
-+ /* Detect and prevent integer overflow */
-+ if (newSize > (size_t)(-1) / sizeof(NAMED *)) {
-+ return NULL;
-+ }
-+
-+ tsize = newSize * sizeof(NAMED *);
-+ newV = (NAMED **)table->mem->malloc_fcn(tsize);
- if (! newV)
- return NULL;
- memset(newV, 0, tsize);
-@@ -6786,6 +7289,20 @@
- if (dtd->scaffCount >= dtd->scaffSize) {
- CONTENT_SCAFFOLD *temp;
- if (dtd->scaffold) {
-+ /* Detect and prevent integer overflow */
-+ if (dtd->scaffSize > UINT_MAX / 2u) {
-+ return -1;
-+ }
-+ /* 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 (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) {
-+ return -1;
-+ }
-+#endif
-+
- temp = (CONTENT_SCAFFOLD *)REALLOC(
- parser, dtd->scaffold, dtd->scaffSize * 2 *
sizeof(CONTENT_SCAFFOLD));
- if (temp == NULL)
-@@ -6817,55 +7334,130 @@
- return next;
- }
-
--static void
--build_node(XML_Parser parser, int src_node, XML_Content *dest,
-- XML_Content **contpos, XML_Char **strpos) {
-- DTD *const dtd = parser->m_dtd; /* save one level of indirection */
-- dest->type = dtd->scaffold[src_node].type;
-- dest->quant = dtd->scaffold[src_node].quant;
-- if (dest->type == XML_CTYPE_NAME) {
-- const XML_Char *src;
-- dest->name = *strpos;
-- src = dtd->scaffold[src_node].name;
-- for (;;) {
-- *(*strpos)++ = *src;
-- if (! *src)
-- break;
-- src++;
-- }
-- dest->numchildren = 0;
-- dest->children = NULL;
-- } else {
-- unsigned int i;
-- int cn;
-- dest->numchildren = dtd->scaffold[src_node].childcnt;
-- dest->children = *contpos;
-- *contpos += dest->numchildren;
-- for (i = 0, cn = dtd->scaffold[src_node].firstchild; i <
dest->numchildren;
-- i++, cn = dtd->scaffold[cn].nextsib) {
-- build_node(parser, cn, &(dest->children[i]), contpos, strpos);
-- }
-- dest->name = NULL;
-- }
--}
--
- static XML_Content *
- build_model(XML_Parser parser) {
- DTD *const dtd = parser->m_dtd; /* save one level of indirection */
- XML_Content *ret;
-- XML_Content *cpos;
-- XML_Char *str;
-- int allocsize = (dtd->scaffCount * sizeof(XML_Content)
-- + (dtd->contentStringLen * sizeof(XML_Char)));
-+ XML_Char *str; /* the current string writing location */
-+ size_t allocsize;
-+ XML_Content *dest; /* tree node writing location, moves upwards */
-+ XML_Content *destLimit;
-+ XML_Content *jobDest; /* next free writing location in target array */
-+
-+ /* 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 (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) {
-+ return NULL;
-+ }
-+ if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) {
-+ return NULL;
-+ }
-+#endif
-+ if (dtd->scaffCount * sizeof(XML_Content)
-+ > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) {
-+ return NULL;
-+ }
-+
-+ allocsize = (dtd->scaffCount * sizeof(XML_Content)
-+ + (dtd->contentStringLen * sizeof(XML_Char)));
-
- ret = (XML_Content *)MALLOC(parser, allocsize);
- if (! ret)
- return NULL;
-
-- str = (XML_Char *)(&ret[dtd->scaffCount]);
-- cpos = &ret[1];
-+ /* What follows is an iterative implementation (of what was previously done
-+ * recursively in a dedicated function called "build_node". The old
recursive
-+ * build_node could be forced into stack exhaustion from input as small as a
-+ * few megabyte, and so that was a security issue. Hence, a function call
-+ * stack is avoided now by resolving recursion.)
-+ *
-+ * The iterative approach works as follows:
-+ *
-+ * - We have two writing pointers, both walking up the result array; one
does
-+ * the work, the other creates "jobs" for its colleague to do, and leads
-+ * the way:
-+ *
-+ * - The faster one, pointer jobDest, always leads and writes "what job
-+ * to do" by the other, once they reach that place in the
-+ * array: leader "jobDest" stores the source node array index (relative
-+ * to array dtd->scaffold) in field "numchildren".
-+ *
-+ * - The slower one, pointer dest, looks at the value stored in the
-+ * "numchildren" field (which actually holds a source node array index
-+ * at that time) and puts the real data from dtd->scaffold in.
-+ *
-+ * - Before the loop starts, jobDest writes source array index 0
-+ * (where the root node is located) so that dest will have something to do
-+ * when it starts operation.
-+ *
-+ * - Whenever nodes with children are encountered, jobDest appends
-+ * them as new jobs, in order. As a result, tree node siblings are
-+ * adjacent in the resulting array, for example:
-+ *
-+ * [0] root, has two children
-+ * [1] first child of 0, has three children
-+ * [3] first child of 1, does not have children
-+ * [4] second child of 1, does not have children
-+ * [5] third child of 1, does not have children
-+ * [2] second child of 0, does not have children
-+ *
-+ * Or (the same data) presented in flat array view:
-+ *
-+ * [0] root, has two children
-+ *
-+ * [1] first child of 0, has three children
-+ * [2] second child of 0, does not have children
-+ *
-+ * [3] first child of 1, does not have children
-+ * [4] second child of 1, does not have children
-+ * [5] third child of 1, does not have children
-+ *
-+ * - The algorithm repeats until all target array indices have been
processed.
-+ */
-+ dest = ret; /* tree node writing location, moves upwards */
-+ destLimit = &ret[dtd->scaffCount];
-+ jobDest = ret; /* next free writing location in target array */
-+ str = (XML_Char *)&ret[dtd->scaffCount];
-+
-+ /* Add the starting job, the root node (index 0) of the source tree */
-+ (jobDest++)->numchildren = 0;
-+
-+ for (; dest < destLimit; dest++) {
-+ /* Retrieve source tree array index from job storage */
-+ const int src_node = (int)dest->numchildren;
-+
-+ /* Convert item */
-+ dest->type = dtd->scaffold[src_node].type;
-+ dest->quant = dtd->scaffold[src_node].quant;
-+ if (dest->type == XML_CTYPE_NAME) {
-+ const XML_Char *src;
-+ dest->name = str;
-+ src = dtd->scaffold[src_node].name;
-+ for (;;) {
-+ *str++ = *src;
-+ if (! *src)
-+ break;
-+ src++;
-+ }
-+ dest->numchildren = 0;
-+ dest->children = NULL;
-+ } else {
-+ unsigned int i;
-+ int cn;
-+ dest->name = NULL;
-+ dest->numchildren = dtd->scaffold[src_node].childcnt;
-+ dest->children = jobDest;
-+
-+ /* Append scaffold indices of children to array */
-+ for (i = 0, cn = dtd->scaffold[src_node].firstchild;
-+ i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib)
-+ (jobDest++)->numchildren = (unsigned int)cn;
-+ }
-+ }
-
-- build_node(parser, 0, ret, &cpos, &str);
- return ret;
- }
-
-@@ -6894,7 +7486,7 @@
-
- static XML_Char *
- copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
-- int charsRequired = 0;
-+ size_t charsRequired = 0;
- XML_Char *result;
-
- /* First determine how long the string is */
-@@ -6912,3 +7504,766 @@
- memcpy(result, s, charsRequired * sizeof(XML_Char));
- return result;
- }
-+#ifdef XML_DTD
-+
-+static float
-+accountingGetCurrentAmplification(XML_Parser rootParser) {
-+ const XmlBigCount countBytesOutput
-+ = rootParser->m_accounting.countBytesDirect
-+ + rootParser->m_accounting.countBytesIndirect;
-+ const float amplificationFactor
-+ = rootParser->m_accounting.countBytesDirect
-+ ? (countBytesOutput
-+ / (float)(rootParser->m_accounting.countBytesDirect))
-+ : 1.0f;
-+ assert(! rootParser->m_parentParser);
-+ return amplificationFactor;
-+}
-+
-+static void
-+accountingReportStats(XML_Parser originParser, const char *epilog) {
-+ const XML_Parser rootParser = getRootParserOf(originParser, NULL);
-+ float amplificationFactor;
-+ assert(! rootParser->m_parentParser);
-+
-+ if (rootParser->m_accounting.debugLevel < 1) {
-+ return;
-+ }
-+
-+ amplificationFactor
-+ = accountingGetCurrentAmplification(rootParser);
-+ fprintf(stderr,
-+ "expat: Accounting(%p): Direct " EXPAT_FMT_ULL(
-+ "10") ", indirect " EXPAT_FMT_ULL("10") ", amplification
%8.2f%s",
-+ (void *)rootParser, rootParser->m_accounting.countBytesDirect,
-+ rootParser->m_accounting.countBytesIndirect,
-+ (double)amplificationFactor, epilog);
-+}
-+
-+static void
-+accountingOnAbort(XML_Parser originParser) {
-+ accountingReportStats(originParser, " ABORTING\n");
-+}
-+
-+static void
-+accountingReportDiff(XML_Parser rootParser,
-+ unsigned int levelsAwayFromRootParser, const char
*before,
-+ const char *after, ptrdiff_t bytesMore, int source_line,
-+ enum XML_Account account) {
-+ const char ellipis[] = "[..]";
-+ const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ -
1;
-+ const unsigned int contextLength = 10;
-+ const char *walker = before;
-+
-+ assert(! rootParser->m_parentParser);
-+
-+ fprintf(stderr,
-+ " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"",
-+ bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP",
-+ levelsAwayFromRootParser, source_line, 10, "");
-+
-+ /* Note: Performance is of no concern here */
-+ if ((rootParser->m_accounting.debugLevel >= 3)
-+ || (after - before)
-+ <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) {
-+ for (; walker < after; walker++) {
-+ fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
-+ }
-+ } else {
-+ for (; walker < before + contextLength; walker++) {
-+ fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
-+ }
-+ fprintf(stderr, ellipis);
-+ walker = after - contextLength;
-+ for (; walker < after; walker++) {
-+ fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
-+ }
-+ }
-+ fprintf(stderr, "\"\n");
-+}
-+
-+static XML_Bool
-+accountingDiffTolerated(XML_Parser originParser, int tok, const char *before,
-+ const char *after, int source_line,
-+ enum XML_Account account) {
-+ unsigned int levelsAwayFromRootParser;
-+ XML_Parser rootParser;
-+ int isDirect;
-+ ptrdiff_t bytesMore;
-+ XmlBigCount * additionTarget;
-+ XmlBigCount countBytesOutput;
-+ float amplificationFactor;
-+ XML_Bool tolerated;
-+ /* Note: We need to check the token type *first* to be sure that
-+ * we can even access variable <after>, safely.
-+ * E.g. for XML_TOK_NONE <after> may hold an invalid pointer. */
-+ switch (tok) {
-+ case XML_TOK_INVALID:
-+ case XML_TOK_PARTIAL:
-+ case XML_TOK_PARTIAL_CHAR:
-+ case XML_TOK_NONE:
-+ return XML_TRUE;
-+ }
-+
-+ if (account == XML_ACCOUNT_NONE)
-+ return XML_TRUE; /* because these bytes have been accounted for, already
*/
-+
-+ rootParser
-+ = getRootParserOf(originParser, &levelsAwayFromRootParser);
-+ assert(! rootParser->m_parentParser);
-+
-+ isDirect
-+ = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser);
-+ bytesMore = after - before;
-+
-+ additionTarget
-+ = isDirect ? &rootParser->m_accounting.countBytesDirect
-+ : &rootParser->m_accounting.countBytesIndirect;
-+
-+ /* Detect and avoid integer overflow */
-+ if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore)
-+ return XML_FALSE;
-+ *additionTarget += bytesMore;
-+
-+ countBytesOutput
-+ = rootParser->m_accounting.countBytesDirect
-+ + rootParser->m_accounting.countBytesIndirect;
-+ amplificationFactor
-+ = accountingGetCurrentAmplification(rootParser);
-+ tolerated
-+ = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes)
-+ || (amplificationFactor
-+ <= rootParser->m_accounting.maximumAmplificationFactor);
-+
-+ if (rootParser->m_accounting.debugLevel >= 2) {
-+ accountingReportStats(rootParser, "");
-+ accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after,
-+ bytesMore, source_line, account);
-+ }
-+
-+ return tolerated;
-+}
-+
-+unsigned long long
-+testingAccountingGetCountBytesDirect(XML_Parser parser) {
-+ if (! parser)
-+ return 0;
-+ return parser->m_accounting.countBytesDirect;
-+}
-+
-+unsigned long long
-+testingAccountingGetCountBytesIndirect(XML_Parser parser) {
-+ if (! parser)
-+ return 0;
-+ return parser->m_accounting.countBytesIndirect;
-+}
-+
-+static void
-+entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity,
-+ const char *action, int sourceLine) {
-+ const char * entityName;
-+ assert(! rootParser->m_parentParser);
-+ if (rootParser->m_entity_stats.debugLevel < 1)
-+ return;
-+
-+# if defined(XML_UNICODE)
-+ entityName = "[..]";
-+# else
-+ entityName = entity->name;
-+# endif
-+
-+ fprintf(
-+ stderr,
-+ "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d
(xmlparse.c:%d)\n",
-+ (void *)rootParser, rootParser->m_entity_stats.countEverOpened,
-+ rootParser->m_entity_stats.currentDepth,
-+ rootParser->m_entity_stats.maximumDepthSeen,
-+ (rootParser->m_entity_stats.currentDepth - 1) * 2, "",
-+ entity->is_param ? "%" : "&", entityName, action, entity->textLen,
-+ sourceLine);
-+}
-+
-+static void
-+entityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine)
{
-+ const XML_Parser rootParser = getRootParserOf(originParser, NULL);
-+ assert(! rootParser->m_parentParser);
-+
-+ rootParser->m_entity_stats.countEverOpened++;
-+ rootParser->m_entity_stats.currentDepth++;
-+ if (rootParser->m_entity_stats.currentDepth
-+ > rootParser->m_entity_stats.maximumDepthSeen) {
-+ rootParser->m_entity_stats.maximumDepthSeen++;
-+ }
-+
-+ entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine);
-+}
-+
-+static void
-+entityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int
sourceLine) {
-+ const XML_Parser rootParser = getRootParserOf(originParser, NULL);
-+ assert(! rootParser->m_parentParser);
-+
-+ entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine);
-+ rootParser->m_entity_stats.currentDepth--;
-+}
-+
-+static XML_Parser
-+getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) {
-+ XML_Parser rootParser = parser;
-+ unsigned int stepsTakenUpwards = 0;
-+ while (rootParser->m_parentParser) {
-+ rootParser = rootParser->m_parentParser;
-+ stepsTakenUpwards++;
-+ }
-+ assert(! rootParser->m_parentParser);
-+ if (outLevelDiff != NULL) {
-+ *outLevelDiff = stepsTakenUpwards;
-+ }
-+ return rootParser;
-+}
-+
-+const char *
-+unsignedCharToPrintable(unsigned char c) {
-+ switch (c) {
-+ case 0:
-+ return "\\0";
-+ case 1:
-+ return "\\x1";
-+ case 2:
-+ return "\\x2";
-+ case 3:
-+ return "\\x3";
-+ case 4:
-+ return "\\x4";
-+ case 5:
-+ return "\\x5";
-+ case 6:
-+ return "\\x6";
-+ case 7:
-+ return "\\x7";
-+ case 8:
-+ return "\\x8";
-+ case 9:
-+ return "\\t";
-+ case 10:
-+ return "\\n";
-+ case 11:
-+ return "\\xB";
-+ case 12:
-+ return "\\xC";
-+ case 13:
-+ return "\\r";
-+ case 14:
-+ return "\\xE";
-+ case 15:
-+ return "\\xF";
-+ case 16:
-+ return "\\x10";
-+ case 17:
-+ return "\\x11";
-+ case 18:
-+ return "\\x12";
-+ case 19:
-+ return "\\x13";
-+ case 20:
-+ return "\\x14";
-+ case 21:
-+ return "\\x15";
-+ case 22:
-+ return "\\x16";
-+ case 23:
-+ return "\\x17";
-+ case 24:
-+ return "\\x18";
-+ case 25:
-+ return "\\x19";
-+ case 26:
-+ return "\\x1A";
-+ case 27:
-+ return "\\x1B";
-+ case 28:
-+ return "\\x1C";
-+ case 29:
-+ return "\\x1D";
-+ case 30:
-+ return "\\x1E";
-+ case 31:
-+ return "\\x1F";
-+ case 32:
-+ return " ";
-+ case 33:
-+ return "!";
-+ case 34:
-+ return "\\\"";
-+ case 35:
-+ return "#";
-+ case 36:
-+ return "$";
-+ case 37:
-+ return "%";
-+ case 38:
-+ return "&";
-+ case 39:
-+ return "'";
-+ case 40:
-+ return "(";
-+ case 41:
-+ return ")";
-+ case 42:
-+ return "*";
-+ case 43:
-+ return "+";
-+ case 44:
-+ return ",";
-+ case 45:
-+ return "-";
-+ case 46:
-+ return ".";
-+ case 47:
-+ return "/";
-+ case 48:
-+ return "0";
-+ case 49:
-+ return "1";
-+ case 50:
-+ return "2";
-+ case 51:
-+ return "3";
-+ case 52:
-+ return "4";
-+ case 53:
-+ return "5";
-+ case 54:
-+ return "6";
-+ case 55:
-+ return "7";
-+ case 56:
-+ return "8";
-+ case 57:
-+ return "9";
-+ case 58:
-+ return ":";
-+ case 59:
-+ return ";";
-+ case 60:
-+ return "<";
-+ case 61:
-+ return "=";
-+ case 62:
-+ return ">";
-+ case 63:
-+ return "?";
-+ case 64:
-+ return "@";
-+ case 65:
-+ return "A";
-+ case 66:
-+ return "B";
-+ case 67:
-+ return "C";
-+ case 68:
-+ return "D";
-+ case 69:
-+ return "E";
-+ case 70:
-+ return "F";
-+ case 71:
-+ return "G";
-+ case 72:
-+ return "H";
-+ case 73:
-+ return "I";
-+ case 74:
-+ return "J";
-+ case 75:
-+ return "K";
-+ case 76:
-+ return "L";
-+ case 77:
-+ return "M";
-+ case 78:
-+ return "N";
-+ case 79:
-+ return "O";
-+ case 80:
-+ return "P";
-+ case 81:
-+ return "Q";
-+ case 82:
-+ return "R";
-+ case 83:
-+ return "S";
-+ case 84:
-+ return "T";
-+ case 85:
-+ return "U";
-+ case 86:
-+ return "V";
-+ case 87:
-+ return "W";
-+ case 88:
-+ return "X";
-+ case 89:
-+ return "Y";
-+ case 90:
-+ return "Z";
-+ case 91:
-+ return "[";
-+ case 92:
-+ return "\\\\";
-+ case 93:
-+ return "]";
-+ case 94:
-+ return "^";
-+ case 95:
-+ return "_";
-+ case 96:
-+ return "`";
-+ case 97:
-+ return "a";
-+ case 98:
-+ return "b";
-+ case 99:
-+ return "c";
-+ case 100:
-+ return "d";
-+ case 101:
-+ return "e";
-+ case 102:
-+ return "f";
-+ case 103:
-+ return "g";
-+ case 104:
-+ return "h";
-+ case 105:
-+ return "i";
-+ case 106:
-+ return "j";
-+ case 107:
-+ return "k";
-+ case 108:
-+ return "l";
-+ case 109:
-+ return "m";
-+ case 110:
-+ return "n";
-+ case 111:
-+ return "o";
-+ case 112:
-+ return "p";
-+ case 113:
-+ return "q";
-+ case 114:
-+ return "r";
-+ case 115:
-+ return "s";
-+ case 116:
-+ return "t";
-+ case 117:
-+ return "u";
-+ case 118:
-+ return "v";
-+ case 119:
-+ return "w";
-+ case 120:
-+ return "x";
-+ case 121:
-+ return "y";
-+ case 122:
-+ return "z";
-+ case 123:
-+ return "{";
-+ case 124:
-+ return "|";
-+ case 125:
-+ return "}";
-+ case 126:
-+ return "~";
-+ case 127:
-+ return "\\x7F";
-+ case 128:
-+ return "\\x80";
-+ case 129:
-+ return "\\x81";
-+ case 130:
-+ return "\\x82";
-+ case 131:
-+ return "\\x83";
-+ case 132:
-+ return "\\x84";
-+ case 133:
-+ return "\\x85";
-+ case 134:
-+ return "\\x86";
-+ case 135:
-+ return "\\x87";
-+ case 136:
-+ return "\\x88";
-+ case 137:
-+ return "\\x89";
-+ case 138:
-+ return "\\x8A";
-+ case 139:
-+ return "\\x8B";
-+ case 140:
-+ return "\\x8C";
-+ case 141:
-+ return "\\x8D";
-+ case 142:
-+ return "\\x8E";
-+ case 143:
-+ return "\\x8F";
-+ case 144:
-+ return "\\x90";
-+ case 145:
-+ return "\\x91";
-+ case 146:
-+ return "\\x92";
-+ case 147:
-+ return "\\x93";
-+ case 148:
-+ return "\\x94";
-+ case 149:
-+ return "\\x95";
-+ case 150:
-+ return "\\x96";
-+ case 151:
-+ return "\\x97";
-+ case 152:
-+ return "\\x98";
-+ case 153:
-+ return "\\x99";
-+ case 154:
-+ return "\\x9A";
-+ case 155:
-+ return "\\x9B";
-+ case 156:
-+ return "\\x9C";
-+ case 157:
-+ return "\\x9D";
-+ case 158:
-+ return "\\x9E";
-+ case 159:
-+ return "\\x9F";
-+ case 160:
-+ return "\\xA0";
-+ case 161:
-+ return "\\xA1";
-+ case 162:
-+ return "\\xA2";
-+ case 163:
-+ return "\\xA3";
-+ case 164:
-+ return "\\xA4";
-+ case 165:
-+ return "\\xA5";
-+ case 166:
-+ return "\\xA6";
-+ case 167:
-+ return "\\xA7";
-+ case 168:
-+ return "\\xA8";
-+ case 169:
-+ return "\\xA9";
-+ case 170:
-+ return "\\xAA";
-+ case 171:
-+ return "\\xAB";
-+ case 172:
-+ return "\\xAC";
-+ case 173:
-+ return "\\xAD";
-+ case 174:
-+ return "\\xAE";
-+ case 175:
-+ return "\\xAF";
-+ case 176:
-+ return "\\xB0";
-+ case 177:
-+ return "\\xB1";
-+ case 178:
-+ return "\\xB2";
-+ case 179:
-+ return "\\xB3";
-+ case 180:
-+ return "\\xB4";
-+ case 181:
-+ return "\\xB5";
-+ case 182:
-+ return "\\xB6";
-+ case 183:
-+ return "\\xB7";
-+ case 184:
-+ return "\\xB8";
-+ case 185:
-+ return "\\xB9";
-+ case 186:
-+ return "\\xBA";
-+ case 187:
-+ return "\\xBB";
-+ case 188:
-+ return "\\xBC";
-+ case 189:
-+ return "\\xBD";
-+ case 190:
-+ return "\\xBE";
-+ case 191:
-+ return "\\xBF";
-+ case 192:
-+ return "\\xC0";
-+ case 193:
-+ return "\\xC1";
-+ case 194:
-+ return "\\xC2";
-+ case 195:
-+ return "\\xC3";
-+ case 196:
-+ return "\\xC4";
-+ case 197:
-+ return "\\xC5";
-+ case 198:
-+ return "\\xC6";
-+ case 199:
-+ return "\\xC7";
-+ case 200:
-+ return "\\xC8";
-+ case 201:
-+ return "\\xC9";
-+ case 202:
-+ return "\\xCA";
-+ case 203:
-+ return "\\xCB";
-+ case 204:
-+ return "\\xCC";
-+ case 205:
-+ return "\\xCD";
-+ case 206:
-+ return "\\xCE";
-+ case 207:
-+ return "\\xCF";
-+ case 208:
-+ return "\\xD0";
-+ case 209:
-+ return "\\xD1";
-+ case 210:
-+ return "\\xD2";
-+ case 211:
-+ return "\\xD3";
-+ case 212:
-+ return "\\xD4";
-+ case 213:
-+ return "\\xD5";
-+ case 214:
-+ return "\\xD6";
-+ case 215:
-+ return "\\xD7";
-+ case 216:
-+ return "\\xD8";
-+ case 217:
-+ return "\\xD9";
-+ case 218:
-+ return "\\xDA";
-+ case 219:
-+ return "\\xDB";
-+ case 220:
-+ return "\\xDC";
-+ case 221:
-+ return "\\xDD";
-+ case 222:
-+ return "\\xDE";
-+ case 223:
-+ return "\\xDF";
-+ case 224:
-+ return "\\xE0";
-+ case 225:
-+ return "\\xE1";
-+ case 226:
-+ return "\\xE2";
-+ case 227:
-+ return "\\xE3";
-+ case 228:
-+ return "\\xE4";
-+ case 229:
-+ return "\\xE5";
-+ case 230:
-+ return "\\xE6";
-+ case 231:
-+ return "\\xE7";
-+ case 232:
-+ return "\\xE8";
-+ case 233:
-+ return "\\xE9";
-+ case 234:
-+ return "\\xEA";
-+ case 235:
-+ return "\\xEB";
-+ case 236:
-+ return "\\xEC";
-+ case 237:
-+ return "\\xED";
-+ case 238:
-+ return "\\xEE";
-+ case 239:
-+ return "\\xEF";
-+ case 240:
-+ return "\\xF0";
-+ case 241:
-+ return "\\xF1";
-+ case 242:
-+ return "\\xF2";
-+ case 243:
-+ return "\\xF3";
-+ case 244:
-+ return "\\xF4";
-+ case 245:
-+ return "\\xF5";
-+ case 246:
-+ return "\\xF6";
-+ case 247:
-+ return "\\xF7";
-+ case 248:
-+ return "\\xF8";
-+ case 249:
-+ return "\\xF9";
-+ case 250:
-+ return "\\xFA";
-+ case 251:
-+ return "\\xFB";
-+ case 252:
-+ return "\\xFC";
-+ case 253:
-+ return "\\xFD";
-+ case 254:
-+ return "\\xFE";
-+ case 255:
-+ return "\\xFF";
-+ default:
-+ assert(0); /* never gets here */
-+ return "dead code";
-+ }
-+ assert(0); /* never gets here */
-+}
-+
-+#endif /* XML_DTD */
-+
-+static unsigned long
-+getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) {
-+ const char *const valueOrNull = getenv(variableName);
-+ const char * value;
-+ char *afterValue;
-+ unsigned long debugLevel;
-+ if (valueOrNull == NULL) {
-+ return defaultDebugLevel;
-+ }
-+ value = valueOrNull;
-+
-+ errno = 0;
-+ afterValue = (char *)value;
-+ debugLevel = strtoul(value, &afterValue, 10);
-+ if ((errno != 0) || (afterValue[0] != '\0')) {
-+ errno = 0;
-+ return defaultDebugLevel;
-+ }
-+
-+ return debugLevel;
-+}
-diff -ru expat-2.2.10/lib/xmltok.c misc/build/expat-2.2.10/lib/xmltok.c
---- expat-2.2.10/lib/xmltok.c 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/lib/xmltok.c 2022-10-11 15:32:24.331994000
-0400
-@@ -269,8 +269,14 @@
-
- #define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p))
- #define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc,
p))
--#define IS_INVALID_CHAR(enc, p, n)
\
-- (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
-+#ifdef XML_MIN_SIZE
-+# define IS_INVALID_CHAR(enc, p, n)
\
-+ (AS_NORMAL_ENCODING(enc)->isInvalid##n
\
-+ && AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
-+#else
-+# define IS_INVALID_CHAR(enc, p, n)
\
-+ (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
-+#endif
-
- #ifdef XML_MIN_SIZE
- # define IS_NAME_CHAR_MINBPC(enc, p)
\
-diff -ru expat-2.2.10/lib/xmltok_impl.c
misc/build/expat-2.2.10/lib/xmltok_impl.c
---- expat-2.2.10/lib/xmltok_impl.c 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/lib/xmltok_impl.c 2022-10-11 15:32:24.332994000
-0400
-@@ -61,7 +61,7 @@
- case BT_LEAD##n:
\
- if (end - ptr < n)
\
- return XML_TOK_PARTIAL_CHAR;
\
-- if (! IS_NAME_CHAR(enc, ptr, n)) {
\
-+ if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NAME_CHAR(enc, ptr, n)) {
\
- *nextTokPtr = ptr;
\
- return XML_TOK_INVALID;
\
- }
\
-@@ -90,7 +90,7 @@
- case BT_LEAD##n:
\
- if (end - ptr < n)
\
- return XML_TOK_PARTIAL_CHAR;
\
-- if (! IS_NMSTRT_CHAR(enc, ptr, n)) {
\
-+ if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NMSTRT_CHAR(enc, ptr, n)) {
\
- *nextTokPtr = ptr;
\
- return XML_TOK_INVALID;
\
- }
\
-@@ -1134,6 +1134,10 @@
- case BT_LEAD##n:
\
- if (end - ptr < n)
\
- return XML_TOK_PARTIAL_CHAR;
\
-+ if (IS_INVALID_CHAR(enc, ptr, n)) {
\
-+ *nextTokPtr = ptr;
\
-+ return XML_TOK_INVALID;
\
-+ }
\
- if (IS_NMSTRT_CHAR(enc, ptr, n)) {
\
- ptr += n;
\
- tok = XML_TOK_NAME;
\
-diff -ru expat-2.2.10/lib/xmltok_ns.c misc/build/expat-2.2.10/lib/xmltok_ns.c
---- expat-2.2.10/lib/xmltok_ns.c 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/lib/xmltok_ns.c 2022-10-11 15:32:24.333994000
-0400
-@@ -89,7 +89,7 @@
- static const ENCODING *
- NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) {
- # define ENCODING_MAX 128
-- char buf[ENCODING_MAX];
-+ char buf[ENCODING_MAX] = "";
- char *p = buf;
- int i;
- XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
-diff -ru expat-2.2.10/tests/benchmark/Makefile.in
misc/build/expat-2.2.10/tests/benchmark/Makefile.in
---- expat-2.2.10/tests/benchmark/Makefile.in 2020-10-03 11:37:06.000000000
-0400
-+++ misc/build/expat-2.2.10/tests/benchmark/Makefile.in 2021-07-18
18:17:02.796167000 -0400
-@@ -1,7 +1,7 @@
--# Makefile.in generated by automake 1.16.2 from Makefile.am.
-+# Makefile.in generated by automake 1.16.1 from Makefile.am.
- # @configure_input@
-
--# Copyright (C) 1994-2020 Free Software Foundation, Inc.
-+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
-
- # This Makefile.in is free software; the Free Software Foundation
- # gives unlimited permission to copy and/or distribute it,
-@@ -335,7 +335,6 @@
- prefix = @prefix@
- program_transform_name = @program_transform_name@
- psdir = @psdir@
--runstatedir = @runstatedir@
- sbindir = @sbindir@
- sharedstatedir = @sharedstatedir@
- srcdir = @srcdir@
-diff -ru expat-2.2.10/tests/Makefile.in
misc/build/expat-2.2.10/tests/Makefile.in
---- expat-2.2.10/tests/Makefile.in 2020-10-03 11:37:06.000000000 -0400
-+++ misc/build/expat-2.2.10/tests/Makefile.in 2021-07-18 18:17:02.770167000
-0400
-@@ -1,7 +1,7 @@
--# Makefile.in generated by automake 1.16.2 from Makefile.am.
-+# Makefile.in generated by automake 1.16.1 from Makefile.am.
- # @configure_input@
-
--# Copyright (C) 1994-2020 Free Software Foundation, Inc.
-+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
-
- # This Makefile.in is free software; the Free Software Foundation
- # gives unlimited permission to copy and/or distribute it,
-@@ -616,7 +616,6 @@
- prefix = @prefix@
- program_transform_name = @program_transform_name@
- psdir = @psdir@
--runstatedir = @runstatedir@
- sbindir = @sbindir@
- sharedstatedir = @sharedstatedir@
- srcdir = @srcdir@
-diff -ru expat-2.2.10/tests/minicheck.c
misc/build/expat-2.2.10/tests/minicheck.c
---- expat-2.2.10/tests/minicheck.c 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/tests/minicheck.c 2022-10-11 15:32:24.333994000
-0400
-@@ -141,11 +141,18 @@
- }
-
- static void
--add_failure(SRunner *runner, int verbosity) {
-- runner->nfailures++;
-+handle_success(int verbosity) {
- if (verbosity >= CK_VERBOSE) {
-- printf("%s:%d: %s\n", _check_current_filename, _check_current_lineno,
-- _check_current_function);
-+ printf("PASS: %s\n", _check_current_function);
-+ }
-+}
-+
-+static void
-+handle_failure(SRunner *runner, int verbosity, const char *phase_info) {
-+ runner->nfailures++;
-+ if (verbosity != CK_SILENT) {
-+ printf("FAIL: %s (%s at %s:%d)\n", _check_current_function, phase_info,
-+ _check_current_filename, _check_current_lineno);
- }
- }
-
-@@ -164,14 +171,14 @@
- if (tc->setup != NULL) {
- /* setup */
- if (setjmp(env)) {
-- add_failure(runner, verbosity);
-+ handle_failure(runner, verbosity, "during setup");
- continue;
- }
- tc->setup();
- }
- /* test */
- if (setjmp(env)) {
-- add_failure(runner, verbosity);
-+ handle_failure(runner, verbosity, "during actual test");
- continue;
- }
- (tc->tests[i])();
-@@ -179,15 +186,17 @@
- /* teardown */
- if (tc->teardown != NULL) {
- if (setjmp(env)) {
-- add_failure(runner, verbosity);
-+ handle_failure(runner, verbosity, "during teardown");
- continue;
- }
- tc->teardown();
- }
-+
-+ handle_success(verbosity);
- }
- tc = tc->next_tcase;
- }
-- if (verbosity) {
-+ if (verbosity != CK_SILENT) {
- int passed = runner->nchecks - runner->nfailures;
- double percentage = ((double)passed) / runner->nchecks;
- int display = (int)(percentage * 100);
-@@ -203,8 +212,8 @@
- it is.
- */
- UNUSED_P(condition);
-- UNUSED_P(file);
-- UNUSED_P(line);
-+ _check_current_filename = file;
-+ _check_current_lineno = line;
- if (msg != NULL) {
- const int has_newline = (msg[strlen(msg) - 1] == '\n');
- fprintf(stderr, "ERROR: %s%s", msg, has_newline ? "" : "\n");
-diff -ru expat-2.2.10/tests/runtests.c misc/build/expat-2.2.10/tests/runtests.c
---- expat-2.2.10/tests/runtests.c 2020-10-03 11:14:57.000000000 -0400
-+++ misc/build/expat-2.2.10/tests/runtests.c 2022-10-11 18:20:29.493872000
-0400
-@@ -45,6 +45,7 @@
- #include <stddef.h> /* ptrdiff_t */
- #include <ctype.h>
- #include <limits.h>
-+#include <math.h> /* NAN, INFINITY, isnan */
-
- #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600)
- /* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */
-@@ -72,7 +73,7 @@
- #include "expat.h"
- #include "chardata.h"
- #include "structdata.h"
--#include "internal.h" /* for UNUSED_P only */
-+#include "internal.h"
- #include "minicheck.h"
- #include "memcheck.h"
- #include "siphash.h"
-@@ -4904,6 +4905,78 @@
- }
- END_TEST
-
-+void
-+suspending_comment_handler(void *userData, const XML_Char *data) {
-+ UNUSED_P(data);
-+ XML_Parser parser = (XML_Parser)userData;
-+ XML_StopParser(parser, XML_TRUE);
-+}
-+
-+START_TEST(test_suspend_resume_internal_entity_issue_629) {
-+ const char *const text
-+ = "<!DOCTYPE a [<!ENTITY e '<!--COMMENT-->a'>]><a>&e;<b>\n"
-+ "<"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-+ "/>"
-+ "</b></a>";
-+ const size_t firstChunkSizeBytes = 54;
-+
-+ XML_Parser parser = XML_ParserCreate(NULL);
-+ XML_SetUserData(parser, parser);
-+ XML_SetCommentHandler(parser, suspending_comment_handler);
-+
-+ if (XML_Parse(parser, text, (int)firstChunkSizeBytes, XML_FALSE)
-+ != XML_STATUS_SUSPENDED)
-+ xml_failure(parser);
-+ if (XML_ResumeParser(parser) != XML_STATUS_OK)
-+ xml_failure(parser);
-+ if (XML_Parse(parser, text + firstChunkSizeBytes,
-+ (int)(strlen(text) - firstChunkSizeBytes), XML_TRUE)
-+ != XML_STATUS_OK)
-+ xml_failure(parser);
-+ XML_ParserFree(parser);
-+}
-+END_TEST
-+
- /* Test syntax error is caught at parse resumption */
- START_TEST(test_resume_entity_with_syntax_error) {
- const char *text = "<!DOCTYPE doc [\n"
-@@ -11231,6 +11304,381 @@
- }
- END_TEST
-
-+#if defined(XML_DTD)
-+typedef enum XML_Status (*XmlParseFunction)(XML_Parser, const char *, int,
int);
-+
-+struct AccountingTestCase {
-+ const char *primaryText;
-+ const char *firstExternalText; /* often NULL */
-+ const char *secondExternalText; /* often NULL */
-+ const unsigned long long expectedCountBytesIndirectExtra;
-+ XML_Bool singleBytesWanted;
-+};
-+
-+static int
-+accounting_external_entity_ref_handler(XML_Parser parser,
-+ const XML_Char *context,
-+ const XML_Char *base,
-+ const XML_Char *systemId,
-+ const XML_Char *publicId) {
-+ UNUSED_P(context);
-+ UNUSED_P(base);
-+ UNUSED_P(publicId);
-+
-+ const struct AccountingTestCase *const testCase
-+ = (const struct AccountingTestCase *)XML_GetUserData(parser);
-+
-+ const char *externalText = NULL;
-+ if (xcstrcmp(systemId, XCS("first.ent")) == 0) {
-+ externalText = testCase->firstExternalText;
-+ } else if (xcstrcmp(systemId, XCS("second.ent")) == 0) {
-+ externalText = testCase->secondExternalText;
-+ } else {
-+ assert(! "systemId is neither \"first.ent\" nor \"second.ent\"");
-+ }
-+ assert(externalText);
-+
-+ XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
-+ assert(entParser);
-+
-+ const XmlParseFunction xmlParseFunction
-+ = testCase->singleBytesWanted ? _XML_Parse_SINGLE_BYTES : XML_Parse;
-+
-+ const enum XML_Status status = xmlParseFunction(
-+ entParser, externalText, (int)strlen(externalText), XML_TRUE);
-+
-+ XML_ParserFree(entParser);
-+ return status;
-+}
-+
-+START_TEST(test_accounting_precision) {
-+ const XML_Bool filled_later = XML_TRUE; /* value is arbitrary */
-+ struct AccountingTestCase cases[] = {
-+ {"<e/>", NULL, NULL, 0, 0},
-+ {"<e></e>", NULL, NULL, 0, 0},
-+
-+ /* Attributes */
-+ {"<e k1=\"v2\" k2=\"v2\"/>", NULL, NULL, 0, filled_later},
-+ {"<e k1=\"v2\" k2=\"v2\"></e>", NULL, NULL, 0, 0},
-+ {"<p:e xmlns:p=\"https://domain.invalid/\" />", NULL, NULL, 0,
-+ filled_later},
-+ {"<e k=\"&'><"\" />", NULL, NULL,
-+ sizeof(XML_Char) * 5 /* number of predefined entites */, filled_later},
-+ {"<e1 xmlns='https://example.org/'>\n"
-+ " <e2 xmlns=''/>\n"
-+ "</e1>",
-+ NULL, NULL, 0, filled_later},
-+
-+ /* Text */
-+ {"<e>text</e>", NULL, NULL, 0, filled_later},
-+ {"<e1><e2>text1<e3/>text2</e2></e1>", NULL, NULL, 0, filled_later},
-+ {"<e>&'><"</e>", NULL, NULL,
-+ sizeof(XML_Char) * 5 /* number of predefined entites */, filled_later},
-+ {"<e>A)</e>", NULL, NULL, 0, filled_later},
-+
-+ /* Prolog */
-+ {"<?xml version=\"1.0\"?><root/>", NULL, NULL, 0, filled_later},
-+
-+ /* Whitespace */
-+ {" <e1> <e2> </e2> </e1> ", NULL, NULL, 0, filled_later},
-+ {"<e1 ><e2 /></e1 >", NULL, NULL, 0, filled_later},
-+ {"<e1><e2 k = \"v\"/><e3 k = 'v'/></e1>", NULL, NULL, 0, filled_later},
-+
-+ /* Comments */
-+ {"<!-- Comment --><e><!-- Comment --></e>", NULL, NULL, 0,
filled_later},
-+
-+ /* Processing instructions */
-+ {"<?xml-stylesheet type=\"text/xsl\" href=\"https://domain.invalid/\"
media=\"all\"?><e/>",
-+ NULL, NULL, 0, filled_later},
-+ {"<?pi0?><?pi1 ?><?pi2 ?><!DOCTYPE r SYSTEM 'first.ent'><r/>",
-+ "<?pi3?><!ENTITY % e1 SYSTEM 'second.ent'><?pi4?>%e1;<?pi5?>",
"<?pi6?>",
-+ 0, filled_later},
-+
-+ /* CDATA */
-+ {"<e><![CDATA[one two three]]></e>", NULL, NULL, 0, filled_later},
-+
-+ /* Conditional sections */
-+ {"<!DOCTYPE r [\n"
-+ "<!ENTITY % draft 'INCLUDE'>\n"
-+ "<!ENTITY % final 'IGNORE'>\n"
-+ "<!ENTITY % import SYSTEM \"first.ent\">\n"
-+ "%import;\n"
-+ "]>\n"
-+ "<r/>\n",
-+ "<![%draft;[<!--1-->]]>\n"
-+ "<![%final;[<!--22-->]]>",
-+ NULL, sizeof(XML_Char) * (strlen("INCLUDE") + strlen("IGNORE")),
-+ filled_later},
-+
-+ /* General entities */
-+ {"<!DOCTYPE root [\n"
-+ "<!ENTITY nine \"123456789\">\n"
-+ "]>\n"
-+ "<root>&nine;</root>",
-+ NULL, NULL, sizeof(XML_Char) * strlen("123456789"), filled_later},
-+ {"<!DOCTYPE root [\n"
-+ "<!ENTITY nine \"123456789\">\n"
-+ "]>\n"
-+ "<root k1=\"&nine;\"/>",
-+ NULL, NULL, sizeof(XML_Char) * strlen("123456789"), filled_later},
-+ {"<!DOCTYPE root [\n"
-+ "<!ENTITY nine \"123456789\">\n"
-+ "<!ENTITY nine2 \"&nine;&nine;\">\n"
-+ "]>\n"
-+ "<root>&nine2;&nine2;&nine2;</root>",
-+ NULL, NULL,
-+ sizeof(XML_Char) * 3 /* calls to &nine2; */ * 2 /* calls to &nine; */
-+ * (strlen("&nine;") + strlen("123456789")),
-+ filled_later},
-+ {"<!DOCTYPE r [\n"
-+ " <!ENTITY five SYSTEM 'first.ent'>\n"
-+ "]>\n"
-+ "<r>&five;</r>",
-+ "12345", NULL, 0, filled_later},
-+
-+ /* Parameter entities */
-+ {"<!DOCTYPE r [\n"
-+ "<!ENTITY % comment \"<!---->\">\n"
-+ "%comment;\n"
-+ "]>\n"
-+ "<r/>",
-+ NULL, NULL, sizeof(XML_Char) * strlen("<!---->"), filled_later},
-+ {"<!DOCTYPE r [\n"
-+ "<!ENTITY % ninedef \"<!ENTITY nine "123456789">\">\n"
-+ "%ninedef;\n"
-+ "]>\n"
-+ "<r>&nine;</r>",
-+ NULL, NULL,
-+ sizeof(XML_Char)
-+ * (strlen("<!ENTITY nine \"123456789\">") + strlen("123456789")),
-+ filled_later},
-+ {"<!DOCTYPE r [\n"
-+ "<!ENTITY % comment \"<!--1-->\">\n"
-+ "<!ENTITY % comment2 \"%comment;<!--22-->%comment;\">\n"
-+ "%comment2;\n"
-+ "]>\n"
-+ "<r/>\n",
-+ NULL, NULL,
-+ sizeof(XML_Char)
-+ * (strlen("%comment;<!--22-->%comment;") + 2 * strlen("<!--1-->")),
-+ filled_later},
-+ {"<!DOCTYPE r [\n"
-+ " <!ENTITY % five \"12345\">\n"
-+ " <!ENTITY % five2def \"<!ENTITY five2
"[%five;][%five;]]]]">\">\n"
-+ " %five2def;\n"
-+ "]>\n"
-+ "<r>&five2;</r>",
-+ NULL, NULL, /* from "%five2def;": */
-+ sizeof(XML_Char)
-+ * (strlen("<!ENTITY five2 \"[%five;][%five;]]]]\">")
-+ + 2 /* calls to "%five;" */ * strlen("12345")
-+ + /* from "&five2;": */ strlen("[12345][12345]]]]")),
-+ filled_later},
-+ {"<!DOCTYPE r SYSTEM \"first.ent\">\n"
-+ "<r/>",
-+ "<!ENTITY % comment '<!--1-->'>\n"
-+ "<!ENTITY % comment2
'<!--22-->%comment;<!--22-->%comment;<!--22-->'>\n"
-+ "%comment2;",
-+ NULL,
-+ sizeof(XML_Char)
-+ * (strlen("<!--22-->%comment;<!--22-->%comment;<!--22-->")
-+ + 2 /* calls to "%comment;" */ * strlen("<!---->")),
-+ filled_later},
-+ {"<!DOCTYPE r SYSTEM 'first.ent'>\n"
-+ "<r/>",
-+ "<!ENTITY % e1 PUBLIC 'foo' 'second.ent'>\n"
-+ "<!ENTITY % e2 '<!--22-->%e1;<!--22-->'>\n"
-+ "%e2;\n",
-+ "<!--1-->", sizeof(XML_Char) * strlen("<!--22--><!--1--><!--22-->"),
-+ filled_later},
-+ {
-+ "<!DOCTYPE r SYSTEM 'first.ent'>\n"
-+ "<r/>",
-+ "<!ENTITY % e1 SYSTEM 'second.ent'>\n"
-+ "<!ENTITY % e2 '%e1;'>",
-+ "<?xml version='1.0' encoding='utf-8'?>\n"
-+ "hello\n"
-+ "xml" /* without trailing newline! */,
-+ 0,
-+ filled_later,
-+ },
-+ {
-+ "<!DOCTYPE r SYSTEM 'first.ent'>\n"
-+ "<r/>",
-+ "<!ENTITY % e1 SYSTEM 'second.ent'>\n"
-+ "<!ENTITY % e2 '%e1;'>",
-+ "<?xml version='1.0' encoding='utf-8'?>\n"
-+ "hello\n"
-+ "xml\n" /* with trailing newline! */,
-+ 0,
-+ filled_later,
-+ },
-+ {"<!DOCTYPE doc SYSTEM 'first.ent'>\n"
-+ "<doc></doc>\n",
-+ "<!ELEMENT doc EMPTY>\n"
-+ "<!ENTITY % e1 SYSTEM 'second.ent'>\n"
-+ "<!ENTITY % e2 '%e1;'>\n"
-+ "%e1;\n",
-+ "\xEF\xBB\xBF<!ATTLIST doc a1 CDATA 'value'>" /* UTF-8 BOM */,
-+ strlen("\xEF\xBB\xBF<!ATTLIST doc a1 CDATA 'value'>"), filled_later},
-+ {"<!DOCTYPE r [\n"
-+ " <!ENTITY five SYSTEM 'first.ent'>\n"
-+ "]>\n"
-+ "<r>&five;</r>",
-+ "\xEF\xBB\xBF" /* UTF-8 BOM */, NULL, 0, filled_later},
-+ };
-+
-+ const size_t countCases = sizeof(cases) / sizeof(cases[0]);
-+ size_t u = 0;
-+ for (; u < countCases; u++) {
-+ size_t v = 0;
-+ for (; v < 2; v++) {
-+ const XML_Bool singleBytesWanted = (v == 0) ? XML_FALSE : XML_TRUE;
-+ const unsigned long long expectedCountBytesDirect
-+ = strlen(cases[u].primaryText);
-+ const unsigned long long expectedCountBytesIndirect
-+ = (cases[u].firstExternalText ? strlen(cases[u].firstExternalText)
-+ : 0)
-+ + (cases[u].secondExternalText ?
strlen(cases[u].secondExternalText)
-+ : 0)
-+ + cases[u].expectedCountBytesIndirectExtra;
-+
-+ XML_Parser parser = XML_ParserCreate(NULL);
-+ XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
-+ if (cases[u].firstExternalText) {
-+ XML_SetExternalEntityRefHandler(parser,
-+
accounting_external_entity_ref_handler);
-+ XML_SetUserData(parser, (void *)&cases[u]);
-+ cases[u].singleBytesWanted = singleBytesWanted;
-+ }
-+
-+ const XmlParseFunction xmlParseFunction
-+ = singleBytesWanted ? _XML_Parse_SINGLE_BYTES : XML_Parse;
-+
-+ enum XML_Status status
-+ = xmlParseFunction(parser, cases[u].primaryText,
-+ (int)strlen(cases[u].primaryText), XML_TRUE);
-+ if (status != XML_STATUS_OK) {
-+ _xml_failure(parser, __FILE__, __LINE__);
-+ }
-+
-+ const unsigned long long actualCountBytesDirect
-+ = testingAccountingGetCountBytesDirect(parser);
-+ const unsigned long long actualCountBytesIndirect
-+ = testingAccountingGetCountBytesIndirect(parser);
-+
-+ XML_ParserFree(parser);
-+
-+ if (actualCountBytesDirect != expectedCountBytesDirect) {
-+ fprintf(
-+ stderr,
-+ "Document " EXPAT_FMT_SIZE_T("") " of " EXPAT_FMT_SIZE_T("") ",
%s: Expected " EXPAT_FMT_ULL(
-+ "") " count direct bytes, got " EXPAT_FMT_ULL("") "
instead.\n",
-+ u + 1, countCases, singleBytesWanted ? "single bytes" : "chunks",
-+ expectedCountBytesDirect, actualCountBytesDirect);
-+ fail("Count of direct bytes is off");
-+ }
-+
-+ if (actualCountBytesIndirect != expectedCountBytesIndirect) {
-+ fprintf(
-+ stderr,
-+ "Document " EXPAT_FMT_SIZE_T("") " of " EXPAT_FMT_SIZE_T("") ",
%s: Expected " EXPAT_FMT_ULL(
-+ "") " count indirect bytes, got " EXPAT_FMT_ULL("") "
instead.\n",
-+ u + 1, countCases, singleBytesWanted ? "single bytes" : "chunks",
-+ expectedCountBytesIndirect, actualCountBytesIndirect);
-+ fail("Count of indirect bytes is off");
-+ }
-+ }
-+ }
-+}
-+END_TEST
-+
-+START_TEST(test_billion_laughs_attack_protection_api) {
-+ XML_Parser parserWithoutParent = XML_ParserCreate(NULL);
-+ XML_Parser parserWithParent
-+ = XML_ExternalEntityParserCreate(parserWithoutParent, NULL, NULL);
-+ if (parserWithoutParent == NULL)
-+ fail("parserWithoutParent is NULL");
-+ if (parserWithParent == NULL)
-+ fail("parserWithParent is NULL");
-+
-+ // XML_SetBillionLaughsAttackProtectionMaximumAmplification, error cases
-+ if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(NULL, 123.0f)
-+ == XML_TRUE)
-+ fail("Call with NULL parser is NOT supposed to succeed");
-+ if
(XML_SetBillionLaughsAttackProtectionMaximumAmplification(parserWithParent,
-+ 123.0f)
-+ == XML_TRUE)
-+ fail("Call with non-root parser is NOT supposed to succeed");
-+ if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
-+ parserWithoutParent, NAN)
-+ == XML_TRUE)
-+ fail("Call with NaN limit is NOT supposed to succeed");
-+ if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
-+ parserWithoutParent, -1.0f)
-+ == XML_TRUE)
-+ fail("Call with negative limit is NOT supposed to succeed");
-+ if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
-+ parserWithoutParent, 0.9f)
-+ == XML_TRUE)
-+ fail("Call with positive limit <1.0 is NOT supposed to succeed");
-+
-+ // XML_SetBillionLaughsAttackProtectionMaximumAmplification, success cases
-+ if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
-+ parserWithoutParent, 1.0f)
-+ == XML_FALSE)
-+ fail("Call with positive limit >=1.0 is supposed to succeed");
-+ if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
-+ parserWithoutParent, 123456.789f)
-+ == XML_FALSE)
-+ fail("Call with positive limit >=1.0 is supposed to succeed");
-+ if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
-+ parserWithoutParent, INFINITY)
-+ == XML_FALSE)
-+ fail("Call with positive limit >=1.0 is supposed to succeed");
-+
-+ // XML_SetBillionLaughsAttackProtectionActivationThreshold, error cases
-+ if (XML_SetBillionLaughsAttackProtectionActivationThreshold(NULL, 123)
-+ == XML_TRUE)
-+ fail("Call with NULL parser is NOT supposed to succeed");
-+ if
(XML_SetBillionLaughsAttackProtectionActivationThreshold(parserWithParent,
-+ 123)
-+ == XML_TRUE)
-+ fail("Call with non-root parser is NOT supposed to succeed");
-+
-+ // XML_SetBillionLaughsAttackProtectionActivationThreshold, success cases
-+ if (XML_SetBillionLaughsAttackProtectionActivationThreshold(
-+ parserWithoutParent, 123)
-+ == XML_FALSE)
-+ fail("Call with non-NULL parentless parser is supposed to succeed");
-+
-+ XML_ParserFree(parserWithParent);
-+ XML_ParserFree(parserWithoutParent);
-+}
-+END_TEST
-+
-+START_TEST(test_helper_unsigned_char_to_printable) {
-+ // Smoke test
-+ unsigned char uc = 0;
-+ for (; uc < (unsigned char)-1; uc++) {
-+ const char *const printable = unsignedCharToPrintable(uc);
-+ if (printable == NULL)
-+ fail("unsignedCharToPrintable returned NULL");
-+ if (strlen(printable) < (size_t)1)
-+ fail("unsignedCharToPrintable returned empty string");
-+ }
-+
-+ // Two concrete samples
-+ if (strcmp(unsignedCharToPrintable('A'), "A") != 0)
-+ fail("unsignedCharToPrintable result mistaken");
-+ if (strcmp(unsignedCharToPrintable('\\'), "\\\\") != 0)
-+ fail("unsignedCharToPrintable result mistaken");
-+}
-+END_TEST
-+#endif // defined(XML_DTD)
-+
-+
-+
- static Suite *
- make_suite(void) {
- Suite *s = suite_create("basic");
-@@ -11239,6 +11687,9 @@
- TCase *tc_misc = tcase_create("miscellaneous tests");
- TCase *tc_alloc = tcase_create("allocation tests");
- TCase *tc_nsalloc = tcase_create("namespace allocation tests");
-+#if defined(XML_DTD)
-+ TCase *tc_accounting = tcase_create("accounting tests");
-+#endif
-
- suite_add_tcase(s, tc_basic);
- tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
-@@ -11387,6 +11838,8 @@
- tcase_add_test(tc_basic, test_partial_char_in_epilog);
- tcase_add_test(tc_basic, test_hash_collision);
- tcase_add_test__ifdef_xml_dtd(tc_basic,
test_suspend_resume_internal_entity);
-+ tcase_add_test__ifdef_xml_dtd(tc_basic,
-+
test_suspend_resume_internal_entity_issue_629);
- tcase_add_test__ifdef_xml_dtd(tc_basic,
test_resume_entity_with_syntax_error);
- tcase_add_test__ifdef_xml_dtd(tc_basic,
test_suspend_resume_parameter_entity);
- tcase_add_test(tc_basic, test_restart_on_error);
-@@ -11603,6 +12056,13 @@
- tcase_add_test(tc_nsalloc, test_nsalloc_long_systemid_in_ext);
- tcase_add_test(tc_nsalloc, test_nsalloc_prefixed_element);
-
-+#if defined(XML_DTD)
-+ suite_add_tcase(s, tc_accounting);
-+ 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);
-+#endif
-+
- return s;
- }
-
-diff -ru expat-2.2.10/xmlwf/Makefile.in
misc/build/expat-2.2.10/xmlwf/Makefile.in
---- expat-2.2.10/xmlwf/Makefile.in 2020-10-03 11:37:06.000000000 -0400
-+++ misc/build/expat-2.2.10/xmlwf/Makefile.in 2021-07-18 18:17:02.826167000
-0400
-@@ -1,7 +1,7 @@
--# Makefile.in generated by automake 1.16.2 from Makefile.am.
-+# Makefile.in generated by automake 1.16.1 from Makefile.am.
- # @configure_input@
-
--# Copyright (C) 1994-2020 Free Software Foundation, Inc.
-+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
-
- # This Makefile.in is free software; the Free Software Foundation
- # gives unlimited permission to copy and/or distribute it,
-@@ -344,7 +344,6 @@
- prefix = @prefix@
- program_transform_name = @program_transform_name@
- psdir = @psdir@
--runstatedir = @runstatedir@
- sbindir = @sbindir@
- sharedstatedir = @sharedstatedir@
- srcdir = @srcdir@
-diff -ru expat-2.2.10/xmlwf/xmltchar.h misc/build/expat-2.2.10/xmlwf/xmltchar.h
---- expat-2.2.10/xmlwf/xmltchar.h 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/xmlwf/xmltchar.h 2021-07-18 17:21:48.697559000
-0400
-@@ -54,6 +54,8 @@
- # define tmain wmain
- # define tremove _wremove
- # define tchar wchar_t
-+# define tcstof wcstof
-+# define tcstoull wcstoull
- #else /* not XML_UNICODE */
- # define T(x) x
- # define ftprintf fprintf
-@@ -71,4 +73,6 @@
- # define tmain main
- # define tremove remove
- # define tchar char
-+# define tcstof strtof
-+# define tcstoull strtoull
- #endif /* not XML_UNICODE */
-diff -ru expat-2.2.10/xmlwf/xmlwf.c misc/build/expat-2.2.10/xmlwf/xmlwf.c
---- expat-2.2.10/xmlwf/xmlwf.c 2020-09-25 13:47:39.000000000 -0400
-+++ misc/build/expat-2.2.10/xmlwf/xmlwf.c 2021-08-25 18:35:36.883146000
-0400
-@@ -30,11 +30,15 @@
- USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-+#include <expat_config.h>
-+
- #include <assert.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <stddef.h>
- #include <string.h>
-+#include <math.h> /* for isnan */
-+#include <errno.h>
-
- #include "expat.h"
- #include "codepage.h"
-@@ -50,6 +54,14 @@
- # include <wchar.h>
- #endif
-
-+enum ExitCode {
-+ XMLWF_EXIT_SUCCESS = 0,
-+ XMLWF_EXIT_INTERNAL_ERROR = 1,
-+ XMLWF_EXIT_NOT_WELLFORMED = 2,
-+ XMLWF_EXIT_OUTPUT_ERROR = 3,
-+ XMLWF_EXIT_USAGE_ERROR = 4,
-+};
-+
- /* Structures for handler user data */
- typedef struct NotationList {
- struct NotationList *next;
-@@ -875,6 +887,12 @@
- T(" -t write no XML output for [t]iming of plain parsing\n")
- T(" -N enable adding doctype and [n]otation declarations\n")
- T("\n")
-+ T("billion laughs attack protection:\n")
-+ T(" NOTE: If you ever need to increase these values for non-attack
payload, please file a bug report.\n")
-+ T("\n")
-+ T(" -a FACTOR set maximum tolerated [a]mplification factor
(default: 100.0)\n")
-+ T(" -b BYTES set number of output [b]ytes needed to activate
(default: 8 MiB)\n")
-+ T("\n")
- T("info arguments:\n")
- T(" -h show this [h]elp message and exit\n")
- T(" -v show program's [v]ersion number and exit\n")
-@@ -891,6 +909,19 @@
- int wmain(int argc, XML_Char **argv);
- #endif
-
-+#define XMLWF_SHIFT_ARG_INTO(constCharStarTarget, argc, argv, i, j)
\
-+ {
\
-+ if (argv[i][j + 1] == T('\0')) {
\
-+ if (++i == argc)
\
-+ usage(argv[0], XMLWF_EXIT_USAGE_ERROR);
\
-+ constCharStarTarget = argv[i];
\
-+ } else {
\
-+ constCharStarTarget = argv[i] + j + 1;
\
-+ }
\
-+ i++;
\
-+ j = 0;
\
-+ }
-+
- int
- tmain(int argc, XML_Char **argv) {
- int i, j;
-@@ -902,6 +933,11 @@
- int useNamespaces = 0;
- int requireStandalone = 0;
- int requiresNotations = 0;
-+
-+ float attackMaximumAmplification = -1.0f; /* signaling "not set" */
-+ unsigned long long attackThresholdBytes;
-+ XML_Bool attackThresholdGiven = XML_FALSE;
-+
- enum XML_ParamEntityParsing paramEntityParsing
- = XML_PARAM_ENTITY_PARSING_NEVER;
- int useStdin = 0;
-@@ -990,6 +1026,49 @@
- case T('v'):
- showVersion(argv[0]);
- return 0;
-+ case T('a'): {
-+ const XML_Char *valueText = NULL;
-+ XMLWF_SHIFT_ARG_INTO(valueText, argc, argv, i, j);
-+
-+ errno = 0;
-+ XML_Char *afterValueText = (XML_Char *)valueText;
-+ attackMaximumAmplification = tcstof(valueText, &afterValueText);
-+ if ((errno != 0) || (afterValueText[0] != T('\0'))
-+ || isnan(attackMaximumAmplification)
-+ || (attackMaximumAmplification < 1.0f)) {
-+ // This prevents tperror(..) from reporting misleading "[..]: Success"
-+ errno = ERANGE;
-+ tperror(T("invalid amplification limit") T(
-+ " (needs a floating point number greater or equal than 1.0)"));
-+ exit(XMLWF_EXIT_USAGE_ERROR);
-+ }
-+#ifndef XML_DTD
-+ ftprintf(stderr, T("Warning: Given amplification limit ignored") T(
-+ ", xmlwf has been compiled without DTD
support.\n"));
-+#endif
-+ break;
-+ }
-+ case T('b'): {
-+ const XML_Char *valueText = NULL;
-+ XMLWF_SHIFT_ARG_INTO(valueText, argc, argv, i, j);
-+
-+ errno = 0;
-+ XML_Char *afterValueText = (XML_Char *)valueText;
-+ attackThresholdBytes = tcstoull(valueText, &afterValueText, 10);
-+ if ((errno != 0) || (afterValueText[0] != T('\0'))) {
-+ // This prevents tperror(..) from reporting misleading "[..]: Success"
-+ errno = ERANGE;
-+ tperror(T("invalid ignore threshold")
-+ T(" (needs an integer from 0 to 2^64-1)"));
-+ exit(XMLWF_EXIT_USAGE_ERROR);
-+ }
-+ attackThresholdGiven = XML_TRUE;
-+#ifndef XML_DTD
-+ ftprintf(stderr, T("Warning: Given attack threshold ignored") T(
-+ ", xmlwf has been compiled without DTD
support.\n"));
-+#endif
-+ break;
-+ }
- case T('\0'):
- if (j > 1) {
- i++;
-@@ -1020,6 +1099,19 @@
- exit(1);
- }
-
-+ if (attackMaximumAmplification != -1.0f) {
-+#ifdef XML_DTD
-+ XML_SetBillionLaughsAttackProtectionMaximumAmplification(
-+ parser, attackMaximumAmplification);
-+#endif
-+ }
-+ if (attackThresholdGiven) {
-+#ifdef XML_DTD
-+ XML_SetBillionLaughsAttackProtectionActivationThreshold(
-+ parser, attackThresholdBytes);
-+#endif
-+ }
-+
- if (requireStandalone)
- XML_SetNotStandaloneHandler(parser, notStandalone);
- XML_SetParamEntityParsing(parser, paramEntityParsing);
-diff -ru expat-2.2.10/xmlwf/xmlwf_helpgen.py
misc/build/expat-2.2.10/xmlwf/xmlwf_helpgen.py
---- expat-2.2.10/xmlwf/xmlwf_helpgen.py 2020-09-25 13:47:39.000000000
-0400
-+++ misc/build/expat-2.2.10/xmlwf/xmlwf_helpgen.py 2021-07-18
17:21:48.697559000 -0400
-@@ -57,6 +57,14 @@
- output_mode.add_argument('-t', action='store_true', help='write no XML output
for [t]iming of plain parsing')
- output_related.add_argument('-N', action='store_true', help='enable adding
doctype and [n]otation declarations')
-
-+billion_laughs = parser.add_argument_group('billion laughs attack protection',
-+ description='NOTE: '
-+ 'If you ever need to
increase these values '
-+ 'for non-attack
payload, please file a bug report.')
-+billion_laughs.add_argument('-a', metavar='FACTOR',
-+ help='set maximum tolerated [a]mplification
factor (default: 100.0)')
-+billion_laughs.add_argument('-b', metavar='BYTES', help='set number of output
[b]ytes needed to activate (default: 8 MiB)')
-+
- parser.add_argument('files', metavar='FILE', nargs='*', help='file to process
(default: STDIN)')
-
- info = parser.add_argument_group('info arguments')