Ver Fonte

Expat 2.7.0

Source commit: 259c2ec3c375a59e6e254032f1545e2b1b0b8f94
Martin Prikryl há 7 meses atrás
pai
commit
83506bca1c

+ 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.6.4 is the source directory of expat, add a subdirectory
+Assuming ~/expat-2.7.0 is the source directory of expat, add a subdirectory
 build and change into that directory:
 build and change into that directory:
-~/expat-2.6.4$ mkdir build && cd build
-~/expat-2.6.4/build$
+~/expat-2.7.0$ mkdir build && cd build
+~/expat-2.7.0/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.6.4/build$ cmake ..
+~/expat-2.7.0/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.6.4/build
+-- Build files have been written to: /home/patrick/expat-2.7.0/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.6.4/build$ make && make test && make install
+~/expat-2.7.0/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

+ 77 - 24
libs/expat/CMakeLists.txt

@@ -7,7 +7,7 @@
 #
 #
 # Copyright (c) 2010      Patrick Spendrin <[email protected]>
 # Copyright (c) 2010      Patrick Spendrin <[email protected]>
 # Copyright (c) 2012      Karl Waclawek <[email protected]>
 # Copyright (c) 2012      Karl Waclawek <[email protected]>
-# Copyright (c) 2016-2024 Sebastian Pipping <[email protected]>
+# Copyright (c) 2016-2025 Sebastian Pipping <[email protected]>
 # Copyright (c) 2016      Sergei Nikulov <[email protected]>
 # Copyright (c) 2016      Sergei Nikulov <[email protected]>
 # Copyright (c) 2016      Björn Lindahl <[email protected]>
 # Copyright (c) 2016      Björn Lindahl <[email protected]>
 # Copyright (c) 2016      Tobias Taschner <[email protected]>
 # Copyright (c) 2016      Tobias Taschner <[email protected]>
@@ -30,15 +30,16 @@
 # Copyright (c) 2020      Thomas Beutlich <[email protected]>
 # Copyright (c) 2020      Thomas Beutlich <[email protected]>
 # Copyright (c) 2021      Alex Richardson <[email protected]>
 # Copyright (c) 2021      Alex Richardson <[email protected]>
 # Copyright (c) 2022      Johnny Jazeix <[email protected]>
 # Copyright (c) 2022      Johnny Jazeix <[email protected]>
+# Copyright (c) 2022      Mark Brand <[email protected]>
 # Copyright (c) 2022      David Faure <[email protected]>
 # Copyright (c) 2022      David Faure <[email protected]>
 # Unlike most of Expat,
 # Unlike most of Expat,
 # this file is copyrighted under the BSD-license for buildsystem files of KDE.
 # this file is copyrighted under the BSD-license for buildsystem files of KDE.
 
 
-cmake_minimum_required(VERSION 3.5.0)
+cmake_minimum_required(VERSION 3.13.0)
 
 
 project(expat
 project(expat
     VERSION
     VERSION
-        2.6.4
+        2.7.0
     LANGUAGES
     LANGUAGES
         C
         C
 )
 )
@@ -134,7 +135,7 @@ expat_shy_set(EXPAT_SHARED_LIBS ${_EXPAT_SHARED_LIBS_DEFAULT} CACHE BOOL "Build
 expat_shy_set(EXPAT_BUILD_DOCS ${_EXPAT_BUILD_DOCS_DEFAULT} CACHE BOOL "Build man page for xmlwf")
 expat_shy_set(EXPAT_BUILD_DOCS ${_EXPAT_BUILD_DOCS_DEFAULT} CACHE BOOL "Build man page for xmlwf")
 expat_shy_set(EXPAT_BUILD_FUZZERS OFF CACHE BOOL "Build fuzzers for the expat library")
 expat_shy_set(EXPAT_BUILD_FUZZERS OFF CACHE BOOL "Build fuzzers for the expat library")
 expat_shy_set(EXPAT_BUILD_PKGCONFIG ${_EXPAT_BUILD_PKGCONFIG_DEFAULT} CACHE BOOL "Build pkg-config file")
 expat_shy_set(EXPAT_BUILD_PKGCONFIG ${_EXPAT_BUILD_PKGCONFIG_DEFAULT} CACHE BOOL "Build pkg-config file")
-expat_shy_set(EXPAT_OSSFUZZ_BUILD OFF CACHE BOOL "Build fuzzers via ossfuzz for the expat library")
+expat_shy_set(EXPAT_OSSFUZZ_BUILD OFF CACHE BOOL "Build fuzzers via OSS-Fuzz for the expat library")
 if(UNIX OR _EXPAT_HELP)
 if(UNIX OR _EXPAT_HELP)
     expat_shy_set(EXPAT_WITH_LIBBSD OFF CACHE BOOL "Utilize libbsd (for arc4random_buf)")
     expat_shy_set(EXPAT_WITH_LIBBSD OFF CACHE BOOL "Utilize libbsd (for arc4random_buf)")
 endif()
 endif()
@@ -169,11 +170,15 @@ if(NOT _EXPAT_HELP)
     mark_as_advanced(_EXPAT_M32)
     mark_as_advanced(_EXPAT_M32)
 endif()
 endif()
 
 
-if(EXPAT_BUILD_TESTS)
+if(EXPAT_BUILD_TESTS OR EXPAT_BUILD_FUZZERS)
     # We have to call enable_language() before modifying any CMAKE_CXX_* variables
     # We have to call enable_language() before modifying any CMAKE_CXX_* variables
     enable_language(CXX)
     enable_language(CXX)
 
 
-    set(CMAKE_CXX_STANDARD 11)
+    if (EXPAT_BUILD_FUZZERS)
+        set(CMAKE_CXX_STANDARD 17)  # for std::string_view for Abseil for libprotobuf-mutator
+    else()
+        set(CMAKE_CXX_STANDARD 11)
+    endif()
     set(CMAKE_CXX_STANDARD_REQUIRED ON)
     set(CMAKE_CXX_STANDARD_REQUIRED ON)
     set(CMAKE_CXX_EXTENSIONS OFF)  # i.e. -std=c++11 rather than default -std=gnu++11
     set(CMAKE_CXX_EXTENSIONS OFF)  # i.e. -std=c++11 rather than default -std=gnu++11
 endif()
 endif()
@@ -320,7 +325,7 @@ if(FLAG_VISIBILITY)
   endif()
   endif()
   set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -fvisibility=hidden")
   set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -fvisibility=hidden")
 endif()
 endif()
-if(MINGW)
+if(MINGW AND ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU"))
     # Without __USE_MINGW_ANSI_STDIO the compiler produces a false positive
     # Without __USE_MINGW_ANSI_STDIO the compiler produces a false positive
     set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -Wno-pedantic-ms-format")
     set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -Wno-pedantic-ms-format")
 endif()
 endif()
@@ -467,7 +472,7 @@ foreach(build_type_upper
 endforeach()
 endforeach()
 
 
 set(LIBCURRENT 11)  # sync
 set(LIBCURRENT 11)  # sync
-set(LIBREVISION 0)  # with
+set(LIBREVISION 1)  # with
 set(LIBAGE 10)      # configure.ac!
 set(LIBAGE 10)      # configure.ac!
 math(EXPR LIBCURRENT_MINUS_AGE "${LIBCURRENT} - ${LIBAGE}")
 math(EXPR LIBCURRENT_MINUS_AGE "${LIBCURRENT} - ${LIBAGE}")
 
 
@@ -587,7 +592,7 @@ if(EXPAT_BUILD_TOOLS)
 
 
     if(MINGW AND _EXPAT_UNICODE_WCHAR_T)
     if(MINGW AND _EXPAT_UNICODE_WCHAR_T)
         # https://gcc.gnu.org/onlinedocs/gcc/x86-Windows-Options.html
         # https://gcc.gnu.org/onlinedocs/gcc/x86-Windows-Options.html
-        set_target_properties(xmlwf PROPERTIES LINK_FLAGS -municode)
+        target_link_options(xmlwf PRIVATE -municode)
     endif()
     endif()
 
 
     if(EXPAT_BUILD_DOCS)
     if(EXPAT_BUILD_DOCS)
@@ -724,7 +729,7 @@ if(EXPAT_BUILD_FUZZERS)
         message(SEND_ERROR
         message(SEND_ERROR
             "OSS-Fuzz builds require the environment variable "
             "OSS-Fuzz builds require the environment variable "
             "LIB_FUZZING_ENGINE to be set. If you are seeing this "
             "LIB_FUZZING_ENGINE to be set. If you are seeing this "
-            "warning, it points to a deeper problem in the ossfuzz "
+            "warning, it points to a deeper problem in the OSS-Fuzz "
             "build setup.")
             "build setup.")
     endif()
     endif()
 
 
@@ -743,24 +748,78 @@ if(EXPAT_BUILD_FUZZERS)
             target_link_libraries(${target_name} fuzzpat)
             target_link_libraries(${target_name} fuzzpat)
             target_compile_definitions(${target_name}
             target_compile_definitions(${target_name}
                 PRIVATE ENCODING_FOR_FUZZING=${encoding_type})
                 PRIVATE ENCODING_FOR_FUZZING=${encoding_type})
-            if(NOT EXPAT_OSSFUZZ_BUILD)
-                target_compile_options(${target_name} PRIVATE -fsanitize=fuzzer-no-link)
-            endif()
-            # NOTE: Avoiding target_link_options here only because it needs CMake >=3.13
             if(EXPAT_OSSFUZZ_BUILD)
             if(EXPAT_OSSFUZZ_BUILD)
-                set_target_properties(${target_name} PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE})
+                target_link_options(${target_name} PRIVATE $ENV{LIB_FUZZING_ENGINE})
                 set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE "CXX")
                 set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE "CXX")
             else()
             else()
