Explorar el Código

Expat 2.5.0

Source commit: 4beb97a00a75286913b089a097437d9400c279a6
Martin Prikryl hace 3 años
padre
commit
4dd5406f18

+ 6 - 6
libs/expat/CMake.README

@@ -3,25 +3,25 @@
 The cmake based buildsystem for expat works on Windows (cygwin, mingw, Visual
 Studio) and should work on all other platform cmake supports.
 
-Assuming ~/expat-2.4.9 is the source directory of expat, add a subdirectory
+Assuming ~/expat-2.5.0 is the source directory of expat, add a subdirectory
 build and change into that directory:
-~/expat-2.4.9$ mkdir build && cd build
-~/expat-2.4.9/build$
+~/expat-2.5.0$ mkdir build && cd build
+~/expat-2.5.0/build$
 
 From that directory, call cmake first, then call make, make test and
 make install in the usual way:
-~/expat-2.4.9/build$ cmake ..
+~/expat-2.5.0/build$ cmake ..
 -- The C compiler identification is GNU
 -- The CXX compiler identification is GNU
 ....
 -- Configuring done
 -- Generating done
--- Build files have been written to: /home/patrick/expat-2.4.9/build
+-- Build files have been written to: /home/patrick/expat-2.5.0/build
 
 If you want to specify the install location for your files, append
 -DCMAKE_INSTALL_PREFIX=/your/install/path to the cmake call.
 
-~/expat-2.4.9/build$ make && make test && make install
+~/expat-2.5.0/build$ make && make test && make install
 Scanning dependencies of target expat
 [  5%] Building C object CMakeFiles/expat.dir/lib/xmlparse.c.o
 [ 11%] Building C object CMakeFiles/expat.dir/lib/xmlrole.c.o

+ 13 - 13
libs/expat/CMakeLists.txt

@@ -38,7 +38,7 @@ cmake_minimum_required(VERSION 3.1.3)
 
 project(expat
     VERSION
-        2.4.9
+        2.5.0
     LANGUAGES
         C
 )
