浏览代码

Expat 2.2.3

(cherry picked from commit de1d10640a688201c93b32ab660d09b00184b263)

Source commit: 64dc7684cf0b8c29f8bbeb88ac8bb1e3a1755372
Martin Prikryl 8 年之前
父节点
当前提交
efa1d7dfb0

+ 6 - 6
libs/expat/CMake.README

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

+ 3 - 2
libs/expat/CMakeLists.txt

@@ -6,7 +6,7 @@ project(expat)
 cmake_minimum_required(VERSION 2.6)
 cmake_minimum_required(VERSION 2.6)
 set(PACKAGE_BUGREPORT "[email protected]")
 set(PACKAGE_BUGREPORT "[email protected]")
 set(PACKAGE_NAME "expat")
 set(PACKAGE_NAME "expat")
-set(PACKAGE_VERSION "2.2.2")
+set(PACKAGE_VERSION "2.2.3")
 set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
 set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
 set(PACKAGE_TARNAME "${PACKAGE_NAME}")
 set(PACKAGE_TARNAME "${PACKAGE_NAME}")
 
 
@@ -54,6 +54,7 @@ if(WIN32)
 endif(WIN32)
 endif(WIN32)
 
 
 set(expat_SRCS
 set(expat_SRCS
+    lib/loadlibrary.c
     lib/xmlparse.c
     lib/xmlparse.c
     lib/xmlrole.c
     lib/xmlrole.c
     lib/xmltok.c
     lib/xmltok.c
@@ -76,7 +77,7 @@ endif(BUILD_shared)
 add_library(expat ${_SHARED} ${expat_SRCS})
 add_library(expat ${_SHARED} ${expat_SRCS})
 
 
 set(LIBCURRENT 7)   # sync
 set(LIBCURRENT 7)   # sync
-set(LIBREVISION 4)  # with
+set(LIBREVISION 5)  # with
 set(LIBAGE 6)       # configure.ac!
 set(LIBAGE 6)       # configure.ac!
 math(EXPR LIBCURRENT_MINUS_AGE "${LIBCURRENT} - ${LIBAGE}")
 math(EXPR LIBCURRENT_MINUS_AGE "${LIBCURRENT} - ${LIBAGE}")
 
 

+ 40 - 0
libs/expat/Changes

@@ -2,6 +2,46 @@ NOTE: We are looking for help with a few things:
       https://github.com/libexpat/libexpat/labels/help%20wanted
       https://github.com/libexpat/libexpat/labels/help%20wanted
       If you can help, please get in touch.  Thanks!
       If you can help, please get in touch.  Thanks!
 
 
+Release 2.2.3 Wed August 2 2017
+        Security fixes:
+             #82  CVE-2017-11742 -- Windows: Fix DLL hijacking vulnerability
+                    using Steve Holme's LoadLibrary wrapper for/of cURL
+
+        Bug fixes:
+             #85  Fix a dangling pointer issue related to realloc
+
+        Other changes:
+                  Increase code coverage
+             #91  Linux: Allow getrandom to fail if nonblocking pool has not
+                    yet been initialized and read /dev/urandom then, instead.
+                    This is in line with what recent Python does.
+             #81  Pre-10.7/Lion macOS: Support entropy from arc4random
+             #86  Check that a UTF-16 encoding in an XML declaration has the
+                    right endianness
+        #4 #5 #7  Recover correctly when some reallocations fail
+                  Repair "./configure && make" for systems without any
+                    provider of high quality entropy
+                    and try reading /dev/urandom on those
+                  Ensure that user-defined character encodings have converter
+                    functions when they are needed
+                  Fix mis-leading description of argument -c in xmlwf.1
+                  Rely on macro HAVE_ARC4RANDOM_BUF (rather than __CloudABI__)
+                    for CloudABI
+            #100  Fix use of SIPHASH_MAIN in siphash.h
+             #23  Test suite: Fix memory leaks
+                  Version info bumped from 7:4:6 to 7:5:6
+
+        Special thanks to:
+            Chanho Park
+            Joe Orton
+            Pascal Cuoq
+            Rhodri James
+            Simon McVittie
+            Vadim Zeitlin
+            Viktor Szakats
+                 and
+            Core Infrastructure Initiative
+
 Release 2.2.2 Wed July 12 2017
 Release 2.2.2 Wed July 12 2017
         Security fixes:
         Security fixes:
              #43  Protect against compilation without any source of high
              #43  Protect against compilation without any source of high

+ 2 - 1
libs/expat/MANIFEST

@@ -12,7 +12,7 @@ Changes
 ConfigureChecks.cmake
 ConfigureChecks.cmake
 MANIFEST
 MANIFEST
 Makefile.in
 Makefile.in
-README
+README.md
 configure
 configure
 configure.ac
 configure.ac
 expat_config.h.in
 expat_config.h.in
@@ -45,6 +45,7 @@ lib/internal.h
 lib/latin1tab.h
 lib/latin1tab.h
 lib/libexpat.def
 lib/libexpat.def
 lib/libexpatw.def
 lib/libexpatw.def
+lib/loadlibrary.c
 lib/nametab.h
 lib/nametab.h
 lib/siphash.h
 lib/siphash.h
 lib/utf8tab.h
 lib/utf8tab.h

+ 3 - 1
libs/expat/Makefile.in

@@ -128,7 +128,7 @@ LINK_LIB = $(LIBTOOL) $(LTFLAGS) --mode=link $(COMPILE) -no-undefined $(VSNFLAG)
 LINK_EXE = $(LIBTOOL) $(LTFLAGS) --mode=link $(COMPILE) $(LDFLAGS) -o $@
 LINK_EXE = $(LIBTOOL) $(LTFLAGS) --mode=link $(COMPILE) $(LDFLAGS) -o $@
 LINK_CXX_EXE = $(LIBTOOL) $(LTFLAGS) --mode=link $(CXXCOMPILE) $(LDFLAGS) -o $@
 LINK_CXX_EXE = $(LIBTOOL) $(LTFLAGS) --mode=link $(CXXCOMPILE) $(LDFLAGS) -o $@
 
 
-LIB_OBJS = lib/xmlparse.lo lib/xmltok.lo lib/xmlrole.lo
+LIB_OBJS = lib/loadlibrary.lo lib/xmlparse.lo lib/xmltok.lo lib/xmlrole.lo
 $(LIBRARY): $(LIB_OBJS)
 $(LIBRARY): $(LIB_OBJS)
 	$(LINK_LIB) $(LIB_OBJS)
 	$(LINK_LIB) $(LIB_OBJS)
 
 
@@ -138,6 +138,8 @@ expat.pc: $(top_builddir)/config.status
 lib/xmlparse.lo: lib/xmlparse.c lib/expat.h lib/siphash.h lib/xmlrole.h lib/xmltok.h \
 lib/xmlparse.lo: lib/xmlparse.c lib/expat.h lib/siphash.h lib/xmlrole.h lib/xmltok.h \
 	$(top_builddir)/expat_config.h lib/expat_external.h lib/internal.h
 	$(top_builddir)/expat_config.h lib/expat_external.h lib/internal.h
 
 
+lib/loadlibrary.lo: lib/loadlibrary.c
+
 lib/xmlrole.lo: lib/xmlrole.c lib/ascii.h lib/xmlrole.h \
 lib/xmlrole.lo: lib/xmlrole.c lib/ascii.h lib/xmlrole.h \
 	$(top_builddir)/expat_config.h lib/expat_external.h lib/internal.h
 	$(top_builddir)/expat_config.h lib/expat_external.h lib/internal.h
 
 

+ 126 - 0
libs/expat/README.md

@@ -0,0 +1,126 @@
+# Expat, Release 2.2.3
+
+This is Expat, a C library for parsing XML, started by
+[James Clark](https://en.wikipedia.org/wiki/James_Clark_(programmer)) in 1997.
+Expat is a stream-oriented XML parser.  This means that you register
+handlers with the parser before starting the parse.  These handlers
+are called when the parser discovers the associated structures in the
+document being parsed.  A start tag is an example of the kind of
+structures for which you may register handlers.
+
+Windows users should use the
+[`expat_win32` package](https://sourceforge.net/projects/expat/files/expat_win32/),
+which includes both precompiled libraries and executables, and source code for
+developers.
+
+Expat is [free software](https://www.gnu.org/philosophy/free-sw.en.html).
+You may copy, distribute, and modify it under the terms of the License
+contained in the file
+[`COPYING`](https://github.com/libexpat/libexpat/blob/master/expat/COPYING)
+distributed with this package.
+This license is the same as the MIT/X Consortium license.
+
+If you are building Expat from a check-out from the
+[Git repository](https://github.com/libexpat/libexpat/),
+you need to run a script that generates the configure script using the
+GNU autoconf and libtool tools.  To do this, you need to have
+autoconf 2.58 or newer. Run the script like this:
+
+```console
+./buildconf.sh
+```
+
+Once this has been done, follow the same instructions as for building
+from a source distribution.
+
+To build Expat from a source distribution, you first run the
+configuration shell script in the top level distribution directory:
+
+```console
+./configure
+```
+
+There are many options which you may provide to configure (which you
+can discover by running configure with the `--help` option).  But the
+one of most interest is the one that sets the installation directory.
+By default, the configure script will set things up to install
+libexpat into `/usr/local/lib`, `expat.h` into `/usr/local/include`, and
+`xmlwf` into `/usr/local/bin`.  If, for example, you'd prefer to install
+into `/home/me/mystuff/lib`, `/home/me/mystuff/include`, and
+`/home/me/mystuff/bin`, you can tell `configure` about that with:
+
+```console
+./configure --prefix=/home/me/mystuff
+```
+
+Another interesting option is to enable 64-bit integer support for
+line and column numbers and the over-all byte index:
+
+```console
+./configure CPPFLAGS=-DXML_LARGE_SIZE
+```
+
+However, such a modification would be a breaking change to the ABI
+and is therefore not recommended for general use — e.g. as part of
+a Linux distribution — but rather for builds with special requirements.
+
+After running the configure script, the `make` command will build
+things and `make install` will install things into their proper
+location.  Have a look at the `Makefile` to learn about additional
+`make` options.  Note that you need to have write permission into
+the directories into which things will be installed.
+
+If you are interested in building Expat to provide document
+information in UTF-16 encoding rather than the default UTF-8, follow
+these instructions (after having run `make distclean`):
+
+1. For UTF-16 output as unsigned short (and version/error strings as char),
+   run:<br/>
+   `./configure CPPFLAGS=-DXML_UNICODE`<br/>
+   For UTF-16 output as `wchar_t` (incl. version/error strings), run:<br/>
+   `./configure CFLAGS="-g -O2 -fshort-wchar" CPPFLAGS=-DXML_UNICODE_WCHAR_T`
+   <br/>Note: The latter requires libc compiled with `-fshort-wchar`, as well.
+
+1. Edit `Makefile`, changing:<br/>
+   `LIBRARY = libexpat.la`<br/>
+   to:<br/>
+   `LIBRARY = libexpatw.la`<br/>
+   (Note the additional "w" in the library name.)
+
+1. Run `make buildlib` (which builds the library only).
+   Or, to save step 2, run `make buildlib LIBRARY=libexpatw.la`.
+
+1. Run `make installlib` (which installs the library only).
+   Or, if step 2 was omitted, run `make installlib LIBRARY=libexpatw.la`.
+
+Using `DESTDIR` or `INSTALL_ROOT` is enabled, with `INSTALL_ROOT` being the
+default value for `DESTDIR`, and the rest of the make file using only
+`DESTDIR`.  It works as follows:
+
+```console
+make install DESTDIR=/path/to/image
+```
+
+overrides the in-makefile set `DESTDIR`, while both
+
+```console
+INSTALL_ROOT=/path/to/image make install
+make install INSTALL_ROOT=/path/to/image
+```
+
+use `DESTDIR=$(INSTALL_ROOT)`, even if `DESTDIR` eventually is defined in the
+environment, because variable-setting priority is
+1. commandline
+2. in-makefile
+3. environment
+
+Note: This only applies to the Expat library itself, building UTF-16 versions
+of xmlwf and the tests is currently not supported.
+
+When using Expat with a project using autoconf for configuration, you
+can use the probing macro in `conftools/expat.m4` to determine how to
+include Expat.  See the comments at the top of that file for more
+information.
+
+A reference manual is available in the file `doc/reference.html` in this
+distribution.

+ 1 - 0
libs/expat/bcb5/expat.bpf

@@ -1,6 +1,7 @@
 USEUNIT("..\lib\xmlparse.c");
 USEUNIT("..\lib\xmlparse.c");
 USEUNIT("..\lib\xmlrole.c");
 USEUNIT("..\lib\xmlrole.c");
 USEUNIT("..\lib\xmltok.c");
 USEUNIT("..\lib\xmltok.c");
+USEUNIT("..\lib\loadlibrary.c");
 USEDEF("libexpat_mtd.def");
 USEDEF("libexpat_mtd.def");
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 #define DllEntryPoint
 #define DllEntryPoint

+ 1 - 1
libs/expat/bcb5/expat.bpr

@@ -5,7 +5,7 @@
     <VERSION value="BCB.05.03"/>
     <VERSION value="BCB.05.03"/>
     <PROJECT value="Release\libexpat_mtd.dll"/>
     <PROJECT value="Release\libexpat_mtd.dll"/>
     <OBJFILES value="Release\obj\libexpat\xmlparse.obj Release\obj\libexpat\xmlrole.obj 
     <OBJFILES value="Release\obj\libexpat\xmlparse.obj Release\obj\libexpat\xmlrole.obj 
-      Release\obj\libexpat\xmltok.obj"/>
+      Release\obj\libexpat\xmltok.obj Release\obj\libexpat\loadlibrary.obj"/>
     <RESFILES value=""/>
     <RESFILES value=""/>
     <IDLFILES value=""/>
     <IDLFILES value=""/>
     <IDLGENFILES value=""/>
     <IDLGENFILES value=""/>

+ 1 - 1
libs/expat/bcb5/expat.mak

@@ -15,7 +15,7 @@ VERSION = BCB.05.03
 # ---------------------------------------------------------------------------
 # ---------------------------------------------------------------------------
 PROJECT = Release\libexpat_mtd.dll
 PROJECT = Release\libexpat_mtd.dll
 OBJFILES = Release\obj\libexpat\xmlparse.obj Release\obj\libexpat\xmlrole.obj \
 OBJFILES = Release\obj\libexpat\xmlparse.obj Release\obj\libexpat\xmlrole.obj \
-    Release\obj\libexpat\xmltok.obj
+    Release\obj\libexpat\xmltok.obj Release\obj\libexpat\loadlibrary.obj
 RESFILES = 
 RESFILES = 
 MAINSOURCE = expat.bpf
 MAINSOURCE = expat.bpf
 RESDEPEN = $(RESFILES)
 RESDEPEN = $(RESFILES)

+ 1 - 0
libs/expat/bcb5/expat_static.bpf

@@ -1,5 +1,6 @@
 USEUNIT("..\lib\xmlparse.c");
 USEUNIT("..\lib\xmlparse.c");
 USEUNIT("..\lib\xmlrole.c");
 USEUNIT("..\lib\xmlrole.c");
 USEUNIT("..\lib\xmltok.c");
 USEUNIT("..\lib\xmltok.c");
+USEUNIT("..\lib\loadlibrary.c");
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 #define Library
 #define Library

+ 2 - 1
libs/expat/bcb5/expat_static.bpr

@@ -6,7 +6,8 @@
     <PROJECT value="Release\libexpats_mtd.lib"/>
     <PROJECT value="Release\libexpats_mtd.lib"/>
     <OBJFILES value="Release\obj\libexpat_static\xmlparse.obj 
     <OBJFILES value="Release\obj\libexpat_static\xmlparse.obj 
       Release\obj\libexpat_static\xmlrole.obj 
       Release\obj\libexpat_static\xmlrole.obj 
-      Release\obj\libexpat_static\xmltok.obj"/>
+      Release\obj\libexpat_static\xmltok.obj
+      Release\obj\libexpat_static\loadlibrary.obj"/>
     <RESFILES value=""/>
     <RESFILES value=""/>
     <IDLFILES value=""/>
     <IDLFILES value=""/>
     <IDLGENFILES value=""/>
     <IDLGENFILES value=""/>

+ 2 - 1
libs/expat/bcb5/expat_static.mak

@@ -16,7 +16,8 @@ VERSION = BCB.05.03
 PROJECT = Release\libexpats_mtd.lib
 PROJECT = Release\libexpats_mtd.lib
 OBJFILES = Release\obj\libexpat_static\xmlparse.obj \
 OBJFILES = Release\obj\libexpat_static\xmlparse.obj \
     Release\obj\libexpat_static\xmlrole.obj \
     Release\obj\libexpat_static\xmlrole.obj \
-    Release\obj\libexpat_static\xmltok.obj
+    Release\obj\libexpat_static\xmltok.obj \
+    Release\obj\libexpat_static\loadlibrary.obj
 RESFILES = 
 RESFILES = 
 MAINSOURCE = expat_static.bpf
 MAINSOURCE = expat_static.bpf
 RESDEPEN = $(RESFILES)
 RESDEPEN = $(RESFILES)

+ 1 - 0
libs/expat/bcb5/expatw.bpf

@@ -1,6 +1,7 @@
 USEUNIT("..\lib\xmlparse.c");
 USEUNIT("..\lib\xmlparse.c");
 USEUNIT("..\lib\xmlrole.c");
 USEUNIT("..\lib\xmlrole.c");
 USEUNIT("..\lib\xmltok.c");
 USEUNIT("..\lib\xmltok.c");
+USEUNIT("..\lib\loadlibrary.c");
 USEDEF("libexpatw_mtd.def");
 USEDEF("libexpatw_mtd.def");
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 #define DllEntryPoint
 #define DllEntryPoint

+ 1 - 1
libs/expat/bcb5/expatw.bpr

@@ -5,7 +5,7 @@
     <VERSION value="BCB.05.03"/>
     <VERSION value="BCB.05.03"/>
     <PROJECT value="Release\libexpatw_mtd.dll"/>
     <PROJECT value="Release\libexpatw_mtd.dll"/>
     <OBJFILES value="Release\obj\libexpatw\xmlparse.obj Release\obj\libexpatw\xmlrole.obj 
     <OBJFILES value="Release\obj\libexpatw\xmlparse.obj Release\obj\libexpatw\xmlrole.obj 
-      Release\obj\libexpatw\xmltok.obj"/>
+      Release\obj\libexpatw\xmltok.obj Release\obj\libexpatw\loadlibrary.obj"/>
     <RESFILES value=""/>
     <RESFILES value=""/>
     <IDLFILES value=""/>
     <IDLFILES value=""/>
     <IDLGENFILES value=""/>
     <IDLGENFILES value=""/>

+ 1 - 1
libs/expat/bcb5/expatw.mak

@@ -15,7 +15,7 @@ VERSION = BCB.05.03
 # ---------------------------------------------------------------------------
 # ---------------------------------------------------------------------------
 PROJECT = Release\libexpatw_mtd.dll
 PROJECT = Release\libexpatw_mtd.dll
 OBJFILES = Release\obj\libexpatw\xmlparse.obj Release\obj\libexpatw\xmlrole.obj \
 OBJFILES = Release\obj\libexpatw\xmlparse.obj Release\obj\libexpatw\xmlrole.obj \
-    Release\obj\libexpatw\xmltok.obj
+    Release\obj\libexpatw\xmltok.obj Release\obj\libexpatw\loadlibrary.obj
 RESFILES = 
 RESFILES = 
 MAINSOURCE = expatw.bpf
 MAINSOURCE = expatw.bpf
 RESDEPEN = $(RESFILES)
 RESDEPEN = $(RESFILES)

+ 1 - 0
libs/expat/bcb5/expatw_static.bpf

@@ -1,5 +1,6 @@
 USEUNIT("..\lib\xmlparse.c");
 USEUNIT("..\lib\xmlparse.c");
 USEUNIT("..\lib\xmlrole.c");
 USEUNIT("..\lib\xmlrole.c");
 USEUNIT("..\lib\xmltok.c");
 USEUNIT("..\lib\xmltok.c");
+USEUNIT("..\lib\loadlibrary.c");
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 #define Library
 #define Library

+ 2 - 1
libs/expat/bcb5/expatw_static.bpr

@@ -6,7 +6,8 @@
     <PROJECT value="Release\libexpatws_mtd.lib"/>
     <PROJECT value="Release\libexpatws_mtd.lib"/>
     <OBJFILES value="Release\obj\libexpatw_static\xmlparse.obj 
     <OBJFILES value="Release\obj\libexpatw_static\xmlparse.obj 
       Release\obj\libexpatw_static\xmlrole.obj 
       Release\obj\libexpatw_static\xmlrole.obj 
-      Release\obj\libexpatw_static\xmltok.obj"/>
+      Release\obj\libexpatw_static\xmltok.obj
+      Release\obj\libexpatw_static\loadlibrary.obj"/>
     <RESFILES value=""/>
     <RESFILES value=""/>
     <IDLFILES value=""/>
     <IDLFILES value=""/>
     <IDLGENFILES value=""/>
     <IDLGENFILES value=""/>

+ 2 - 1
libs/expat/bcb5/expatw_static.mak

@@ -16,7 +16,8 @@ VERSION = BCB.05.03
 PROJECT = Release\libexpatws_mtd.lib
 PROJECT = Release\libexpatws_mtd.lib
 OBJFILES = Release\obj\libexpatw_static\xmlparse.obj \
 OBJFILES = Release\obj\libexpatw_static\xmlparse.obj \
     Release\obj\libexpatw_static\xmlrole.obj \
     Release\obj\libexpatw_static\xmlrole.obj \
-    Release\obj\libexpatw_static\xmltok.obj
+    Release\obj\libexpatw_static\xmltok.obj \
+    Release\obj\libexpatw_static\loadlibrary.obj
 RESFILES = 
 RESFILES = 
 MAINSOURCE = expatw_static.bpf
 MAINSOURCE = expatw_static.bpf
 RESDEPEN = $(RESFILES)
 RESDEPEN = $(RESFILES)

+ 46 - 10
libs/expat/configure

@@ -1,6 +1,6 @@
 #! /bin/sh
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for expat 2.2.2.
+# Generated by GNU Autoconf 2.69 for expat 2.2.3.
 #
 #
 # Report bugs to <[email protected]>.
 # Report bugs to <[email protected]>.
 #
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 # Identity of this package.
 PACKAGE_NAME='expat'
 PACKAGE_NAME='expat'
 PACKAGE_TARNAME='expat'
 PACKAGE_TARNAME='expat'
-PACKAGE_VERSION='2.2.2'
-PACKAGE_STRING='expat 2.2.2'
+PACKAGE_VERSION='2.2.3'
+PACKAGE_STRING='expat 2.2.3'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_URL=''
 PACKAGE_URL=''
 
 
@@ -1293,7 +1293,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # 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.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
   cat <<_ACEOF
-\`configure' configures expat 2.2.2 to adapt to many kinds of systems.
+\`configure' configures expat 2.2.3 to adapt to many kinds of systems.
 
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
 
@@ -1358,7 +1358,7 @@ fi
 
 
 if test -n "$ac_init_help"; then
 if test -n "$ac_init_help"; then
   case $ac_init_help in
   case $ac_init_help in
-     short | recursive ) echo "Configuration of expat 2.2.2:";;
+     short | recursive ) echo "Configuration of expat 2.2.3:";;
    esac
    esac
   cat <<\_ACEOF
   cat <<\_ACEOF
 
 
@@ -1472,7 +1472,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
 if $ac_init_version; then
   cat <<\_ACEOF
   cat <<\_ACEOF
-expat configure 2.2.2
+expat configure 2.2.3
 generated by GNU Autoconf 2.69
 generated by GNU Autoconf 2.69
 
 
 Copyright (C) 2012 Free Software Foundation, Inc.
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2016,7 +2016,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 running configure, to aid debugging if configure makes a mistake.
 
 
-It was created by expat $as_me 2.2.2, which was
+It was created by expat $as_me 2.2.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
 
   $ $0 $@
   $ $0 $@
@@ -2404,7 +2404,7 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 
 
 
 LIBCURRENT=7   # sync
 LIBCURRENT=7   # sync
-LIBREVISION=4  # with
+LIBREVISION=5  # with
 LIBAGE=6       # CMakeLists.txt!
 LIBAGE=6       # CMakeLists.txt!
 
 
 ac_config_headers="$ac_config_headers expat_config.h"
 ac_config_headers="$ac_config_headers expat_config.h"
@@ -15962,6 +15962,39 @@ else
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 $as_echo "no" >&6; }
 
 
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for arc4random (BSD, macOS or libbsd)" >&5
+$as_echo_n "checking for arc4random (BSD, macOS or libbsd)... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+      #if defined(HAVE_LIBBSD)
+      # include <bsd/stdlib.h>
+      #else
+      # include <stdlib.h>
+      #endif
+      int main() {
+          arc4random();
+          return 0;
+      }
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+
+$as_echo "#define HAVE_ARC4RANDOM 1" >>confdefs.h
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
 fi
 fi
 rm -f core conftest.err conftest.$ac_objext \
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
     conftest$ac_exeext conftest.$ac_ext
@@ -16269,6 +16302,9 @@ $as_echo "#define XML_NS 1" >>confdefs.h
 $as_echo "#define XML_DTD 1" >>confdefs.h
 $as_echo "#define XML_DTD 1" >>confdefs.h
 
 
 
 
+$as_echo "#define XML_DEV_URANDOM 1" >>confdefs.h
+
+
 # Check whether --enable-xml-context was given.
 # Check whether --enable-xml-context was given.
 if test "${enable_xml_context+set}" = set; then :
 if test "${enable_xml_context+set}" = set; then :
   enableval=$enable_xml_context; enable_xml_context=${enableval}
   enableval=$enable_xml_context; enable_xml_context=${enableval}
@@ -16800,7 +16836,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 # values after options handling.
 ac_log="
 ac_log="
-This file was extended by expat $as_me 2.2.2, which was
+This file was extended by expat $as_me 2.2.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_FILES    = $CONFIG_FILES
@@ -16866,7 +16902,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 ac_cs_version="\\
-expat config.status 2.2.2
+expat config.status 2.2.3
 configured by $0, generated by GNU Autoconf 2.69,
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
   with options \\"\$ac_cs_config\\"
 
 

+ 22 - 1
libs/expat/configure.ac

@@ -46,7 +46,7 @@ dnl If the API changes incompatibly set LIBAGE back to 0
 dnl
 dnl
 
 
 LIBCURRENT=7   # sync
 LIBCURRENT=7   # sync
-LIBREVISION=4  # with
+LIBREVISION=5  # with
 LIBAGE=6       # CMakeLists.txt!
 LIBAGE=6       # CMakeLists.txt!
 
 
 AC_CONFIG_HEADER(expat_config.h)
 AC_CONFIG_HEADER(expat_config.h)
@@ -126,6 +126,25 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([
     AC_MSG_RESULT([yes])
     AC_MSG_RESULT([yes])
 ], [
 ], [
     AC_MSG_RESULT([no])
     AC_MSG_RESULT([no])
+
+    AC_MSG_CHECKING([for arc4random (BSD, macOS or libbsd)])
+    AC_LINK_IFELSE([AC_LANG_SOURCE([
+      #if defined(HAVE_LIBBSD)
+      # include <bsd/stdlib.h>
+      #else
+      # include <stdlib.h>
+      #endif
+      int main() {
+          arc4random();
+          return 0;
+      }
+    ])], [
+        AC_DEFINE([HAVE_ARC4RANDOM], [1],
+            [Define to 1 if you have the `arc4random' function.])
+        AC_MSG_RESULT([yes])
+    ], [
+        AC_MSG_RESULT([no])
+    ])
 ])
 ])
 
 
 
 
@@ -180,6 +199,8 @@ AC_DEFINE([XML_NS], 1,
           [Define to make XML Namespaces functionality available.])
           [Define to make XML Namespaces functionality available.])
 AC_DEFINE([XML_DTD], 1,
 AC_DEFINE([XML_DTD], 1,
           [Define to make parameter entity parsing functionality available.])
           [Define to make parameter entity parsing functionality available.])