-                set_target_properties(${target_name} PROPERTIES LINK_FLAGS -fsanitize=fuzzer)
+                target_compile_options(${target_name} PRIVATE -fsanitize=fuzzer)
+                target_link_options(${target_name} PRIVATE -fsanitize=fuzzer)
             endif()
             endif()
             set_property(
             set_property(
                 TARGET ${target_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY fuzz)
                 TARGET ${target_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY fuzz)
         endforeach()
         endforeach()
     endforeach()
     endforeach()
+
+    find_package(Protobuf REQUIRED)
+
+    # Only include libprotobuf-mutator here so we don't build it in non-fuzz
+    # configurations.
+    include(ExternalProject)
+
+    set(ProtobufMutator_PREFIX libprotobuf-mutator)
+    set(ProtobufMutator_PATH ${CMAKE_CURRENT_BINARY_DIR}/${ProtobufMutator_PREFIX}/src/${ProtobufMutator_PREFIX})
+    set(ProtobufMutator_BUILD_PATH ${ProtobufMutator_PATH}-build)
+    set(ProtobufMutator_INCLUDE_DIR ${ProtobufMutator_PATH})
+    set(ProtobufMutator_LIBRARIES ${ProtobufMutator_BUILD_PATH}/src/libfuzzer/libprotobuf-mutator-libfuzzer.a ${ProtobufMutator_BUILD_PATH}/src/libprotobuf-mutator.a)
+
+    ExternalProject_Add(
+        ${ProtobufMutator_PREFIX}
+        PREFIX ${ProtobufMutator_PREFIX}
+        GIT_REPOSITORY https://github.com/google/libprotobuf-mutator.git
+        GIT_TAG 57928f41ae52bb27666aa15b310130d086dac245  # v1.4-16-g57928f4
+        CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+        CMAKE_CACHE_ARGS
+            -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
+            -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
+            -DLIB_PROTO_MUTATOR_EXAMPLES:BOOL=OFF
+            -DLIB_PROTO_MUTATOR_TESTING:BOOL=OFF
+        BUILD_BYPRODUCTS ${ProtobufMutator_LIBRARIES}
+        UPDATE_COMMAND true
+        INSTALL_COMMAND true)
+
+    # Check for availability of protobuf compiler to avoid hard-to-understand
+    # errors from make(1) down the line as seen with CMake 3.25.1 on Debian
+    if(NOT Protobuf_PROTOC_EXECUTABLE)
+        message(SEND_ERROR
+            "The protobuf compiler (protoc) could not be found. "
+            "Is it installed and working properly?")
+    endif()
+
+    protobuf_generate_cpp(XML_LPM_FUZZER_PROTO_SRCS
+                          XML_LPM_FUZZER_PROTO_HDRS
+                          fuzz/xml_lpm_fuzzer.proto)
+
+    add_executable(xml_lpm_fuzzer
+                   fuzz/xml_lpm_fuzzer.cpp
+                   ${XML_LPM_FUZZER_PROTO_SRCS})
+    target_include_directories(xml_lpm_fuzzer PUBLIC ${ProtobufMutator_INCLUDE_DIR})
+    target_link_libraries(xml_lpm_fuzzer
+                          fuzzpat
+                          ${ProtobufMutator_LIBRARIES}
+                          ${Protobuf_LIBRARIES})
+    add_dependencies(xml_lpm_fuzzer ${ProtobufMutator_PREFIX})
+
+    if(EXPAT_OSSFUZZ_BUILD)
+        target_link_options(xml_lpm_fuzzer PRIVATE $ENV{LIB_FUZZING_ENGINE})
+    else()
+        target_compile_options(xml_lpm_fuzzer PRIVATE -fsanitize=fuzzer)
+        target_link_options(xml_lpm_fuzzer PRIVATE -fsanitize=fuzzer)
+    endif()
+    set_property(TARGET xml_lpm_fuzzer PROPERTY RUNTIME_OUTPUT_DIRECTORY fuzz)
 else()
 else()
     if(EXPAT_OSSFUZZ_BUILD)
     if(EXPAT_OSSFUZZ_BUILD)
         message(SEND_ERROR
         message(SEND_ERROR
-                "Attempting to perform an ossfuzz build without turning on the fuzzer build. "
+                "Attempting to perform an OSS-Fuzz build without turning on the fuzzer build. "
                 "This is likely in error - consider adding "
                 "This is likely in error - consider adding "
                 "-DEXPAT_BUILD_FUZZERS=ON to your cmake execution.")
                 "-DEXPAT_BUILD_FUZZERS=ON to your cmake execution.")
     endif()
     endif()
@@ -913,13 +972,7 @@ elseif(EXPAT_CHAR_TYPE STREQUAL "wchar_t")
 else()
 else()
     set(_EXPAT_CHAR_TYPE_SUMMARY "ERROR")
     set(_EXPAT_CHAR_TYPE_SUMMARY "ERROR")
 endif()
 endif()
-# NOTE: We're not accessing global property GENERATOR_IS_MULTI_CONFIG
-#       because that would require CMake >=3.9
-if(CMAKE_CONFIGURATION_TYPES)
-    set(_EXPAT_GENERATOR_IS_MULTI_CONFIG TRUE)
-else()
-    set(_EXPAT_GENERATOR_IS_MULTI_CONFIG FALSE)
-endif()
+get_property(_EXPAT_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
 
 
 message(STATUS "===========================================================================")
 message(STATUS "===========================================================================")
 message(STATUS "")
 message(STATUS "")

+ 83 - 2
libs/expat/Changes

@@ -11,16 +11,23 @@
 !! The following topics need *additional skilled C developers* to progress   !!
 !! The following topics need *additional skilled C developers* to progress   !!
 !! in a timely manner or at all (loosely ordered by descending priority):    !!
 !! in a timely manner or at all (loosely ordered by descending priority):    !!
 !!                                                                           !!
 !!                                                                           !!
-!! - <blink>fixing a complex non-public security issue</blink>,              !!
 !! - teaming up on researching and fixing future security reports and        !!
 !! - teaming up on researching and fixing future security reports and        !!
 !!   ClusterFuzz findings with few-days-max response times in communication  !!
 !!   ClusterFuzz findings with few-days-max response times in communication  !!
 !!   in order to (1) have a sound fix ready before the end of a 90 days      !!
 !!   in order to (1) have a sound fix ready before the end of a 90 days      !!
 !!   grace period and (2) in a sustainable manner,                           !!
 !!   grace period and (2) in a sustainable manner,                           !!
+!! - helping CPython Expat bindings with supporting Expat's billion laughs   !!
+!!   attack protection API (https://github.com/python/cpython/issues/90949): !!
+!!   - XML_SetBillionLaughsAttackProtectionActivationThreshold               !!
+!!   - XML_SetBillionLaughsAttackProtectionMaximumAmplification              !!
+!! - helping Perl's XML::Parser Expat bindings with supporting Expat's       !!
+!!   security API (https://github.com/cpan-authors/XML-Parser/issues/102):   !!
+!!   - XML_SetBillionLaughsAttackProtectionActivationThreshold               !!
+!!   - XML_SetBillionLaughsAttackProtectionMaximumAmplification              !!
+!!   - XML_SetReparseDeferralEnabled                                         !!
 !! - implementing and auto-testing XML 1.0r5 support                         !!
 !! - implementing and auto-testing XML 1.0r5 support                         !!
 !!   (needs discussion before pull requests),                                !!
 !!   (needs discussion before pull requests),                                !!
 !! - smart ideas on fixing the Autotools CMake files generation issue        !!
 !! - smart ideas on fixing the Autotools CMake files generation issue        !!
 !!   without breaking CI (needs discussion before pull requests),            !!
 !!   without breaking CI (needs discussion before pull requests),            !!
-!! - the Windows binaries topic (needs requirements engineering first),      !!
 !! - pushing migration from `int` to `size_t` further                        !!
 !! - pushing migration from `int` to `size_t` further                        !!
 !!   including edge-cases test coverage (needs discussion before anything).  !!
 !!   including edge-cases test coverage (needs discussion before anything).  !!
 !!                                                                           !!
 !!                                                                           !!
@@ -30,6 +37,78 @@
 !! THANK YOU!                        Sebastian Pipping -- Berlin, 2024-03-09 !!
 !! THANK YOU!                        Sebastian Pipping -- Berlin, 2024-03-09 !!
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 
+Release 2.7.0 Thu March 13 2025
+        Security fixes:
+       #893 #973  CVE-2024-8176 -- Fix crash from chaining a large number
+                    of entities caused by stack overflow by resolving use of
+                    recursion, for all three uses of entities:
+                    - general entities in character data ("<e>&g1;</e>")
+                    - general entities in attribute values ("<e k1='&g1;'/>")
+                    - parameter entities ("%p1;")
+                    Known impact is (reliable and easy) denial of service:
+                    CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H/E:H/RL:O/RC:C
+                    (Base Score: 7.5, Temporal Score: 7.2)
+                    Please note that a layer of compression around XML can
+                    significantly reduce the minimum attack payload size.
+
+        Other changes:
+       #935 #937  Autotools: Make generated CMake files look for
+                    libexpat.@[email protected] on macOS
+            #925  Autotools: Sync CMake templates with CMake 3.29
+  #945 #962 #966  CMake: Drop support for CMake <3.13
+            #942  CMake: Small fuzzing related improvements
+            #921  docs: Add missing documentation of error code
+                    XML_ERROR_NOT_STARTED that was introduced with 2.6.4
+            #941  docs: Document need for C++11 compiler for use from C++
+            #959  tests/benchmark: Fix a (harmless) TOCTTOU
+            #944  Windows: Fix installer target location of file xmlwf.xml
+                    for CMake
+            #953  Windows: Address warning -Wunknown-warning-option
+                    about -Wno-pedantic-ms-format from LLVM MinGW
+            #971  Address Cppcheck warnings
+       #969 #970  Mass-migrate links from http:// to https://
+    #947 #958 ..
+       #974 #975  Document changes since the previous release
+       #974 #975  Version info bumped from 11:0:10 (libexpat*.so.1.10.0)
+                    to 11:1:10 (libexpat*.so.1.10.1); see https://verbump.de/
+                    for what these numbers do
+
+        Infrastructure:
+            #926  tests: Increase robustness
+    #927 #932 ..
+       #930 #933  tests: Increase test coverage
+    #617 #950 ..
+    #951 #952 ..
+    #954 #955 ..  Fuzzing: Add new fuzzer "xml_lpm_fuzzer" based on
+            #961    Google's libprotobuf-mutator ("LPM")
+            #957  Fuzzing|CI: Start producing fuzzing code coverage reports
+            #936  CI: Pass -q -q for LCOV >=2.1 in coverage.sh
+            #942  CI: Small fuzzing related improvements
+    #139 #203 ..
+       #791 #946  CI: Make GitHub Actions build using MSVC on Windows and
+                      produce 32bit and 64bit Windows binaries
+            #956  CI: Get off of about-to-be-removed Ubuntu 20.04
+       #960 #964  CI: Start uploading to Coverity Scan for static analysis
+            #972  CI: Stop loading DTD from the internet to address flaky CI
+            #971  CI: Adapt to breaking changes in Cppcheck
+
+        Special thanks to:
+            Alexander Gieringer
+            Berkay Eren Ürün
+            Hanno Böck
+            Jann Horn
+            Mark Brand
+            Sebastian Andrzej Siewior
+            Snild Dolkow
+            Thomas Pröll
+            Tomas Korbar
+            valord577
+                 and
+            Google Project Zero
+            Linutronix
+            Red Hat
+            Siemens
+
 Release 2.6.4 Wed November 6 2024
 Release 2.6.4 Wed November 6 2024
         Security fixes:
         Security fixes:
             #915  CVE-2024-50602 -- Fix crash within function XML_ResumeParser
             #915  CVE-2024-50602 -- Fix crash within function XML_ResumeParser
@@ -46,6 +125,8 @@ Release 2.6.4 Wed November 6 2024
             #904  tests: Resolve duplicate handler
             #904  tests: Resolve duplicate handler
        #317 #918  tests: Improve tests on doctype closing (ex CVE-2019-15903)
        #317 #918  tests: Improve tests on doctype closing (ex CVE-2019-15903)
             #914  Fix signedness of format strings
             #914  Fix signedness of format strings
+            #915  For use from C++, expat.h started requiring C++11 due to
+                    use of C99 features
        #919 #920  Version info bumped from 10:3:9 (libexpat*.so.1.9.3)
        #919 #920  Version info bumped from 10:3:9 (libexpat*.so.1.9.3)
                     to 11:0:10 (libexpat*.so.1.10.0); see https://verbump.de/
                     to 11:0:10 (libexpat*.so.1.10.0); see https://verbump.de/
                     for what these numbers do
                     for what these numbers do

+ 6 - 11
libs/expat/README.md

@@ -11,7 +11,7 @@
 > at the top of the `Changes` file.
 > at the top of the `Changes` file.
 
 
 
 
-# Expat, Release 2.6.4
+# Expat, Release 2.7.0
 
 
 This is Expat, a C99 library for parsing
 This is Expat, a C99 library for parsing
 [XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by
 [XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by
@@ -22,9 +22,9 @@ are called when the parser discovers the associated structures in the
 document being parsed.  A start tag is an example of the kind of
 document being parsed.  A start tag is an example of the kind of
 structures for which you may register handlers.
 structures for which you may register handlers.
 
 
-Expat supports the following compilers:
+Expat supports the following C99 compilers:
 
 
-- GNU GCC >=4.5
+- GNU GCC >=4.5 (for use from C) or GNU GCC >=4.8.1 (for use from C++)
 - LLVM Clang >=3.5
 - LLVM Clang >=3.5
 - Microsoft Visual Studio >=16.0/2019 (rolling `${today} minus 5 years`)
 - Microsoft Visual Studio >=16.0/2019 (rolling `${today} minus 5 years`)
 
 
@@ -52,7 +52,7 @@ This approach leverages CMake's own [module `FindEXPAT`](https://cmake.org/cmake
 Notice the *uppercase* `EXPAT` in the following example:
 Notice the *uppercase* `EXPAT` in the following example:
 
 
 ```cmake
 ```cmake
-cmake_minimum_required(VERSION 3.0)  # or 3.10, see below
+cmake_minimum_required(VERSION 3.10)
 
 
 project(hello VERSION 1.0.0)
 project(hello VERSION 1.0.0)
 
 
@@ -62,12 +62,7 @@ add_executable(hello
     hello.c
     hello.c
 )
 )
 
 
-# a) for CMake >=3.10 (see CMake's FindEXPAT docs)
 target_link_libraries(hello PUBLIC EXPAT::EXPAT)
 target_link_libraries(hello PUBLIC EXPAT::EXPAT)
-
-# b) for CMake >=3.0
-target_include_directories(hello PRIVATE ${EXPAT_INCLUDE_DIRS})
-target_link_libraries(hello PUBLIC ${EXPAT_LIBRARIES})
 ```
 ```
 
 
 ### b) `find_package` with Config Mode
 ### b) `find_package` with Config Mode
@@ -85,7 +80,7 @@ or
 Notice the *lowercase* `expat` in the following example:
 Notice the *lowercase* `expat` in the following example:
 
 
 ```cmake
 ```cmake
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.10)
 
 
 project(hello VERSION 1.0.0)
 project(hello VERSION 1.0.0)
 
 
@@ -295,7 +290,7 @@ EXPAT_ENABLE_INSTALL:BOOL=ON
 // Use /MT flag (static CRT) when compiling in MSVC
 // Use /MT flag (static CRT) when compiling in MSVC
 EXPAT_MSVC_STATIC_CRT:BOOL=OFF
 EXPAT_MSVC_STATIC_CRT:BOOL=OFF
 
 
-// Build fuzzers via ossfuzz for the expat library
+// Build fuzzers via OSS-Fuzz for the expat library
 EXPAT_OSSFUZZ_BUILD:BOOL=OFF
 EXPAT_OSSFUZZ_BUILD:BOOL=OFF
 
 
 // Build a shared expat library
 // Build a shared expat library

+ 2 - 2
libs/expat/cmake/autotools/expat-noconfig__macos.cmake.in

@@ -8,12 +8,12 @@ set(CMAKE_IMPORT_FILE_VERSION 1)
 # Import target "expat::expat" for configuration "NoConfig"
 # Import target "expat::expat" for configuration "NoConfig"
 set_property(TARGET expat::expat APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
 set_property(TARGET expat::expat APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
 set_target_properties(expat::expat PROPERTIES
 set_target_properties(expat::expat PROPERTIES
-  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/@LIBDIR_BASENAME@/libexpat.@SO_MAJOR@.@SO_MINOR@.@SO_PATCH@.dylib"
+  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/@LIBDIR_BASENAME@/libexpat.@[email protected]"
   IMPORTED_SONAME_NOCONFIG "@rpath/libexpat.@[email protected]"
   IMPORTED_SONAME_NOCONFIG "@rpath/libexpat.@[email protected]"
   )
   )
 
 
 list(APPEND _cmake_import_check_targets expat::expat )
 list(APPEND _cmake_import_check_targets expat::expat )
-list(APPEND _cmake_import_check_files_for_expat::expat "${_IMPORT_PREFIX}/@LIBDIR_BASENAME@/libexpat.@SO_MAJOR@.@SO_MINOR@.@SO_PATCH@.dylib" )
+list(APPEND _cmake_import_check_files_for_expat::expat "${_IMPORT_PREFIX}/@LIBDIR_BASENAME@/libexpat.@[email protected]" )
 
 
 # Commands beyond this point should not need to know the version.
 # Commands beyond this point should not need to know the version.
 set(CMAKE_IMPORT_FILE_VERSION)
 set(CMAKE_IMPORT_FILE_VERSION)

+ 2 - 2
libs/expat/cmake/autotools/expat.cmake

@@ -1,13 +1,13 @@
 # Generated by CMake
 # Generated by CMake
 
 
 if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
 if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
-   message(FATAL_ERROR "CMake >= 2.8.0 required")
+   message(FATAL_ERROR "CMake >= 2.8.12 required")
 endif()
 endif()
 if(CMAKE_VERSION VERSION_LESS "2.8.12")
 if(CMAKE_VERSION VERSION_LESS "2.8.12")
    message(FATAL_ERROR "CMake >= 2.8.12 required")
    message(FATAL_ERROR "CMake >= 2.8.12 required")
 endif()
 endif()
 cmake_policy(PUSH)
 cmake_policy(PUSH)
-cmake_policy(VERSION 2.8.12...3.28)
+cmake_policy(VERSION 2.8.12...3.29)
 #----------------------------------------------------------------
 #----------------------------------------------------------------
 # Generated CMake target import file.
 # Generated CMake target import file.
 #----------------------------------------------------------------
 #----------------------------------------------------------------

Diff do ficheiro suprimidas por serem muito extensas
+ 651 - 83
libs/expat/configure


+ 2 - 2
libs/expat/configure.ac

@@ -11,7 +11,7 @@ dnl   Copyright (c) 2000      Clark Cooper <[email protected]>
 dnl   Copyright (c) 2000-2005 Fred L. Drake, Jr. <[email protected]>
 dnl   Copyright (c) 2000-2005 Fred L. Drake, Jr. <[email protected]>
 dnl   Copyright (c) 2001-2003 Greg Stein <[email protected]>
 dnl   Copyright (c) 2001-2003 Greg Stein <[email protected]>
 dnl   Copyright (c) 2006-2012 Karl Waclawek <[email protected]>
 dnl   Copyright (c) 2006-2012 Karl Waclawek <[email protected]>
-dnl   Copyright (c) 2016-2024 Sebastian Pipping <[email protected]>
+dnl   Copyright (c) 2016-2025 Sebastian Pipping <[email protected]>
 dnl   Copyright (c) 2017      S. P. Zeidler <[email protected]>
 dnl   Copyright (c) 2017      S. P. Zeidler <[email protected]>
 dnl   Copyright (c) 2017      Stephen Groat <[email protected]>
 dnl   Copyright (c) 2017      Stephen Groat <[email protected]>
 dnl   Copyright (c) 2017-2020 Joe Orton <[email protected]>
 dnl   Copyright (c) 2017-2020 Joe Orton <[email protected]>
@@ -85,7 +85,7 @@ dnl If the API changes incompatibly set LIBAGE back to 0
 dnl
 dnl
 
 
 LIBCURRENT=11  # sync
 LIBCURRENT=11  # sync
-LIBREVISION=0  # with
+LIBREVISION=1  # with
 LIBAGE=10      # CMakeLists.txt!
 LIBAGE=10      # CMakeLists.txt!
 
 
 AC_CONFIG_HEADERS([expat_config.h])
 AC_CONFIG_HEADERS([expat_config.h])

+ 203 - 54
libs/expat/conftools/ltmain.sh

@@ -2,7 +2,7 @@
 ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
 ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
 ##               by inline-source v2019-02-19.15
 ##               by inline-source v2019-02-19.15
 
 
-# libtool (GNU libtool) 2.5.3
+# libtool (GNU libtool) 2.5.4
 # Provide generalized library-building support services.
 # Provide generalized library-building support services.
 # Written by Gordon Matzigkeit <[email protected]>, 1996
 # Written by Gordon Matzigkeit <[email protected]>, 1996
 
 
@@ -31,8 +31,8 @@
 
 
 PROGRAM=libtool
 PROGRAM=libtool
 PACKAGE=libtool
 PACKAGE=libtool
-VERSION=2.5.3
-package_revision=2.5.3
+VERSION=2.5.4
+package_revision=2.5.4
 
 
 
 
 ## ------ ##
 ## ------ ##
@@ -589,7 +589,7 @@ func_require_term_colors ()
 
 
   # _G_HAVE_PLUSEQ_OP
   # _G_HAVE_PLUSEQ_OP
   # Can be empty, in which case the shell is probed, "yes" if += is
   # Can be empty, in which case the shell is probed, "yes" if += is
-  # useable or anything else if it does not work.
+  # usable or anything else if it does not work.
   test -z "$_G_HAVE_PLUSEQ_OP" \
   test -z "$_G_HAVE_PLUSEQ_OP" \
     && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
     && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
     && _G_HAVE_PLUSEQ_OP=yes
     && _G_HAVE_PLUSEQ_OP=yes
@@ -739,7 +739,7 @@ eval 'func_dirname ()
 #             to NONDIR_REPLACEMENT.
 #             to NONDIR_REPLACEMENT.
 #             value returned in "$func_dirname_result"
 #             value returned in "$func_dirname_result"
 #   basename: Compute filename of FILE.
 #   basename: Compute filename of FILE.
-#             value retuned in "$func_basename_result"
+#             value returned in "$func_basename_result"
 # For efficiency, we do not delegate to the functions above but instead
 # For efficiency, we do not delegate to the functions above but instead
 # duplicate the functionality here.
 # duplicate the functionality here.
 eval 'func_dirname_and_basename ()
 eval 'func_dirname_and_basename ()
@@ -897,7 +897,7 @@ func_mkdir_p ()
       # While some portion of DIR does not yet exist...
       # While some portion of DIR does not yet exist...
       while test ! -d "$_G_directory_path"; do
       while test ! -d "$_G_directory_path"; do
         # ...make a list in topmost first order.  Use a colon delimited
         # ...make a list in topmost first order.  Use a colon delimited
-	# list incase some portion of path contains whitespace.
+	# list in case some portion of path contains whitespace.
         _G_dir_list=$_G_directory_path:$_G_dir_list
         _G_dir_list=$_G_directory_path:$_G_dir_list
 
 
         # If the last portion added has no slash in it, the list is done
         # If the last portion added has no slash in it, the list is done
@@ -2215,7 +2215,30 @@ func_version ()
 # End:
 # End:
 
 
 # Set a version string.
 # Set a version string.
-scriptversion='(GNU libtool) 2.5.3'
+scriptversion='(GNU libtool) 2.5.4'
+
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $debug_cmd
+
+	year=`date +%Y`
+
+	cat <<EOF
+$progname $scriptversion
+Copyright (C) $year Free Software Foundation, Inc.
+License GPLv2+: GNU GPL version 2 or later <https://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+Originally written by Gordon Matzigkeit, 1996
+(See AUTHORS for complete contributor listing)
+EOF
+
+    exit $?
+}
 
 
 
 
 # func_echo ARG...
 # func_echo ARG...
@@ -2238,18 +2261,6 @@ func_echo ()
 }
 }
 
 
 
 
-# func_warning ARG...
-# -------------------
-# Libtool warnings are not categorized, so override funclib.sh
-# func_warning with this simpler definition.
-func_warning ()
-{
-    $debug_cmd
-
-    $warning_func ${1+"$@"}
-}
-
-
 ## ---------------- ##
 ## ---------------- ##
 ## Options parsing. ##
 ## Options parsing. ##
 ## ---------------- ##
 ## ---------------- ##
@@ -2261,19 +2272,23 @@ usage='$progpath [OPTION]... [MODE-ARG]...'
 
 
 # Short help message in response to '-h'.
 # Short help message in response to '-h'.
 usage_message="Options:
 usage_message="Options:
-       --config             show all configuration variables
-       --debug              enable verbose shell tracing
-   -n, --dry-run            display commands without modifying any files
-       --features           display basic configuration information and exit
-       --mode=MODE          use operation mode MODE
-       --no-warnings        equivalent to '-Wnone'
-       --preserve-dup-deps  don't remove duplicate dependency libraries
-       --quiet, --silent    don't print informational messages
-       --tag=TAG            use configuration variables from tag TAG
-   -v, --verbose            print more informational messages than default
-       --version            print version information
-   -W, --warnings=CATEGORY  report the warnings falling in CATEGORY [all]
-   -h, --help, --help-all   print short, long, or detailed help message
+       --config                 show all configuration variables
+       --debug                  enable verbose shell tracing
+   -n, --dry-run                display commands without modifying any files
+       --features               display basic configuration information
+       --finish                 use operation '--mode=finish'
+       --mode=MODE              use operation mode MODE
+       --no-finish              don't update shared library cache
+       --no-quiet, --no-silent  print default informational messages
+       --no-warnings            equivalent to '-Wnone'
+       --preserve-dup-deps      don't remove duplicate dependency libraries
+       --quiet, --silent        don't print informational messages
+       --reorder-cache=DIRS     reorder shared library cache for preferred DIRS
+       --tag=TAG                use configuration variables from tag TAG
+   -v, --verbose                print more informational messages than default
+       --version                print version information
+   -W, --warnings=CATEGORY      report the warnings falling in CATEGORY [all]
+   -h, --help, --help-all       print short, long, or detailed help message
 "
 "
 
 
 # Additional text appended to 'usage_message' in response to '--help'.
 # Additional text appended to 'usage_message' in response to '--help'.
@@ -2306,7 +2321,7 @@ include the following information:
        compiler:       $LTCC
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.5.3
+       version:        $progname $scriptversion
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
 
@@ -2502,8 +2517,11 @@ libtool_options_prep ()
     opt_dry_run=false
     opt_dry_run=false
     opt_help=false
     opt_help=false
     opt_mode=
     opt_mode=
+    opt_reorder_cache=false
     opt_preserve_dup_deps=false
     opt_preserve_dup_deps=false
     opt_quiet=false
     opt_quiet=false
+    opt_finishing=true
+    opt_warning=
 
 
     nonopt=
     nonopt=
     preserve_args=
     preserve_args=
@@ -2593,14 +2611,18 @@ libtool_parse_options ()
                           clean|compile|execute|finish|install|link|relink|uninstall) ;;
                           clean|compile|execute|finish|install|link|relink|uninstall) ;;
 
 
                           # Catch anything else as an error
                           # Catch anything else as an error
-                          *) func_error "invalid argument for $_G_opt"
+                          *) func_error "invalid argument '$1' for $_G_opt"
                              exit_cmd=exit
                              exit_cmd=exit
-                             break
                              ;;
                              ;;
                         esac
                         esac
                         shift
                         shift
                         ;;
                         ;;
 
 
+        --no-finish)
+                        opt_finishing=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
         --no-silent|--no-quiet)
         --no-silent|--no-quiet)
                         opt_quiet=false
                         opt_quiet=false
                         func_append preserve_args " $_G_opt"
                         func_append preserve_args " $_G_opt"
@@ -2616,6 +2638,24 @@ libtool_parse_options ()
                         func_append preserve_args " $_G_opt"
                         func_append preserve_args " $_G_opt"
                         ;;
                         ;;
 
 