@@ -436,9 +436,9 @@ foreach(build_type_upper
     set_property(TARGET expat PROPERTY ${build_type_upper}_POSTFIX ${EXPAT_${build_type_upper}_POSTFIX})
 endforeach()
 
-set(LIBCURRENT 9)   # sync
-set(LIBREVISION 9)  # with
-set(LIBAGE 8)       # configure.ac!
+set(LIBCURRENT 9)    # sync
+set(LIBREVISION 10)  # with
+set(LIBAGE 8)        # configure.ac!
 math(EXPR LIBCURRENT_MINUS_AGE "${LIBCURRENT} - ${LIBAGE}")
 
 if(NOT WIN32)
@@ -459,7 +459,7 @@ if(NOT WIN32)
     endif()
 endif()
 
-if(MINGW)
+if(MINGW AND EXPAT_SHARED_LIBS)
     set_target_properties(expat PROPERTIES SUFFIX "-${LIBCURRENT_MINUS_AGE}.dll")
 endif()
 
@@ -469,7 +469,7 @@ if(WIN32 AND NOT MINGW)
     #       Everything but MSVC is already adding prefix "lib", automatically.
     # NOTE: "set_property(TARGET expat PROPERTY PREFIX lib)" would only affect *.dll
     #       files but not *.lib files, so we have to rely on property OUTPUT_NAME, instead.
-    #       Property CMAKE_*_POSTFIX still applies.
+    #       Target property <CONFIG>_POSTFIX still applies.
     set(_EXPAT_OUTPUT_NAME libexpat)
     set_property(TARGET expat PROPERTY OUTPUT_NAME ${_EXPAT_OUTPUT_NAME})
 else()
@@ -520,8 +520,8 @@ if(EXPAT_BUILD_PKGCONFIG)
     foreach(_build_type ${CMAKE_BUILD_TYPE} Debug Release RelWithDebInfo MinSizeRel)
         string(TOLOWER "${_build_type}" _build_type_lower)
         string(TOUPPER "${_build_type}" _build_type_upper)
-        set_property(TARGET expat PROPERTY "pkgconfig_${_build_type_lower}_name" "expat${CMAKE_${_build_type_upper}_POSTFIX}")
-        set_property(TARGET expat PROPERTY "pkgconfig_${_build_type_lower}_output_name" "${_EXPAT_OUTPUT_NAME}${CMAKE_${_build_type_upper}_POSTFIX}")
+        set_property(TARGET expat PROPERTY "pkgconfig_${_build_type_lower}_name" "expat${EXPAT_${_build_type_upper}_POSTFIX}")
+        set_property(TARGET expat PROPERTY "pkgconfig_${_build_type_lower}_output_name" "${_EXPAT_OUTPUT_NAME}${EXPAT_${_build_type_upper}_POSTFIX}")
         if(_EXPAT_LIBM_FOUND)
             set_property(TARGET expat PROPERTY "pkgconfig_libm" "-lm")
         else()
@@ -580,12 +580,12 @@ endif()
 #
 if(EXPAT_BUILD_EXAMPLES)
     add_executable(elements examples/elements.c)
-    set_property(TARGET elements PROPERTY RUNTIME_OUTPUT_DIRECTORY examples)
-    target_link_libraries(elements expat)
-
     add_executable(outline examples/outline.c)
-    set_property(TARGET outline PROPERTY RUNTIME_OUTPUT_DIRECTORY examples)
-    target_link_libraries(outline expat)
+
+    foreach(_target elements outline)
+        set_property(TARGET ${_target} PROPERTY RUNTIME_OUTPUT_DIRECTORY examples)
+        target_link_libraries(${_target} expat)
+    endforeach()
 endif()
 
 #

+ 34 - 0
libs/expat/Changes

@@ -2,6 +2,40 @@ NOTE: We are looking for help with a few things:
       https://github.com/libexpat/libexpat/labels/help%20wanted
       If you can help, please get in touch.  Thanks!
 
+Release 2.5.0 Tue October 25 2022
+        Security fixes:
+  #616 #649 #650  CVE-2022-43680 -- Fix heap use-after-free after overeager
+                    destruction of a shared DTD in function
+                    XML_ExternalEntityParserCreate in out-of-memory situations.
+                    Expected impact is denial of service or potentially
+                    arbitrary code execution.
+
+        Bug fixes:
+       #612 #645  Fix curruption from undefined entities
+       #613 #654  Fix case when parsing was suspended while processing nested
+                    entities
+  #616 #652 #653  Stop leaking opening tag bindings after a closing tag
+                    mismatch error where a parser is reset through
+                    XML_ParserReset and then reused to parse
+            #656  CMake: Fix generation of pkg-config file
+            #658  MinGW|CMake: Fix static library name
+
+        Other changes:
+            #663  Protect header expat_config.h from multiple inclusion
+            #666  examples: Make use of XML_GetBuffer and be more
+                    consistent across examples
+            #648  Address compiler warnings
+       #667 #668  Version info bumped from 9:9:8 to 9:10:8;
+                    see https://verbump.de/ for what these numbers do
+
+        Special thanks to:
+            Jann Horn
+            Mark Brand
+            Osyotr
+            Rhodri James
+                 and
+            Google Project Zero
+
 Release 2.4.9 Tue September 20 2022
         Security fixes:
        #629 #640  CVE-2022-40674 -- Heap use-after-free vulnerability in

+ 1 - 1
libs/expat/README.md

@@ -5,7 +5,7 @@
 [![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
 
 
-# Expat, Release 2.4.9
+# Expat, Release 2.5.0
 
 This is Expat, a C library for parsing XML, started by
 [James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997.

+ 104 - 46
libs/expat/configure

@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for expat 2.4.9.
+# Generated by GNU Autoconf 2.71 for expat 2.5.0.
 #
 # Report bugs to <[email protected]>.
 #
@@ -621,8 +621,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='expat'
 PACKAGE_TARNAME='expat'
-PACKAGE_VERSION='2.4.9'
-PACKAGE_STRING='expat 2.4.9'
+PACKAGE_VERSION='2.5.0'
+PACKAGE_STRING='expat 2.5.0'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_URL=''
 
@@ -1415,7 +1415,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures expat 2.4.9 to adapt to many kinds of systems.
+\`configure' configures expat 2.5.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1486,7 +1486,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of expat 2.4.9:";;
+     short | recursive ) echo "Configuration of expat 2.5.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1620,7 +1620,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-expat configure 2.4.9
+expat configure 2.5.0
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1772,7 +1772,7 @@ else $as_nop
 #define $2 innocuous_$2
 
 /* System header to define __stub macros and hopefully few prototypes,
-   which can conflict with char $2 (); below.  */
+   which can conflict with char $2 (void); below.  */
 
 #include <limits.h>
 #undef $2
@@ -1783,7 +1783,7 @@ else $as_nop
 #ifdef __cplusplus
 extern "C"
 #endif
-char $2 ();
+char $2 (void);
 /* The GNU C library defines this for functions which it implements
     to always fail with ENOSYS.  Some functions are actually named
     something starting with __ and the normal name is an alias.  */
@@ -2251,7 +2251,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by expat $as_me 2.4.9, which was
+It was created by expat $as_me 2.5.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -3818,7 +3818,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='expat'
- VERSION='2.4.9'
+ VERSION='2.5.0'
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -3924,9 +3924,9 @@ fi
 
 
 
-LIBCURRENT=9   # sync
-LIBREVISION=9  # with
-LIBAGE=8       # CMakeLists.txt!
+LIBCURRENT=9    # sync
+LIBREVISION=10  # with
+LIBAGE=8        # CMakeLists.txt!
 
 ac_config_headers="$ac_config_headers expat_config.h"
 
@@ -3940,6 +3940,8 @@ ac_config_headers="$ac_config_headers expat_config.h"
 
 
 
+
+
 DEPDIR="${am__leading_dot}deps"
 
 ac_config_commands="$ac_config_commands depfiles"
@@ -13210,8 +13212,14 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
+   builtin and then its argument prototype would still apply.
+   The 'extern "C"' is for builds by C++ compilers;
+   although this is not generally supported in C code supporting it here
+   has little cost and some practical benefit (sr 110532).  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen (void);
 int
 main (void)
 {
@@ -13272,8 +13280,14 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char shl_load ();
+   builtin and then its argument prototype would still apply.
+   The 'extern "C"' is for builds by C++ compilers;
+   although this is not generally supported in C code supporting it here
+   has little cost and some practical benefit (sr 110532).  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load (void);
 int
 main (void)
 {
@@ -13316,8 +13330,14 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
+   builtin and then its argument prototype would still apply.
+   The 'extern "C"' is for builds by C++ compilers;
+   although this is not generally supported in C code supporting it here
+   has little cost and some practical benefit (sr 110532).  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen (void);
 int
 main (void)
 {
@@ -13355,8 +13375,14 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char dlopen ();
+   builtin and then its argument prototype would still apply.
+   The 'extern "C"' is for builds by C++ compilers;
+   although this is not generally supported in C code supporting it here
+   has little cost and some practical benefit (sr 110532).  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen (void);
 int
 main (void)
 {
@@ -13394,8 +13420,14 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char dld_link ();
+   builtin and then its argument prototype would still apply.
+   The 'extern "C"' is for builds by C++ compilers;
+   although this is not generally supported in C code supporting it here
+   has little cost and some practical benefit (sr 110532).  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link (void);
 int
 main (void)
 {
@@ -18708,22 +18740,23 @@ unsigned short int ascii_mm[] =
 		int use_ebcdic (int i) {
 		  return ebcdic_mm[i] + ebcdic_ii[i];
 		}
-		extern int foo;
-
-int
-main (void)
-{
-return use_ascii (foo) == use_ebcdic (foo);
-  ;
-  return 0;
-}
+		int
+		main (int argc, char **argv)
+		{
+		  /* Intimidate the compiler so that it does not
+		     optimize the arrays away.  */
+		  char *p = argv[0];
+		  ascii_mm[1] = *p++; ebcdic_mm[1] = *p++;
+		  ascii_ii[1] = *p++; ebcdic_ii[1] = *p++;
+		  return use_ascii (argc) == use_ebcdic (*p);
+		}
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"
+if ac_fn_c_try_link "$LINENO"
 then :
-  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+  if grep BIGenDianSyS conftest$ac_exeext >/dev/null; then
 	      ac_cv_c_bigendian=yes
 	    fi
-	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+	    if grep LiTTleEnDian conftest$ac_exeext >/dev/null ; then
 	      if test "$ac_cv_c_bigendian" = unknown; then
 		ac_cv_c_bigendian=no
 	      else
@@ -18732,7 +18765,8 @@ then :
 	      fi
 	    fi
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
 else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -19008,8 +19042,14 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char _mwvalidcheckl ();
+   builtin and then its argument prototype would still apply.
+   The 'extern "C"' is for builds by C++ compilers;
+   although this is not generally supported in C code supporting it here
+   has little cost and some practical benefit (sr 110532).  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _mwvalidcheckl (void);
 int
 main (void)
 {
@@ -19048,8 +19088,14 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char cos ();
+   builtin and then its argument prototype would still apply.
+   The 'extern "C"' is for builds by C++ compilers;
+   although this is not generally supported in C code supporting it here
+   has little cost and some practical benefit (sr 110532).  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cos (void);
 int
 main (void)
 {
@@ -19090,8 +19136,14 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char cos ();
+   builtin and then its argument prototype would still apply.
+   The 'extern "C"' is for builds by C++ compilers;
+   although this is not generally supported in C code supporting it here
+   has little cost and some practical benefit (sr 110532).  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cos (void);
 int
 main (void)
 {
@@ -19146,8 +19198,14 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-char arc4random_buf ();
+   builtin and then its argument prototype would still apply.
+   The 'extern "C"' is for builds by C++ compilers;
+   although this is not generally supported in C code supporting it here
+   has little cost and some practical benefit (sr 110532).  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char arc4random_buf (void);
 int
 main (void)
 {
@@ -20364,7 +20422,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by expat $as_me 2.4.9, which was
+This file was extended by expat $as_me 2.5.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -20432,7 +20490,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-expat config.status 2.4.9
+expat config.status 2.5.0
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 

+ 6 - 3
libs/expat/configure.ac

@@ -81,11 +81,14 @@ dnl
 dnl If the API changes incompatibly set LIBAGE back to 0
 dnl
 
-LIBCURRENT=9   # sync
-LIBREVISION=9  # with
-LIBAGE=8       # CMakeLists.txt!
+LIBCURRENT=9    # sync
+LIBREVISION=10  # with
+LIBAGE=8        # CMakeLists.txt!
 
 AC_CONFIG_HEADERS([expat_config.h])
+AH_TOP([#ifndef EXPAT_CONFIG_H
+#define EXPAT_CONFIG_H 1])
+AH_BOTTOM([#endif // ndef EXPAT_CONFIG_H])
 
 AM_PROG_AR
 AC_PROG_INSTALL

+ 1 - 1
libs/expat/doc/reference.html

@@ -50,7 +50,7 @@
   <div>
     <h1>
       The Expat XML Parser
-      <small>Release 2.4.9</small>
+      <small>Release 2.5.0</small>
     </h1>
   </div>
 <div class="content">

+ 1 - 1
libs/expat/doc/xmlwf.1

@@ -5,7 +5,7 @@
 \\$2 \(la\\$1\(ra\\$3
 ..
 .if \n(.g .mso www.tmac
-.TH XMLWF 1 "September 20, 2022" "" ""
+.TH XMLWF 1 "October 25, 2022" "" ""
 .SH NAME
 xmlwf \- Determines if an XML document is well-formed
 .SH SYNOPSIS

+ 1 - 1
libs/expat/doc/xmlwf.xml

@@ -21,7 +21,7 @@
           "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
   <!ENTITY dhfirstname "<firstname>Scott</firstname>">
   <!ENTITY dhsurname   "<surname>Bronson</surname>">
-  <!ENTITY dhdate      "<date>September 20, 2022</date>">
+  <!ENTITY dhdate      "<date>October 25, 2022</date>">
   <!-- Please adjust this^^ date whenever cutting a new release. -->
   <!ENTITY dhsection   "<manvolnum>1</manvolnum>">
   <!ENTITY dhemail     "<email>[email protected]</email>">

+ 33 - 14
libs/expat/examples/elements.c

@@ -14,7 +14,7 @@
    Copyright (c) 2001-2003 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2004-2006 Karl Waclawek <[email protected]>
    Copyright (c) 2005-2007 Steven Solie <[email protected]>
-   Copyright (c) 2016-2019 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2022 Sebastian Pipping <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2019      Zhongyuan Zhou <[email protected]>
    Licensed under the MIT license:
@@ -49,7 +49,6 @@
 #endif
 
 #ifdef XML_UNICODE_WCHAR_T
-#  include <wchar.h>
 #  define XML_FMT_STR "ls"
 #else
 #  define XML_FMT_STR "s"
@@ -58,7 +57,7 @@
 static void XMLCALL
 startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
   int i;
-  int *depthPtr = (int *)userData;
+  int *const depthPtr = (int *)userData;
   (void)atts;
 
   for (i = 0; i < *depthPtr; i++)
@@ -69,34 +68,54 @@ startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
 
 static void XMLCALL
 endElement(void *userData, const XML_Char *name) {
-  int *depthPtr = (int *)userData;
+  int *const depthPtr = (int *)userData;
   (void)name;
 
   *depthPtr -= 1;
 }
 
 int
-main(int argc, char *argv[]) {
-  char buf[BUFSIZ];
+main(void) {
   XML_Parser parser = XML_ParserCreate(NULL);
   int done;
   int depth = 0;
-  (void)argc;
-  (void)argv;
+
+  if (! parser) {
+    fprintf(stderr, "Couldn't allocate memory for parser\n");
+    return 1;
+  }
 
   XML_SetUserData(parser, &depth);
   XML_SetElementHandler(parser, startElement, endElement);
+
   do {
-    size_t len = fread(buf, 1, sizeof(buf), stdin);
-    done = len < sizeof(buf);
-    if (XML_Parse(parser, buf, (int)len, done) == XML_STATUS_ERROR) {
-      fprintf(stderr, "%" XML_FMT_STR " at line %" XML_FMT_INT_MOD "u\n",
-              XML_ErrorString(XML_GetErrorCode(parser)),
-              XML_GetCurrentLineNumber(parser));
+    void *const buf = XML_GetBuffer(parser, BUFSIZ);
+    if (! buf) {
+      fprintf(stderr, "Couldn't allocate memory for buffer\n");
+      XML_ParserFree(parser);
+      return 1;
+    }
+
+    const size_t len = fread(buf, 1, BUFSIZ, stdin);
+
+    if (ferror(stdin)) {
+      fprintf(stderr, "Read error\n");
+      XML_ParserFree(parser);
+      return 1;
+    }
+
+    done = feof(stdin);
+
+    if (XML_ParseBuffer(parser, (int)len, done) == XML_STATUS_ERROR) {
+      fprintf(stderr,
+              "Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
+              XML_GetCurrentLineNumber(parser),
+              XML_ErrorString(XML_GetErrorCode(parser)));
       XML_ParserFree(parser);
       return 1;
     }
   } while (! done);
+
   XML_ParserFree(parser);
   return 0;
 }

+ 39 - 38
libs/expat/examples/outline.c

@@ -12,7 +12,7 @@
    Copyright (c) 2001-2003 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2005-2007 Steven Solie <[email protected]>
    Copyright (c) 2005-2006 Karl Waclawek <[email protected]>
-   Copyright (c) 2016-2019 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2022 Sebastian Pipping <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Licensed under the MIT license:
 
@@ -51,73 +51,74 @@
 #  define XML_FMT_STR "s"
 #endif
 
-#define BUFFSIZE 8192
-
-char Buff[BUFFSIZE];
-
-int Depth;
-
 static void XMLCALL
-start(void *data, const XML_Char *el, const XML_Char **attr) {
+startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
   int i;
-  (void)data;
+  int *const depthPtr = (int *)userData;
 
-  for (i = 0; i < Depth; i++)
+  for (i = 0; i < *depthPtr; i++)
     printf("  ");
 
-  printf("%" XML_FMT_STR, el);
+  printf("%" XML_FMT_STR, name);
 
-  for (i = 0; attr[i]; i += 2) {
-    printf(" %" XML_FMT_STR "='%" XML_FMT_STR "'", attr[i], attr[i + 1]);
+  for (i = 0; atts[i]; i += 2) {
+    printf(" %" XML_FMT_STR "='%" XML_FMT_STR "'", atts[i], atts[i + 1]);
   }
 
   printf("\n");
-  Depth++;
+  *depthPtr += 1;
 }
 
 static void XMLCALL
-end(void *data, const XML_Char *el) {
-  (void)data;
-  (void)el;
+endElement(void *userData, const XML_Char *name) {
+  int *const depthPtr = (int *)userData;
+  (void)name;
 
-  Depth--;
+  *depthPtr -= 1;
 }
 
 int
-main(int argc, char *argv[]) {
-  XML_Parser p = XML_ParserCreate(NULL);
-  (void)argc;
-  (void)argv;
+main(void) {
+  XML_Parser parser = XML_ParserCreate(NULL);
+  int done;
+  int depth = 0;
 
-  if (! p) {
+  if (! parser) {
     fprintf(stderr, "Couldn't allocate memory for parser\n");
-    exit(-1);
+    return 1;
   }
 
-  XML_SetElementHandler(p, start, end);
+  XML_SetUserData(parser, &depth);
+  XML_SetElementHandler(parser, startElement, endElement);
 
-  for (;;) {
-    int done;
-    int len;
+  do {
+    void *const buf = XML_GetBuffer(parser, BUFSIZ);
+    if (! buf) {
+      fprintf(stderr, "Couldn't allocate memory for buffer\n");
+      XML_ParserFree(parser);
+      return 1;
+    }
+
+    const size_t len = fread(buf, 1, BUFSIZ, stdin);
 
-    len = (int)fread(Buff, 1, BUFFSIZE, stdin);
     if (ferror(stdin)) {
       fprintf(stderr, "Read error\n");
-      exit(-1);
+      XML_ParserFree(parser);
+      return 1;
     }
+
     done = feof(stdin);
 
-    if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) {
+    if (XML_ParseBuffer(parser, (int)len, done) == XML_STATUS_ERROR) {
       fprintf(stderr,
               "Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
-              XML_GetCurrentLineNumber(p),
-              XML_ErrorString(XML_GetErrorCode(p)));
-      exit(-1);
+              XML_GetCurrentLineNumber(parser),
+              XML_ErrorString(XML_GetErrorCode(parser)));
+      XML_ParserFree(parser);
+      return 1;
     }
+  } while (! done);
 
-    if (done)
-      break;
-  }
-  XML_ParserFree(p);
+  XML_ParserFree(parser);
   return 0;
 }

+ 9 - 4
libs/expat/expat_config.h

@@ -1,6 +1,9 @@
 /* expat_config.h.  Generated from expat_config.h.in by configure.  */
 /* expat_config.h.in.  Generated from configure.ac by autoheader.  */
 
+#ifndef EXPAT_CONFIG_H
+#define EXPAT_CONFIG_H 1
+
 /* Define if building universal (internal helper macro) */
 /* #undef AC_APPLE_UNIVERSAL_BUILD */
 
@@ -11,7 +14,7 @@
 /* #undef HAVE_ARC4RANDOM */
 
 /* Define to 1 if you have the `arc4random_buf' function. */
-/* #undef HAVE_ARC4RANDOM_BUF */
+#define HAVE_ARC4RANDOM_BUF 1
 
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
@@ -77,7 +80,7 @@
 #define PACKAGE_NAME "expat"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "expat 2.4.9"
+#define PACKAGE_STRING "expat 2.5.0"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "expat"
@@ -86,7 +89,7 @@
 #define PACKAGE_URL ""
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "2.4.9"
+#define PACKAGE_VERSION "2.5.0"
 
 /* Define to 1 if all of the C90 standard headers exist (not just the ones
    required in a freestanding environment). This macro is provided for
@@ -94,7 +97,7 @@
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "2.4.9"
+#define VERSION "2.5.0"
 
 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
    significant byte first (like Motorola and SPARC, unlike Intel). */
@@ -133,3 +136,5 @@
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 /* #undef size_t */
+
+#endif // ndef EXPAT_CONFIG_H

+ 5 - 0
libs/expat/expat_config.h.cmake

@@ -1,5 +1,8 @@
 /* expat_config.h.cmake.  Based upon generated expat_config.h.in.  */
 
+#ifndef EXPAT_CONFIG_H
+#define EXPAT_CONFIG_H 1
+
 /* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
 #cmakedefine BYTEORDER @BYTEORDER@
 
@@ -113,3 +116,5 @@
 
 /* Define to `unsigned' if <sys/types.h> does not define. */
 #cmakedefine size_t @SIZE_T@
+
+#endif // ndef EXPAT_CONFIG_H

+ 5 - 0
libs/expat/expat_config.h.in

@@ -1,5 +1,8 @@
 /* expat_config.h.in.  Generated from configure.ac by autoheader.  */
 
+#ifndef EXPAT_CONFIG_H
+#define EXPAT_CONFIG_H 1
+
 /* Define if building universal (internal helper macro) */
 #undef AC_APPLE_UNIVERSAL_BUILD
 
@@ -132,3 +135,5 @@
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
+
+#endif // ndef EXPAT_CONFIG_H

+ 2 - 2
libs/expat/lib/expat.h

@@ -1054,8 +1054,8 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(
    See http://semver.org.
 */
 #define XML_MAJOR_VERSION 2
-#define XML_MINOR_VERSION 4
-#define XML_MICRO_VERSION 9
+#define XML_MINOR_VERSION 5
+#define XML_MICRO_VERSION 0
 
 #ifdef __cplusplus
 }

+ 0 - 80
libs/expat/lib/libexpatw.def

@@ -1,80 +0,0 @@
-; DEF file for MS VC++
-
-LIBRARY
-EXPORTS
-  XML_DefaultCurrent @1
-  XML_ErrorString @2
-  XML_ExpatVersion @3
-  XML_ExpatVersionInfo @4
-  XML_ExternalEntityParserCreate @5
-  XML_GetBase @6
-  XML_GetBuffer @7
-  XML_GetCurrentByteCount @8
-  XML_GetCurrentByteIndex @9
-  XML_GetCurrentColumnNumber @10
-  XML_GetCurrentLineNumber @11
-  XML_GetErrorCode @12
-  XML_GetIdAttributeIndex @13
-  XML_GetInputContext @14
-  XML_GetSpecifiedAttributeCount @15
-  XML_Parse @16
-  XML_ParseBuffer @17
-  XML_ParserCreate @18
-  XML_ParserCreateNS @19
-  XML_ParserCreate_MM @20
-  XML_ParserFree @21
-  XML_SetAttlistDeclHandler @22
-  XML_SetBase @23
-  XML_SetCdataSectionHandler @24
-  XML_SetCharacterDataHandler @25
-  XML_SetCommentHandler @26
-  XML_SetDefaultHandler @27
-  XML_SetDefaultHandlerExpand @28
-  XML_SetDoctypeDeclHandler @29
-  XML_SetElementDeclHandler @30
-  XML_SetElementHandler @31
-  XML_SetEncoding @32
-  XML_SetEndCdataSectionHandler @33
-  XML_SetEndDoctypeDeclHandler @34
-  XML_SetEndElementHandler @35
-  XML_SetEndNamespaceDeclHandler @36
-  XML_SetEntityDeclHandler @37
-  XML_SetExternalEntityRefHandler @38
-  XML_SetExternalEntityRefHandlerArg @39
-  XML_SetNamespaceDeclHandler @40
-  XML_SetNotStandaloneHandler @41
-  XML_SetNotationDeclHandler @42
-  XML_SetParamEntityParsing @43
-  XML_SetProcessingInstructionHandler @44
-  XML_SetReturnNSTriplet @45
-  XML_SetStartCdataSectionHandler @46
-  XML_SetStartDoctypeDeclHandler @47
-  XML_SetStartElementHandler @48
-  XML_SetStartNamespaceDeclHandler @49
-  XML_SetUnknownEncodingHandler @50
-  XML_SetUnparsedEntityDeclHandler @51
-  XML_SetUserData @52
-  XML_SetXmlDeclHandler @53
-  XML_UseParserAsHandlerArg @54
-; added with version 1.95.3
-  XML_ParserReset @55
-  XML_SetSkippedEntityHandler @56
-; added with version 1.95.5
-  XML_GetFeatureList @57
-  XML_UseForeignDTD @58
-; added with version 1.95.6
-  XML_FreeContentModel @59
-  XML_MemMalloc @60
-  XML_MemRealloc @61
-  XML_MemFree @62
-; added with version 1.95.8
-  XML_StopParser @63
-  XML_ResumeParser @64
-  XML_GetParsingStatus @65
-; added with version 2.1.1
-; XML_GetAttributeInfo @66
-  XML_SetHashSalt @67
-; internal @68 removed with version 2.3.1
-; added with version 2.4.0
-  XML_SetBillionLaughsAttackProtectionActivationThreshold @69
-  XML_SetBillionLaughsAttackProtectionMaximumAmplification @70

+ 32 - 15
libs/expat/lib/xmlparse.c

@@ -1,4 +1,4 @@
-/* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065e42784e001db4f23de324 (2.4.9+)
+/* 5ab094ffadd6edfc94c3eee53af44a86951f9f1f0933ada3114bbce2bfb02c99 (2.5.0+)
                             __  __            _
                          ___\ \/ /_ __   __ _| |_
                         / _ \\  /| '_ \ / _` | __|
@@ -35,6 +35,7 @@
    Copyright (c) 2021      Dong-hee Na <[email protected]>
    Copyright (c) 2022      Samanta Navarro <[email protected]>
    Copyright (c) 2022      Jeffrey Walton <[email protected]>
+   Copyright (c) 2022      Jann Horn <[email protected]>
    Licensed under the MIT license:
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -1068,6 +1069,14 @@ parserCreate(const XML_Char *encodingName,
   parserInit(parser, encodingName);
 
   if (encodingName && ! parser->m_protocolEncodingName) {
+    if (dtd) {
+      // We need to stop the upcoming call to XML_ParserFree from happily
+      // destroying parser->m_dtd because the DTD is shared with the parent
+      // parser and the only guard that keeps XML_ParserFree from destroying
+      // parser->m_dtd is parser->m_isParamEntity but it will be set to
+      // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all).
+      parser->m_dtd = NULL;
+    }
     XML_ParserFree(parser);
     return NULL;
   }
@@ -3011,9 +3020,6 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
         int len;
         const char *rawName;
         TAG *tag = parser->m_tagStack;
-        parser->m_tagStack = tag->parent;
-        tag->parent = parser->m_freeTagList;
-        parser->m_freeTagList = tag;
         rawName = s + enc->minBytesPerChar * 2;
         len = XmlNameLength(enc, rawName);
         if (len != tag->rawNameLength
@@ -3021,6 +3027,9 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
           *eventPP = rawName;
           return XML_ERROR_TAG_MISMATCH;
         }
+        parser->m_tagStack = tag->parent;
+        tag->parent = parser->m_freeTagList;
+        parser->m_freeTagList = tag;
         --parser->m_tagLevel;
         if (parser->m_endElementHandler) {
           const XML_Char *localPart;
@@ -4975,10 +4984,10 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
               parser->m_handlerArg, parser->m_declElementType->name,
               parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
               role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
-          poolClear(&parser->m_tempPool);
           handleDefault = XML_FALSE;
         }
       }
+      poolClear(&parser->m_tempPool);
       break;
     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
@@ -5386,7 +5395,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
              *
              * If 'standalone' is false, the DTD must have no
              * parameter entities or we wouldn't have passed the outer
-             * 'if' statement.  That measn the only entity in the hash
+             * 'if' statement.  That means the only entity in the hash
              * table is the external subset name "#" which cannot be
              * given as a parameter entity name in XML syntax, so the
              * lookup must have returned NULL and we don't even reach
@@ -5798,19 +5807,27 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
 
   if (result != XML_ERROR_NONE)
     return result;
-  else if (textEnd != next
-           && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
+
+  if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
     entity->processed = (int)(next - (const char *)entity->textPtr);
     return result;
-  } else {
+  }
+
 #ifdef XML_DTD
-    entityTrackingOnClose(parser, entity, __LINE__);
+  entityTrackingOnClose(parser, entity, __LINE__);
 #endif
-    entity->open = XML_FALSE;
-    parser->m_openInternalEntities = openEntity->next;
-    /* put openEntity back in list of free instances */
-    openEntity->next = parser->m_freeInternalEntities;
-    parser->m_freeInternalEntities = openEntity;
+  entity->open = XML_FALSE;
+  parser->m_openInternalEntities = openEntity->next;
+  /* put openEntity back in list of free instances */
+  openEntity->next = parser->m_freeInternalEntities;
+  parser->m_freeInternalEntities = openEntity;
+
+  // If there are more open entities we want to stop right here and have the
+  // upcoming call to XML_ResumeParser continue with entity content, or it would
+  // be ignored altogether.
+  if (parser->m_openInternalEntities != NULL
+      && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
+    return XML_ERROR_NONE;
   }
 
 #ifdef XML_DTD

+ 1 - 1
libs/expat/lib/xmltok_impl.h

@@ -45,7 +45,7 @@ enum {
   BT_LF,       /* line feed = "\n" */
   BT_GT,       /* greater than = ">" */
   BT_QUOT,     /* quotation character = "\"" */
-  BT_APOS,     /* aposthrophe = "'" */
+  BT_APOS,     /* apostrophe = "'" */
   BT_EQUALS,   /* equal sign = "=" */
   BT_QUEST,    /* question mark = "?" */
   BT_EXCL,     /* exclamation mark = "!" */

+ 174 - 3
libs/expat/tests/runtests.c

@@ -11,7 +11,7 @@
    Copyright (c) 2005-2007 Steven Solie <[email protected]>
    Copyright (c) 2005-2012 Karl Waclawek <[email protected]>
    Copyright (c) 2016-2022 Sebastian Pipping <[email protected]>
-   Copyright (c) 2017-2018 Rhodri James <[email protected]>
+   Copyright (c) 2017-2022 Rhodri James <[email protected]>
    Copyright (c) 2017      Joe Orton <[email protected]>
    Copyright (c) 2017      José Gutiérrez de la Concha <[email protected]>
    Copyright (c) 2018      Marco Maggi <[email protected]>
@@ -4990,7 +4990,7 @@ START_TEST(test_suspend_resume_internal_entity) {
 }
 END_TEST
 
-void
+static void XMLCALL
 suspending_comment_handler(void *userData, const XML_Char *data) {
   UNUSED_P(data);
   XML_Parser parser = (XML_Parser)userData;
@@ -6734,6 +6734,102 @@ START_TEST(test_empty_element_abort) {
 }
 END_TEST
 
+/* Regression test for GH issue #612: unfinished m_declAttributeType
+ * allocation in ->m_tempPool can corrupt following allocation.
+ */
+static int XMLCALL
+external_entity_unfinished_attlist(XML_Parser parser, const XML_Char *context,
+                                   const XML_Char *base,
+                                   const XML_Char *systemId,
+                                   const XML_Char *publicId) {
+  const char *text = "<!ELEMENT barf ANY>\n"
+                     "<!ATTLIST barf my_attr (blah|%blah;a|foo) #REQUIRED>\n"
+                     "<!--COMMENT-->\n";
+  XML_Parser ext_parser;
+
+  UNUSED_P(base);
+  UNUSED_P(publicId);
+  if (systemId == NULL)
+    return XML_STATUS_OK;
+
+  ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
+  if (ext_parser == NULL)
+    fail("Could not create external entity parser");
+
+  if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
+      == XML_STATUS_ERROR)
+    xml_failure(ext_parser);
+
+  XML_ParserFree(ext_parser);
+  return XML_STATUS_OK;
+}
+
+START_TEST(test_pool_integrity_with_unfinished_attr) {
+  const char *text = "<?xml version='1.0' encoding='UTF-8'?>\n"
+                     "<!DOCTYPE foo [\n"
+                     "<!ELEMENT foo ANY>\n"
+                     "<!ENTITY % entp SYSTEM \"external.dtd\">\n"
+                     "%entp;\n"
+                     "]>\n"
+                     "<a></a>\n";
+  const XML_Char *expected = XCS("COMMENT");
+  CharData storage;
+
+  CharData_Init(&storage);
+  XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+  XML_SetExternalEntityRefHandler(g_parser, external_entity_unfinished_attlist);
+  XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler);
+  XML_SetCommentHandler(g_parser, accumulate_comment);
+  XML_SetUserData(g_parser, &storage);
+  if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
+      == XML_STATUS_ERROR)
+    xml_failure(g_parser);
+  CharData_CheckXMLChars(&storage, expected);
+}
+END_TEST
+
+typedef struct {
+  XML_Parser parser;
+  CharData *storage;
+} ParserPlusStorage;
+
+static void XMLCALL
+accumulate_and_suspend_comment_handler(void *userData, const XML_Char *data) {
+  ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData;
+  accumulate_comment(parserPlusStorage->storage, data);
+  XML_StopParser(parserPlusStorage->parser, XML_TRUE);
+}
+
+START_TEST(test_nested_entity_suspend) {
+  const char *const text = "<!DOCTYPE a [\n"
+                           "  <!ENTITY e1 '<!--e1-->'>\n"
+                           "  <!ENTITY e2 '<!--e2 head-->&e1;<!--e2 tail-->'>\n"
+                           "  <!ENTITY e3 '<!--e3 head-->&e2;<!--e3 tail-->'>\n"
+                           "]>\n"
+                           "<a><!--start-->&e3;<!--end--></a>";
+  const XML_Char *const expected = XCS("start") XCS("e3 head") XCS("e2 head")
+      XCS("e1") XCS("e2 tail") XCS("e3 tail") XCS("end");
+  CharData storage;
+  XML_Parser parser = XML_ParserCreate(NULL);
+  ParserPlusStorage parserPlusStorage = {parser, &storage};
+
+  CharData_Init(&storage);
+  XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+  XML_SetCommentHandler(parser, accumulate_and_suspend_comment_handler);
+  XML_SetUserData(parser, &parserPlusStorage);
+
+  enum XML_Status status = XML_Parse(parser, text, (int)strlen(text), XML_TRUE);
+  while (status == XML_STATUS_SUSPENDED) {
+    status = XML_ResumeParser(parser);
+  }
+  if (status != XML_STATUS_OK)
+    xml_failure(parser);
+
+  CharData_CheckXMLChars(&storage, expected);
+  XML_ParserFree(parser);
+}
+END_TEST
+
 /*
  * Namespaces tests.
  */
@@ -7661,7 +7757,7 @@ START_TEST(test_misc_version) {
     fail("Version mismatch");
 
 #if ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T)
-  if (xcstrcmp(version_text, XCS("expat_2.4.9"))) /* needs bump on releases */
+  if (xcstrcmp(version_text, XCS("expat_2.5.0"))) /* needs bump on releases */
     fail("XML_*_VERSION in expat.h out of sync?\n");
 #else
   /* If we have XML_UNICODE defined but not XML_UNICODE_WCHAR_T
@@ -7873,6 +7969,28 @@ START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) {
 }
 END_TEST
 
+START_TEST(test_misc_tag_mismatch_reset_leak) {
+#ifdef XML_NS
+  const char *const text = "<open xmlns='https://namespace1.test'></close>";
+  XML_Parser parser = XML_ParserCreateNS(NULL, XCS('\n'));
+
+  if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
+    fail("Call to parse was expected to fail");
+  if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
+    fail("Call to parse was expected to fail from a closing tag mismatch");
+
+  XML_ParserReset(parser, NULL);
+
+  if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
+    fail("Call to parse was expected to fail");
+  if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
+    fail("Call to parse was expected to fail from a closing tag mismatch");
+
+  XML_ParserFree(parser);
+#endif
+}
+END_TEST
+
 static void
 alloc_setup(void) {
   XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
@@ -10090,6 +10208,53 @@ START_TEST(test_alloc_long_notation) {
 }
 END_TEST
 
+static int XMLCALL
+external_entity_parser_create_alloc_fail_handler(XML_Parser parser,
+                                                 const XML_Char *context,
+                                                 const XML_Char *base,
+                                                 const XML_Char *systemId,
+                                                 const XML_Char *publicId) {
+  UNUSED_P(base);
+  UNUSED_P(systemId);
+  UNUSED_P(publicId);
+
+  if (context != NULL)
+    fail("Unexpected non-NULL context");
+
+  // The following number intends to fail the upcoming allocation in line
+  // "parser->m_protocolEncodingName = copyString(encodingName,
+  // &(parser->m_mem));" in function parserInit.
+  allocation_count = 3;
+
+  const XML_Char *const encodingName = XCS("UTF-8"); // needs something non-NULL
+  const XML_Parser ext_parser
+      = XML_ExternalEntityParserCreate(parser, context, encodingName);
+  if (ext_parser != NULL)
+    fail(
+        "Call to XML_ExternalEntityParserCreate was expected to fail out-of-memory");
+
+  allocation_count = ALLOC_ALWAYS_SUCCEED;
+  return XML_STATUS_ERROR;
+}
+
+START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) {
+  const char *const text = "<!DOCTYPE doc SYSTEM 'foo'><doc/>";
+
+  XML_SetExternalEntityRefHandler(
+      g_parser, external_entity_parser_create_alloc_fail_handler);
+  XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+
+  if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
+      != XML_STATUS_ERROR)
+    fail("Call to parse was expected to fail");
+
+  if (XML_GetErrorCode(g_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
+    fail("Call to parse was expected to fail from the external entity handler");
+
+  XML_ParserReset(g_parser, NULL);
+}
+END_TEST
+
 static void
 nsalloc_setup(void) {
   XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
@@ -12169,6 +12334,9 @@ make_suite(void) {
   tcase_add_test(tc_basic, test_bad_notation);
   tcase_add_test(tc_basic, test_default_doctype_handler);
   tcase_add_test(tc_basic, test_empty_element_abort);
+  tcase_add_test__ifdef_xml_dtd(tc_basic,
+                                test_pool_integrity_with_unfinished_attr);
+  tcase_add_test(tc_basic, test_nested_entity_suspend);
 
   suite_add_tcase(s, tc_namespace);
   tcase_add_checked_fixture(tc_namespace, namespace_setup, namespace_teardown);
@@ -12221,6 +12389,7 @@ make_suite(void) {
   tcase_add_test(tc_misc, test_misc_stop_during_end_handler_issue_240_2);
   tcase_add_test__ifdef_xml_dtd(
       tc_misc, test_misc_deny_internal_entity_closing_doctype_issue_317);
+  tcase_add_test(tc_misc, test_misc_tag_mismatch_reset_leak);
 
   suite_add_tcase(s, tc_alloc);
   tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
@@ -12279,6 +12448,8 @@ make_suite(void) {
   tcase_add_test(tc_alloc, test_alloc_long_public_id);
   tcase_add_test(tc_alloc, test_alloc_long_entity_value);
   tcase_add_test(tc_alloc, test_alloc_long_notation);
+  tcase_add_test__ifdef_xml_dtd(
+      tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail);
 
   suite_add_tcase(s, tc_nsalloc);
   tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown);

+ 1 - 1
libs/expat/win32/expat.iss

@@ -37,7 +37,7 @@
 ; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 ; USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-#define expatVer "2.4.9"
+#define expatVer "2.5.0"
 
 [Setup]
 AppName=Expat