+AC_DEFINE([XML_DEV_URANDOM], 1,
+          [Define to include code reading entropy from `/dev/urandom'.])
 
 
 AC_ARG_ENABLE([xml-context],
 AC_ARG_ENABLE([xml-context],
   AS_HELP_STRING([--enable-xml-context @<:@COUNT@:>@],
   AS_HELP_STRING([--enable-xml-context @<:@COUNT@:>@],

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

@@ -71,7 +71,7 @@ If the input file is well-formed and \fBxmlwf\fR
 doesn't encounter any errors, the input file is simply copied to
 doesn't encounter any errors, the input file is simply copied to
 the output directory unchanged.
 the output directory unchanged.
 This implies no namespaces (turns off \*(T<\fB\-n\fR\*(T>) and
 This implies no namespaces (turns off \*(T<\fB\-n\fR\*(T>) and
-requires \*(T<\fB\-d\fR\*(T> to specify an output file.
+requires \*(T<\fB\-d\fR\*(T> to specify an output directory.
 .TP 
 .TP 
 \*(T<\fB\-d output\-dir\fR\*(T>
 \*(T<\fB\-d output\-dir\fR\*(T>
 Specifies a directory to contain transformed
 Specifies a directory to contain transformed

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

@@ -146,7 +146,7 @@ supports both.
   doesn't encounter any errors, the input file is simply copied to
   doesn't encounter any errors, the input file is simply copied to
   the output directory unchanged.
   the output directory unchanged.
   This implies no namespaces (turns off <option>-n</option>) and
   This implies no namespaces (turns off <option>-n</option>) and
-  requires <option>-d</option> to specify an output file.
+  requires <option>-d</option> to specify an output directory.
   		</para>
   		</para>
         </listitem>
         </listitem>
       </varlistentry>
       </varlistentry>

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

@@ -3,6 +3,9 @@
 /* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
 /* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
 #undef BYTEORDER
 #undef BYTEORDER
 
 
+/* Define to 1 if you have the `arc4random' function. */
+#undef HAVE_ARC4RANDOM
+
 /* Define to 1 if you have the `arc4random_buf' function. */
 /* Define to 1 if you have the `arc4random_buf' function. */
 #undef HAVE_ARC4RANDOM_BUF
 #undef HAVE_ARC4RANDOM_BUF
 
 
@@ -94,6 +97,9 @@
    point. */
    point. */
 #undef XML_CONTEXT_BYTES
 #undef XML_CONTEXT_BYTES
 
 
+/* Define to include code reading entropy from `/dev/urandom'. */
+#undef XML_DEV_URANDOM
+
 /* Define to make parameter entity parsing functionality available. */
 /* Define to make parameter entity parsing functionality available. */
 #undef XML_DTD
 #undef XML_DTD
 
 

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

@@ -1048,7 +1048,7 @@ XML_GetFeatureList(void);
 */
 */
 #define XML_MAJOR_VERSION 2
 #define XML_MAJOR_VERSION 2
 #define XML_MINOR_VERSION 2
 #define XML_MINOR_VERSION 2
-#define XML_MICRO_VERSION 2
+#define XML_MICRO_VERSION 3
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 141 - 0
libs/expat/lib/loadlibrary.c

@@ -0,0 +1,141 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2016 - 2017, Steve Holme, <[email protected]>.
+ *
+ * All rights reserved.
+ *
+ * Permission to  use, copy,  modify, and distribute  this software  for any
+ * purpose with  or without fee is  hereby granted, provided that  the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
+ * EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
+ * MERCHANTABILITY, FITNESS FOR A  PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR  OTHERWISE, ARISING FROM, OUT OF OR  IN CONNECTION WITH
+ * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice,  the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings  in this  Software without  prior written  authorization of  the
+ * copyright holder.
+ *
+ ***************************************************************************/
+
+#if defined(_WIN32)
+
+#include <windows.h>
+#include <tchar.h>
+
+
+HMODULE _Expat_LoadLibrary(LPCTSTR filename);
+
+
+#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH)
+#define LOAD_WITH_ALTERED_SEARCH_PATH  0x00000008
+#endif
+
+#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
+#define LOAD_LIBRARY_SEARCH_SYSTEM32   0x00000800
+#endif
+
+/* We use our own typedef here since some headers might lack these */
+typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
+
+/* See function definitions in winbase.h */
+#ifdef UNICODE
+#  ifdef _WIN32_WCE
+#    define LOADLIBARYEX  L"LoadLibraryExW"
+#  else
+#    define LOADLIBARYEX  "LoadLibraryExW"
+#  endif
+#else
+#  define LOADLIBARYEX    "LoadLibraryExA"
+#endif
+
+
+/*
+ * _Expat_LoadLibrary()
+ *
+ * This is used to dynamically load DLLs using the most secure method available
+ * for the version of Windows that we are running on.
+ *
+ * Parameters:
+ *
+ * filename  [in] - The filename or full path of the DLL to load. If only the
+ *                  filename is passed then the DLL will be loaded from the
+ *                  Windows system directory.
+ *
+ * Returns the handle of the module on success; otherwise NULL.
+ */
+HMODULE _Expat_LoadLibrary(LPCTSTR filename)
+{
+  HMODULE hModule = NULL;
+  LOADLIBRARYEX_FN pLoadLibraryEx = NULL;
+
+  /* Get a handle to kernel32 so we can access it's functions at runtime */
+  HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
+  if(!hKernel32)
+    return NULL;
+
+  /* Attempt to find LoadLibraryEx() which is only available on Windows 2000
+     and above */
+  pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX);
+
+  /* Detect if there's already a path in the filename and load the library if
+     there is. Note: Both back slashes and forward slashes have been supported
+     since the earlier days of DOS at an API level although they are not
+     supported by command prompt */
+  if(_tcspbrk(filename, TEXT("\\/"))) {
+    /** !checksrc! disable BANNEDFUNC 1 **/
+    hModule = pLoadLibraryEx ?
+      pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
+      LoadLibrary(filename);
+  }
+  /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only
+     supported on Windows Vista, Windows Server 2008, Windows 7 and Windows
+     Server 2008 R2 with this patch or natively on Windows 8 and above */
+  else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) {
+    /* Load the DLL from the Windows system directory */
+    hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+  }
+  else {
+    /* Attempt to get the Windows system path */
+    UINT systemdirlen = GetSystemDirectory(NULL, 0);
+    if(systemdirlen) {
+      /* Allocate space for the full DLL path (Room for the null terminator
+         is included in systemdirlen) */
+      size_t filenamelen = _tcslen(filename);
+      TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen));
+      if(path && GetSystemDirectory(path, systemdirlen)) {
+        /* Calculate the full DLL path */
+        _tcscpy(path + _tcslen(path), TEXT("\\"));
+        _tcscpy(path + _tcslen(path), filename);
+
+        /* Load the DLL from the Windows system directory */
+        /** !checksrc! disable BANNEDFUNC 1 **/
+        hModule = pLoadLibraryEx ?
+          pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
+          LoadLibrary(path);
+
+      }
+      free(path);
+    }
+  }
+
+  return hModule;
+}
+
+#else /* defined(_WIN32) */
+
+/* ISO C requires a translation unit to contain at least one declaration
+   [-Wempty-translation-unit] */
+typedef int _TRANSLATION_UNIT_LOAD_LIBRARY_C_NOT_EMTPY;
+
+#endif /* defined(_WIN32) */