+        --reorder-cache)
+                        opt_reorder_cache=true
+                        shared_lib_dirs=$1
+                        if test -n "$shared_lib_dirs"; then
+                          case $1 in
+                            # Must begin with /:
+                            /*) ;;
+
+                            # Catch anything else as an error (relative paths)
+                            *) func_error "invalid argument '$1' for $_G_opt"
+                               func_error "absolute paths are required for $_G_opt"
+                               exit_cmd=exit
+                               ;;
+                          esac
+                        fi
+                        shift
+                        ;;
+
         --silent|--quiet)
         --silent|--quiet)
                         opt_quiet=:
                         opt_quiet=:
                         opt_verbose=false
                         opt_verbose=false
@@ -2652,6 +2692,18 @@ libtool_parse_options ()
 func_add_hook func_parse_options libtool_parse_options
 func_add_hook func_parse_options libtool_parse_options
 
 
 
 
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+    if $opt_warning; then
+        $debug_cmd
+        $warning_func ${1+"$@"}
+    fi
+}
+
 
 
 # libtool_validate_options [ARG]...
 # libtool_validate_options [ARG]...
 # ---------------------------------
 # ---------------------------------
@@ -3181,6 +3233,15 @@ func_convert_path_front_back_pathsep ()
 # end func_convert_path_front_back_pathsep
 # end func_convert_path_front_back_pathsep
 
 
 
 
+# func_convert_delimited_path PATH ORIG_DELIMITER NEW_DELIMITER
+# Replaces a delimiter for a given path.
+func_convert_delimited_path ()
+{
+	converted_path=`$ECHO "$1" | $SED "s#$2#$3#g"`
+}
+# end func_convert_delimited_path
+
+
 ##################################################
 ##################################################
 # $build to $host FILE NAME CONVERSION FUNCTIONS #
 # $build to $host FILE NAME CONVERSION FUNCTIONS #
 ##################################################
 ##################################################
@@ -3515,6 +3576,65 @@ func_dll_def_p ()
 }
 }
 
 
 
 
+# func_reorder_shared_lib_cache DIRS
+# Reorder the shared library cache by unconfiguring previous shared library cache
+# and configuring preferred search directories before previous search directories.
+# Previous shared library cache: /usr/lib /usr/local/lib
+# Preferred search directories: /tmp/testing
+# Reordered shared library cache: /tmp/testing /usr/lib /usr/local/lib
+func_reorder_shared_lib_cache ()
+{
+	$debug_cmd
+
+	case $host_os in
+	  openbsd*)
+	    get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"`
+	    func_convert_delimited_path "$get_search_directories" ':' '\ '
+	    save_search_directories=$converted_path
+	    func_convert_delimited_path "$1" ':' '\ '
+
+	    # Ensure directories exist
+	    for dir in $converted_path; do
+	      # Ensure each directory is an absolute path
+	      case $dir in
+	        /*) ;;
+	        *) func_error "Directory '$dir' is not an absolute path"
+	           exit $EXIT_FAILURE ;;
+	      esac
+	      # Ensure no trailing slashes
+	      func_stripname '' '/' "$dir"
+	      dir=$func_stripname_result
+	      if test -d "$dir"; then
+	        if test -n "$preferred_search_directories"; then
+	          preferred_search_directories="$preferred_search_directories $dir"
+	        else
+	          preferred_search_directories=$dir
+	        fi
+	      else
+	        func_error "Directory '$dir' does not exist"
+	        exit $EXIT_FAILURE
+	      fi
+	    done
+
+	    PATH="$PATH:/sbin" ldconfig -U $save_search_directories
+	    PATH="$PATH:/sbin" ldconfig -m $preferred_search_directories $save_search_directories
+	    get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"`
+	    func_convert_delimited_path "$get_search_directories" ':' '\ '
+	    reordered_search_directories=$converted_path
+
+	    $ECHO "Original: $save_search_directories"
+	    $ECHO "Reordered: $reordered_search_directories"
+	    exit $EXIT_SUCCESS
+	  ;;
+	  *)
+	    func_error "--reorder-cache is not supported for host_os=$host_os."
+	    exit $EXIT_FAILURE
+	  ;;
+	esac
+}
+# end func_reorder_shared_lib_cache
+
+
 # func_mode_compile arg...
 # func_mode_compile arg...
 func_mode_compile ()
 func_mode_compile ()
 {
 {
@@ -4087,6 +4207,12 @@ if $opt_help; then
 fi
 fi
 
 
 
 
+# If option '--reorder-cache', reorder the shared library cache and exit.
+if $opt_reorder_cache; then
+    func_reorder_shared_lib_cache $shared_lib_dirs
+fi
+
+
 # func_mode_execute arg...
 # func_mode_execute arg...
 func_mode_execute ()
 func_mode_execute ()
 {
 {
@@ -4271,7 +4397,7 @@ func_mode_finish ()
       fi
       fi
     fi
     fi
 
 
-    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs" && $opt_finishing; then
       for libdir in $libdirs; do
       for libdir in $libdirs; do
 	if test -n "$finish_cmds"; then
 	if test -n "$finish_cmds"; then
 	  # Do each command in the finish commands.
 	  # Do each command in the finish commands.
@@ -4296,6 +4422,12 @@ func_mode_finish ()
       for libdir in $libdirs; do
       for libdir in $libdirs; do
 	$ECHO "   $libdir"
 	$ECHO "   $libdir"
       done
       done
+      if test "false" = "$opt_finishing"; then
+        echo
+        echo "NOTE: finish_cmds were not executed during testing, so you must"
+        echo "manually run ldconfig to add a given test directory, LIBDIR, to"
+        echo "the search path for generated executables."
+      fi
       echo
       echo
       echo "If you ever happen to want to link against installed libraries"
       echo "If you ever happen to want to link against installed libraries"
       echo "in a given directory, LIBDIR, you must either use libtool, and"
       echo "in a given directory, LIBDIR, you must either use libtool, and"
@@ -4532,8 +4664,15 @@ func_mode_install ()
 	func_append dir "$objdir"
 	func_append dir "$objdir"
 
 
 	if test -n "$relink_command"; then
 	if test -n "$relink_command"; then
+	  # Strip any trailing slash from the destination.
+	  func_stripname '' '/' "$libdir"
+	  destlibdir=$func_stripname_result
+
+	  func_stripname '' '/' "$destdir"
+	  s_destdir=$func_stripname_result
+
 	  # Determine the prefix the user has applied to our future dir.
 	  # Determine the prefix the user has applied to our future dir.
-	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+	  inst_prefix_dir=`$ECHO "X$s_destdir" | $Xsed -e "s%$destlibdir\$%%"`
 
 
 	  # Don't allow the user to place us outside of our expected
 	  # Don't allow the user to place us outside of our expected
 	  # location b/c this prevents finding dependent libraries that
 	  # location b/c this prevents finding dependent libraries that
@@ -6782,6 +6921,7 @@ func_mode_link ()
     finalize_command=$nonopt
     finalize_command=$nonopt
 
 
     compile_rpath=
     compile_rpath=
+    compile_rpath_tail=
     finalize_rpath=
     finalize_rpath=
     compile_shlibpath=
     compile_shlibpath=
     finalize_shlibpath=
     finalize_shlibpath=
@@ -7337,7 +7477,8 @@ func_mode_link ()
       # Tru64 UNIX uses -model [arg] to determine the layout of C++
       # Tru64 UNIX uses -model [arg] to determine the layout of C++
       # classes, name mangling, and exception handling.
       # classes, name mangling, and exception handling.
       # Darwin uses the -arch flag to determine output architecture.
       # Darwin uses the -arch flag to determine output architecture.
-      -model|-arch|-isysroot|--sysroot)
+      # -q <option> for IBM XL C/C++ compiler.
+      -model|-arch|-isysroot|--sysroot|-q)
 	func_append compiler_flags " $arg"
 	func_append compiler_flags " $arg"
 	func_append compile_command " $arg"
 	func_append compile_command " $arg"
 	func_append finalize_command " $arg"
 	func_append finalize_command " $arg"
@@ -8433,10 +8574,11 @@ func_mode_link ()
 	    case " $sys_lib_dlsearch_path " in
 	    case " $sys_lib_dlsearch_path " in
 	    *" $absdir "*) ;;
 	    *" $absdir "*) ;;
 	    *)
 	    *)
-	      case "$compile_rpath " in
+	      case "$compile_rpath$compile_rpath_tail " in
 	      *" $absdir "*) ;;
 	      *" $absdir "*) ;;
 	      *) case $absdir in
 	      *) case $absdir in
                  "$progdir/"*) func_append compile_rpath " $absdir" ;;
                  "$progdir/"*) func_append compile_rpath " $absdir" ;;
+                 *) func_append compile_rpath_tail " $absdir" ;;
 		 esac
 		 esac
 	      esac
 	      esac
 	      ;;
 	      ;;
@@ -8509,10 +8651,11 @@ func_mode_link ()
 	    case " $sys_lib_dlsearch_path " in
 	    case " $sys_lib_dlsearch_path " in
 	    *" $absdir "*) ;;
 	    *" $absdir "*) ;;
 	    *)
 	    *)
-	      case "$compile_rpath " in
+	      case "$compile_rpath$compile_rpath_tail " in
 	      *" $absdir "*) ;;
 	      *" $absdir "*) ;;
 	      *) case $absdir in
 	      *) case $absdir in
                  "$progdir/"*) func_append compile_rpath " $absdir" ;;
                  "$progdir/"*) func_append compile_rpath " $absdir" ;;
+                 *) func_append compile_rpath_tail " $absdir" ;;
 		 esac
 		 esac
 	      esac
 	      esac
 	      ;;
 	      ;;
@@ -8588,6 +8731,7 @@ func_mode_link ()
 		case $host in
 		case $host in
 		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
 		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
 		  *-*-sysv4*uw2*) add_dir=-L$dir ;;
 		  *-*-sysv4*uw2*) add_dir=-L$dir ;;
+		  *-*-emscripten*) add_dir=-L$dir ;;
 		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
 		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
 		    *-*-unixware7*) add_dir=-L$dir ;;
 		    *-*-unixware7*) add_dir=-L$dir ;;
 		  *-*-darwin* )
 		  *-*-darwin* )
@@ -8876,6 +9020,8 @@ func_mode_link ()
       done # for deplib in $libs
       done # for deplib in $libs
 
 
       func_append temp_rpath "$temp_rpath_tail"
       func_append temp_rpath "$temp_rpath_tail"
+      func_append compile_rpath "$compile_rpath_tail"
+
       if test link = "$pass"; then
       if test link = "$pass"; then
 	if test prog = "$linkmode"; then
 	if test prog = "$linkmode"; then
 	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
 	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
@@ -9163,6 +9309,9 @@ func_mode_link ()
 	    revision=$number_minor
 	    revision=$number_minor
 	    lt_irix_increment=no
 	    lt_irix_increment=no
 	    ;;
 	    ;;
+	  *)
+	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
+	    ;;
 	  esac
 	  esac
 	  ;;
 	  ;;
 	no)
 	no)
@@ -10059,20 +10208,7 @@ func_mode_link ()
 	  last_robj=
 	  last_robj=
 	  k=1
 	  k=1
 
 
-	  if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
-	    output=$output_objdir/$output_la.lnkscript
-	    func_verbose "creating GNU ld script: $output"
-	    echo 'INPUT (' > $output
-	    for obj in $save_libobjs
-	    do
-	      func_to_tool_file "$obj"
-	      $ECHO "$func_to_tool_file_result" >> $output
-	    done
-	    echo ')' >> $output
-	    func_append delfiles " $output"
-	    func_to_tool_file "$output"
-	    output=$func_to_tool_file_result
-	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
+	  if test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
 	    output=$output_objdir/$output_la.lnk
 	    output=$output_objdir/$output_la.lnk
 	    func_verbose "creating linker input file list: $output"
 	    func_verbose "creating linker input file list: $output"
 	    : > $output
 	    : > $output
@@ -10091,6 +10227,19 @@ func_mode_link ()
 	    func_append delfiles " $output"
 	    func_append delfiles " $output"
 	    func_to_tool_file "$output"
 	    func_to_tool_file "$output"
 	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
 	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
+	    output=$output_objdir/$output_la.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    echo 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    echo ')' >> $output
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$func_to_tool_file_result
 	  else
 	  else
 	    if test -n "$save_libobjs"; then
 	    if test -n "$save_libobjs"; then
 	      func_verbose "creating reloadable object files..."
 	      func_verbose "creating reloadable object files..."

+ 7 - 2
libs/expat/doc/reference.html

@@ -14,7 +14,7 @@
    Copyright (c) 2000      Clark Cooper <[email protected]>
    Copyright (c) 2000      Clark Cooper <[email protected]>
    Copyright (c) 2000-2004 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2000-2004 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2002-2012 Karl Waclawek <[email protected]>
    Copyright (c) 2002-2012 Karl Waclawek <[email protected]>
-   Copyright (c) 2017-2024 Sebastian Pipping <[email protected]>
+   Copyright (c) 2017-2025 Sebastian Pipping <[email protected]>
    Copyright (c) 2017      Jakub Wilk <[email protected]>
    Copyright (c) 2017      Jakub Wilk <[email protected]>
    Copyright (c) 2021      Tomas Korbar <[email protected]>
    Copyright (c) 2021      Tomas Korbar <[email protected]>
    Copyright (c) 2021      Nicolas Cavallari <[email protected]>
    Copyright (c) 2021      Nicolas Cavallari <[email protected]>
@@ -52,7 +52,7 @@
   <div>
   <div>
     <h1>
     <h1>
       The Expat XML Parser
       The Expat XML Parser
-      <small>Release 2.6.4</small>
+      <small>Release 2.7.0</small>
     </h1>
     </h1>
   </div>
   </div>
 <div class="content">
 <div class="content">
@@ -1267,6 +1267,11 @@ call-backs, except when parsing an external parameter entity and
 <code>XML_STATUS_ERROR</code> otherwise.  The possible error codes
 <code>XML_STATUS_ERROR</code> otherwise.  The possible error codes
 are:</p>
 are:</p>
 <dl>
 <dl>
+  <dt><code>XML_ERROR_NOT_STARTED</code></dt>
+  <dd>
+    when stopping or suspending a parser before it has started,
+    added in Expat 2.6.4.
+  </dd>
   <dt><code>XML_ERROR_SUSPENDED</code></dt>
   <dt><code>XML_ERROR_SUSPENDED</code></dt>
   <dd>when suspending an already suspended parser.</dd>
   <dd>when suspending an already suspended parser.</dd>
   <dt><code>XML_ERROR_FINISHED</code></dt>
   <dt><code>XML_ERROR_FINISHED</code></dt>

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

@@ -5,7 +5,7 @@
 \\$2 \(la\\$1\(ra\\$3
 \\$2 \(la\\$1\(ra\\$3
 ..
 ..
 .if \n(.g .mso www.tmac
 .if \n(.g .mso www.tmac
-.TH XMLWF 1 "November 6, 2024" "" ""
+.TH XMLWF 1 "March 13, 2025" "" ""
 .SH NAME
 .SH NAME
 xmlwf \- Determines if an XML document is well-formed
 xmlwf \- Determines if an XML document is well-formed
 .SH SYNOPSIS
 .SH SYNOPSIS

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

@@ -9,7 +9,7 @@
    Copyright (c) 2001      Scott Bronson <[email protected]>
    Copyright (c) 2001      Scott Bronson <[email protected]>
    Copyright (c) 2002-2003 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2002-2003 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2009      Karl Waclawek <[email protected]>
    Copyright (c) 2009      Karl Waclawek <[email protected]>
-   Copyright (c) 2016-2024 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2025 Sebastian Pipping <[email protected]>
    Copyright (c) 2016      Ardo van Rangelrooij <[email protected]>
    Copyright (c) 2016      Ardo van Rangelrooij <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2020      Joe Orton <[email protected]>
    Copyright (c) 2020      Joe Orton <[email protected]>
@@ -21,7 +21,7 @@
           "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
           "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
   <!ENTITY dhfirstname "<firstname>Scott</firstname>">
   <!ENTITY dhfirstname "<firstname>Scott</firstname>">
   <!ENTITY dhsurname   "<surname>Bronson</surname>">
   <!ENTITY dhsurname   "<surname>Bronson</surname>">
-  <!ENTITY dhdate      "<date>November 6, 2024</date>">
+  <!ENTITY dhdate      "<date>March 13, 2025</date>">
   <!-- Please adjust this^^ date whenever cutting a new release. -->
   <!-- Please adjust this^^ date whenever cutting a new release. -->
   <!ENTITY dhsection   "<manvolnum>1</manvolnum>">
   <!ENTITY dhsection   "<manvolnum>1</manvolnum>">
   <!ENTITY dhemail     "<email>[email protected]</email>">
   <!ENTITY dhemail     "<email>[email protected]</email>">

+ 3 - 3
libs/expat/expat_config.h

@@ -83,7 +83,7 @@
 #define PACKAGE_NAME "expat"
 #define PACKAGE_NAME "expat"
 
 
 /* Define to the full name and version of this package. */
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "expat 2.6.4"
+#define PACKAGE_STRING "expat 2.7.0"
 
 
 /* Define to the one symbol short name of this package. */
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "expat"
 #define PACKAGE_TARNAME "expat"
@@ -92,7 +92,7 @@
 #define PACKAGE_URL ""
 #define PACKAGE_URL ""
 
 
 /* Define to the version of this package. */
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "2.6.4"
+#define PACKAGE_VERSION "2.7.0"
 
 
 /* Define to 1 if all of the C90 standard headers exist (not just the ones
 /* 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
    required in a freestanding environment). This macro is provided for
@@ -100,7 +100,7 @@
 #define STDC_HEADERS 1
 #define STDC_HEADERS 1
 
 
 /* Version number of package */
 /* Version number of package */
-#define VERSION "2.6.4"
+#define VERSION "2.7.0"
 
 
 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
    significant byte first (like Motorola and SPARC, unlike Intel). */
    significant byte first (like Motorola and SPARC, unlike Intel). */

+ 1 - 1
libs/expat/fuzz/xml_parse_fuzzer.c

@@ -5,7 +5,7 @@
  * you may not use this file except in compliance with the License.
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * You may obtain a copy of the License at
  *
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *      https://www.apache.org/licenses/LICENSE-2.0
  *
  *
  * Unless required by applicable law or agreed to in writing, software
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * distributed under the License is distributed on an "AS IS" BASIS,

+ 1 - 1
libs/expat/fuzz/xml_parsebuffer_fuzzer.c

@@ -5,7 +5,7 @@
  * you may not use this file except in compliance with the License.
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * You may obtain a copy of the License at
  *
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *      https://www.apache.org/licenses/LICENSE-2.0
  *
  *
  * Unless required by applicable law or agreed to in writing, software
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * distributed under the License is distributed on an "AS IS" BASIS,

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

@@ -11,7 +11,7 @@
    Copyright (c) 2000-2005 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2000-2005 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2001-2002 Greg Stein <[email protected]>
    Copyright (c) 2001-2002 Greg Stein <[email protected]>
    Copyright (c) 2002-2016 Karl Waclawek <[email protected]>
    Copyright (c) 2002-2016 Karl Waclawek <[email protected]>
-   Copyright (c) 2016-2024 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2025 Sebastian Pipping <[email protected]>
    Copyright (c) 2016      Cristian Rodríguez <[email protected]>
    Copyright (c) 2016      Cristian Rodríguez <[email protected]>
    Copyright (c) 2016      Thomas Beutlich <[email protected]>
    Copyright (c) 2016      Thomas Beutlich <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
@@ -1067,8 +1067,8 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
    See https://semver.org
    See https://semver.org
 */
 */
 #define XML_MAJOR_VERSION 2
 #define XML_MAJOR_VERSION 2
-#define XML_MINOR_VERSION 6
-#define XML_MICRO_VERSION 4
+#define XML_MINOR_VERSION 7
+#define XML_MICRO_VERSION 0
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 418 - 154
libs/expat/lib/xmlparse.c

@@ -1,4 +1,4 @@
-/* c5625880f4bf417c1463deee4eb92d86ff413f802048621c57e25fe483eb59e4 (2.6.4+)
+/* 7d6840a33c250b74adb0ba295d6ec818dccebebaffc8c3ed27d0b29c28adbeb3 (2.7.0+)
                             __  __            _
                             __  __            _
                          ___\ \/ /_ __   __ _| |_
                          ___\ \/ /_ __   __ _| |_
                         / _ \\  /| '_ \ / _` | __|
                         / _ \\  /| '_ \ / _` | __|
@@ -13,7 +13,7 @@
    Copyright (c) 2002-2016 Karl Waclawek <[email protected]>
    Copyright (c) 2002-2016 Karl Waclawek <[email protected]>
    Copyright (c) 2005-2009 Steven Solie <[email protected]>
    Copyright (c) 2005-2009 Steven Solie <[email protected]>
    Copyright (c) 2016      Eric Rahm <[email protected]>
    Copyright (c) 2016      Eric Rahm <[email protected]>
-   Copyright (c) 2016-2024 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2025 Sebastian Pipping <[email protected]>
    Copyright (c) 2016      Gaurav <[email protected]>
    Copyright (c) 2016      Gaurav <[email protected]>
    Copyright (c) 2016      Thomas Beutlich <[email protected]>
    Copyright (c) 2016      Thomas Beutlich <[email protected]>
    Copyright (c) 2016      Gustavo Grieco <[email protected]>
    Copyright (c) 2016      Gustavo Grieco <[email protected]>
@@ -39,7 +39,7 @@
    Copyright (c) 2022      Sean McBride <[email protected]>
    Copyright (c) 2022      Sean McBride <[email protected]>
    Copyright (c) 2023      Owain Davies <[email protected]>
    Copyright (c) 2023      Owain Davies <[email protected]>
    Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <[email protected]>
    Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <[email protected]>
-   Copyright (c) 2024      Berkay Eren Ürün <[email protected]>
+   Copyright (c) 2024-2025 Berkay Eren Ürün <[email protected]>
    Copyright (c) 2024      Hanno Böck <[email protected]>
    Copyright (c) 2024      Hanno Böck <[email protected]>
    Licensed under the MIT license:
    Licensed under the MIT license:
 
 
@@ -325,6 +325,10 @@ typedef struct {
   const XML_Char *publicId;
   const XML_Char *publicId;
   const XML_Char *notation;
   const XML_Char *notation;
   XML_Bool open;
   XML_Bool open;
+  XML_Bool hasMore; /* true if entity has not been completely processed */
+  /* An entity can be open while being already completely processed (hasMore ==
+    XML_FALSE). The reason is the delayed closing of entities until their inner
+    entities are processed and closed */
   XML_Bool is_param;
   XML_Bool is_param;
   XML_Bool is_internal; /* true if declared in internal subset outside PE */
   XML_Bool is_internal; /* true if declared in internal subset outside PE */
 } ENTITY;
 } ENTITY;
@@ -415,6 +419,12 @@ typedef struct {
   int *scaffIndex;
   int *scaffIndex;
 } DTD;
 } DTD;
 
 
+enum EntityType {
+  ENTITY_INTERNAL,
+  ENTITY_ATTRIBUTE,
+  ENTITY_VALUE,
+};
+
 typedef struct open_internal_entity {
 typedef struct open_internal_entity {
   const char *internalEventPtr;
   const char *internalEventPtr;
   const char *internalEventEndPtr;
   const char *internalEventEndPtr;
@@ -422,6 +432,7 @@ typedef struct open_internal_entity {
   ENTITY *entity;
   ENTITY *entity;
   int startTagLevel;
   int startTagLevel;
   XML_Bool betweenDecl; /* WFC: PE Between Declarations */
   XML_Bool betweenDecl; /* WFC: PE Between Declarations */
+  enum EntityType type;
 } OPEN_INTERNAL_ENTITY;
 } OPEN_INTERNAL_ENTITY;
 
 
 enum XML_Account {
 enum XML_Account {
@@ -481,8 +492,8 @@ static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
                                const char *next, const char **nextPtr,
                                const char *next, const char **nextPtr,
                                XML_Bool haveMore, XML_Bool allowClosingDoctype,
                                XML_Bool haveMore, XML_Bool allowClosingDoctype,
                                enum XML_Account account);
                                enum XML_Account account);
-static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
-                                            XML_Bool betweenDecl);
+static enum XML_Error processEntity(XML_Parser parser, ENTITY *entity,
+                                    XML_Bool betweenDecl, enum EntityType type);
 static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
 static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
                                 const ENCODING *enc, const char *start,
                                 const ENCODING *enc, const char *start,
                                 const char *end, const char **endPtr,
                                 const char *end, const char **endPtr,
@@ -513,18 +524,22 @@ static enum XML_Error storeAttributeValue(XML_Parser parser,
                                           const char *ptr, const char *end,
                                           const char *ptr, const char *end,
                                           STRING_POOL *pool,
                                           STRING_POOL *pool,
                                           enum XML_Account account);
                                           enum XML_Account account);
-static enum XML_Error appendAttributeValue(XML_Parser parser,
-                                           const ENCODING *enc,
-                                           XML_Bool isCdata, const char *ptr,
-                                           const char *end, STRING_POOL *pool,
-                                           enum XML_Account account);
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
+                     const char *ptr, const char *end, STRING_POOL *pool,
+                     enum XML_Account account, const char **nextPtr);
 static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
 static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
                                     const char *start, const char *end);
                                     const char *start, const char *end);
 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType);
 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType);
 #if XML_GE == 1
 #if XML_GE == 1
 static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
 static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
                                        const char *start, const char *end,
                                        const char *start, const char *end,
-                                       enum XML_Account account);
+                                       enum XML_Account account,
+                                       const char **nextPtr);
+static enum XML_Error callStoreEntityValue(XML_Parser parser,
+                                           const ENCODING *enc,
+                                           const char *start, const char *end,
+                                           enum XML_Account account);
 #else
 #else
 static enum XML_Error storeSelfEntityValue(XML_Parser parser, ENTITY *entity);
 static enum XML_Error storeSelfEntityValue(XML_Parser parser, ENTITY *entity);
 #endif
 #endif
@@ -709,6 +724,10 @@ struct XML_ParserStruct {
   const char *m_positionPtr;
   const char *m_positionPtr;
   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
   OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
   OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
+  OPEN_INTERNAL_ENTITY *m_openAttributeEntities;
+  OPEN_INTERNAL_ENTITY *m_freeAttributeEntities;
+  OPEN_INTERNAL_ENTITY *m_openValueEntities;
+  OPEN_INTERNAL_ENTITY *m_freeValueEntities;
   XML_Bool m_defaultExpandInternalEntities;
   XML_Bool m_defaultExpandInternalEntities;
   int m_tagLevel;
   int m_tagLevel;
   ENTITY *m_declEntity;
   ENTITY *m_declEntity;
@@ -756,6 +775,7 @@ struct XML_ParserStruct {
   ACCOUNTING m_accounting;
   ACCOUNTING m_accounting;
   ENTITY_STATS m_entity_stats;
   ENTITY_STATS m_entity_stats;
 #endif
 #endif
+  XML_Bool m_reenter;
 };
 };
 
 
 #define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
 #define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
@@ -1028,7 +1048,29 @@ callProcessor(XML_Parser parser, const char *start, const char *end,
 #if defined(XML_TESTING)
 #if defined(XML_TESTING)
   g_bytesScanned += (unsigned)have_now;
   g_bytesScanned += (unsigned)have_now;
 #endif
 #endif
-  const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr);
+  // Run in a loop to eliminate dangerous recursion depths
+  enum XML_Error ret;
+  *endPtr = start;
+  while (1) {
+    // Use endPtr as the new start in each iteration, since it will
+    // be set to the next start point by m_processor.
+    ret = parser->m_processor(parser, *endPtr, end, endPtr);
+
+    // Make parsing status (and in particular XML_SUSPENDED) take
+    // precedence over re-enter flag when they disagree
+    if (parser->m_parsingStatus.parsing != XML_PARSING) {
+      parser->m_reenter = XML_FALSE;
+    }
+
+    if (! parser->m_reenter) {
+      break;
+    }
+
+    parser->m_reenter = XML_FALSE;
+    if (ret != XML_ERROR_NONE)
+      return ret;
+  }
+
   if (ret == XML_ERROR_NONE) {
   if (ret == XML_ERROR_NONE) {
     // if we consumed nothing, remember what we had on this parse attempt.
     // if we consumed nothing, remember what we had on this parse attempt.
     if (*endPtr == start) {
     if (*endPtr == start) {
@@ -1139,6 +1181,8 @@ parserCreate(const XML_Char *encodingName,
   parser->m_freeBindingList = NULL;
   parser->m_freeBindingList = NULL;
   parser->m_freeTagList = NULL;
   parser->m_freeTagList = NULL;
   parser->m_freeInternalEntities = NULL;
   parser->m_freeInternalEntities = NULL;
+  parser->m_freeAttributeEntities = NULL;
+  parser->m_freeValueEntities = NULL;
 
 
   parser->m_groupSize = 0;
   parser->m_groupSize = 0;
   parser->m_groupConnector = NULL;
   parser->m_groupConnector = NULL;
@@ -1241,6 +1285,8 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
   parser->m_eventEndPtr = NULL;
   parser->m_eventEndPtr = NULL;
   parser->m_positionPtr = NULL;
   parser->m_positionPtr = NULL;
   parser->m_openInternalEntities = NULL;
   parser->m_openInternalEntities = NULL;
+  parser->m_openAttributeEntities = NULL;
+  parser->m_openValueEntities = NULL;
   parser->m_defaultExpandInternalEntities = XML_TRUE;
   parser->m_defaultExpandInternalEntities = XML_TRUE;
   parser->m_tagLevel = 0;
   parser->m_tagLevel = 0;
   parser->m_tagStack = NULL;
   parser->m_tagStack = NULL;
@@ -1251,6 +1297,8 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
   parser->m_unknownEncodingData = NULL;
   parser->m_unknownEncodingData = NULL;
   parser->m_parentParser = NULL;
   parser->m_parentParser = NULL;
   parser->m_parsingStatus.parsing = XML_INITIALIZED;
   parser->m_parsingStatus.parsing = XML_INITIALIZED;
+  // Reentry can only be triggered inside m_processor calls
+  parser->m_reenter = XML_FALSE;
 #ifdef XML_DTD
 #ifdef XML_DTD
   parser->m_isParamEntity = XML_FALSE;
   parser->m_isParamEntity = XML_FALSE;
   parser->m_useForeignDTD = XML_FALSE;
   parser->m_useForeignDTD = XML_FALSE;
@@ -1310,6 +1358,24 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
     openEntity->next = parser->m_freeInternalEntities;
     openEntity->next = parser->m_freeInternalEntities;
     parser->m_freeInternalEntities = openEntity;
     parser->m_freeInternalEntities = openEntity;
   }
   }
+  /* move m_openAttributeEntities to m_freeAttributeEntities (i.e. same task but
+   * for attributes) */
+  openEntityList = parser->m_openAttributeEntities;
+  while (openEntityList) {
+    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
+    openEntityList = openEntity->next;
+    openEntity->next = parser->m_freeAttributeEntities;
+    parser->m_freeAttributeEntities = openEntity;
+  }
+  /* move m_openValueEntities to m_freeValueEntities (i.e. same task but
+   * for value entities) */
+  openEntityList = parser->m_openValueEntities;
+  while (openEntityList) {
+    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
+    openEntityList = openEntity->next;
+    openEntity->next = parser->m_freeValueEntities;
+    parser->m_freeValueEntities = openEntity;
+  }
   moveToFreeBindingList(parser, parser->m_inheritedBindings);
   moveToFreeBindingList(parser, parser->m_inheritedBindings);
   FREE(parser, parser->m_unknownEncodingMem);
   FREE(parser, parser->m_unknownEncodingMem);
   if (parser->m_unknownEncodingRelease)
   if (parser->m_unknownEncodingRelease)
@@ -1323,6 +1389,19 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
   return XML_TRUE;
   return XML_TRUE;
 }
 }
 
 
+static XML_Bool
+parserBusy(XML_Parser parser) {
+  switch (parser->m_parsingStatus.parsing) {
+  case XML_PARSING:
+  case XML_SUSPENDED:
+    return XML_TRUE;
+  case XML_INITIALIZED:
+  case XML_FINISHED:
+  default:
+    return XML_FALSE;
+  }
+}
+
 enum XML_Status XMLCALL
 enum XML_Status XMLCALL
 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
   if (parser == NULL)
   if (parser == NULL)
@@ -1331,8 +1410,7 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
      XXX There's no way for the caller to determine which of the
      XXX There's no way for the caller to determine which of the
      XXX possible error cases caused the XML_STATUS_ERROR return.
      XXX possible error cases caused the XML_STATUS_ERROR return.
   */
   */
-  if (parser->m_parsingStatus.parsing == XML_PARSING
-      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parserBusy(parser))
     return XML_STATUS_ERROR;
     return XML_STATUS_ERROR;
 
 
   /* Get rid of any previous encoding name */
   /* Get rid of any previous encoding name */
@@ -1569,7 +1647,34 @@ XML_ParserFree(XML_Parser parser) {
     entityList = entityList->next;
     entityList = entityList->next;
     FREE(parser, openEntity);
     FREE(parser, openEntity);
   }
   }
-
+  /* free m_openAttributeEntities and m_freeAttributeEntities */
+  entityList = parser->m_openAttributeEntities;
+  for (;;) {
+    OPEN_INTERNAL_ENTITY *openEntity;
+    if (entityList == NULL) {
+      if (parser->m_freeAttributeEntities == NULL)
+        break;
+      entityList = parser->m_freeAttributeEntities;
+      parser->m_freeAttributeEntities = NULL;
+    }
+    openEntity = entityList;
+    entityList = entityList->next;
+    FREE(parser, openEntity);
+  }
+  /* free m_openValueEntities and m_freeValueEntities */
+  entityList = parser->m_openValueEntities;
+  for (;;) {
+    OPEN_INTERNAL_ENTITY *openEntity;
+    if (entityList == NULL) {
+      if (parser->m_freeValueEntities == NULL)
+        break;
+      entityList = parser->m_freeValueEntities;
+      parser->m_freeValueEntities = NULL;
+    }
+    openEntity = entityList;
+    entityList = entityList->next;
+    FREE(parser, openEntity);
+  }
   destroyBindings(parser->m_freeBindingList, parser);
   destroyBindings(parser->m_freeBindingList, parser);
   destroyBindings(parser->m_inheritedBindings, parser);
   destroyBindings(parser->m_inheritedBindings, parser);
   poolDestroy(&parser->m_tempPool);
   poolDestroy(&parser->m_tempPool);
@@ -1611,8 +1716,7 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
     return XML_ERROR_INVALID_ARGUMENT;
     return XML_ERROR_INVALID_ARGUMENT;
 #ifdef XML_DTD
 #ifdef XML_DTD
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
-  if (parser->m_parsingStatus.parsing == XML_PARSING
-      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parserBusy(parser))
     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
   parser->m_useForeignDTD = useDTD;
   parser->m_useForeignDTD = useDTD;
   return XML_ERROR_NONE;
   return XML_ERROR_NONE;
@@ -1627,8 +1731,7 @@ XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
   if (parser == NULL)
   if (parser == NULL)
     return;
     return;
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
-  if (parser->m_parsingStatus.parsing == XML_PARSING
-      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parserBusy(parser))
     return;
     return;
   parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
   parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
 }
 }
@@ -1897,8 +2000,7 @@ XML_SetParamEntityParsing(XML_Parser parser,
   if (parser == NULL)
   if (parser == NULL)
     return 0;
     return 0;
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
-  if (parser->m_parsingStatus.parsing == XML_PARSING
-      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parserBusy(parser))
     return 0;
     return 0;
 #ifdef XML_DTD
 #ifdef XML_DTD
   parser->m_paramEntityParsing = peParsing;
   parser->m_paramEntityParsing = peParsing;
@@ -1915,8 +2017,7 @@ XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
   if (parser->m_parentParser)
   if (parser->m_parentParser)
     return XML_SetHashSalt(parser->m_parentParser, hash_salt);
     return XML_SetHashSalt(parser->m_parentParser, hash_salt);
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
   /* block after XML_Parse()/XML_ParseBuffer() has been called */
-  if (parser->m_parsingStatus.parsing == XML_PARSING
-      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
+  if (parserBusy(parser))
     return 0;
     return 0;
   parser->m_hash_secret_salt = hash_salt;
   parser->m_hash_secret_salt = hash_salt;
   return 1;
   return 1;
@@ -2230,6 +2331,11 @@ XML_GetBuffer(XML_Parser parser, int len) {
   return parser->m_bufferEnd;
   return parser->m_bufferEnd;
 }
 }
 
 
+static void
+triggerReenter(XML_Parser parser) {
+  parser->m_reenter = XML_TRUE;
+}
+
 enum XML_Status XMLCALL
 enum XML_Status XMLCALL
 XML_StopParser(XML_Parser parser, XML_Bool resumable) {
 XML_StopParser(XML_Parser parser, XML_Bool resumable) {
   if (parser == NULL)
   if (parser == NULL)
@@ -2704,8 +2810,9 @@ static enum XML_Error PTRCALL
 contentProcessor(XML_Parser parser, const char *start, const char *end,
 contentProcessor(XML_Parser parser, const char *start, const char *end,
                  const char **endPtr) {
                  const char **endPtr) {
   enum XML_Error result = doContent(
   enum XML_Error result = doContent(
-      parser, 0, parser->m_encoding, start, end, endPtr,
-      (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
+      parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, start, end,
+      endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer,
+      XML_ACCOUNT_DIRECT);
   if (result == XML_ERROR_NONE) {
   if (result == XML_ERROR_NONE) {
     if (! storeRawNames(parser))
     if (! storeRawNames(parser))
       return XML_ERROR_NO_MEMORY;
       return XML_ERROR_NO_MEMORY;
@@ -2793,6 +2900,11 @@ externalEntityInitProcessor3(XML_Parser parser, const char *start,
       return XML_ERROR_NONE;
       return XML_ERROR_NONE;
     case XML_FINISHED:
     case XML_FINISHED:
       return XML_ERROR_ABORTED;
       return XML_ERROR_ABORTED;
+    case XML_PARSING:
+      if (parser->m_reenter) {
+        return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE
+      }
+      /* Fall through */
     default:
     default:
       start = next;
       start = next;
     }
     }
@@ -2966,7 +3078,7 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
             reportDefault(parser, enc, s, next);
             reportDefault(parser, enc, s, next);
           break;
           break;
         }
         }
-        result = processInternalEntity(parser, entity, XML_FALSE);
+        result = processEntity(parser, entity, XML_FALSE, ENTITY_INTERNAL);
         if (result != XML_ERROR_NONE)
         if (result != XML_ERROR_NONE)
           return result;
           return result;
       } else if (parser->m_externalEntityRefHandler) {
       } else if (parser->m_externalEntityRefHandler) {
@@ -3092,7 +3204,9 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
     }
     }
       if ((parser->m_tagLevel == 0)
       if ((parser->m_tagLevel == 0)
           && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
           && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
-        if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
+        if (parser->m_parsingStatus.parsing == XML_SUSPENDED
+            || (parser->m_parsingStatus.parsing == XML_PARSING
+                && parser->m_reenter))
           parser->m_processor = epilogProcessor;
           parser->m_processor = epilogProcessor;
         else
         else
           return epilogProcessor(parser, next, end, nextPtr);
           return epilogProcessor(parser, next, end, nextPtr);
@@ -3153,7 +3267,9 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
         }
         }
         if ((parser->m_tagLevel == 0)
         if ((parser->m_tagLevel == 0)
             && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
             && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
-          if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
+          if (parser->m_parsingStatus.parsing == XML_SUSPENDED
+              || (parser->m_parsingStatus.parsing == XML_PARSING
+                  && parser->m_reenter))
             parser->m_processor = epilogProcessor;
             parser->m_processor = epilogProcessor;
           else
           else
             return epilogProcessor(parser, next, end, nextPtr);
             return epilogProcessor(parser, next, end, nextPtr);
@@ -3293,6 +3409,12 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
       return XML_ERROR_NONE;
       return XML_ERROR_NONE;
     case XML_FINISHED:
     case XML_FINISHED:
       return XML_ERROR_ABORTED;
       return XML_ERROR_ABORTED;
+    case XML_PARSING:
+      if (parser->m_reenter) {
+        *nextPtr = next;
+        return XML_ERROR_NONE;
+      }
+      /* Fall through */
     default:;
     default:;
     }
     }
   }
   }
@@ -4217,6 +4339,11 @@ doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
       return XML_ERROR_NONE;
       return XML_ERROR_NONE;
     case XML_FINISHED:
     case XML_FINISHED:
       return XML_ERROR_ABORTED;
       return XML_ERROR_ABORTED;
+    case XML_PARSING:
+      if (parser->m_reenter) {
+        return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE
+      }
+      /* Fall through */
     default:;
     default:;
     }
     }
   }
   }
@@ -4549,7 +4676,7 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
       }
       }
       /* found end of entity value - can store it now */
       /* found end of entity value - can store it now */
       return storeEntityValue(parser, parser->m_encoding, s, end,
       return storeEntityValue(parser, parser->m_encoding, s, end,
-                              XML_ACCOUNT_DIRECT);
+                              XML_ACCOUNT_DIRECT, NULL);
     } else if (tok == XML_TOK_XML_DECL) {
     } else if (tok == XML_TOK_XML_DECL) {
       enum XML_Error result;
       enum XML_Error result;
       result = processXmlDecl(parser, 0, start, next);
       result = processXmlDecl(parser, 0, start, next);
@@ -4676,7 +4803,7 @@ entityValueProcessor(XML_Parser parser, const char *s, const char *end,
         break;
         break;
       }
       }
       /* found end of entity value - can store it now */
       /* found end of entity value - can store it now */
-      return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT);
+      return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT, NULL);
     }
     }
     start = next;
     start = next;
   }
   }
@@ -5119,9 +5246,9 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
 #if XML_GE == 1
 #if XML_GE == 1
         // This will store the given replacement text in
         // This will store the given replacement text in
         // parser->m_declEntity->textPtr.
         // parser->m_declEntity->textPtr.
-        enum XML_Error result
-            = storeEntityValue(parser, enc, s + enc->minBytesPerChar,
-                               next - enc->minBytesPerChar, XML_ACCOUNT_NONE);
+        enum XML_Error result = callStoreEntityValue(
+            parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar,
+            XML_ACCOUNT_NONE);
         if (parser->m_declEntity) {
         if (parser->m_declEntity) {
           parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
           parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
           parser->m_declEntity->textLen
           parser->m_declEntity->textLen
@@ -5546,7 +5673,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
           enum XML_Error result;
           enum XML_Error result;
           XML_Bool betweenDecl
           XML_Bool betweenDecl
               = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
               = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
-          result = processInternalEntity(parser, entity, betweenDecl);
+          result = processEntity(parser, entity, betweenDecl, ENTITY_INTERNAL);
           if (result != XML_ERROR_NONE)
           if (result != XML_ERROR_NONE)
             return result;
             return result;
           handleDefault = XML_FALSE;
           handleDefault = XML_FALSE;
@@ -5751,6 +5878,12 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
       return XML_ERROR_NONE;
       return XML_ERROR_NONE;
     case XML_FINISHED:
     case XML_FINISHED:
       return XML_ERROR_ABORTED;
       return XML_ERROR_ABORTED;
+    case XML_PARSING:
+      if (parser->m_reenter) {
+        *nextPtr = next;
+        return XML_ERROR_NONE;
+      }
+    /* Fall through */
     default:
     default:
       s = next;
       s = next;
       tok = XmlPrologTok(enc, s, end, &next);
       tok = XmlPrologTok(enc, s, end, &next);
@@ -5825,21 +5958,49 @@ epilogProcessor(XML_Parser parser, const char *s, const char *end,
       return XML_ERROR_NONE;
       return XML_ERROR_NONE;
     case XML_FINISHED:
     case XML_FINISHED:
       return XML_ERROR_ABORTED;
       return XML_ERROR_ABORTED;
+    case XML_PARSING:
+      if (parser->m_reenter) {
+        return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE
+      }
+    /* Fall through */
     default:;
     default:;
     }
     }
   }
   }
 }
 }
 
 
 static enum XML_Error
 static enum XML_Error
-processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
-  const char *textStart, *textEnd;
-  const char *next;
-  enum XML_Error result;
-  OPEN_INTERNAL_ENTITY *openEntity;
+processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl,
+              enum EntityType type) {
+  OPEN_INTERNAL_ENTITY *openEntity, **openEntityList, **freeEntityList;
+  switch (type) {
+  case ENTITY_INTERNAL:
+    parser->m_processor = internalEntityProcessor;
+    openEntityList = &parser->m_openInternalEntities;
+    freeEntityList = &parser->m_freeInternalEntities;
+    break;
+  case ENTITY_ATTRIBUTE:
+    openEntityList = &parser->m_openAttributeEntities;
+    freeEntityList = &parser->m_freeAttributeEntities;
+    break;
+  case ENTITY_VALUE:
+    openEntityList = &parser->m_openValueEntities;
+    freeEntityList = &parser->m_freeValueEntities;
+    break;
+    /* default case serves merely as a safety net in case of a
+     * wrong entityType. Therefore we exclude the following lines
+     * from the test coverage.
+     *
+     * LCOV_EXCL_START
+     */
+  default:
+    // Should not reach here
+    assert(0);
+    /* LCOV_EXCL_STOP */
+  }
 
 
-  if (parser->m_freeInternalEntities) {
-    openEntity = parser->m_freeInternalEntities;
-    parser->m_freeInternalEntities = openEntity->next;
+  if (*freeEntityList) {
+    openEntity = *freeEntityList;
+    *freeEntityList = openEntity->next;
   } else {
   } else {
     openEntity
     openEntity
         = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
         = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
@@ -5847,55 +6008,34 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
       return XML_ERROR_NO_MEMORY;
       return XML_ERROR_NO_MEMORY;
   }
   }
   entity->open = XML_TRUE;
   entity->open = XML_TRUE;
+  entity->hasMore = XML_TRUE;
 #if XML_GE == 1
 #if XML_GE == 1
   entityTrackingOnOpen(parser, entity, __LINE__);
   entityTrackingOnOpen(parser, entity, __LINE__);
 #endif
 #endif
   entity->processed = 0;
   entity->processed = 0;
-  openEntity->next = parser->m_openInternalEntities;
-  parser->m_openInternalEntities = openEntity;
+  openEntity->next = *openEntityList;
+  *openEntityList = openEntity;
   openEntity->entity = entity;
   openEntity->entity = entity;
+  openEntity->type = type;
   openEntity->startTagLevel = parser->m_tagLevel;
   openEntity->startTagLevel = parser->m_tagLevel;
   openEntity->betweenDecl = betweenDecl;
   openEntity->betweenDecl = betweenDecl;
   openEntity->internalEventPtr = NULL;
   openEntity->internalEventPtr = NULL;
   openEntity->internalEventEndPtr = NULL;
   openEntity->internalEventEndPtr = NULL;
-  textStart = (const char *)entity->textPtr;
-  textEnd = (const char *)(entity->textPtr + entity->textLen);
-  /* Set a safe default value in case 'next' does not get set */
-  next = textStart;
-
-  if (entity->is_param) {
-    int tok
-        = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
-    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
-                      tok, next, &next, XML_FALSE, XML_FALSE,
-                      XML_ACCOUNT_ENTITY_EXPANSION);
-  } else {
-    result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
-                       textStart, textEnd, &next, XML_FALSE,
-                       XML_ACCOUNT_ENTITY_EXPANSION);
-  }
 
 
-  if (result == XML_ERROR_NONE) {
-    if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
-      entity->processed = (int)(next - textStart);
-      parser->m_processor = internalEntityProcessor;
-    } else if (parser->m_openInternalEntities->entity == entity) {
-#if XML_GE == 1
-      entityTrackingOnClose(parser, entity, __LINE__);
-#endif /* XML_GE == 1 */
-      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;
-    }
+  // Only internal entities make use of the reenter flag
+  // therefore no need to set it for other entity types
+  if (type == ENTITY_INTERNAL) {
+    triggerReenter(parser);
   }
   }