+ 4 - 1
libs/expat/lib/siphash.h

@@ -11,6 +11,9 @@
  * --------------------------------------------------------------------------
  * --------------------------------------------------------------------------
  * HISTORY:
  * HISTORY:
  *
  *
+ * 2017-07-25  (Vadim Zeitlin)
+ *   - Fix use of SIPHASH_MAIN macro
+ *
  * 2017-07-05  (Sebastian Pipping)
  * 2017-07-05  (Sebastian Pipping)
  *   - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++
  *   - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++
  *   - Add const qualifiers at two places
  *   - Add const qualifiers at two places
@@ -350,7 +353,7 @@ static int sip24_valid(void) {
 } /* sip24_valid() */
 } /* sip24_valid() */
 
 
 
 
-#if SIPHASH_MAIN
+#ifdef SIPHASH_MAIN
 
 
 #include <stdio.h>
 #include <stdio.h>
 
 

+ 370 - 58
libs/expat/lib/xmlparse.c

@@ -1,7 +1,7 @@
 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
    See the file COPYING for copying permission.
    See the file COPYING for copying permission.
 
 
-   cd4063469a95eab9a93001afb109e3dee122cdda4635bbec36257fc01c327348 (2.2.2+)
+   101bfd65d1ff3d1511cf6671e6aae65f82cd97df6f4da137d46d510731830ad9 (2.2.3+)
 */
 */
 
 
 #if !defined(_GNU_SOURCE)
 #if !defined(_GNU_SOURCE)