-  return result;
+  return XML_ERROR_NONE;
 }
 }
 
 
 static enum XML_Error PTRCALL
 static enum XML_Error PTRCALL
 internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
 internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
                         const char **nextPtr) {
                         const char **nextPtr) {
+  UNUSED_P(s);
+  UNUSED_P(end);
+  UNUSED_P(nextPtr);
   ENTITY *entity;
   ENTITY *entity;
   const char *textStart, *textEnd;
   const char *textStart, *textEnd;
   const char *next;
   const char *next;
@@ -5905,68 +6045,67 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
     return XML_ERROR_UNEXPECTED_STATE;
     return XML_ERROR_UNEXPECTED_STATE;
 
 
   entity = openEntity->entity;
   entity = openEntity->entity;
-  textStart = ((const char *)entity->textPtr) + entity->processed;
-  textEnd = (const char *)(entity->textPtr + entity->textLen);
-  /* Set a safe default value in case 'next' does not get set */
-  next = textStart;
-
-  if (entity->is_param) {
-    int tok
-        = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
-    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
-                      tok, next, &next, XML_FALSE, XML_TRUE,
-                      XML_ACCOUNT_ENTITY_EXPANSION);
-  } else {
-    result = doContent(parser, openEntity->startTagLevel,
-                       parser->m_internalEncoding, textStart, textEnd, &next,
-                       XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
-  }
 
 
-  if (result != XML_ERROR_NONE)
-    return result;
+  // This will return early
+  if (entity->hasMore) {
+    textStart = ((const char *)entity->textPtr) + entity->processed;
+    textEnd = (const char *)(entity->textPtr + entity->textLen);
+    /* Set a safe default value in case 'next' does not get set */
+    next = textStart;
+
+    if (entity->is_param) {
+      int tok
+          = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
+      result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
+                        tok, next, &next, XML_FALSE, XML_FALSE,
+                        XML_ACCOUNT_ENTITY_EXPANSION);
+    } else {
+      result = doContent(parser, openEntity->startTagLevel,
+                         parser->m_internalEncoding, textStart, textEnd, &next,
+                         XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
+    }
+
+    if (result != XML_ERROR_NONE)
+      return result;
+    // Check if entity is complete, if not, mark down how much of it is
+    // processed
+    if (textEnd != next
+        && (parser->m_parsingStatus.parsing == XML_SUSPENDED
+            || (parser->m_parsingStatus.parsing == XML_PARSING
+                && parser->m_reenter))) {
+      entity->processed = (int)(next - (const char *)entity->textPtr);
+      return result;
+    }
 
 
-  if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
-    entity->processed = (int)(next - (const char *)entity->textPtr);
+    // Entity is complete. We cannot close it here since we need to first
+    // process its possible inner entities (which are added to the
+    // m_openInternalEntities during doProlog or doContent calls above)
+    entity->hasMore = XML_FALSE;
+    triggerReenter(parser);
     return result;
     return result;
-  }
+  } // End of entity processing, "if" block will return here
 
 
+  // Remove fully processed openEntity from open entity list.
 #if XML_GE == 1
 #if XML_GE == 1
   entityTrackingOnClose(parser, entity, __LINE__);
   entityTrackingOnClose(parser, entity, __LINE__);
 #endif
 #endif
+  // openEntity is m_openInternalEntities' head, as we set it at the start of
+  // this function and we skipped doProlog and doContent calls with hasMore set
+  // to false. This means we can directly remove the head of
+  // m_openInternalEntities
+  assert(parser->m_openInternalEntities == openEntity);
   entity->open = XML_FALSE;
   entity->open = XML_FALSE;
-  parser->m_openInternalEntities = openEntity->next;
+  parser->m_openInternalEntities = parser->m_openInternalEntities->next;
+
   /* put openEntity back in list of free instances */
   /* put openEntity back in list of free instances */
   openEntity->next = parser->m_freeInternalEntities;
   openEntity->next = parser->m_freeInternalEntities;
   parser->m_freeInternalEntities = openEntity;
   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;
-  }
-
-  if (entity->is_param) {
-    int tok;
-    parser->m_processor = prologProcessor;
-    tok = XmlPrologTok(parser->m_encoding, s, end, &next);
-    return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
-                    (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
-                    XML_ACCOUNT_DIRECT);
-  } else {
-    parser->m_processor = contentProcessor;
-    /* see externalEntityContentProcessor vs contentProcessor */
-    result = doContent(parser, parser->m_parentParser ? 1 : 0,
-                       parser->m_encoding, s, end, nextPtr,
-                       (XML_Bool)! parser->m_parsingStatus.finalBuffer,
-                       XML_ACCOUNT_DIRECT);
-    if (result == XML_ERROR_NONE) {
-      if (! storeRawNames(parser))
-        return XML_ERROR_NO_MEMORY;
-    }
-    return result;
+  if (parser->m_openInternalEntities == NULL) {
+    parser->m_processor = entity->is_param ? prologProcessor : contentProcessor;
   }
   }
+  triggerReenter(parser);
+  return XML_ERROR_NONE;
 }
 }
 
 
 static enum XML_Error PTRCALL
 static enum XML_Error PTRCALL
@@ -5982,8 +6121,70 @@ static enum XML_Error
 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
                     const char *ptr, const char *end, STRING_POOL *pool,
                     const char *ptr, const char *end, STRING_POOL *pool,
                     enum XML_Account account) {
                     enum XML_Account account) {
-  enum XML_Error result
-      = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account);
+  const char *next = ptr;
+  enum XML_Error result = XML_ERROR_NONE;
+
+  while (1) {
+    if (! parser->m_openAttributeEntities) {
+      result = appendAttributeValue(parser, enc, isCdata, next, end, pool,
+                                    account, &next);
+    } else {
+      OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openAttributeEntities;
+      if (! openEntity)
+        return XML_ERROR_UNEXPECTED_STATE;
+
+      ENTITY *const entity = openEntity->entity;
+      const char *const textStart
+          = ((const char *)entity->textPtr) + entity->processed;
+      const char *const textEnd
+          = (const char *)(entity->textPtr + entity->textLen);
+      /* Set a safe default value in case 'next' does not get set */
+      const char *nextInEntity = textStart;
+      if (entity->hasMore) {
+        result = appendAttributeValue(
+            parser, parser->m_internalEncoding, isCdata, textStart, textEnd,
+            pool, XML_ACCOUNT_ENTITY_EXPANSION, &nextInEntity);
+        if (result != XML_ERROR_NONE)
+          break;
+        // Check if entity is complete, if not, mark down how much of it is
+        // processed. A XML_SUSPENDED check here is not required as
+        // appendAttributeValue will never suspend the parser.
+        if (textEnd != nextInEntity) {
+          entity->processed
+              = (int)(nextInEntity - (const char *)entity->textPtr);
+          continue;
+        }
+
+        // Entity is complete. We cannot close it here since we need to first
+        // process its possible inner entities (which are added to the
+        // m_openAttributeEntities during appendAttributeValue)
+        entity->hasMore = XML_FALSE;
+        continue;
+      } // End of entity processing, "if" block skips the rest
+
+      // Remove fully processed openEntity from open entity list.
+#if XML_GE == 1
+      entityTrackingOnClose(parser, entity, __LINE__);
+#endif
+      // openEntity is m_openAttributeEntities' head, since we set it at the
+      // start of this function and because we skipped appendAttributeValue call
+      // with hasMore set to false. This means we can directly remove the head
+      // of m_openAttributeEntities
+      assert(parser->m_openAttributeEntities == openEntity);
+      entity->open = XML_FALSE;
+      parser->m_openAttributeEntities = parser->m_openAttributeEntities->next;
+
+      /* put openEntity back in list of free instances */
+      openEntity->next = parser->m_freeAttributeEntities;
+      parser->m_freeAttributeEntities = openEntity;
+    }
+
+    // Break if an error occurred or there is nothing left to process
+    if (result || (parser->m_openAttributeEntities == NULL && end == next)) {
+      break;
+    }
+  }
+
   if (result)
   if (result)
     return result;
     return result;
   if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
   if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
@@ -5996,7 +6197,7 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
 static enum XML_Error
 static enum XML_Error
 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
                      const char *ptr, const char *end, STRING_POOL *pool,
                      const char *ptr, const char *end, STRING_POOL *pool,
-                     enum XML_Account account) {
+                     enum XML_Account account, const char **nextPtr) {
   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
 #ifndef XML_DTD
 #ifndef XML_DTD
   UNUSED_P(account);
   UNUSED_P(account);
@@ -6014,6 +6215,9 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
 #endif
 #endif
     switch (tok) {
     switch (tok) {
     case XML_TOK_NONE:
     case XML_TOK_NONE:
+      if (nextPtr) {
+        *nextPtr = next;
+      }
       return XML_ERROR_NONE;
       return XML_ERROR_NONE;
     case XML_TOK_INVALID:
     case XML_TOK_INVALID:
       if (enc == parser->m_encoding)
       if (enc == parser->m_encoding)
@@ -6154,21 +6358,11 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
         return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
         return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
       } else {
       } else {
         enum XML_Error result;
         enum XML_Error result;
-        const XML_Char *textEnd = entity->textPtr + entity->textLen;
-        entity->open = XML_TRUE;
-#if XML_GE == 1
-        entityTrackingOnOpen(parser, entity, __LINE__);
-#endif
-        result = appendAttributeValue(parser, parser->m_internalEncoding,
-                                      isCdata, (const char *)entity->textPtr,
-                                      (const char *)textEnd, pool,
-                                      XML_ACCOUNT_ENTITY_EXPANSION);
-#if XML_GE == 1
-        entityTrackingOnClose(parser, entity, __LINE__);
-#endif
-        entity->open = XML_FALSE;
-        if (result)
-          return result;
+        result = processEntity(parser, entity, XML_FALSE, ENTITY_ATTRIBUTE);
+        if ((result == XML_ERROR_NONE) && (nextPtr != NULL)) {
+          *nextPtr = next;
+        }
+        return result;
       }
       }
     } break;
     } break;
     default:
     default:
@@ -6197,7 +6391,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
 static enum XML_Error
 static enum XML_Error
 storeEntityValue(XML_Parser parser, const ENCODING *enc,
 storeEntityValue(XML_Parser parser, const ENCODING *enc,
                  const char *entityTextPtr, const char *entityTextEnd,
                  const char *entityTextPtr, const char *entityTextEnd,
-                 enum XML_Account account) {
+                 enum XML_Account account, const char **nextPtr) {
   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
   STRING_POOL *pool = &(dtd->entityValuePool);
   STRING_POOL *pool = &(dtd->entityValuePool);
   enum XML_Error result = XML_ERROR_NONE;
   enum XML_Error result = XML_ERROR_NONE;
@@ -6215,8 +6409,9 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
       return XML_ERROR_NO_MEMORY;
       return XML_ERROR_NO_MEMORY;
   }
   }
 
 
+  const char *next;
   for (;;) {
   for (;;) {
-    const char *next
+    next
         = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
         = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
 
 
@@ -6278,16 +6473,8 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
           } else
           } else
             dtd->keepProcessing = dtd->standalone;
             dtd->keepProcessing = dtd->standalone;
         } else {
         } else {
-          entity->open = XML_TRUE;
-          entityTrackingOnOpen(parser, entity, __LINE__);
-          result = storeEntityValue(
-              parser, parser->m_internalEncoding, (const char *)entity->textPtr,
-              (const char *)(entity->textPtr + entity->textLen),
-              XML_ACCOUNT_ENTITY_EXPANSION);
-          entityTrackingOnClose(parser, entity, __LINE__);
-          entity->open = XML_FALSE;
-          if (result)
-            goto endEntityValue;
+          result = processEntity(parser, entity, XML_FALSE, ENTITY_VALUE);
+          goto endEntityValue;
         }
         }
         break;
         break;
       }
       }
@@ -6375,6 +6562,81 @@ endEntityValue:
 #  ifdef XML_DTD
 #  ifdef XML_DTD
   parser->m_prologState.inEntityValue = oldInEntityValue;
   parser->m_prologState.inEntityValue = oldInEntityValue;
 #  endif /* XML_DTD */
 #  endif /* XML_DTD */
+  // If 'nextPtr' is given, it should be updated during the processing
+  if (nextPtr != NULL) {
+    *nextPtr = next;
+  }
+  return result;
+}
+
+static enum XML_Error
+callStoreEntityValue(XML_Parser parser, const ENCODING *enc,
+                     const char *entityTextPtr, const char *entityTextEnd,
+                     enum XML_Account account) {
+  const char *next = entityTextPtr;
+  enum XML_Error result = XML_ERROR_NONE;
+  while (1) {
+    if (! parser->m_openValueEntities) {
+      result
+          = storeEntityValue(parser, enc, next, entityTextEnd, account, &next);
+    } else {
+      OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openValueEntities;
+      if (! openEntity)
+        return XML_ERROR_UNEXPECTED_STATE;
+
+      ENTITY *const entity = openEntity->entity;
+      const char *const textStart
+          = ((const char *)entity->textPtr) + entity->processed;
+      const char *const textEnd
+          = (const char *)(entity->textPtr + entity->textLen);
+      /* Set a safe default value in case 'next' does not get set */
+      const char *nextInEntity = textStart;
+      if (entity->hasMore) {
+        result = storeEntityValue(parser, parser->m_internalEncoding, textStart,
+                                  textEnd, XML_ACCOUNT_ENTITY_EXPANSION,
+                                  &nextInEntity);
+        if (result != XML_ERROR_NONE)
+          break;
+        // Check if entity is complete, if not, mark down how much of it is
+        // processed. A XML_SUSPENDED check here is not required as
+        // appendAttributeValue will never suspend the parser.
+        if (textEnd != nextInEntity) {
+          entity->processed
+              = (int)(nextInEntity - (const char *)entity->textPtr);
+          continue;
+        }
+
+        // Entity is complete. We cannot close it here since we need to first
+        // process its possible inner entities (which are added to the
+        // m_openValueEntities during storeEntityValue)
+        entity->hasMore = XML_FALSE;
+        continue;
+      } // End of entity processing, "if" block skips the rest
+
+      // Remove fully processed openEntity from open entity list.
+#  if XML_GE == 1
+      entityTrackingOnClose(parser, entity, __LINE__);
+#  endif
+      // openEntity is m_openValueEntities' head, since we set it at the
+      // start of this function and because we skipped storeEntityValue call
+      // with hasMore set to false. This means we can directly remove the head
+      // of m_openValueEntities
+      assert(parser->m_openValueEntities == openEntity);
+      entity->open = XML_FALSE;
+      parser->m_openValueEntities = parser->m_openValueEntities->next;
+
+      /* put openEntity back in list of free instances */
+      openEntity->next = parser->m_freeValueEntities;
+      parser->m_freeValueEntities = openEntity;
+    }
+
+    // Break if an error occurred or there is nothing left to process
+    if (result
+        || (parser->m_openValueEntities == NULL && entityTextEnd == next)) {
+      break;
+    }
+  }
+
   return result;
   return result;
 }
 }
 
 
@@ -8542,11 +8804,13 @@ unsignedCharToPrintable(unsigned char c) {
     return "\\xFE";
     return "\\xFE";
   case 255:
   case 255:
     return "\\xFF";
     return "\\xFF";
+  // LCOV_EXCL_START
   default:
   default:
     assert(0); /* never gets here */
     assert(0); /* never gets here */
     return "dead code";
     return "dead code";
   }
   }
   assert(0); /* never gets here */
   assert(0); /* never gets here */
+  // LCOV_EXCL_STOP
 }
 }
 
 
 #endif /* XML_GE == 1 */
 #endif /* XML_GE == 1 */

+ 151 - 44
libs/expat/m4/libtool.m4

@@ -32,7 +32,7 @@ m4_define([_LT_COPYING], [dnl
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ])
 ])
 
 
-# serial 62 LT_INIT
+# serial 63 LT_INIT
 
 
 
 
 # LT_PREREQ(VERSION)
 # LT_PREREQ(VERSION)
@@ -1100,6 +1100,21 @@ _LT_EOF
     if test yes = "$lt_cv_apple_cc_single_mod"; then
     if test yes = "$lt_cv_apple_cc_single_mod"; then
       _lt_dar_single_mod='$single_module'
       _lt_dar_single_mod='$single_module'
     fi
     fi
+    _lt_dar_needs_single_mod=no
+    case $host_os in
+    rhapsody* | darwin1.*)
+      _lt_dar_needs_single_mod=yes ;;
+    darwin*)
+      # When targeting Mac OS X 10.4 (darwin 8) or later,
+      # -single_module is the default and -multi_module is unsupported.
+      # The toolchain on macOS 10.14 (darwin 18) and later cannot
+      # target any OS version that needs -single_module.
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+      10.0,*-darwin[[567]].*|10.[[0-3]],*-darwin[[5-9]].*|10.[[0-3]],*-darwin1[[0-7]].*)
+        _lt_dar_needs_single_mod=yes ;;
+      esac
+    ;;
+    esac
     if test yes = "$lt_cv_ld_exported_symbols_list"; then
     if test yes = "$lt_cv_ld_exported_symbols_list"; then
       _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
       _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
     else
     else
@@ -1145,7 +1160,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
     _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
     _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
     _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
     _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
     m4_if([$1], [CXX],
     m4_if([$1], [CXX],
-[   if test yes != "$lt_cv_apple_cc_single_mod"; then
+[   if test yes = "$_lt_dar_needs_single_mod" -a yes != "$lt_cv_apple_cc_single_mod"; then
       _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
       _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
       _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
       _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
     fi
     fi
@@ -1710,9 +1725,9 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=12288;    # 12K is about right
     lt_cv_sys_max_cmd_len=12288;    # 12K is about right
     ;;
     ;;
 
 
-  gnu*)
-    # Under GNU Hurd, this test is not required because there is
-    # no limit to the length of command line arguments.
+  gnu* | ironclad*)
+    # Under GNU Hurd and Ironclad, this test is not required because there
+    # is no limit to the length of command line arguments.
     # Libtool will interpret -1 as no limit whatsoever
     # Libtool will interpret -1 as no limit whatsoever
     lt_cv_sys_max_cmd_len=-1;
     lt_cv_sys_max_cmd_len=-1;
     ;;
     ;;
@@ -2566,28 +2581,28 @@ cygwin* | mingw* | windows* | pw32* | cegcc*)
     # gcc
     # gcc
     library_names_spec='$libname.dll.a'
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    # If user builds GCC with mulitlibs enabled,
+    # If user builds GCC with multilib enabled,
     # it should just install on $(libdir)
     # it should just install on $(libdir)
     # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones.
     # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones.
-    if test yes = $multilib; then
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
-      dldir=$destdir/`dirname \$dlpath`~
-      $install_prog $dir/$dlname $destdir/$dlname~
-      chmod a+x $destdir/$dlname~
-      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-        eval '\''$striplib $destdir/$dlname'\'' || exit \$?;
-      fi'
+    if test xyes = x"$multilib"; then
+      postinstall_cmds='base_file=`basename \$file`~
+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+        dldir=$destdir/`dirname \$dlpath`~
+        $install_prog $dir/$dlname $destdir/$dlname~
+        chmod a+x $destdir/$dlname~
+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+          eval '\''$striplib $destdir/$dlname'\'' || exit \$?;
+        fi'
     else
     else
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
-      dldir=$destdir/`dirname \$dlpath`~
-      test -d \$dldir || mkdir -p \$dldir~
-      $install_prog $dir/$dlname \$dldir/$dlname~
-      chmod a+x \$dldir/$dlname~
-      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-      fi'
+      postinstall_cmds='base_file=`basename \$file`~
+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+        dldir=$destdir/`dirname \$dlpath`~
+        test -d \$dldir || mkdir -p \$dldir~
+        $install_prog $dir/$dlname \$dldir/$dlname~
+        chmod a+x \$dldir/$dlname~
+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+          eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+        fi'
     fi
     fi
     postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
     postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
       dlpath=$dir/\$dldll~
       dlpath=$dir/\$dldll~
@@ -2784,8 +2799,9 @@ haiku*)
   soname_spec='$libname$release$shared_ext$major'
   soname_spec='$libname$release$shared_ext$major'
   shlibpath_var=LIBRARY_PATH
   shlibpath_var=LIBRARY_PATH
   shlibpath_overrides_runpath=no
   shlibpath_overrides_runpath=no
-  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
-  hardcode_into_libs=yes
+  sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib'
+  sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib'
+  hardcode_into_libs=no
   ;;
   ;;
 
 
 hpux9* | hpux10* | hpux11*)
 hpux9* | hpux10* | hpux11*)
@@ -2963,6 +2979,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   dynamic_linker='GNU/Linux ld.so'
   dynamic_linker='GNU/Linux ld.so'
   ;;
   ;;
 
 
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
 netbsd*)
 netbsd*)
   version_type=sunos
   version_type=sunos
   need_lib_prefix=no
   need_lib_prefix=no
@@ -2981,6 +3009,18 @@ netbsd*)
   hardcode_into_libs=yes
   hardcode_into_libs=yes
   ;;
   ;;
 
 
+*-mlibc)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  dynamic_linker='mlibc ld.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
 newsos6)
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
   version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
   library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
@@ -3060,6 +3100,17 @@ rdos*)
   dynamic_linker=no
   dynamic_linker=no
   ;;
   ;;
 
 
+serenity*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  dynamic_linker='SerenityOS LibELF'
+  ;;
+
 solaris*)
 solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_lib_prefix=no
@@ -3157,6 +3208,21 @@ uts4*)
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_var=LD_LIBRARY_PATH
   ;;
   ;;
 
 
+emscripten*)
+  version_type=none
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext'
+  soname_spec='$libname$release$shared_ext'
+  finish_cmds=
+  dynamic_linker="Emscripten linker"
+  _LT_COMPILER_PIC($1)='-fPIC'
+  _LT_TAGVAR(archive_cmds, $1)='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib'
+  _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym'
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(no_undefined_flag, $1)=
+  ;;
+
 *)
 *)
   dynamic_linker=no
   dynamic_linker=no
   ;;
   ;;
@@ -3621,7 +3687,11 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   lt_cv_deplibs_check_method=pass_all
   lt_cv_deplibs_check_method=pass_all
   ;;
   ;;
 
 
-netbsd*)
+*-mlibc)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
   else
   else
@@ -3655,6 +3725,10 @@ rdos*)
   lt_cv_deplibs_check_method=pass_all
   lt_cv_deplibs_check_method=pass_all
   ;;
   ;;
 
 
+serenity*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
 solaris*)
 solaris*)
   lt_cv_deplibs_check_method=pass_all
   lt_cv_deplibs_check_method=pass_all
   ;;
   ;;
@@ -4127,7 +4201,8 @@ _LT_EOF
   if AC_TRY_EVAL(ac_compile); then
   if AC_TRY_EVAL(ac_compile); then
     # Now try to grab the symbols.
     # Now try to grab the symbols.
     nlist=conftest.nm
     nlist=conftest.nm
-    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
       if sort "$nlist" | uniq > "$nlist"T; then
 	mv -f "$nlist"T "$nlist"
 	mv -f "$nlist"T "$nlist"
@@ -4499,7 +4574,9 @@ m4_if([$1], [CXX], [
 	    ;;
 	    ;;
 	esac
 	esac
 	;;
 	;;
-      netbsd*)
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *-mlibc)
 	;;
 	;;
       *qnx* | *nto*)
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4529,6 +4606,8 @@ m4_if([$1], [CXX], [
 	;;
 	;;
       psos*)
       psos*)
 	;;
 	;;
+      serenity*)
+        ;;
       solaris*)
       solaris*)
 	case $cc_basename in
 	case $cc_basename in
 	  CC* | sunCC*)
 	  CC* | sunCC*)
@@ -4767,7 +4846,7 @@ m4_if([$1], [CXX], [
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
         ;;
         ;;
-      *flang* | ftn)
+      *flang* | ftn | f18* | f95*)
         # Flang compiler.
         # Flang compiler.
 	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
@@ -4855,6 +4934,12 @@ m4_if([$1], [CXX], [
       _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       ;;
       ;;
 
 
+    *-mlibc)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+      ;;
+
     *nto* | *qnx*)
     *nto* | *qnx*)
       # QNX uses GNU C++, but need to define -shared option too, otherwise
       # QNX uses GNU C++, but need to define -shared option too, otherwise
       # it will coredump.
       # it will coredump.
@@ -4871,6 +4956,9 @@ m4_if([$1], [CXX], [
       _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
       _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
       ;;
       ;;
 
 
+    serenity*)
+      ;;
+
     solaris*)
     solaris*)
       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
       _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
@@ -5076,9 +5164,6 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
     # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
     with_gnu_ld=yes
     with_gnu_ld=yes
     ;;
     ;;
-  openbsd*)
-    with_gnu_ld=no
-    ;;
   esac
   esac
 
 
   _LT_TAGVAR(ld_shlibs, $1)=yes
   _LT_TAGVAR(ld_shlibs, $1)=yes
@@ -5189,6 +5274,7 @@ _LT_EOF
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
       _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
       _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
       _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
       _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      _LT_TAGVAR(file_list_spec, $1)='@'
 
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
         _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
         _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
@@ -5208,7 +5294,7 @@ _LT_EOF
 
 
     haiku*)
     haiku*)
       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=no
       ;;
       ;;
 
 
     os2*)
     os2*)
@@ -5314,6 +5400,7 @@ _LT_EOF
 
 
 	case $cc_basename in
 	case $cc_basename in
 	tcc*)
 	tcc*)
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
 	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
 	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
 	  ;;
 	  ;;
 	xlf* | bgf* | bgxlf* | mpixlf*)
 	xlf* | bgf* | bgxlf* | mpixlf*)
@@ -5334,7 +5421,12 @@ _LT_EOF
       fi
       fi
       ;;
       ;;
 
 
-    netbsd*)
+    *-mlibc)
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
 	wlarc=
@@ -5653,14 +5745,14 @@ _LT_EOF
 	# Tell ltmain to make .dll files, not .so files.
 	# Tell ltmain to make .dll files, not .so files.
 	shrext_cmds=.dll
 	shrext_cmds=.dll
 	# FIXME: Setting linknames here is a bad hack.
 	# FIXME: Setting linknames here is a bad hack.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -Fe $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	_LT_TAGVAR(archive_cmds, $1)='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
 	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
 	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
             cp "$export_symbols" "$output_objdir/$soname.def";
             cp "$export_symbols" "$output_objdir/$soname.def";
             echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
             echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
           else
           else
             $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
             $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
           fi~
           fi~
-          $CC -Fe $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+          $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
           linknames='
           linknames='
 	# The linker will not automatically build a static lib if we build a DLL.
 	# The linker will not automatically build a static lib if we build a DLL.
 	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
@@ -5872,11 +5964,15 @@ _LT_EOF
 	# Fabrice Bellard et al's Tiny C Compiler
 	# Fabrice Bellard et al's Tiny C Compiler
 	_LT_TAGVAR(ld_shlibs, $1)=yes
 	_LT_TAGVAR(ld_shlibs, $1)=yes
 	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
 	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
 	;;
 	;;
       esac
       esac
       ;;
       ;;
 
 
-    netbsd*)
+    *-mlibc)
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
       else
@@ -5977,6 +6073,9 @@ _LT_EOF
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       ;;
       ;;
 
 
+    serenity*)
+      ;;
+
     solaris*)
     solaris*)
       _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
       _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
       if test yes = "$GCC"; then
       if test yes = "$GCC"; then
@@ -6502,7 +6601,7 @@ if test yes != "$_lt_caught_CXX_error"; then
       # Commands to make compiler produce verbose output that lists
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'
 
 
     else
     else
       GXX=no
       GXX=no
@@ -6764,6 +6863,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  _LT_TAGVAR(always_export_symbols, $1)=no
 	  _LT_TAGVAR(always_export_symbols, $1)=no
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
 
 
 	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
 	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
 	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
@@ -6851,7 +6951,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 
 
       haiku*)
       haiku*)
         _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
         _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(link_all_deplibs, $1)=no
         ;;
         ;;
 
 
       hpux9*)
       hpux9*)
@@ -6943,7 +7043,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # from the output so that they don't get included in the library
 	    # dependencies.
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " [[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	    ;;
           *)
           *)
 	    if test yes = "$GXX"; then
 	    if test yes = "$GXX"; then
@@ -7175,6 +7275,10 @@ if test yes != "$_lt_caught_CXX_error"; then
 	esac
 	esac
 	;;
 	;;
 
 
+      *-mlibc)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
       netbsd*)
       netbsd*)
         if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
         if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
 	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
@@ -7282,7 +7386,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	      # Commands to make compiler produce verbose output that lists
 	      # Commands to make compiler produce verbose output that lists
 	      # what "hidden" libraries, object files and flags are used when
 	      # what "hidden" libraries, object files and flags are used when
 	      # linking a shared library.
 	      # linking a shared library.
-	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'
 
 
 	    else
 	    else
 	      # FIXME: insert proper C++ library support
 	      # FIXME: insert proper C++ library support
@@ -7297,6 +7401,9 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=no
         _LT_TAGVAR(ld_shlibs, $1)=no
         ;;
         ;;
 
 
+      serenity*)
+        ;;
+
       sunos4*)
       sunos4*)
         case $cc_basename in
         case $cc_basename in
           CC*)
           CC*)
@@ -7366,7 +7473,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        # Commands to make compiler produce verbose output that lists
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'
 	      else
 	      else
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # platform.
 	        # platform.
@@ -7377,7 +7484,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        # Commands to make compiler produce verbose output that lists
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'
 	      fi
 	      fi
 
 
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'

+ 5 - 5
libs/expat/m4/ltversion.m4

@@ -10,15 +10,15 @@
 
 
 # @configure_input@
 # @configure_input@
 
 
-# serial 4392 ltversion.m4
+# serial 4441 ltversion.m4
 # This file is part of GNU Libtool
 # This file is part of GNU Libtool
 
 
-m4_define([LT_PACKAGE_VERSION], [2.5.3])
-m4_define([LT_PACKAGE_REVISION], [2.5.3])
+m4_define([LT_PACKAGE_VERSION], [2.5.4])
+m4_define([LT_PACKAGE_REVISION], [2.5.4])
 
 
 AC_DEFUN([LTVERSION_VERSION],
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.5.3'
-macro_revision='2.5.3'
+[macro_version='2.5.4'
+macro_revision='2.5.4'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 _LT_DECL(, macro_revision, 0)
 ])
 ])

+ 4 - 1
libs/expat/tests/acc_tests.c

@@ -360,13 +360,16 @@ END_TEST
 START_TEST(test_helper_unsigned_char_to_printable) {
 START_TEST(test_helper_unsigned_char_to_printable) {
   // Smoke test
   // Smoke test
   unsigned char uc = 0;
   unsigned char uc = 0;
-  for (; uc < (unsigned char)-1; uc++) {
+  for (;; uc++) {
     set_subtest("char %u", (unsigned)uc);
     set_subtest("char %u", (unsigned)uc);
     const char *const printable = unsignedCharToPrintable(uc);
     const char *const printable = unsignedCharToPrintable(uc);
     if (printable == NULL)
     if (printable == NULL)
       fail("unsignedCharToPrintable returned NULL");
       fail("unsignedCharToPrintable returned NULL");
     else if (strlen(printable) < (size_t)1)
     else if (strlen(printable) < (size_t)1)
       fail("unsignedCharToPrintable returned empty string");
       fail("unsignedCharToPrintable returned empty string");
+    if (uc == (unsigned char)-1) {
+      break;
+    }
   }
   }
 
 
   // Two concrete samples
   // Two concrete samples

+ 27 - 0
libs/expat/tests/alloc_tests.c

@@ -19,6 +19,7 @@
    Copyright (c) 2020      Tim Gates <[email protected]>
    Copyright (c) 2020      Tim Gates <[email protected]>
    Copyright (c) 2021      Donghee Na <[email protected]>
    Copyright (c) 2021      Donghee Na <[email protected]>
    Copyright (c) 2023      Sony Corporation / Snild Dolkow <[email protected]>
    Copyright (c) 2023      Sony Corporation / Snild Dolkow <[email protected]>
+   Copyright (c) 2025      Berkay Eren Ürün <[email protected]>
    Licensed under the MIT license:
    Licensed under the MIT license:
 
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -450,6 +451,31 @@ START_TEST(test_alloc_internal_entity) {
 }
 }
 END_TEST
 END_TEST
 
 
+START_TEST(test_alloc_parameter_entity) {
+  const char *text = "<!DOCTYPE foo ["
+                     "<!ENTITY % param1 \"<!ENTITY internal 'some_text'>\">"
+                     "%param1;"
+                     "]> <foo>&internal;content</foo>";
+  int i;
+  const int alloc_test_max_repeats = 30;
+
+  for (i = 0; i < alloc_test_max_repeats; i++) {
+    g_allocation_count = i;
+    XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+    if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
+        != XML_STATUS_ERROR)
+      break;
+    alloc_teardown();
+    alloc_setup();
+  }
+  g_allocation_count = -1;
+  if (i == 0)
+    fail("Parameter entity processed despite duff allocator");
+  if (i == alloc_test_max_repeats)
+    fail("Parameter entity not processed at max allocation count");
+}
+END_TEST
+
 /* Test the robustness against allocation failure of element handling
 /* Test the robustness against allocation failure of element handling
  * Based on test_dtd_default_handling().
  * Based on test_dtd_default_handling().
  */
  */
@@ -2079,6 +2105,7 @@ make_alloc_test_case(Suite *s) {
   tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_external_entity);
   tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_external_entity);
   tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_ext_entity_set_encoding);
   tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_ext_entity_set_encoding);
   tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_internal_entity);
   tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_internal_entity);
+  tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_parameter_entity);
   tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_dtd_default_handling);
   tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_dtd_default_handling);
   tcase_add_test(tc_alloc, test_alloc_explicit_encoding);
   tcase_add_test(tc_alloc, test_alloc_explicit_encoding);
   tcase_add_test(tc_alloc, test_alloc_set_base);
   tcase_add_test(tc_alloc, test_alloc_set_base);

+ 322 - 9
libs/expat/tests/basic_tests.c

@@ -10,7 +10,7 @@
    Copyright (c) 2003      Greg Stein <[email protected]>
    Copyright (c) 2003      Greg Stein <[email protected]>
    Copyright (c) 2005-2007 Steven Solie <[email protected]>
    Copyright (c) 2005-2007 Steven Solie <[email protected]>
    Copyright (c) 2005-2012 Karl Waclawek <[email protected]>
    Copyright (c) 2005-2012 Karl Waclawek <[email protected]>
-   Copyright (c) 2016-2024 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2025 Sebastian Pipping <[email protected]>
    Copyright (c) 2017-2022 Rhodri James <[email protected]>
    Copyright (c) 2017-2022 Rhodri James <[email protected]>
    Copyright (c) 2017      Joe Orton <[email protected]>
    Copyright (c) 2017      Joe Orton <[email protected]>
    Copyright (c) 2017      José Gutiérrez de la Concha <[email protected]>
    Copyright (c) 2017      José Gutiérrez de la Concha <[email protected]>
@@ -19,6 +19,7 @@
    Copyright (c) 2020      Tim Gates <[email protected]>
    Copyright (c) 2020      Tim Gates <[email protected]>
    Copyright (c) 2021      Donghee Na <[email protected]>
    Copyright (c) 2021      Donghee Na <[email protected]>
    Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <[email protected]>
    Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <[email protected]>
+   Copyright (c) 2024-2025 Berkay Eren Ürün <[email protected]>
    Licensed under the MIT license:
    Licensed under the MIT license:
 
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -1191,6 +1192,22 @@ START_TEST(test_not_standalone_handler_accept) {
 }
 }
 END_TEST
 END_TEST
 
 
+START_TEST(test_entity_start_tag_level_greater_than_one) {
+  const char *const text = "<!DOCTYPE t1 [\n"
+                           "  <!ENTITY e1 'hello'>\n"
+                           "]>\n"
+                           "<t1>\n"
+                           "  <t2>&e1;</t2>\n"
+                           "</t1>\n";
+
+  XML_Parser parser = XML_ParserCreate(NULL);
+  assert_true(_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text),
+                                      /*isFinal*/ XML_TRUE)
+              == XML_STATUS_OK);
+  XML_ParserFree(parser);
+}
+END_TEST
+
 START_TEST(test_wfc_no_recursive_entity_refs) {
 START_TEST(test_wfc_no_recursive_entity_refs) {
   const char *text = "<!DOCTYPE doc [\n"
   const char *text = "<!DOCTYPE doc [\n"
                      "  <!ENTITY entity '&#38;entity;'>\n"
                      "  <!ENTITY entity '&#38;entity;'>\n"
@@ -1202,6 +1219,93 @@ START_TEST(test_wfc_no_recursive_entity_refs) {
 }
 }
 END_TEST
 END_TEST
 
 
+START_TEST(test_no_indirectly_recursive_entity_refs) {
+  struct TestCase {
+    const char *doc;
+    bool usesParameterEntities;
+  };
+
+  const struct TestCase cases[] = {
+      // general entity + character data
+      {"<!DOCTYPE a [\n"
+       "  <!ENTITY e1 '&e2;'>\n"
+       "  <!ENTITY e2 '&e1;'>\n"
+       "]><a>&e2;</a>\n",
+       false},
+
+      // general entity + attribute value
+      {"<!DOCTYPE a [\n"
+       "  <!ENTITY e1 '&e2;'>\n"
+       "  <!ENTITY e2 '&e1;'>\n"
+       "]><a k1='&e2;' />\n",
+       false},
+
+      // parameter entity
+      {"<!DOCTYPE doc [\n"
+       "  <!ENTITY % p1 '&#37;p2;'>\n"
+       "  <!ENTITY % p2 '&#37;p1;'>\n"
+       "  <!ENTITY % define_g \"<!ENTITY g '&#37;p2;'>\">\n"
+       "  %define_g;\n"
+       "]>\n"
+       "<doc/>\n",
+       true},
+  };
+  const XML_Bool reset_or_not[] = {XML_TRUE, XML_FALSE};
+
+  for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
+    for (size_t j = 0; j < sizeof(reset_or_not) / sizeof(reset_or_not[0]);
+         j++) {
+      const XML_Bool reset_wanted = reset_or_not[j];
+      const char *const doc = cases[i].doc;
+      const bool usesParameterEntities = cases[i].usesParameterEntities;
+
+      set_subtest("[%i,reset=%i] %s", (int)i, (int)j, doc);
+
+#ifdef XML_DTD // both GE and DTD
+      const bool rejection_expected = true;
+#elif XML_GE == 1 // GE but not DTD
+      const bool rejection_expected = ! usesParameterEntities;
+#else             // neither DTD nor GE
+      const bool rejection_expected = false;
+#endif
+
+      XML_Parser parser = XML_ParserCreate(NULL);
+
+#ifdef XML_DTD
+      if (usesParameterEntities) {
+        assert_true(
+            XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS)
+            == 1);
+      }
+#else
+      UNUSED_P(usesParameterEntities);
+#endif // XML_DTD
+
+      const enum XML_Status status
+          = _XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc),
+                                    /*isFinal*/ XML_TRUE);
+
+      if (rejection_expected) {
+        assert_true(status == XML_STATUS_ERROR);
+        assert_true(XML_GetErrorCode(parser) == XML_ERROR_RECURSIVE_ENTITY_REF);
+      } else {
+        assert_true(status == XML_STATUS_OK);
+      }
+
+      if (reset_wanted) {
+        // This covers free'ing of (eventually) all three open entity lists by
+        // XML_ParserReset.
+        XML_ParserReset(parser, NULL);
+      }
+
+      // This covers free'ing of (eventually) all three open entity lists by
+      // XML_ParserFree (unless XML_ParserReset has already done that above).
+      XML_ParserFree(parser);
+    }
+  }
+}
+END_TEST
+
 START_TEST(test_recursive_external_parameter_entity_2) {
 START_TEST(test_recursive_external_parameter_entity_2) {
   struct TestCase {
   struct TestCase {
     const char *doc;
     const char *doc;
@@ -1417,7 +1521,9 @@ START_TEST(test_suspend_parser_between_char_data_calls) {
 
 
   XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler);
   XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler);
   g_resumable = XML_TRUE;
   g_resumable = XML_TRUE;
-  if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
+  // can't use SINGLE_BYTES here, because it'll return early on suspension, and
+  // we won't know exactly how much input we actually managed to give Expat.
+  if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
       != XML_STATUS_SUSPENDED)
       != XML_STATUS_SUSPENDED)
     xml_failure(g_parser);
     xml_failure(g_parser);
   if (XML_GetErrorCode(g_parser) != XML_ERROR_NONE)
   if (XML_GetErrorCode(g_parser) != XML_ERROR_NONE)
@@ -1446,7 +1552,9 @@ START_TEST(test_repeated_stop_parser_between_char_data_calls) {
   XML_SetCharacterDataHandler(g_parser, parser_stop_character_handler);
   XML_SetCharacterDataHandler(g_parser, parser_stop_character_handler);
   g_resumable = XML_TRUE;
   g_resumable = XML_TRUE;
   g_abortable = XML_FALSE;
   g_abortable = XML_FALSE;
-  if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
+  // can't use SINGLE_BYTES here, because it'll return early on suspension, and
+  // we won't know exactly how much input we actually managed to give Expat.
+  if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
       != XML_STATUS_SUSPENDED)
       != XML_STATUS_SUSPENDED)
     fail("Failed to double-suspend parser");
     fail("Failed to double-suspend parser");
 
 
@@ -1830,12 +1938,19 @@ END_TEST
 
 
 /* Test suspending the parser in cdata handler */
 /* Test suspending the parser in cdata handler */
 START_TEST(test_suspend_parser_between_cdata_calls) {
 START_TEST(test_suspend_parser_between_cdata_calls) {
+  if (g_chunkSize != 0) {
+    // this test does not use SINGLE_BYTES, because of suspension
+    return;
+  }
+
   const char *text = long_cdata_text;
   const char *text = long_cdata_text;
   enum XML_Status result;
   enum XML_Status result;
 
 
   XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler);
   XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler);
   g_resumable = XML_TRUE;
   g_resumable = XML_TRUE;
-  result = _XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE);
+  // can't use SINGLE_BYTES here, because it'll return early on suspension, and
+  // we won't know exactly how much input we actually managed to give Expat.
+  result = XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE);
   if (result != XML_STATUS_SUSPENDED) {
   if (result != XML_STATUS_SUSPENDED) {
     if (result == XML_STATUS_ERROR)
     if (result == XML_STATUS_ERROR)
       xml_failure(g_parser);
       xml_failure(g_parser);
@@ -2378,6 +2493,11 @@ END_TEST
  * entity.  Exercises some obscure code in XML_ParserReset().
  * entity.  Exercises some obscure code in XML_ParserReset().
  */
  */
 START_TEST(test_reset_in_entity) {
 START_TEST(test_reset_in_entity) {
+  if (g_chunkSize != 0) {
+    // this test does not use SINGLE_BYTES, because of suspension
+    return;
+  }
+
   const char *text = "<!DOCTYPE doc [\n"
   const char *text = "<!DOCTYPE doc [\n"
                      "<!ENTITY wombat 'wom'>\n"
                      "<!ENTITY wombat 'wom'>\n"
                      "<!ENTITY entity 'hi &wom; there'>\n"
                      "<!ENTITY entity 'hi &wom; there'>\n"
@@ -2387,7 +2507,9 @@ START_TEST(test_reset_in_entity) {
 
 
   g_resumable = XML_TRUE;
   g_resumable = XML_TRUE;
   XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler);
   XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler);
-  if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
+  // can't use SINGLE_BYTES here, because it'll return early on suspension, and
+  // we won't know exactly how much input we actually managed to give Expat.
+  if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
       == XML_STATUS_ERROR)
       == XML_STATUS_ERROR)
     xml_failure(g_parser);
     xml_failure(g_parser);
   XML_GetParsingStatus(g_parser, &status);
   XML_GetParsingStatus(g_parser, &status);
@@ -3634,7 +3756,9 @@ START_TEST(test_suspend_xdecl) {
   XML_SetXmlDeclHandler(g_parser, entity_suspending_xdecl_handler);
   XML_SetXmlDeclHandler(g_parser, entity_suspending_xdecl_handler);
   XML_SetUserData(g_parser, g_parser);
   XML_SetUserData(g_parser, g_parser);
   g_resumable = XML_TRUE;
   g_resumable = XML_TRUE;
-  if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
+  // can't use SINGLE_BYTES here, because it'll return early on suspension, and
+  // we won't know exactly how much input we actually managed to give Expat.
+  if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
       != XML_STATUS_SUSPENDED)
       != XML_STATUS_SUSPENDED)
     xml_failure(g_parser);
     xml_failure(g_parser);
   if (XML_GetErrorCode(g_parser) != XML_ERROR_NONE)
   if (XML_GetErrorCode(g_parser) != XML_ERROR_NONE)