@@ -21,6 +21,8 @@
 #include <sys/time.h>                   /* gettimeofday() */
 #include <sys/time.h>                   /* gettimeofday() */
 #include <sys/types.h>                  /* getpid() */
 #include <sys/types.h>                  /* getpid() */
 #include <unistd.h>                     /* getpid() */
 #include <unistd.h>                     /* getpid() */
+#include <fcntl.h>                      /* O_RDONLY */
+#include <errno.h>
 #endif
 #endif
 
 
 #define XML_BUILDING_EXPAT 1
 #define XML_BUILDING_EXPAT 1
@@ -36,22 +38,30 @@
 #include "siphash.h"
 #include "siphash.h"
 
 
 #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
 #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
-# include <errno.h>
 # if defined(HAVE_GETRANDOM)
 # if defined(HAVE_GETRANDOM)
 #  include <sys/random.h>    /* getrandom */
 #  include <sys/random.h>    /* getrandom */
 # else
 # else
 #  include <unistd.h>        /* syscall */
 #  include <unistd.h>        /* syscall */
 #  include <sys/syscall.h>   /* SYS_getrandom */
 #  include <sys/syscall.h>   /* SYS_getrandom */
 # endif
 # endif
+# if ! defined(GRND_NONBLOCK)
+#  define GRND_NONBLOCK  0x0001
+# endif  /* defined(GRND_NONBLOCK) */
 #endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
 #endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
 
 
-#if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD)
+#if defined(HAVE_LIBBSD) \
+    && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
 # include <bsd/stdlib.h>
 # include <bsd/stdlib.h>
 #endif
 #endif
 
 
+#if defined(_WIN32) && !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
+# define LOAD_LIBRARY_SEARCH_SYSTEM32  0x00000800
+#endif
 
 
 #if !defined(HAVE_GETRANDOM) && !defined(HAVE_SYSCALL_GETRANDOM) \
 #if !defined(HAVE_GETRANDOM) && !defined(HAVE_SYSCALL_GETRANDOM) \
-    && !defined(HAVE_ARC4RANDOM_BUF) && !defined(_WIN32) \
+    && !defined(HAVE_ARC4RANDOM_BUF) && !defined(HAVE_ARC4RANDOM) \
+    && !defined(XML_DEV_URANDOM) \
+    && !defined(_WIN32) \
     && !defined(XML_POOR_ENTROPY)
     && !defined(XML_POOR_ENTROPY)
 # error  \
 # error  \
     You do not have support for any sources of high quality entropy \
     You do not have support for any sources of high quality entropy \
@@ -60,8 +70,11 @@
     Your options include: \
     Your options include: \
       * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
       * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
       * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
       * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
-      * BSD / macOS (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
+      * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
+      * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \
       * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
       * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
+      * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
+      * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \
       * Windows (RtlGenRandom): _WIN32. \
       * Windows (RtlGenRandom): _WIN32. \
     \
     \
     If insist on not using any of these, bypass this error by defining \
     If insist on not using any of these, bypass this error by defining \
@@ -744,10 +757,10 @@ static const XML_Char implicitContext[] = {
 
 
 /* Obtain entropy on Linux 3.17+ */
 /* Obtain entropy on Linux 3.17+ */
 static int
 static int
-writeRandomBytes_getrandom(void * target, size_t count) {
+writeRandomBytes_getrandom_nonblock(void * target, size_t count) {
   int success = 0;  /* full count bytes written? */
   int success = 0;  /* full count bytes written? */
   size_t bytesWrittenTotal = 0;
   size_t bytesWrittenTotal = 0;
-  const unsigned int getrandomFlags = 0;
+  const unsigned int getrandomFlags = GRND_NONBLOCK;
 
 
   do {
   do {
     void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
     void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
@@ -765,7 +778,7 @@ writeRandomBytes_getrandom(void * target, size_t count) {
       if (bytesWrittenTotal >= count)
       if (bytesWrittenTotal >= count)
         success = 1;
         success = 1;
     }
     }
-  } while (! success && (errno == EINTR || errno == EAGAIN));
+  } while (! success && (errno == EINTR));
 
 
   return success;
   return success;
 }
 }
@@ -773,12 +786,67 @@ writeRandomBytes_getrandom(void * target, size_t count) {
 #endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
 #endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
 
 
 
 
+#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
+
+/* Extract entropy from /dev/urandom */
+static int
+writeRandomBytes_dev_urandom(void * target, size_t count) {
+  int success = 0;  /* full count bytes written? */
+  size_t bytesWrittenTotal = 0;
+
+  const int fd = open("/dev/urandom", O_RDONLY);
+  if (fd < 0) {
+    return 0;
+  }
+
+  do {
+    void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
+    const size_t bytesToWrite = count - bytesWrittenTotal;
+
+    const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
+
+    if (bytesWrittenMore > 0) {
+      bytesWrittenTotal += bytesWrittenMore;
+      if (bytesWrittenTotal >= count)
+        success = 1;
+    }
+  } while (! success && (errno == EINTR));
+
+  close(fd);
+  return success;
+}
+
+#endif  /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
+
+
+#if defined(HAVE_ARC4RANDOM)
+
+static void
+writeRandomBytes_arc4random(void * target, size_t count) {
+  size_t bytesWrittenTotal = 0;
+
+  while (bytesWrittenTotal < count) {
+    const uint32_t random32 = arc4random();
+    size_t i = 0;
+
+    for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
+        i++, bytesWrittenTotal++) {
+      const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
+      ((uint8_t *)target)[bytesWrittenTotal] = random8;
+    }
+  }
+}
+
+#endif  /* defined(HAVE_ARC4RANDOM) */
+
+
 #ifdef _WIN32
 #ifdef _WIN32
 
 
 typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
 typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
+HMODULE _Expat_LoadLibrary(LPCTSTR filename);  /* see loadlibrary.c */
 
 
 /* Obtain entropy on Windows XP / Windows Server 2003 and later.
 /* Obtain entropy on Windows XP / Windows Server 2003 and later.
- * Hint on RtlGenRandom and the following article from libsodioum.
+ * Hint on RtlGenRandom and the following article from libsodium.
  *
  *
  * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
  * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
  * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
  * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
@@ -786,7 +854,7 @@ typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
 static int
 static int
 writeRandomBytes_RtlGenRandom(void * target, size_t count) {
 writeRandomBytes_RtlGenRandom(void * target, size_t count) {
   int success = 0;  /* full count bytes written? */
   int success = 0;  /* full count bytes written? */
-  const HMODULE advapi32 = LoadLibrary(TEXT("ADVAPI32.DLL"));
+  const HMODULE advapi32 = _Expat_LoadLibrary(TEXT("ADVAPI32.DLL"));
 
 
   if (advapi32) {
   if (advapi32) {
     const RTLGENRANDOM_FUNC RtlGenRandom
     const RTLGENRANDOM_FUNC RtlGenRandom
@@ -805,6 +873,8 @@ writeRandomBytes_RtlGenRandom(void * target, size_t count) {
 #endif /* _WIN32 */
 #endif /* _WIN32 */
 
 
 
 
+#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
+
 static unsigned long
 static unsigned long
 gather_time_entropy(void)
 gather_time_entropy(void)
 {
 {
@@ -829,6 +899,9 @@ gather_time_entropy(void)
 #endif
 #endif
 }
 }
 
 
+#endif  /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
+
+
 static unsigned long
 static unsigned long
 ENTROPY_DEBUG(const char * label, unsigned long entropy) {
 ENTROPY_DEBUG(const char * label, unsigned long entropy) {
   const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
   const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
@@ -846,10 +919,12 @@ generate_hash_secret_salt(XML_Parser parser)
 {
 {
   unsigned long entropy;
   unsigned long entropy;
   (void)parser;
   (void)parser;
-#if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__)
-  (void)gather_time_entropy;
+#if defined(HAVE_ARC4RANDOM_BUF)
   arc4random_buf(&entropy, sizeof(entropy));
   arc4random_buf(&entropy, sizeof(entropy));
   return ENTROPY_DEBUG("arc4random_buf", entropy);
   return ENTROPY_DEBUG("arc4random_buf", entropy);
+#elif defined(HAVE_ARC4RANDOM)
+  writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
+  return ENTROPY_DEBUG("arc4random", entropy);
 #else
 #else
   /* Try high quality providers first .. */
   /* Try high quality providers first .. */
 #ifdef _WIN32
 #ifdef _WIN32
@@ -857,10 +932,15 @@ generate_hash_secret_salt(XML_Parser parser)
     return ENTROPY_DEBUG("RtlGenRandom", entropy);
     return ENTROPY_DEBUG("RtlGenRandom", entropy);
   }
   }
 #elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
 #elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
-  if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) {
+  if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
     return ENTROPY_DEBUG("getrandom", entropy);
     return ENTROPY_DEBUG("getrandom", entropy);
   }
   }
 #endif
 #endif
+#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
+  if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
+    return ENTROPY_DEBUG("/dev/urandom", entropy);
+  }
+#endif  /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
   /* .. and self-made low quality for backup: */
   /* .. and self-made low quality for backup: */
 
 
   /* Process ID is 0 bits entropy if attacker has local access */
   /* Process ID is 0 bits entropy if attacker has local access */
@@ -1833,9 +1913,22 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
     if (errorCode == XML_ERROR_NONE) {
     if (errorCode == XML_ERROR_NONE) {
       switch (ps_parsing) {
       switch (ps_parsing) {
       case XML_SUSPENDED:
       case XML_SUSPENDED:
+        /* It is hard to be certain, but it seems that this case
+         * cannot occur.  This code is cleaning up a previous parse
+         * with no new data (since len == 0).  Changing the parsing
+         * state requires getting to execute a handler function, and
+         * there doesn't seem to be an opportunity for that while in
+         * this circumstance.
+         *
+         * Given the uncertainty, we retain the code but exclude it
+         * from coverage tests.
+         *
+         * LCOV_EXCL_START
+         */
         XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
         XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
         positionPtr = bufferPtr;
         positionPtr = bufferPtr;
         return XML_STATUS_SUSPENDED;
         return XML_STATUS_SUSPENDED;
+        /* LCOV_EXCL_STOP */
       case XML_INITIALIZED:
       case XML_INITIALIZED:
       case XML_PARSING:
       case XML_PARSING:
         ps_parsing = XML_FINISHED;
         ps_parsing = XML_FINISHED;
@@ -3024,9 +3117,17 @@ doContent(XML_Parser parser,
         return XML_ERROR_NO_MEMORY;
         return XML_ERROR_NO_MEMORY;
       break;
       break;
     default:
     default:
+      /* All of the tokens produced by XmlContentTok() have their own
+       * explicit cases, so this default is not strictly necessary.
+       * However it is a useful safety net, so we retain the code and
+       * simply exclude it from the coverage tests.
+       *
+       * LCOV_EXCL_START
+       */
       if (defaultHandler)
       if (defaultHandler)
         reportDefault(parser, enc, s, next);
         reportDefault(parser, enc, s, next);
       break;
       break;
+      /* LCOV_EXCL_STOP */
     }
     }
     *eventPP = s = next;
     *eventPP = s = next;
     switch (ps_parsing) {
     switch (ps_parsing) {
@@ -3117,13 +3218,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
 #endif
 #endif
     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
     temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
     temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
-    if (temp == NULL)
+    if (temp == NULL) {
+      attsSize = oldAttsSize;
       return XML_ERROR_NO_MEMORY;
       return XML_ERROR_NO_MEMORY;
+    }
     atts = temp;
     atts = temp;
 #ifdef XML_ATTR_INFO
 #ifdef XML_ATTR_INFO
     temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
     temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
-    if (temp2 == NULL)
+    if (temp2 == NULL) {
+      attsSize = oldAttsSize;
       return XML_ERROR_NO_MEMORY;
       return XML_ERROR_NO_MEMORY;
+    }
     attInfo = temp2;
     attInfo = temp2;
 #endif
 #endif
     if (n > oldAttsSize)
     if (n > oldAttsSize)
@@ -3260,6 +3365,7 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
     int j;  /* hash table index */
     int j;  /* hash table index */
     unsigned long version = nsAttsVersion;
     unsigned long version = nsAttsVersion;
     int nsAttsSize = (int)1 << nsAttsPower;
     int nsAttsSize = (int)1 << nsAttsPower;
+    unsigned char oldNsAttsPower = nsAttsPower;
     /* size of hash table must be at least 2 * (# of prefixed attributes) */
     /* size of hash table must be at least 2 * (# of prefixed attributes) */
     if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
     if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
       NS_ATT *temp;
       NS_ATT *temp;
@@ -3269,8 +3375,11 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
         nsAttsPower = 3;
         nsAttsPower = 3;
       nsAttsSize = (int)1 << nsAttsPower;
       nsAttsSize = (int)1 << nsAttsPower;
       temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
       temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
-      if (!temp)
+      if (!temp) {
+        /* Restore actual size of memory in nsAtts */
+        nsAttsPower = oldNsAttsPower;
         return XML_ERROR_NO_MEMORY;
         return XML_ERROR_NO_MEMORY;
+      }
       nsAtts = temp;
       nsAtts = temp;
       version = 0;  /* force re-initialization of nsAtts hash table */
       version = 0;  /* force re-initialization of nsAtts hash table */
     }
     }
@@ -3297,8 +3406,23 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
 
 
         ((XML_Char *)s)[-1] = 0;  /* clear flag */
         ((XML_Char *)s)[-1] = 0;  /* clear flag */
         id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
         id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
-        if (!id || !id->prefix)
-          return XML_ERROR_NO_MEMORY;
+        if (!id || !id->prefix) {
+          /* This code is walking through the appAtts array, dealing
+           * with (in this case) a prefixed attribute name.  To be in
+           * the array, the attribute must have already been bound, so
+           * has to have passed through the hash table lookup once
+           * already.  That implies that an entry for it already
+           * exists, so the lookup above will return a pointer to
+           * already allocated memory.  There is no opportunaity for
+           * the allocator to fail, so the condition above cannot be
+           * fulfilled.
+           *
+           * Since it is difficult to be certain that the above
+           * analysis is complete, we retain the test and merely
+           * remove the code from coverage tests.
+           */
+          return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
+        }
         b = id->prefix->binding;
         b = id->prefix->binding;
         if (!b)
         if (!b)
           return XML_ERROR_UNBOUND_PREFIX;
           return XML_ERROR_UNBOUND_PREFIX;
@@ -3675,8 +3799,16 @@ doCdataSection(XML_Parser parser,
       }
       }
       return XML_ERROR_UNCLOSED_CDATA_SECTION;
       return XML_ERROR_UNCLOSED_CDATA_SECTION;
     default:
     default:
+      /* Every token returned by XmlCdataSectionTok() has its own
+       * explicit case, so this default case will never be executed.
+       * We retain it as a safety net and exclude it from the coverage
+       * statistics.
+       *
+       * LCOV_EXCL_START
+      */
       *eventPP = next;
       *eventPP = next;
       return XML_ERROR_UNEXPECTED_STATE;
       return XML_ERROR_UNEXPECTED_STATE;
+      /* LCOV_EXCL_STOP */
     }
     }
 
 
     *eventPP = s = next;
     *eventPP = s = next;
@@ -3736,8 +3868,20 @@ doIgnoreSection(XML_Parser parser,
     eventEndPP = &eventEndPtr;
     eventEndPP = &eventEndPtr;
   }
   }
   else {
   else {
+    /* It's not entirely clear, but it seems the following two lines
+     * of code cannot be executed.  The only occasions on which 'enc'
+     * is not 'parser->m_encoding' are when this function is called
+     * from the internal entity processing, and IGNORE sections are an
+     * error in internal entities.
+     *
+     * Since it really isn't clear that this is true, we keep the code
+     * and just remove it from our coverage tests.
+     *
+     * LCOV_EXCL_START
+     */
     eventPP = &(openInternalEntities->internalEventPtr);
     eventPP = &(openInternalEntities->internalEventPtr);
     eventEndPP = &(openInternalEntities->internalEventEndPtr);
     eventEndPP = &(openInternalEntities->internalEventEndPtr);
+    /* LCOV_EXCL_STOP */
   }
   }
   *eventPP = s;
   *eventPP = s;
   *startPtr = NULL;
   *startPtr = NULL;
@@ -3770,8 +3914,16 @@ doIgnoreSection(XML_Parser parser,
     }
     }
     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
   default:
   default:
+    /* All of the tokens that XmlIgnoreSectionTok() returns have
+     * explicit cases to handle them, so this default case is never
+     * executed.  We keep it as a safety net anyway, and remove it
+     * from our test coverage statistics.
+     *
+     * LCOV_EXCL_START
+     */
     *eventPP = next;
     *eventPP = next;
     return XML_ERROR_UNEXPECTED_STATE;
     return XML_ERROR_UNEXPECTED_STATE;
+    /* LCOV_EXCL_STOP */
   }
   }
   /* not reached */
   /* not reached */
 }
 }
@@ -3868,7 +4020,14 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
     reportDefault(parser, encoding, s, next);
     reportDefault(parser, encoding, s, next);
   if (protocolEncodingName == NULL) {
   if (protocolEncodingName == NULL) {
     if (newEncoding) {
     if (newEncoding) {
-      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+      /* Check that the specified encoding does not conflict with what
+       * the parser has already deduced.  Do we have the same number
+       * of bytes in the smallest representation of a character?  If
+       * this is UTF-16, is it the same endianness?
+       */
+      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar
+          || (newEncoding->minBytesPerChar == 2 &&
+              newEncoding != encoding)) {
         eventPtr = encodingName;
         eventPtr = encodingName;
         return XML_ERROR_INCORRECT_ENCODING;
         return XML_ERROR_INCORRECT_ENCODING;
       }
       }
@@ -4013,15 +4172,14 @@ entityValueInitProcessor(XML_Parser parser,
       result = processXmlDecl(parser, 0, start, next);
       result = processXmlDecl(parser, 0, start, next);
       if (result != XML_ERROR_NONE)
       if (result != XML_ERROR_NONE)
         return result;
         return result;
-      switch (ps_parsing) {
-      case XML_SUSPENDED:
-        *nextPtr = next;
-        return XML_ERROR_NONE;
-      case XML_FINISHED:
+      /* At this point, ps_parsing cannot be XML_SUSPENDED.  For that
+       * to happen, a parameter entity parsing handler must have
+       * attempted to suspend the parser, which fails and raises an
+       * error.  The parser can be aborted, but can't be suspended.
+       */
+      if (ps_parsing == XML_FINISHED)
         return XML_ERROR_ABORTED;
         return XML_ERROR_ABORTED;
-      default:
-        *nextPtr = next;
-      }
+      *nextPtr = next;
       /* stop scanning for text declaration - we found one */
       /* stop scanning for text declaration - we found one */
       processor = entityValueProcessor;
       processor = entityValueProcessor;
       return entityValueProcessor(parser, next, end, nextPtr);
       return entityValueProcessor(parser, next, end, nextPtr);
@@ -4344,8 +4502,14 @@ doProlog(XML_Parser parser,
                                             &dtd->paramEntities,
                                             &dtd->paramEntities,
                                             externalSubsetName,
                                             externalSubsetName,
                                             sizeof(ENTITY));
                                             sizeof(ENTITY));
-          if (!entity)
-            return XML_ERROR_NO_MEMORY;
+          if (!entity) {
+            /* The external subset name "#" will have already been
+             * inserted into the hash table at the start of the
+             * external entity parsing, so no allocation will happen
+             * and lookup() cannot fail.
+             */
+            return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
+          }
           if (useForeignDTD)
           if (useForeignDTD)
             entity->base = curBase;
             entity->base = curBase;
           dtd->paramEntityRead = XML_FALSE;
           dtd->paramEntityRead = XML_FALSE;
@@ -4824,8 +4988,10 @@ doProlog(XML_Parser parser,
       if (prologState.level >= groupSize) {
       if (prologState.level >= groupSize) {
         if (groupSize) {
         if (groupSize) {
           char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
           char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
-          if (temp == NULL)
+          if (temp == NULL) {
+            groupSize /= 2;
             return XML_ERROR_NO_MEMORY;
             return XML_ERROR_NO_MEMORY;
+          }
           groupConnector = temp;
           groupConnector = temp;
           if (dtd->scaffIndex) {
           if (dtd->scaffIndex) {
             int *temp = (int *)REALLOC(dtd->scaffIndex,
             int *temp = (int *)REALLOC(dtd->scaffIndex,
@@ -4837,8 +5003,10 @@ doProlog(XML_Parser parser,
         }
         }
         else {
         else {
           groupConnector = (char *)MALLOC(groupSize = 32);
           groupConnector = (char *)MALLOC(groupSize = 32);
-          if (!groupConnector)
+          if (!groupConnector) {
+            groupSize = 0;
             return XML_ERROR_NO_MEMORY;
             return XML_ERROR_NO_MEMORY;
+          }
         }
         }
       }
       }
       groupConnector[prologState.level] = 0;
       groupConnector[prologState.level] = 0;
@@ -4901,8 +5069,29 @@ doProlog(XML_Parser parser,
              : !dtd->hasParamEntityRefs)) {
              : !dtd->hasParamEntityRefs)) {
           if (!entity)
           if (!entity)
             return XML_ERROR_UNDEFINED_ENTITY;
             return XML_ERROR_UNDEFINED_ENTITY;
-          else if (!entity->is_internal)
-            return XML_ERROR_ENTITY_DECLARED_IN_PE;
+          else if (!entity->is_internal) {
+            /* It's hard to exhaustively search the code to be sure,
+             * but there doesn't seem to be a way of executing the
+             * following line.  There are two cases:
+             *
+             * 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
+             * 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
+             * the test for an internal entity.
+             *
+             * If 'standalone' is true, it does not seem to be
+             * possible to create entities taking this code path that
+             * are not internal entities, so fail the test above.
+             *
+             * Because this analysis is very uncertain, the code is
+             * being left in place and merely removed from the
+             * coverage test statistics.
+             */
+            return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
+          }
         }
         }
         else if (!entity) {
         else if (!entity) {
           dtd->keepProcessing = dtd->standalone;
           dtd->keepProcessing = dtd->standalone;
@@ -5374,11 +5563,15 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
           break;
           break;
         n = XmlEncode(n, (ICHAR *)buf);
         n = XmlEncode(n, (ICHAR *)buf);
-        if (!n) {
-          if (enc == encoding)
-            eventPtr = ptr;
-          return XML_ERROR_BAD_CHAR_REF;
-        }
+        /* The XmlEncode() functions can never return 0 here.  That
+         * error return happens if the code point passed in is either
+         * negative or greater than or equal to 0x110000.  The
+         * XmlCharRefNumber() functions will all return a number
+         * strictly less than 0x110000 or a negative value if an error
+         * occurred.  The negative value is intercepted above, so
+         * XmlEncode() is never passed a value it might return an
+         * error for.
+         */
         for (i = 0; i < n; i++) {
         for (i = 0; i < n; i++) {
           if (!poolAppendChar(pool, buf[i]))
           if (!poolAppendChar(pool, buf[i]))
             return XML_ERROR_NO_MEMORY;
             return XML_ERROR_NO_MEMORY;
@@ -5452,8 +5645,26 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
           break;
           break;
         }
         }
         if (entity->open) {
         if (entity->open) {
-          if (enc == encoding)
-            eventPtr = ptr;
+          if (enc == encoding) {
+            /* It does not appear that this line can be executed.
+             *
+             * The "if (entity->open)" check catches recursive entity
+             * definitions.  In order to be called with an open
+             * entity, it must have gone through this code before and
+             * been through the recursive call to
+             * appendAttributeValue() some lines below.  That call
+             * sets the local encoding ("enc") to the parser's
+             * internal encoding (internal_utf8 or internal_utf16),
+             * which can never be the same as the principle encoding.
+             * It doesn't appear there is another code path that gets
+             * here with entity->open being TRUE.
+             *
+             * Since it is not certain that this logic is watertight,
+             * we keep the line and merely exclude it from coverage
+             * tests.
+             */
+            eventPtr = ptr; /* LCOV_EXCL_LINE */
+          }
           return XML_ERROR_RECURSIVE_ENTITY_REF;
           return XML_ERROR_RECURSIVE_ENTITY_REF;
         }
         }
         if (entity->notation) {
         if (entity->notation) {
@@ -5480,9 +5691,21 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
       }
       }
       break;
       break;
     default:
     default:
+      /* The only token returned by XmlAttributeValueTok() that does
+       * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
+       * Getting that would require an entity name to contain an
+       * incomplete XML character (e.g. \xE2\x82); however previous
+       * tokenisers will have already recognised and rejected such
+       * names before XmlAttributeValueTok() gets a look-in.  This
+       * default case should be retained as a safety net, but the code
+       * excluded from coverage tests.
+       *
+       * LCOV_EXCL_START
+       */
       if (enc == encoding)
       if (enc == encoding)
         eventPtr = ptr;
         eventPtr = ptr;
       return XML_ERROR_UNEXPECTED_STATE;
       return XML_ERROR_UNEXPECTED_STATE;
+      /* LCOV_EXCL_STOP */
     }
     }
     ptr = next;
     ptr = next;
   }
   }
@@ -5615,12 +5838,15 @@ storeEntityValue(XML_Parser parser,
           goto endEntityValue;
           goto endEntityValue;
         }
         }
         n = XmlEncode(n, (ICHAR *)buf);
         n = XmlEncode(n, (ICHAR *)buf);
-        if (!n) {
-          if (enc == encoding)
-            eventPtr = entityTextPtr;
-          result = XML_ERROR_BAD_CHAR_REF;
-          goto endEntityValue;
-        }
+        /* The XmlEncode() functions can never return 0 here.  That
+         * error return happens if the code point passed in is either
+         * negative or greater than or equal to 0x110000.  The
+         * XmlCharRefNumber() functions will all return a number
+         * strictly less than 0x110000 or a negative value if an error
+         * occurred.  The negative value is intercepted above, so
+         * XmlEncode() is never passed a value it might return an
+         * error for.
+         */
         for (i = 0; i < n; i++) {
         for (i = 0; i < n; i++) {
           if (pool->end == pool->ptr && !poolGrow(pool)) {
           if (pool->end == pool->ptr && !poolGrow(pool)) {
             result = XML_ERROR_NO_MEMORY;
             result = XML_ERROR_NO_MEMORY;
@@ -5641,10 +5867,18 @@ storeEntityValue(XML_Parser parser,
       result = XML_ERROR_INVALID_TOKEN;
       result = XML_ERROR_INVALID_TOKEN;
       goto endEntityValue;
       goto endEntityValue;
     default:
     default:
+      /* This default case should be unnecessary -- all the tokens
+       * that XmlEntityValueTok() can return have their own explicit
+       * cases -- but should be retained for safety.  We do however
+       * exclude it from the coverage statistics.
+       *
+       * LCOV_EXCL_START
+       */
       if (enc == encoding)
       if (enc == encoding)
         eventPtr = entityTextPtr;
         eventPtr = entityTextPtr;
       result = XML_ERROR_UNEXPECTED_STATE;
       result = XML_ERROR_UNEXPECTED_STATE;
       goto endEntityValue;
       goto endEntityValue;
+      /* LCOV_EXCL_STOP */
     }
     }
     entityTextPtr = next;
     entityTextPtr = next;
   }
   }
@@ -5742,8 +5976,25 @@ reportDefault(XML_Parser parser, const ENCODING *enc,
       eventEndPP = &eventEndPtr;
       eventEndPP = &eventEndPtr;
     }
     }
     else {
     else {
+      /* To get here, two things must be true; the parser must be
+       * using a character encoding that is not the same as the
+       * encoding passed in, and the encoding passed in must need
+       * conversion to the internal format (UTF-8 unless XML_UNICODE
+       * is defined).  The only occasions on which the encoding passed
+       * in is not the same as the parser's encoding are when it is
+       * the internal encoding (e.g. a previously defined parameter
+       * entity, already converted to internal format).  This by
+       * definition doesn't need conversion, so the whole branch never
+       * gets executed.
+       *
+       * For safety's sake we don't delete these lines and merely
+       * exclude them from coverage statistics.
+       *
+       * LCOV_EXCL_START
+       */
       eventPP = &(openInternalEntities->internalEventPtr);
       eventPP = &(openInternalEntities->internalEventPtr);
       eventEndPP = &(openInternalEntities->internalEventEndPtr);
       eventEndPP = &(openInternalEntities->internalEventEndPtr);
+      /* LCOV_EXCL_STOP */
     }
     }
     do {
     do {
       ICHAR *dataPtr = (ICHAR *)dataBuf;
       ICHAR *dataPtr = (ICHAR *)dataBuf;
@@ -5912,9 +6163,30 @@ getContext(XML_Parser parser)
     len = dtd->defaultPrefix.binding->uriLen;
     len = dtd->defaultPrefix.binding->uriLen;
     if (namespaceSeparator)
     if (namespaceSeparator)
       len--;
       len--;
-    for (i = 0; i < len; i++)
-      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
-        return NULL;
+    for (i = 0; i < len; i++) {
+      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) {
+        /* Because of memory caching, I don't believe this line can be
+         * executed.
+         *
+         * This is part of a loop copying the default prefix binding
+         * URI into the parser's temporary string pool.  Previously,
+         * that URI was copied into the same string pool, with a
+         * terminating NUL character, as part of setContext().  When
+         * the pool was cleared, that leaves a block definitely big
+         * enough to hold the URI on the free block list of the pool.
+         * The URI copy in getContext() therefore cannot run out of
+         * memory.
+         *
+         * If the pool is used between the setContext() and
+         * getContext() calls, the worst it can do is leave a bigger
+         * block on the front of the free list.  Given that this is
+         * all somewhat inobvious and program logic can be changed, we
+         * don't delete the line but we do exclude it from the test
+         * coverage statistics.
+         */
+        return NULL; /* LCOV_EXCL_LINE */
+      }
+    }
     needSep = XML_TRUE;
     needSep = XML_TRUE;
   }
   }
 
 
@@ -5926,8 +6198,15 @@ getContext(XML_Parser parser)
     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
     if (!prefix)
     if (!prefix)
       break;
       break;
-    if (!prefix->binding)
-      continue;
+    if (!prefix->binding) {
+      /* This test appears to be (justifiable) paranoia.  There does
+       * not seem to be a way of injecting a prefix without a binding
+       * that doesn't get errored long before this function is called.
+       * The test should remain for safety's sake, so we instead
+       * exclude the following line from the coverage statistics.
+       */
+      continue; /* LCOV_EXCL_LINE */
+    }
     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
       return NULL;
       return NULL;
     for (s = prefix->name; *s; s++)
     for (s = prefix->name; *s; s++)
@@ -6598,8 +6877,20 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s)
 static const XML_Char *
 static const XML_Char *
 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
 {
 {
-  if (!pool->ptr && !poolGrow(pool))
-    return NULL;
+  if (!pool->ptr && !poolGrow(pool)) {
+    /* The following line is unreachable given the current usage of
+     * poolCopyStringN().  Currently it is called from exactly one
+     * place to copy the text of a simple general entity.  By that
+     * point, the name of the entity is already stored in the pool, so
+     * pool->ptr cannot be NULL.
+     *
+     * If poolCopyStringN() is used elsewhere as it well might be,
+     * this line may well become executable again.  Regardless, this
+     * sort of check shouldn't be removed lightly, so we just exclude
+     * it from the coverage statistics.
+     */
+    return NULL; /* LCOV_EXCL_LINE */
+  }
   for (; n > 0; --n, s++) {
   for (; n > 0; --n, s++) {
     if (!poolAppendChar(pool, *s))
     if (!poolAppendChar(pool, *s))
       return NULL;
       return NULL;
@@ -6692,8 +6983,19 @@ poolGrow(STRING_POOL *pool)
     int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
     int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
     size_t bytesToAllocate;
     size_t bytesToAllocate;
 
 
-    if (blockSize < 0)
-      return XML_FALSE;
+    // NOTE: Needs to be calculated prior to calling `realloc`
+    //       to avoid dangling pointers:
+    const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
+
+    if (blockSize < 0) {
+      /* This condition traps a situation where either more than
+       * INT_MAX/2 bytes have already been allocated.  This isn't
+       * readily testable, since it is unlikely that an average
+       * machine will have that much memory, so we exclude it from the
+       * coverage statistics.
+       */
+      return XML_FALSE; /* LCOV_EXCL_LINE */
+    }
 
 
     bytesToAllocate = poolBytesToAllocateFor(blockSize);
     bytesToAllocate = poolBytesToAllocateFor(blockSize);
     if (bytesToAllocate == 0)
     if (bytesToAllocate == 0)
@@ -6705,7 +7007,7 @@ poolGrow(STRING_POOL *pool)
       return XML_FALSE;
       return XML_FALSE;
     pool->blocks = temp;
     pool->blocks = temp;
     pool->blocks->size = blockSize;
     pool->blocks->size = blockSize;
-    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+    pool->ptr = pool->blocks->s + offsetInsideBlock;
     pool->start = pool->blocks->s;
     pool->start = pool->blocks->s;
     pool->end = pool->start + blockSize;
     pool->end = pool->start + blockSize;
   }
   }
@@ -6714,8 +7016,18 @@ poolGrow(STRING_POOL *pool)
     int blockSize = (int)(pool->end - pool->start);
     int blockSize = (int)(pool->end - pool->start);
     size_t bytesToAllocate;
     size_t bytesToAllocate;
 
 
-    if (blockSize < 0)
-      return XML_FALSE;
+    if (blockSize < 0) {
+      /* This condition traps a situation where either more than
+       * INT_MAX bytes have already been allocated (which is prevented
+       * by various pieces of program logic, not least this one, never
+       * mind the unlikelihood of actually having that much memory) or
+       * the pool control fields have been corrupted (which could
+       * conceivably happen in an extremely buggy user handler
+       * function).  Either way it isn't readily testable, so we
+       * exclude it from the coverage statistics.
+       */
+      return XML_FALSE;  /* LCOV_EXCL_LINE */
+    }
 
 
     if (blockSize < INIT_BLOCK_SIZE)
     if (blockSize < INIT_BLOCK_SIZE)
       blockSize = INIT_BLOCK_SIZE;
       blockSize = INIT_BLOCK_SIZE;

+ 29 - 1
libs/expat/lib/xmlrole.c

@@ -170,7 +170,14 @@ prolog1(PROLOG_STATE *state,
   case XML_TOK_COMMENT:
   case XML_TOK_COMMENT:
     return XML_ROLE_COMMENT;
     return XML_ROLE_COMMENT;
   case XML_TOK_BOM:
   case XML_TOK_BOM:
-    return XML_ROLE_NONE;
+    /* This case can never arise.  To reach this role function, the
+     * parse must have passed through prolog0 and therefore have had
+     * some form of input, even if only a space.  At that point, a
+     * byte order mark is no longer a valid character (though
+     * technically it should be interpreted as a non-breaking space),
+     * so will be rejected by the tokenizing stages.
+     */
+    return XML_ROLE_NONE; /* LCOV_EXCL_LINE */
   case XML_TOK_DECL_OPEN:
   case XML_TOK_DECL_OPEN:
     if (!XmlNameMatchesAscii(enc,
     if (!XmlNameMatchesAscii(enc,
                              ptr + 2 * MIN_BYTES_PER_CHAR(enc),
                              ptr + 2 * MIN_BYTES_PER_CHAR(enc),
@@ -1285,6 +1292,26 @@ declClose(PROLOG_STATE *state,
   return common(state, tok);
   return common(state, tok);
 }
 }
 
 
+/* This function will only be invoked if the internal logic of the
+ * parser has broken down.  It is used in two cases:
+ *
+ * 1: When the XML prolog has been finished.  At this point the
+ * processor (the parser level above these role handlers) should
+ * switch from prologProcessor to contentProcessor and reinitialise
+ * the handler function.
+ *
+ * 2: When an error has been detected (via common() below).  At this
+ * point again the processor should be switched to errorProcessor,
+ * which will never call a handler.
+ *
+ * The result of this is that error() can only be called if the
+ * processor switch failed to happen, which is an internal error and
+ * therefore we shouldn't be able to provoke it simply by using the
+ * library.  It is a necessary backstop, however, so we merely exclude
+ * it from the coverage statistics.
+ *
+ * LCOV_EXCL_START
+ */
 static int PTRCALL
 static int PTRCALL
 error(PROLOG_STATE *UNUSED_P(state),
 error(PROLOG_STATE *UNUSED_P(state),
       int UNUSED_P(tok),
       int UNUSED_P(tok),
@@ -1294,6 +1321,7 @@ error(PROLOG_STATE *UNUSED_P(state),
 {
 {
   return XML_ROLE_NONE;
   return XML_ROLE_NONE;
 }
 }
+/* LCOV_EXCL_STOP */
 
 
 static int FASTCALL
 static int FASTCALL
 common(PROLOG_STATE *state, int tok)
 common(PROLOG_STATE *state, int tok)

+ 10 - 3
libs/expat/lib/xmltok.c

@@ -1019,7 +1019,11 @@ streqci(const char *s1, const char *s2)
     if (ASCII_a <= c1 && c1 <= ASCII_z)
     if (ASCII_a <= c1 && c1 <= ASCII_z)
       c1 += ASCII_A - ASCII_a;
       c1 += ASCII_A - ASCII_a;
     if (ASCII_a <= c2 && c2 <= ASCII_z)
     if (ASCII_a <= c2 && c2 <= ASCII_z)
-      c2 += ASCII_A - ASCII_a;
+      /* The following line will never get executed.  streqci() is
+       * only called from two places, both of which guarantee to put
+       * upper-case strings into s2.
+       */
+      c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
     if (c1 != c2)
     if (c1 != c2)
       return 0;
       return 0;
     if (!c1)
     if (!c1)
@@ -1291,7 +1295,7 @@ XmlUtf8Encode(int c, char *buf)
   };
   };
 
 
   if (c < 0)
   if (c < 0)
-    return 0;
+    return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */
   if (c < min2) {
   if (c < min2) {
     buf[0] = (char)(c | UTF8_cval1);
     buf[0] = (char)(c | UTF8_cval1);
     return 1;
     return 1;
@@ -1314,7 +1318,7 @@ XmlUtf8Encode(int c, char *buf)
     buf[3] = (char)((c & 0x3f) | 0x80);
     buf[3] = (char)((c & 0x3f) | 0x80);
     return 4;
     return 4;
   }
   }
-  return 0;
+  return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
 }
 }
 
 
 int FASTCALL
 int FASTCALL
@@ -1465,6 +1469,9 @@ XmlInitUnknownEncoding(void *mem,
     else if (c < 0) {
     else if (c < 0) {
       if (c < -4)
       if (c < -4)
         return 0;
         return 0;
+      /* Multi-byte sequences need a converter function */
+      if (!convert)
+        return 0;
       e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
       e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
       e->utf8[i][0] = 0;
       e->utf8[i][0] = 0;
       e->utf16[i] = 0;
       e->utf16[i] = 0;

+ 33 - 6
libs/expat/lib/xmltok_impl.c

@@ -1198,8 +1198,14 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
   const char *start;
   const char *start;
   if (ptr >= end)
   if (ptr >= end)
     return XML_TOK_NONE;
     return XML_TOK_NONE;
-  else if (! HAS_CHAR(enc, ptr, end))
-    return XML_TOK_PARTIAL;
+  else if (! HAS_CHAR(enc, ptr, end)) {
+    /* This line cannot be executed.  The incoming data has already
+     * been tokenized once, so incomplete characters like this have
+     * already been eliminated from the input.  Retaining the paranoia
+     * check is still valuable, however.
+     */
+    return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
+  }
   start = ptr;
   start = ptr;
   while (HAS_CHAR(enc, ptr, end)) {
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     switch (BYTE_TYPE(enc, ptr)) {
@@ -1258,8 +1264,14 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
   const char *start;
   const char *start;
   if (ptr >= end)
   if (ptr >= end)
     return XML_TOK_NONE;
     return XML_TOK_NONE;
-  else if (! HAS_CHAR(enc, ptr, end))
-    return XML_TOK_PARTIAL;
+  else if (! HAS_CHAR(enc, ptr, end)) {
+    /* This line cannot be executed.  The incoming data has already
+     * been tokenized once, so incomplete characters like this have
+     * already been eliminated from the input.  Retaining the paranoia
+     * check is still valuable, however.
+     */
+    return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
+  }
   start = ptr;
   start = ptr;
   while (HAS_CHAR(enc, ptr, end)) {
   while (HAS_CHAR(enc, ptr, end)) {
     switch (BYTE_TYPE(enc, ptr)) {
     switch (BYTE_TYPE(enc, ptr)) {
@@ -1614,6 +1626,14 @@ PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
   return 0;
   return 0;
 }
 }
 
 
+/* This function does not appear to be called from anywhere within the
+ * library code.  It is used via the macro XmlSameName(), which is
+ * defined but never used.  Since it appears in the encoding function
+ * table, removing it is not a thing to be undertaken lightly.  For
+ * the moment, we simply exclude it from coverage tests.
+ *
+ * LCOV_EXCL_START
+ */
 static int PTRCALL
 static int PTRCALL
 PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
 PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
 {
 {
@@ -1677,14 +1697,21 @@ PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
   }
   }
   /* not reached */
   /* not reached */
 }
 }
+/* LCOV_EXCL_STOP */
 
 
 static int PTRCALL
 static int PTRCALL
 PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
 PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
                          const char *end1, const char *ptr2)
                          const char *end1, const char *ptr2)
 {
 {
   for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
   for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
-    if (end1 - ptr1 < MINBPC(enc))
-      return 0;
+    if (end1 - ptr1 < MINBPC(enc)) {
+      /* This line cannot be executed.  THe incoming data has already
+       * been tokenized once, so imcomplete characters like this have
+       * already been eliminated from the input.  Retaining the
+       * paranoia check is still valuable, however.
+       */
+      return 0; /* LCOV_EXCL_LINE */
+    }
     if (!CHAR_MATCHES(enc, ptr1, *ptr2))
     if (!CHAR_MATCHES(enc, ptr1, *ptr2))
       return 0;
       return 0;
   }
   }

+ 1 - 1
libs/expat/tests/chardata.c

@@ -78,7 +78,7 @@ CharData_AppendXMLChars(CharData *storage, const XML_Char *s, int len)
 int
 int
 CharData_CheckString(CharData *storage, const char *expected)
 CharData_CheckString(CharData *storage, const char *expected)
 {
 {
-    char buffer[1280];
+    char buffer[4096];
     int len;
     int len;
     int count;
     int count;
 
 

+ 1 - 1
libs/expat/tests/chardata.h

@@ -18,7 +18,7 @@ extern "C" {
 
 
 typedef struct {
 typedef struct {
     int count;                          /* # of chars, < 0 if not set */
     int count;                          /* # of chars, < 0 if not set */
-    XML_Char data[1024];
+    XML_Char data[2048];
 } CharData;
 } CharData;
 
 
 
 

+ 31 - 1
libs/expat/tests/minicheck.c

@@ -70,6 +70,32 @@ tcase_add_test(TCase *tc, tcase_test_function test)
     tc->ntests++;
     tc->ntests++;
 }
 }
 
 
+static void
+tcase_free(TCase *tc)
+{
+    if (! tc) {
+        return;
+    }
+
+    free(tc->tests);
+    free(tc);
+}
+
+static void
+suite_free(Suite *suite)
+{
+    if (! suite) {
+        return;
+    }
+
+    while (suite->tests != NULL) {
+        TCase *next = suite->tests->next_tcase;
+        tcase_free(suite->tests);
+        suite->tests = next;
+    }
+    free(suite);
+}
+
 SRunner *
 SRunner *
 srunner_create(Suite *suite)
 srunner_create(Suite *suite)
 {
 {
@@ -175,6 +201,10 @@ srunner_ntests_failed(SRunner *runner)
 void
 void
 srunner_free(SRunner *runner)
 srunner_free(SRunner *runner)
 {
 {
-    free(runner->suite);
+    if (! runner) {
+        return;
+    }
+
+    suite_free(runner->suite);
     free(runner);
     free(runner);
 }
 }

文件差异内容过多而无法显示
+ 697 - 96
libs/expat/tests/runtests.c


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

@@ -7,17 +7,17 @@
 [Setup]
 [Setup]
 AppName=Expat
 AppName=Expat
 AppId=expat
 AppId=expat
-AppVersion=2.2.2
-AppVerName=Expat 2.2.2
+AppVersion=2.2.3
+AppVerName=Expat 2.2.3
 AppCopyright=Copyright � 1998-2017 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers
 AppCopyright=Copyright � 1998-2017 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers
 AppPublisher=The Expat Developers
 AppPublisher=The Expat Developers
 AppPublisherURL=http://www.libexpat.org/
 AppPublisherURL=http://www.libexpat.org/
 AppSupportURL=http://www.libexpat.org/
 AppSupportURL=http://www.libexpat.org/
 AppUpdatesURL=http://www.libexpat.org/
 AppUpdatesURL=http://www.libexpat.org/
-UninstallDisplayName=Expat XML Parser 2.2.2
-VersionInfoVersion=2.2.2
+UninstallDisplayName=Expat XML Parser 2.2.3
+VersionInfoVersion=2.2.3
 
 
-DefaultDirName={pf}\Expat 2.2.2
+DefaultDirName={pf}\Expat 2.2.3
 UninstallFilesDir={app}\Uninstall
 UninstallFilesDir={app}\Uninstall
 
 
 Compression=lzma
 Compression=lzma
@@ -35,7 +35,7 @@ Flags: ignoreversion; Source: win32\MANIFEST.txt;           DestDir: "{app}"
 Flags: ignoreversion; Source: AUTHORS;                      DestDir: "{app}"; DestName: AUTHORS.txt
 Flags: ignoreversion; Source: AUTHORS;                      DestDir: "{app}"; DestName: AUTHORS.txt
 Flags: ignoreversion; Source: Changes;                      DestDir: "{app}"; DestName: Changes.txt
 Flags: ignoreversion; Source: Changes;                      DestDir: "{app}"; DestName: Changes.txt
 Flags: ignoreversion; Source: COPYING;                      DestDir: "{app}"; DestName: COPYING.txt
 Flags: ignoreversion; Source: COPYING;                      DestDir: "{app}"; DestName: COPYING.txt
-Flags: ignoreversion; Source: README;                       DestDir: "{app}"; DestName: README.txt
+Flags: ignoreversion; Source: README.md;                    DestDir: "{app}"; DestName: README.txt
 Flags: ignoreversion; Source: doc\*.html;                   DestDir: "{app}\Doc"
 Flags: ignoreversion; Source: doc\*.html;                   DestDir: "{app}\Doc"
 Flags: ignoreversion; Source: doc\*.css;                    DestDir: "{app}\Doc"
 Flags: ignoreversion; Source: doc\*.css;                    DestDir: "{app}\Doc"
 Flags: ignoreversion; Source: doc\*.png;                    DestDir: "{app}\Doc"
 Flags: ignoreversion; Source: doc\*.png;                    DestDir: "{app}\Doc"

部分文件因为文件数量过多而无法显示