@@ -3830,13 +3954,20 @@ END_TEST
 
 
 /* Test syntax error is caught at parse resumption */
 /* Test syntax error is caught at parse resumption */
 START_TEST(test_resume_entity_with_syntax_error) {
 START_TEST(test_resume_entity_with_syntax_error) {
+  if (g_chunkSize != 0) {
+    // this test does not use SINGLE_BYTES, because of suspension
+    return;
+  }
+
   const char *text = "<!DOCTYPE doc [\n"
   const char *text = "<!DOCTYPE doc [\n"
                      "<!ENTITY foo '<suspend>Hi</wombat>'>\n"
                      "<!ENTITY foo '<suspend>Hi</wombat>'>\n"
                      "]>\n"
                      "]>\n"
                      "<doc>&foo;</doc>\n";
                      "<doc>&foo;</doc>\n";
 
 
   XML_SetStartElementHandler(g_parser, start_element_suspender);
   XML_SetStartElementHandler(g_parser, start_element_suspender);
-  if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
+  // can't use SINGLE_BYTES here, because it'll return early on suspension, and
+  // we won't know exactly how much input we actually managed to give Expat.
+  if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
       != XML_STATUS_SUSPENDED)
       != XML_STATUS_SUSPENDED)
     xml_failure(g_parser);
     xml_failure(g_parser);
   if (XML_ResumeParser(g_parser) != XML_STATUS_ERROR)
   if (XML_ResumeParser(g_parser) != XML_STATUS_ERROR)
@@ -3960,7 +4091,7 @@ START_TEST(test_skipped_null_loaded_ext_entity) {
       = {"<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n"
       = {"<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n"
          "<!ENTITY % pe2 '%pe1;'>\n"
          "<!ENTITY % pe2 '%pe1;'>\n"
          "%pe2;\n",
          "%pe2;\n",
-         external_entity_null_loader};
+         external_entity_null_loader, NULL};
 
 
   XML_SetUserData(g_parser, &test_data);
   XML_SetUserData(g_parser, &test_data);
   XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
@@ -3978,7 +4109,7 @@ START_TEST(test_skipped_unloaded_ext_entity) {
       = {"<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n"
       = {"<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n"
          "<!ENTITY % pe2 '%pe1;'>\n"
          "<!ENTITY % pe2 '%pe1;'>\n"
          "%pe2;\n",
          "%pe2;\n",
-         NULL};
+         NULL, NULL};
 
 
   XML_SetUserData(g_parser, &test_data);
   XML_SetUserData(g_parser, &test_data);
   XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
@@ -5278,6 +5409,151 @@ START_TEST(test_pool_integrity_with_unfinished_attr) {
 }
 }
 END_TEST
 END_TEST
 
 
+/* Test a possible early return location in internalEntityProcessor */
+START_TEST(test_entity_ref_no_elements) {
+  const char *const text = "<!DOCTYPE foo [\n"
+                           "<!ENTITY e1 \"test\">\n"
+                           "]> <foo>&e1;"; // intentionally missing newline
+
+  XML_Parser parser = XML_ParserCreate(NULL);
+  assert_true(_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
+              == XML_STATUS_ERROR);
+  assert_true(XML_GetErrorCode(parser) == XML_ERROR_NO_ELEMENTS);
+  XML_ParserFree(parser);
+}
+END_TEST
+
+/* Tests if chained entity references lead to unbounded recursion */
+START_TEST(test_deep_nested_entity) {
+  const size_t N_LINES = 60000;
+  const size_t SIZE_PER_LINE = 50;
+
+  char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
+  if (text == NULL) {
+    fail("malloc failed");
+  }
+
+  char *textPtr = text;
+
+  // Create the XML
+  textPtr += snprintf(textPtr, SIZE_PER_LINE,
+                      "<!DOCTYPE foo [\n"
+                      "	<!ENTITY s0 'deepText'>\n");
+
+  for (size_t i = 1; i < N_LINES; ++i) {
+    textPtr += snprintf(textPtr, SIZE_PER_LINE, "  <!ENTITY s%lu '&s%lu;'>\n",
+                        (long unsigned)i, (long unsigned)(i - 1));
+  }
+
+  snprintf(textPtr, SIZE_PER_LINE, "]> <foo>&s%lu;</foo>\n",
+           (long unsigned)(N_LINES - 1));
+
+  const XML_Char *const expected = XCS("deepText");
+
+  CharData storage;
+  CharData_Init(&storage);
+
+  XML_Parser parser = XML_ParserCreate(NULL);
+
+  XML_SetCharacterDataHandler(parser, accumulate_characters);
+  XML_SetUserData(parser, &storage);
+
+  if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
+      == XML_STATUS_ERROR)
+    xml_failure(parser);
+
+  CharData_CheckXMLChars(&storage, expected);
+  XML_ParserFree(parser);
+  free(text);
+}
+END_TEST
+
+/* Tests if chained entity references in attributes
+lead to unbounded recursion */
+START_TEST(test_deep_nested_attribute_entity) {
+  const size_t N_LINES = 60000;
+  const size_t SIZE_PER_LINE = 100;
+
+  char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
+  if (text == NULL) {
+    fail("malloc failed");
+  }
+
+  char *textPtr = text;
+
+  // Create the XML
+  textPtr += snprintf(textPtr, SIZE_PER_LINE,
+                      "<!DOCTYPE foo [\n"
+                      "	<!ENTITY s0 'deepText'>\n");
+
+  for (size_t i = 1; i < N_LINES; ++i) {
+    textPtr += snprintf(textPtr, SIZE_PER_LINE, "  <!ENTITY s%lu '&s%lu;'>\n",
+                        (long unsigned)i, (long unsigned)(i - 1));
+  }
+
+  snprintf(textPtr, SIZE_PER_LINE, "]> <foo name='&s%lu;'>mainText</foo>\n",
+           (long unsigned)(N_LINES - 1));
+
+  AttrInfo doc_info[] = {{XCS("name"), XCS("deepText")}, {NULL, NULL}};
+  ElementInfo info[] = {{XCS("foo"), 1, NULL, NULL}, {NULL, 0, NULL, NULL}};
+  info[0].attributes = doc_info;
+
+  XML_Parser parser = XML_ParserCreate(NULL);
+  ParserAndElementInfo parserPlusElemenInfo = {parser, info};
+
+  XML_SetStartElementHandler(parser, counting_start_element_handler);
+  XML_SetUserData(parser, &parserPlusElemenInfo);
+
+  if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
+      == XML_STATUS_ERROR)
+    xml_failure(parser);
+
+  XML_ParserFree(parser);
+  free(text);
+}
+END_TEST
+
+START_TEST(test_deep_nested_entity_delayed_interpretation) {
+  const size_t N_LINES = 70000;
+  const size_t SIZE_PER_LINE = 100;
+
+  char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
+  if (text == NULL) {
+    fail("malloc failed");
+  }
+
+  char *textPtr = text;
+
+  // Create the XML
+  textPtr += snprintf(textPtr, SIZE_PER_LINE,
+                      "<!DOCTYPE foo [\n"
+                      "	<!ENTITY %% s0 'deepText'>\n");
+
+  for (size_t i = 1; i < N_LINES; ++i) {
+    textPtr += snprintf(textPtr, SIZE_PER_LINE,
+                        "  <!ENTITY %% s%lu '&#37;s%lu;'>\n", (long unsigned)i,
+                        (long unsigned)(i - 1));
+  }
+
+  snprintf(textPtr, SIZE_PER_LINE,
+           "  <!ENTITY %% define_g \"<!ENTITY g '&#37;s%lu;'>\">\n"
+           "  %%define_g;\n"
+           "]>\n"
+           "<foo/>\n",
+           (long unsigned)(N_LINES - 1));
+
+  XML_Parser parser = XML_ParserCreate(NULL);
+
+  XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+  if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
+      == XML_STATUS_ERROR)
+    xml_failure(parser);
+
+  XML_ParserFree(parser);
+  free(text);
+}
+END_TEST
+
 START_TEST(test_nested_entity_suspend) {
 START_TEST(test_nested_entity_suspend) {
   const char *const text = "<!DOCTYPE a [\n"
   const char *const text = "<!DOCTYPE a [\n"
                            "  <!ENTITY e1 '<!--e1-->'>\n"
                            "  <!ENTITY e1 '<!--e1-->'>\n"
@@ -5308,6 +5584,35 @@ START_TEST(test_nested_entity_suspend) {
 }
 }
 END_TEST
 END_TEST
 
 
+START_TEST(test_nested_entity_suspend_2) {
+  const char *const text = "<!DOCTYPE doc [\n"
+                           "  <!ENTITY ge1 'head1Ztail1'>\n"
+                           "  <!ENTITY ge2 'head2&ge1;tail2'>\n"
+                           "  <!ENTITY ge3 'head3&ge2;tail3'>\n"
+                           "]>\n"
+                           "<doc>&ge3;</doc>";
+  const XML_Char *const expected = XCS("head3") XCS("head2") XCS("head1")
+      XCS("Z") XCS("tail1") XCS("tail2") XCS("tail3");
+  CharData storage;
+  CharData_Init(&storage);
+  XML_Parser parser = XML_ParserCreate(NULL);
+  ParserPlusStorage parserPlusStorage = {parser, &storage};
+
+  XML_SetCharacterDataHandler(parser, accumulate_char_data_and_suspend);
+  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
+
 /* Regression test for quadratic parsing on large tokens */
 /* Regression test for quadratic parsing on large tokens */
 START_TEST(test_big_tokens_scale_linearly) {
 START_TEST(test_big_tokens_scale_linearly) {
   const struct {
   const struct {
@@ -5968,7 +6273,9 @@ make_basic_test_case(Suite *s) {
   tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
   tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
   tcase_add_test(tc_basic, test_not_standalone_handler_reject);
   tcase_add_test(tc_basic, test_not_standalone_handler_reject);
   tcase_add_test(tc_basic, test_not_standalone_handler_accept);
   tcase_add_test(tc_basic, test_not_standalone_handler_accept);
+  tcase_add_test(tc_basic, test_entity_start_tag_level_greater_than_one);
   tcase_add_test__if_xml_ge(tc_basic, test_wfc_no_recursive_entity_refs);
   tcase_add_test__if_xml_ge(tc_basic, test_wfc_no_recursive_entity_refs);
+  tcase_add_test(tc_basic, test_no_indirectly_recursive_entity_refs);
   tcase_add_test__ifdef_xml_dtd(tc_basic, test_ext_entity_invalid_parse);
   tcase_add_test__ifdef_xml_dtd(tc_basic, test_ext_entity_invalid_parse);
   tcase_add_test__if_xml_ge(tc_basic, test_dtd_default_handling);
   tcase_add_test__if_xml_ge(tc_basic, test_dtd_default_handling);
   tcase_add_test(tc_basic, test_dtd_attr_handling);
   tcase_add_test(tc_basic, test_dtd_attr_handling);
@@ -6147,7 +6454,13 @@ make_basic_test_case(Suite *s) {
   tcase_add_test(tc_basic, test_empty_element_abort);
   tcase_add_test(tc_basic, test_empty_element_abort);
   tcase_add_test__ifdef_xml_dtd(tc_basic,
   tcase_add_test__ifdef_xml_dtd(tc_basic,
                                 test_pool_integrity_with_unfinished_attr);
                                 test_pool_integrity_with_unfinished_attr);
+  tcase_add_test__if_xml_ge(tc_basic, test_entity_ref_no_elements);
+  tcase_add_test__if_xml_ge(tc_basic, test_deep_nested_entity);
+  tcase_add_test__if_xml_ge(tc_basic, test_deep_nested_attribute_entity);
+  tcase_add_test__if_xml_ge(tc_basic,
+                            test_deep_nested_entity_delayed_interpretation);
   tcase_add_test__if_xml_ge(tc_basic, test_nested_entity_suspend);
   tcase_add_test__if_xml_ge(tc_basic, test_nested_entity_suspend);
+  tcase_add_test__if_xml_ge(tc_basic, test_nested_entity_suspend_2);
   tcase_add_test(tc_basic, test_big_tokens_scale_linearly);
   tcase_add_test(tc_basic, test_big_tokens_scale_linearly);
   tcase_add_test(tc_basic, test_set_reparse_deferral);
   tcase_add_test(tc_basic, test_set_reparse_deferral);
   tcase_add_test(tc_basic, test_reparse_deferral_is_inherited);
   tcase_add_test(tc_basic, test_reparse_deferral_is_inherited);

+ 43 - 17
libs/expat/tests/benchmark/benchmark.c

@@ -8,7 +8,7 @@
 
 
    Copyright (c) 2003-2006 Karl Waclawek <[email protected]>
    Copyright (c) 2003-2006 Karl Waclawek <[email protected]>
    Copyright (c) 2005-2007 Steven Solie <[email protected]>
    Copyright (c) 2005-2007 Steven Solie <[email protected]>
-   Copyright (c) 2017-2023 Sebastian Pipping <[email protected]>
+   Copyright (c) 2017-2025 Sebastian Pipping <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Licensed under the MIT license:
    Licensed under the MIT license:
 
 
@@ -32,10 +32,18 @@
    USE OR OTHER DEALINGS IN THE SOFTWARE.
    USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 */
 
 
+#define _POSIX_C_SOURCE 1 // fdopen
+
+#if defined(_MSC_VER)
+#  include <io.h> // _open, _close
+#else
+#  include <unistd.h> // close
+#endif
+
+#include <fcntl.h> // open
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <assert.h>
 #include <assert.h>
 #include <stddef.h> // ptrdiff_t
 #include <stddef.h> // ptrdiff_t
-#include <stdlib.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <time.h>
 #include <time.h>
 #include "expat.h"
 #include "expat.h"
@@ -52,17 +60,18 @@
 #  define XML_FMT_STR "s"
 #  define XML_FMT_STR "s"
 #endif
 #endif
 
 
-static void
+static int
 usage(const char *prog, int rc) {
 usage(const char *prog, int rc) {
   fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog);
   fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog);
-  exit(rc);
+  return rc;
 }
 }
 
 
 int
 int
 main(int argc, char *argv[]) {
 main(int argc, char *argv[]) {
   XML_Parser parser;
   XML_Parser parser;
   char *XMLBuf, *XMLBufEnd, *XMLBufPtr;
   char *XMLBuf, *XMLBufEnd, *XMLBufPtr;
-  FILE *fd;
+  int fd;
+  FILE *file;
   struct stat fileAttr;
   struct stat fileAttr;
   int nrOfLoops, bufferSize, i, isFinal;
   int nrOfLoops, bufferSize, i, isFinal;
   size_t fileSize;
   size_t fileSize;
@@ -76,34 +85,51 @@ main(int argc, char *argv[]) {
         ns = 1;
         ns = 1;
         j = 1;
         j = 1;
       } else
       } else
-        usage(argv[0], 1);
+        return usage(argv[0], 1);
     }
     }
   }
   }
 
 
   if (argc != j + 4)
   if (argc != j + 4)
-    usage(argv[0], 1);
+    return usage(argv[0], 1);
 
 
-  if (stat(argv[j + 1], &fileAttr) != 0) {
-    fprintf(stderr, "could not access file '%s'\n", argv[j + 1]);
+  fd = open(argv[j + 1], O_RDONLY);
+  if (fd == -1) {
+    fprintf(stderr, "could not open file '%s'\n", argv[j + 1]);
     return 2;
     return 2;
   }
   }
 
 
-  fd = fopen(argv[j + 1], "r");
-  if (! fd) {
-    fprintf(stderr, "could not open file '%s'\n", argv[j + 1]);
-    exit(2);
+  if (fstat(fd, &fileAttr) != 0) {
+    close(fd);
+    fprintf(stderr, "could not fstat file '%s'\n", argv[j + 1]);
+    return 2;
+  }
+
+  file = fdopen(fd, "r");
+  if (! file) {
+    close(fd);
+    fprintf(stderr, "could not fdopen file '%s'\n", argv[j + 1]);
+    return 2;
   }
   }
 
 
   bufferSize = atoi(argv[j + 2]);
   bufferSize = atoi(argv[j + 2]);
   nrOfLoops = atoi(argv[j + 3]);
   nrOfLoops = atoi(argv[j + 3]);
   if (bufferSize <= 0 || nrOfLoops <= 0) {
   if (bufferSize <= 0 || nrOfLoops <= 0) {
+    fclose(file);
+    close(fd);
     fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n");
     fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n");
-    exit(3);
+    return 3;
   }
   }
 
 
   XMLBuf = malloc(fileAttr.st_size);
   XMLBuf = malloc(fileAttr.st_size);
-  fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, fd);
-  fclose(fd);
+  if (XMLBuf == NULL) {
+    fclose(file);
+    close(fd);
+    fprintf(stderr, "ouf of memory.\n");
+    return 5;
+  }
+  fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, file);
+  fclose(file);
+  close(fd);
 
 
   if (ns)
   if (ns)
     parser = XML_ParserCreateNS(NULL, '!');
     parser = XML_ParserCreateNS(NULL, '!');
@@ -132,7 +158,7 @@ main(int argc, char *argv[]) {
                 XML_GetCurrentColumnNumber(parser));
                 XML_GetCurrentColumnNumber(parser));
         free(XMLBuf);
         free(XMLBuf);
         XML_ParserFree(parser);
         XML_ParserFree(parser);
-        exit(4);
+        return 4;
       }
       }
       XMLBufPtr += bufferSize;
       XMLBufPtr += bufferSize;
     } while (! isFinal);
     } while (! isFinal);

+ 6 - 0
libs/expat/tests/common.c

@@ -202,6 +202,12 @@ _XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len,
     for (; len > chunksize; len -= chunksize, s += chunksize) {
     for (; len > chunksize; len -= chunksize, s += chunksize) {
       enum XML_Status res = XML_Parse(parser, s, chunksize, XML_FALSE);
       enum XML_Status res = XML_Parse(parser, s, chunksize, XML_FALSE);
       if (res != XML_STATUS_OK) {
       if (res != XML_STATUS_OK) {
+        if ((res == XML_STATUS_SUSPENDED) && (len > chunksize)) {
+          fail("Use of function _XML_Parse_SINGLE_BYTES with a chunk size "
+               "greater than 0 (from g_chunkSize) does not work well with "
+               "suspension. Please consider use of plain XML_Parse at this "
+               "place in your test, instead.");
+        }
         return res;
         return res;
       }
       }
     }
     }

+ 23 - 0
libs/expat/tests/handlers.c

@@ -1842,6 +1842,15 @@ element_decl_suspender(void *userData, const XML_Char *name,
   XML_FreeContentModel(g_parser, model);
   XML_FreeContentModel(g_parser, model);
 }
 }
 
 
+void XMLCALL
+suspend_after_element_declaration(void *userData, const XML_Char *name,
+                                  XML_Content *model) {
+  UNUSED_P(name);
+  XML_Parser parser = (XML_Parser)userData;
+  assert_true(XML_StopParser(parser, /*resumable*/ XML_TRUE) == XML_STATUS_OK);
+  XML_FreeContentModel(parser, model);
+}
+
 void XMLCALL
 void XMLCALL
 accumulate_pi_characters(void *userData, const XML_Char *target,
 accumulate_pi_characters(void *userData, const XML_Char *target,
                          const XML_Char *data) {
                          const XML_Char *data) {
@@ -1882,6 +1891,20 @@ accumulate_entity_decl(void *userData, const XML_Char *entityName,
   CharData_AppendXMLChars(storage, XCS("\n"), 1);
   CharData_AppendXMLChars(storage, XCS("\n"), 1);
 }
 }
 
 
+void XMLCALL
+accumulate_char_data_and_suspend(void *userData, const XML_Char *s, int len) {
+  ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData;
+
+  CharData_AppendXMLChars(parserPlusStorage->storage, s, len);
+
+  for (int i = 0; i < len; i++) {
+    if (s[i] == 'Z') {
+      XML_StopParser(parserPlusStorage->parser, /*resumable=*/XML_TRUE);
+      break;
+    }
+  }
+}
+
 void XMLCALL
 void XMLCALL
 accumulate_start_element(void *userData, const XML_Char *name,
 accumulate_start_element(void *userData, const XML_Char *name,
                          const XML_Char **atts) {
                          const XML_Char **atts) {

+ 9 - 0
libs/expat/tests/handlers.h

@@ -325,6 +325,7 @@ extern int XMLCALL external_entity_devaluer(XML_Parser parser,
 typedef struct ext_hdlr_data {
 typedef struct ext_hdlr_data {
   const char *parse_text;
   const char *parse_text;
   XML_ExternalEntityRefHandler handler;
   XML_ExternalEntityRefHandler handler;
+  CharData *storage;
 } ExtHdlrData;
 } ExtHdlrData;
 
 
 extern int XMLCALL external_entity_oneshot_loader(XML_Parser parser,
 extern int XMLCALL external_entity_oneshot_loader(XML_Parser parser,
@@ -557,6 +558,10 @@ extern void XMLCALL suspending_comment_handler(void *userData,
 extern void XMLCALL element_decl_suspender(void *userData, const XML_Char *name,
 extern void XMLCALL element_decl_suspender(void *userData, const XML_Char *name,
                                            XML_Content *model);
                                            XML_Content *model);
 
 
+extern void XMLCALL suspend_after_element_declaration(void *userData,
+                                                      const XML_Char *name,
+                                                      XML_Content *model);
+
 extern void XMLCALL accumulate_pi_characters(void *userData,
 extern void XMLCALL accumulate_pi_characters(void *userData,
                                              const XML_Char *target,
                                              const XML_Char *target,
                                              const XML_Char *data);
                                              const XML_Char *data);
@@ -569,6 +574,10 @@ extern void XMLCALL accumulate_entity_decl(
     const XML_Char *systemId, const XML_Char *publicId,
     const XML_Char *systemId, const XML_Char *publicId,
     const XML_Char *notationName);
     const XML_Char *notationName);
 
 
+extern void XMLCALL accumulate_char_data_and_suspend(void *userData,
+                                                     const XML_Char *s,
+                                                     int len);
+
 extern void XMLCALL accumulate_start_element(void *userData,
 extern void XMLCALL accumulate_start_element(void *userData,
                                              const XML_Char *name,
                                              const XML_Char *name,
                                              const XML_Char **atts);
                                              const XML_Char **atts);

+ 4 - 2
libs/expat/tests/minicheck.h

@@ -14,7 +14,7 @@
 
 
    Copyright (c) 2004-2006 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2004-2006 Fred L. Drake, Jr. <[email protected]>
    Copyright (c) 2006-2012 Karl Waclawek <[email protected]>
    Copyright (c) 2006-2012 Karl Waclawek <[email protected]>
-   Copyright (c) 2016-2024 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2025 Sebastian Pipping <[email protected]>
    Copyright (c) 2022      Rhodri James <[email protected]>
    Copyright (c) 2022      Rhodri James <[email protected]>
    Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <[email protected]>
    Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <[email protected]>
    Licensed under the MIT license:
    Licensed under the MIT license:
@@ -129,8 +129,10 @@ void _check_set_test_info(char const *function, char const *filename,
  * Prototypes for the actual implementation.
  * Prototypes for the actual implementation.
  */
  */
 
 
-#  if defined(__GNUC__)
+#  if defined(__has_attribute)
+#    if __has_attribute(noreturn)
 __attribute__((noreturn))
 __attribute__((noreturn))
+#    endif
 #  endif
 #  endif
 void
 void
 _fail(const char *file, int line, const char *msg);
 _fail(const char *file, int line, const char *msg);

+ 143 - 43
libs/expat/tests/misc_tests.c

@@ -10,7 +10,7 @@
    Copyright (c) 2003      Greg Stein <[email protected]>
    Copyright (c) 2003      Greg Stein <[email protected]>
    Copyright (c) 2005-2007 Steven Solie <[email protected]>
    Copyright (c) 2005-2007 Steven Solie <[email protected]>
    Copyright (c) 2005-2012 Karl Waclawek <[email protected]>
    Copyright (c) 2005-2012 Karl Waclawek <[email protected]>
-   Copyright (c) 2016-2024 Sebastian Pipping <[email protected]>
+   Copyright (c) 2016-2025 Sebastian Pipping <[email protected]>
    Copyright (c) 2017-2022 Rhodri James <[email protected]>
    Copyright (c) 2017-2022 Rhodri James <[email protected]>
    Copyright (c) 2017      Joe Orton <[email protected]>
    Copyright (c) 2017      Joe Orton <[email protected]>
    Copyright (c) 2017      José Gutiérrez de la Concha <[email protected]>
    Copyright (c) 2017      José Gutiérrez de la Concha <[email protected]>
@@ -59,6 +59,9 @@
 #include "handlers.h"
 #include "handlers.h"
 #include "misc_tests.h"
 #include "misc_tests.h"
 
 
+void XMLCALL accumulate_characters_ext_handler(void *userData,
+                                               const XML_Char *s, int len);
+
 /* Test that a failure to allocate the parser structure fails gracefully */
 /* Test that a failure to allocate the parser structure fails gracefully */
 START_TEST(test_misc_alloc_create_parser) {
 START_TEST(test_misc_alloc_create_parser) {
   XML_Memory_Handling_Suite memsuite = {duff_allocator, realloc, free};
   XML_Memory_Handling_Suite memsuite = {duff_allocator, realloc, free};
@@ -208,7 +211,7 @@ START_TEST(test_misc_version) {
   if (! versions_equal(&read_version, &parsed_version))
   if (! versions_equal(&read_version, &parsed_version))
     fail("Version mismatch");
     fail("Version mismatch");
 
 
-  if (xcstrcmp(version_text, XCS("expat_2.6.4"))) /* needs bump on releases */
+  if (xcstrcmp(version_text, XCS("expat_2.7.0"))) /* needs bump on releases */
     fail("XML_*_VERSION in expat.h out of sync?\n");
     fail("XML_*_VERSION in expat.h out of sync?\n");
 }
 }
 END_TEST
 END_TEST
@@ -294,6 +297,7 @@ START_TEST(test_misc_stop_during_end_handler_issue_240_1) {
   parser = XML_ParserCreate(NULL);
   parser = XML_ParserCreate(NULL);
   XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
   XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
   mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
   mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
+  assert_true(mydata != NULL);
   mydata->parser = parser;
   mydata->parser = parser;
   mydata->deep = 0;
   mydata->deep = 0;
   XML_SetUserData(parser, mydata);
   XML_SetUserData(parser, mydata);
@@ -315,6 +319,7 @@ START_TEST(test_misc_stop_during_end_handler_issue_240_2) {
   parser = XML_ParserCreate(NULL);
   parser = XML_ParserCreate(NULL);
   XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
   XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
   mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
   mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
+  assert_true(mydata != NULL);
   mydata->parser = parser;
   mydata->parser = parser;
   mydata->deep = 0;
   mydata->deep = 0;
   XML_SetUserData(parser, mydata);
   XML_SetUserData(parser, mydata);
@@ -328,64 +333,119 @@ START_TEST(test_misc_stop_during_end_handler_issue_240_2) {
 END_TEST
 END_TEST
 
 
 START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) {
 START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) {
-  const char *const inputOne = "<!DOCTYPE d [\n"
-                               "<!ENTITY % e ']><d/>'>\n"
-                               "\n"
-                               "%e;";
+  const char *const inputOne
+      = "<!DOCTYPE d [\n"
+        "<!ENTITY % element_d '<!ELEMENT d (#PCDATA)*>'>\n"
+        "%element_d;\n"
+        "<!ENTITY % e ']><d/>'>\n"
+        "\n"
+        "%e;";
   const char *const inputTwo
   const char *const inputTwo
       = "<!DOCTYPE d [\n"
       = "<!DOCTYPE d [\n"
+        "<!ENTITY % element_d '<!ELEMENT d (#PCDATA)*>'>\n"
+        "%element_d;\n"
         "<!ENTITY % e1 ']><d/>'><!ENTITY % e2 '&#37;e1;'>\n"
         "<!ENTITY % e1 ']><d/>'><!ENTITY % e2 '&#37;e1;'>\n"
         "\n"
         "\n"
         "%e2;";
         "%e2;";
-  const char *const inputThree = "<!DOCTYPE d [\n"
-                                 "<!ENTITY % e ']><d'>\n"
-                                 "\n"
-                                 "%e;/>";
-  const char *const inputIssue317 = "<!DOCTYPE doc [\n"
-                                    "<!ENTITY % foo ']>\n"
-                                    "<doc>Hell<oc (#PCDATA)*>'>\n"
-                                    "%foo;\n"
-                                    "]>\n"
-                                    "<doc>Hello, world</dVc>";
+  const char *const inputThree
+      = "<!DOCTYPE d [\n"
+        "<!ENTITY % element_d '<!ELEMENT d (#PCDATA)*>'>\n"
+        "%element_d;\n"
+        "<!ENTITY % e ']><d'>\n"
+        "\n"
+        "%e;/>";
+  const char *const inputIssue317
+      = "<!DOCTYPE doc [\n"
+        "<!ENTITY % element_doc '<!ELEMENT doc (#PCDATA)*>'>\n"
+        "%element_doc;\n"
+        "<!ENTITY % foo ']>\n"
+        "<doc>Hell<oc (#PCDATA)*>'>\n"
+        "%foo;\n"
+        "]>\n"
+        "<doc>Hello, world</dVc>";
 
 
   const char *const inputs[] = {inputOne, inputTwo, inputThree, inputIssue317};
   const char *const inputs[] = {inputOne, inputTwo, inputThree, inputIssue317};
+  const XML_Bool suspendOrNot[] = {XML_FALSE, XML_TRUE};
   size_t inputIndex = 0;
   size_t inputIndex = 0;
 
 
   for (; inputIndex < sizeof(inputs) / sizeof(inputs[0]); inputIndex++) {
   for (; inputIndex < sizeof(inputs) / sizeof(inputs[0]); inputIndex++) {
-    set_subtest("%s", inputs[inputIndex]);
-    XML_Parser parser;
-    enum XML_Status parseResult;
-    int setParamEntityResult;
-    XML_Size lineNumber;
-    XML_Size columnNumber;
-    const char *const input = inputs[inputIndex];
-
-    parser = XML_ParserCreate(NULL);
-    setParamEntityResult
-        = XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
-    if (setParamEntityResult != 1)
-      fail("Failed to set XML_PARAM_ENTITY_PARSING_ALWAYS.");
-
-    parseResult = _XML_Parse_SINGLE_BYTES(parser, input, (int)strlen(input), 0);
-    if (parseResult != XML_STATUS_ERROR) {
-      parseResult = _XML_Parse_SINGLE_BYTES(parser, "", 0, 1);
+    for (size_t suspendOrNotIndex = 0;
+         suspendOrNotIndex < sizeof(suspendOrNot) / sizeof(suspendOrNot[0]);
+         suspendOrNotIndex++) {
+      const char *const input = inputs[inputIndex];
+      const XML_Bool suspend = suspendOrNot[suspendOrNotIndex];
+      if (suspend && (g_chunkSize > 0)) {
+        // We cannot use _XML_Parse_SINGLE_BYTES below due to suspension, and
+        // so chunk sizes >0 would only repeat the very same test
+        // due to use of plain XML_Parse; we are saving upon that runtime:
+        return;
+      }
+
+      set_subtest("[input=%d suspend=%s] %s", (int)inputIndex,
+                  suspend ? "true" : "false", input);
+      XML_Parser parser;
+      enum XML_Status parseResult;
+      int setParamEntityResult;
+      XML_Size lineNumber;
+      XML_Size columnNumber;
+
+      parser = XML_ParserCreate(NULL);
+      setParamEntityResult
+          = XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+      if (setParamEntityResult != 1)
+        fail("Failed to set XML_PARAM_ENTITY_PARSING_ALWAYS.");
+
+      if (suspend) {
+        XML_SetUserData(parser, parser);
+        XML_SetElementDeclHandler(parser, suspend_after_element_declaration);
+      }
+
+      if (suspend) {
+        // can't use SINGLE_BYTES here, because it'll return early on
+        // suspension, and we won't know exactly how much input we actually
+        // managed to give Expat.
+        parseResult = XML_Parse(parser, input, (int)strlen(input), 0);
+
+        while (parseResult == XML_STATUS_SUSPENDED) {
+          parseResult = XML_ResumeParser(parser);
+        }
+
+        if (parseResult != XML_STATUS_ERROR) {
+          // can't use SINGLE_BYTES here, because it'll return early on
+          // suspension, and we won't know exactly how much input we actually
+          // managed to give Expat.
+          parseResult = XML_Parse(parser, "", 0, 1);
+        }
+
+        while (parseResult == XML_STATUS_SUSPENDED) {
+          parseResult = XML_ResumeParser(parser);
+        }
+      } else {
+        parseResult
+            = _XML_Parse_SINGLE_BYTES(parser, input, (int)strlen(input), 0);
+
+        if (parseResult != XML_STATUS_ERROR) {
+          parseResult = _XML_Parse_SINGLE_BYTES(parser, "", 0, 1);
+        }
+      }
+
       if (parseResult != XML_STATUS_ERROR) {
       if (parseResult != XML_STATUS_ERROR) {
         fail("Parsing was expected to fail but succeeded.");
         fail("Parsing was expected to fail but succeeded.");
       }
       }
-    }
 
 
-    if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
-      fail("Error code does not match XML_ERROR_INVALID_TOKEN");
+      if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
+        fail("Error code does not match XML_ERROR_INVALID_TOKEN");
 
 
-    lineNumber = XML_GetCurrentLineNumber(parser);
-    if (lineNumber != 4)
-      fail("XML_GetCurrentLineNumber does not work as expected.");
+      lineNumber = XML_GetCurrentLineNumber(parser);
+      if (lineNumber != 6)
+        fail("XML_GetCurrentLineNumber does not work as expected.");
 
 
-    columnNumber = XML_GetCurrentColumnNumber(parser);
-    if (columnNumber != 0)
-      fail("XML_GetCurrentColumnNumber does not work as expected.");
+      columnNumber = XML_GetCurrentColumnNumber(parser);
+      if (columnNumber != 0)
+        fail("XML_GetCurrentColumnNumber does not work as expected.");
 
 
-    XML_ParserFree(parser);
+      XML_ParserFree(parser);
+    }
   }
   }
 }
 }
 END_TEST
 END_TEST
@@ -519,6 +579,45 @@ START_TEST(test_misc_stopparser_rejects_unstarted_parser) {
 }
 }
 END_TEST
 END_TEST
 
 
+/* Adaptation of accumulate_characters that takes ExtHdlrData input to work with
+ * test_renter_loop_finite_content below */
+void XMLCALL
+accumulate_characters_ext_handler(void *userData, const XML_Char *s, int len) {
+  ExtHdlrData *const test_data = (ExtHdlrData *)userData;
+  CharData_AppendXMLChars(test_data->storage, s, len);
+}
+
+/* Test that internalEntityProcessor does not re-enter forever;
+ * based on files tests/xmlconf/xmltest/valid/ext-sa/012.{xml,ent} */
+START_TEST(test_renter_loop_finite_content) {
+  CharData storage;
+  CharData_Init(&storage);
+  const char *const text = "<!DOCTYPE doc [\n"
+                           "<!ENTITY e1 '&e2;'>\n"
+                           "<!ENTITY e2 '&e3;'>\n"
+                           "<!ENTITY e3 SYSTEM '012.ent'>\n"
+                           "<!ENTITY e4 '&e5;'>\n"
+                           "<!ENTITY e5 '(e5)'>\n"
+                           "<!ELEMENT doc (#PCDATA)>\n"
+                           "]>\n"
+                           "<doc>&e1;</doc>\n";
+  ExtHdlrData test_data = {"&e4;\n", external_entity_null_loader, &storage};
+  const XML_Char *const expected = XCS("(e5)\n");
+
+  XML_Parser parser = XML_ParserCreate(NULL);
+  assert_true(parser != NULL);
+  XML_SetUserData(parser, &test_data);
+  XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader);
+  XML_SetCharacterDataHandler(parser, accumulate_characters_ext_handler);
+  if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
+      == XML_STATUS_ERROR)
+    xml_failure(parser);
+
+  CharData_CheckXMLChars(&storage, expected);
+  XML_ParserFree(parser);
+}
+END_TEST
+
 void
 void
 make_miscellaneous_test_case(Suite *s) {
 make_miscellaneous_test_case(Suite *s) {
   TCase *tc_misc = tcase_create("miscellaneous tests");
   TCase *tc_misc = tcase_create("miscellaneous tests");
@@ -545,4 +644,5 @@ make_miscellaneous_test_case(Suite *s) {
   tcase_add_test(tc_misc, test_misc_char_handler_stop_without_leak);
   tcase_add_test(tc_misc, test_misc_char_handler_stop_without_leak);
   tcase_add_test(tc_misc, test_misc_resumeparser_not_crashing);
   tcase_add_test(tc_misc, test_misc_resumeparser_not_crashing);
   tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser);
   tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser);
+  tcase_add_test__if_xml_ge(tc_misc, test_renter_loop_finite_content);
 }
 }

+ 3 - 2
libs/expat/tests/xmltest.sh

@@ -2,8 +2,8 @@
 # EXPAT TEST SCRIPT FOR W3C XML TEST SUITE
 # EXPAT TEST SCRIPT FOR W3C XML TEST SUITE
 #
 #
 # This script can be used to exercise Expat against the
 # This script can be used to exercise Expat against the
-# w3c.org xml test suite, available from
-# http://www.w3.org/XML/Test/xmlts20020606.zip.
+# w3c.org xml test suite, available from:
+# https://www.w3.org/XML/Test/xmlts20020606.zip
 #
 #
 # To run this script, first set XMLWF below so that xmlwf can be
 # To run this script, first set XMLWF below so that xmlwf can be
 # found, then set the output directory with OUTPUT.
 # found, then set the output directory with OUTPUT.
@@ -30,6 +30,7 @@
 # Copyright (c) 2002      Karl Waclawek <[email protected]>
 # Copyright (c) 2002      Karl Waclawek <[email protected]>
 # Copyright (c) 2008-2019 Sebastian Pipping <[email protected]>
 # Copyright (c) 2008-2019 Sebastian Pipping <[email protected]>
 # Copyright (c) 2017      Rhodri James <[email protected]>
 # Copyright (c) 2017      Rhodri James <[email protected]>
+# Copyright (c) 2025      Hanno Böck <[email protected]>
 # Licensed under the MIT license:
 # Licensed under the MIT license:
 #
 #
 # Permission is  hereby granted,  free of charge,  to any  person obtaining
 # Permission is  hereby granted,  free of charge,  to any  person obtaining

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

@@ -14,7 +14,7 @@
 ; Copyright (c) 2001      Tim Peters <[email protected]>
 ; Copyright (c) 2001      Tim Peters <[email protected]>
 ; Copyright (c) 2001-2005 Fred L. Drake, Jr. <[email protected]>
 ; Copyright (c) 2001-2005 Fred L. Drake, Jr. <[email protected]>
 ; Copyright (c) 2006-2017 Karl Waclawek <[email protected]>
 ; Copyright (c) 2006-2017 Karl Waclawek <[email protected]>
-; Copyright (c) 2007-2024 Sebastian Pipping <[email protected]>
+; Copyright (c) 2007-2025 Sebastian Pipping <[email protected]>
 ; Copyright (c) 2022      Johnny Jazeix <[email protected]>
 ; Copyright (c) 2022      Johnny Jazeix <[email protected]>
 ; Copyright (c) 2024      Dag-Erling Smørgrav <[email protected]>
 ; Copyright (c) 2024      Dag-Erling Smørgrav <[email protected]>
 ; Licensed under the MIT license:
 ; Licensed under the MIT license:
@@ -38,14 +38,14 @@
 ; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 ; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 ; USE OR OTHER DEALINGS IN THE SOFTWARE.
 ; USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
-#define expatVer "2.6.4"
+#define expatVer "2.7.0"
 
 
 [Setup]
 [Setup]
 AppName=Expat
 AppName=Expat
 AppId=expat
 AppId=expat
 AppVersion={#expatVer}
 AppVersion={#expatVer}
 AppVerName=Expat {#expatVer}
 AppVerName=Expat {#expatVer}
-AppCopyright=Copyright © 1997-2022 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers
+AppCopyright=Copyright © 1997-2025 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers
 AppPublisher=The Expat Developers
 AppPublisher=The Expat Developers
 AppPublisherURL=https://libexpat.github.io/
 AppPublisherURL=https://libexpat.github.io/
 AppSupportURL=https://libexpat.github.io/
 AppSupportURL=https://libexpat.github.io/
@@ -75,7 +75,7 @@ Flags: ignoreversion; Source: COPYING;                      DestDir: "{app}"; De
 Flags: ignoreversion; Source: README.md;                    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\*.xml;                    DestDir: "{app}\Doc"
+Flags: ignoreversion; Source: doc\*.xml;                    DestDir: "{app}\Source\doc"
 Flags: ignoreversion; Source: win32\bin\Release\*.dll;      DestDir: "{app}\Bin"
 Flags: ignoreversion; Source: win32\bin\Release\*.dll;      DestDir: "{app}\Bin"
 Flags: ignoreversion; Source: win32\bin\Release\*.lib;      DestDir: "{app}\Bin"
 Flags: ignoreversion; Source: win32\bin\Release\*.lib;      DestDir: "{app}\Bin"
 Flags: ignoreversion; Source: win32\version.rc.cmake;       DestDir: "{app}\Source\win32"
 Flags: ignoreversion; Source: win32\version.rc.cmake;       DestDir: "{app}\Source\win32"

+ 2 - 1
libs/expat/xmlwf/readfilemap.c

@@ -14,6 +14,7 @@
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2017      Rhodri James <[email protected]>
    Copyright (c) 2017      Franek Korta <[email protected]>
    Copyright (c) 2017      Franek Korta <[email protected]>
    Copyright (c) 2022      Sean McBride <[email protected]>
    Copyright (c) 2022      Sean McBride <[email protected]>
+   Copyright (c) 2025      Hanno Böck <[email protected]>
    Licensed under the MIT license:
    Licensed under the MIT license:
 
 
    Permission is  hereby granted,  free of charge,  to any  person obtaining
    Permission is  hereby granted,  free of charge,  to any  person obtaining
@@ -55,7 +56,7 @@
 #  define EXPAT_read_count_t int
 #  define EXPAT_read_count_t int
 #  define EXPAT_read_req_t unsigned int
 #  define EXPAT_read_req_t unsigned int
 #else /* POSIX */
 #else /* POSIX */
-/* http://pubs.opengroup.org/onlinepubs/009695399/functions/read.html */
+/* https://pubs.opengroup.org/onlinepubs/009695399/functions/read.html */
 #  define EXPAT_read read
 #  define EXPAT_read read
 #  define EXPAT_read_count_t ssize_t
 #  define EXPAT_read_count_t ssize_t
 #  define EXPAT_read_req_t size_t
 #  define EXPAT_read_req_t size_t

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff