mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
contrib/expat: import expat 2.9.0
Changes: https://github.com/libexpat/libexpat/blob/R_2_9_0/expat/Changes Security: CVE-2026-102633 Security: CVE-2026-77214 MFC after: 3 days
This commit is contained in:
commit
22c3edb312
52 files changed
+2952
-835
No files matched your search
+102
-26
@@ -5,21 +5,108 @@
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! <blink>Expat has UNFIXED SECURITY ISSUES!</blink> !!
|
||||
!! Please see https://github.com/libexpat/libexpat/issues/1160 for details. !!
|
||||
!! !!
|
||||
!! Starting 2026-08-01, for up to six months my work maintaining libexpat !!
|
||||
!! will be funded by the City of Munich as part of their !!
|
||||
!! Open Source Sabbatical (https://opensource.muenchen.de/sabbatical.html) !!
|
||||
!! — thank you! !!
|
||||
!! !!
|
||||
!! If your business relies on Expat beyond January 2027, please consider !!
|
||||
!! funding the maintenance of Expat to ensure its health and security for !!
|
||||
!! you and others. Thank you! !!
|
||||
!! !!
|
||||
!! Sebastian Pipping -- Berlin, 2026-09-22 !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// <blink>Expat has UNFIXED SECURITY ISSUES!</blink> //
|
||||
// Please see https://github.com/libexpat/libexpat/issues/1160 for details. //
|
||||
// //
|
||||
// Starting 2026-08-01, for up to six months my work maintaining libexpat //
|
||||
// will be funded by the City of Munich as part of their //
|
||||
// Open Source Sabbatical (https://opensource.muenchen.de/sabbatical.html) //
|
||||
// — thank you! //
|
||||
// //
|
||||
// If your business relies on Expat beyond January 2027, please consider //
|
||||
// funding the maintenance of Expat to ensure its health and security for //
|
||||
// you and others. Thank you! //
|
||||
// //
|
||||
// Sebastian Pipping -- Berlin, 2026-09-22 //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Release 2.9.0 Mon October 5 2026
|
||||
Security fixes:
|
||||
#1392 CVE-2026-102633 -- Integer overflow in function
|
||||
expat_realloc on 32bit platforms
|
||||
#1393 CVE-2026-77214 -- Validate parameter `len` against available
|
||||
buffer capacity in XML_ParseBuffer
|
||||
|
||||
Bug fixes:
|
||||
#1387 lib: Handle OOM when copying encodingName in XML_ParserReset
|
||||
|
||||
New features:
|
||||
#1327 lib: Introduce new "Properties API" to get and set
|
||||
scalar properties for a single parser instance.
|
||||
There are six new functions:
|
||||
- XML_GetPropertyBool
|
||||
- XML_GetPropertyDouble
|
||||
- XML_GetPropertyUInt64
|
||||
- XML_SetPropertyBool
|
||||
- XML_SetPropertyDouble
|
||||
- XML_SetPropertyUInt64
|
||||
And two new enums:
|
||||
- XML_Prop_Error
|
||||
- XML_Parser_Property
|
||||
#1323 lib: Introduce five new 64bit location API functions:
|
||||
- XML_GetCurrentByteCount64
|
||||
- XML_GetCurrentByteIndex64
|
||||
- XML_GetCurrentColumnNumber64
|
||||
- XML_GetCurrentLineNumber64
|
||||
- XML_GetInputContext64
|
||||
These five functions closely mirror their predecessors
|
||||
but are not prone to 32bit integer wrap-around.
|
||||
|
||||
Other changes:
|
||||
#1391 docs: Document the scope of function XML_GetErrorCode
|
||||
#1395 docs: Document length expectations for XML_ParseBuffer
|
||||
#1394 lib: Call unknown encoding release before parser teardown
|
||||
#1370 #1373 lib: Drop (disabled-by-default) attribute info feature
|
||||
These things are now gone:
|
||||
- Public function XML_GetAttributeInfo
|
||||
- Public struct XML_AttrInfo
|
||||
- Macro XML_ATTR_INFO
|
||||
These things are now causing build errors:
|
||||
- Configure option --enable-xml-attr-info
|
||||
- CMake option -DEXPAT_ATTR_INFO=ON
|
||||
#1379 #1382 lib: Drop (disabled-by-default) minimum size feature
|
||||
These things are now gone:
|
||||
- Macro XML_MIN_SIZE
|
||||
These things are now causing build errors:
|
||||
- Configuring with -DXML_MIN_SIZE for CPPFLAGS/CFLAGS
|
||||
- CMake option -DEXPAT_MIN_SIZE=ON
|
||||
#1323 #1411 lib: Deprecate macro XML_LARGE_SIZE (use the new 64bit
|
||||
location API functions instead please)
|
||||
#1323 lib: Deprecate five location API functions that are cursed
|
||||
with integer wrap-around:
|
||||
- XML_GetCurrentByteCount
|
||||
- XML_GetCurrentByteIndex
|
||||
- XML_GetCurrentColumnNumber
|
||||
- XML_GetCurrentLineNumber
|
||||
- XML_GetInputContext
|
||||
#1399 lib: Guard against out-of-handler use of XML_DefaultCurrent
|
||||
#1400 lib: Use size_t for bytesAllocated and peakBytesAllocated
|
||||
#1401 #1402 ..
|
||||
#1404 #1405 lib|xmlwf|tests: Unify use of xcslen, xcscmp and xcsncmp
|
||||
#1406 xmlwf: Add missing `#include "expat.h"`
|
||||
#1389 #1396 Version info bumped from 13:5:12 (libexpat*.so.1.12.5)
|
||||
to 14:0:13 (libexpat*.so.1.13.0); see https://verbump.de/
|
||||
for what these numbers do
|
||||
|
||||
Infrastructure:
|
||||
#1386 CI: Bump MinGW Clang from 23.1.1 to 23.1.2
|
||||
#1410 CI: Bump Fil-C from 0.685 to 0.686
|
||||
#1388 CI: Adapt to breaking changes regarding windows-11-arm image
|
||||
#1403 CI: Limit package cache download runtime
|
||||
|
||||
Special thanks to:
|
||||
Bénédikt Tran
|
||||
Berkay Eren Ürün
|
||||
Fabian Wahle (Hap Security)
|
||||
Filippo Tedeschi
|
||||
Junki Lee
|
||||
Matthew Fernandez
|
||||
Scott Moore
|
||||
Wade Sparks III
|
||||
and
|
||||
City of Munich Open Source Sabbatical
|
||||
VulnCheck
|
||||
|
||||
Release 2.8.5 Tue September 22 2026
|
||||
Security fixes:
|
||||
@@ -33,17 +120,6 @@ Release 2.8.5 Tue September 22 2026
|
||||
Upstream CVSS 3.1 vector:
|
||||
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (CVSS score: 9.8)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The next release will drop two (disabled-by-default) features: //
|
||||
// //
|
||||
// - ATTR_INFO (-DXML_ATTR_INFO, -DEXPAT_ATTR_INFO, --enable-xml-attr-info, //
|
||||
// function XML_GetAttributeInfo, struct XML_AttrInfo) //
|
||||
// - MIN_SIZE (-DXML_MIN_SIZE, -DEXPAT_MIN_SIZE) //
|
||||
// //
|
||||
// If you need them in 2026 and beyond, please share your scenario at //
|
||||
// GitHub issues #1370 (for ATTR_INFO) and/or #1379 (for MIN_SIZE). Thanks! //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Bug fixes:
|
||||
#1346 lib: Fix OOM-related memory leak on a failed overflow check
|
||||
#1371 lib: Fix memory alignment for architectures with 128bit
|
||||
|
||||
@@ -345,12 +345,10 @@ ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXPAT_ATTR_INFO = @EXPAT_ATTR_INFO@
|
||||
EXPAT_CHAR_TYPE = @EXPAT_CHAR_TYPE@
|
||||
EXPAT_CONTEXT_BYTES = @EXPAT_CONTEXT_BYTES@
|
||||
EXPAT_DTD = @EXPAT_DTD@
|
||||
EXPAT_LARGE_SIZE = @EXPAT_LARGE_SIZE@
|
||||
EXPAT_MIN_SIZE = @EXPAT_MIN_SIZE@
|
||||
EXPAT_NS = @EXPAT_NS@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
@@ -405,7 +403,6 @@ SO_PATCH = @SO_PATCH@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
VSCRIPT_LDFLAGS = @VSCRIPT_LDFLAGS@
|
||||
_EXPAT_COMMENT_ATTR_INFO = @_EXPAT_COMMENT_ATTR_INFO@
|
||||
_EXPAT_COMMENT_DTD_OR_GE = @_EXPAT_COMMENT_DTD_OR_GE@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
> Thank you! :heart: :pray:
|
||||
|
||||
|
||||
# Expat, Release 2.8.5
|
||||
# Expat, Release 2.9.0
|
||||
|
||||
This is Expat, a C99 library for parsing
|
||||
[XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by
|
||||
|
||||
@@ -103,9 +103,9 @@ dnl
|
||||
dnl If the API changes incompatibly set LIBAGE back to 0
|
||||
dnl
|
||||
|
||||
LIBCURRENT=13 # sync
|
||||
LIBREVISION=5 # with
|
||||
LIBAGE=12 # CMakeLists.txt!
|
||||
LIBCURRENT=14 # sync
|
||||
LIBREVISION=0 # with
|
||||
LIBAGE=13 # CMakeLists.txt!
|
||||
|
||||
AC_CONFIG_HEADERS([expat_config.h])
|
||||
AH_TOP([#ifndef EXPAT_CONFIG_H
|
||||
@@ -226,9 +226,11 @@ AM_CONDITIONAL([MINGW], [test x${EXPATCFG_ON_MINGW} = xyes])
|
||||
dnl Note: Prefix "_INTERNAL_" here means exclusive use inside of file configure.ac
|
||||
AM_CONDITIONAL([UNICODE], [echo -- "${CPPFLAGS}${CFLAGS}" | ${FGREP} XML_UNICODE >/dev/null])
|
||||
AM_CONDITIONAL([_INTERNAL_UNICODE_WCHAR_T], [echo -- "${CPPFLAGS}${CFLAGS}" | ${FGREP} XML_UNICODE_WCHAR_T >/dev/null])
|
||||
AM_CONDITIONAL([_INTERNAL_MIN_SIZE], [echo -- "${CPPFLAGS}${CFLAGS}" | ${FGREP} XML_MIN_SIZE >/dev/null])
|
||||
AM_CONDITIONAL([_INTERNAL_LARGE_SIZE], [echo -- "${CPPFLAGS}${CFLAGS}" | ${FGREP} XML_LARGE_SIZE >/dev/null])
|
||||
|
||||
AS_IF([echo -- "${CPPFLAGS}${CFLAGS}" | ${FGREP} XML_MIN_SIZE >/dev/null],
|
||||
[AC_MSG_ERROR([Feature XML_MIN_SIZE has been removed. Please open a GitHub issue if you need it back.])])
|
||||
|
||||
LT_LIB_M
|
||||
|
||||
AC_ARG_WITH([arc4random],
|
||||
@@ -428,13 +430,11 @@ AS_IF([test "x${with_dev_urandom}" = "xyes"],
|
||||
|
||||
|
||||
AC_ARG_ENABLE([xml-attr-info],
|
||||
[AS_HELP_STRING([--enable-xml-attr-info],
|
||||
[Enable retrieving the byte offsets for attribute names and values @<:@default=no@:>@])],
|
||||
[],
|
||||
[],
|
||||
[enable_xml_attr_info=no])
|
||||
AS_IF([test "x${enable_xml_attr_info}" = "xyes"],
|
||||
[AC_DEFINE([XML_ATTR_INFO], 1,
|
||||
[Define to allow retrieving the byte offsets for attribute names and values.])])
|
||||
[AC_MSG_ERROR([Feature --enable-xml-attr-info has been removed. Please open a GitHub issue if you need it back.])])
|
||||
|
||||
AC_ARG_ENABLE([xml-context],
|
||||
AS_HELP_STRING([--enable-xml-context @<:@COUNT@:>@],
|
||||
@@ -495,21 +495,12 @@ dnl Configure CMake file templates
|
||||
dnl NOTE: The *_TRUE variables read here are Automake conditionals
|
||||
dnl that are either set to "" when enabled or to "#" when disabled
|
||||
dnl (because they are used to dynamically comment out certain things)
|
||||
AS_IF([test "x${enable_xml_attr_info}" = xyes],
|
||||
[EXPAT_ATTR_INFO=ON
|
||||
_EXPAT_COMMENT_ATTR_INFO=" "],
|
||||
[EXPAT_ATTR_INFO=OFF
|
||||
_EXPAT_COMMENT_ATTR_INFO="#"])
|
||||
AC_SUBST([_EXPAT_COMMENT_ATTR_INFO])
|
||||
EXPAT_DTD=ON
|
||||
_EXPAT_COMMENT_DTD_OR_GE=" "
|
||||
AC_SUBST([_EXPAT_COMMENT_DTD_OR_GE])
|
||||
AS_IF([test "x${_INTERNAL_LARGE_SIZE_TRUE}" = x],
|
||||
[EXPAT_LARGE_SIZE=ON],
|
||||
[EXPAT_LARGE_SIZE=OFF])
|
||||
AS_IF([test "x${_INTERNAL_MIN_SIZE_TRUE}" = x],
|
||||
[EXPAT_MIN_SIZE=ON],
|
||||
[EXPAT_MIN_SIZE=OFF])
|
||||
EXPAT_NS=ON
|
||||
AS_IF([test "x${enable_xml_context}" != xno],
|
||||
[EXPAT_CONTEXT_BYTES=${enable_xml_context}],
|
||||
@@ -525,10 +516,8 @@ LIBDIR_BASENAME="$(basename "${libdir}")"
|
||||
SO_MAJOR="$(expr "${LIBCURRENT}" - "${LIBAGE}")"
|
||||
SO_MINOR="${LIBAGE}"
|
||||
SO_PATCH="${LIBREVISION}"
|
||||
AC_SUBST([EXPAT_ATTR_INFO])
|
||||
AC_SUBST([EXPAT_DTD])
|
||||
AC_SUBST([EXPAT_LARGE_SIZE])
|
||||
AC_SUBST([EXPAT_MIN_SIZE])
|
||||
AC_SUBST([EXPAT_NS])
|
||||
AC_SUBST([EXPAT_CONTEXT_BYTES])
|
||||
AC_SUBST([EXPAT_CHAR_TYPE])
|
||||
|
||||
@@ -234,12 +234,10 @@ ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXPAT_ATTR_INFO = @EXPAT_ATTR_INFO@
|
||||
EXPAT_CHAR_TYPE = @EXPAT_CHAR_TYPE@
|
||||
EXPAT_CONTEXT_BYTES = @EXPAT_CONTEXT_BYTES@
|
||||
EXPAT_DTD = @EXPAT_DTD@
|
||||
EXPAT_LARGE_SIZE = @EXPAT_LARGE_SIZE@
|
||||
EXPAT_MIN_SIZE = @EXPAT_MIN_SIZE@
|
||||
EXPAT_NS = @EXPAT_NS@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
@@ -294,7 +292,6 @@ SO_PATCH = @SO_PATCH@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
VSCRIPT_LDFLAGS = @VSCRIPT_LDFLAGS@
|
||||
_EXPAT_COMMENT_ATTR_INFO = @_EXPAT_COMMENT_ATTR_INFO@
|
||||
_EXPAT_COMMENT_DTD_OR_GE = @_EXPAT_COMMENT_DTD_OR_GE@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<body>
|
||||
<div>
|
||||
<h1>
|
||||
The Expat XML Parser <small>Release 2.8.5</small>
|
||||
The Expat XML Parser <small>Release 2.9.0</small>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
@@ -309,22 +309,76 @@
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetCurrentByteIndex">XML_GetCurrentByteIndex</a>
|
||||
(deprecated)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetCurrentByteIndex64">XML_GetCurrentByteIndex64</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetCurrentLineNumber">XML_GetCurrentLineNumber</a>
|
||||
(deprecated)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetCurrentLineNumber64">XML_GetCurrentLineNumber64</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetCurrentColumnNumber">XML_GetCurrentColumnNumber</a>
|
||||
(deprecated)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href=
|
||||
"#XML_GetCurrentColumnNumber64">XML_GetCurrentColumnNumber64</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetCurrentByteCount">XML_GetCurrentByteCount</a>
|
||||
(deprecated)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetInputContext">XML_GetInputContext</a>
|
||||
<a href="#XML_GetCurrentByteCount64">XML_GetCurrentByteCount64</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetInputContext">XML_GetInputContext</a> (deprecated)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetInputContext64">XML_GetInputContext64</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#properties">Properties / Security Tuning</a>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#XML_GetPropertyBool">XML_GetPropertyBool</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetPropertyDouble">XML_GetPropertyDouble</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetPropertyUInt64">XML_GetPropertyUInt64</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_SetPropertyBool">XML_SetPropertyBool</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_SetPropertyDouble">XML_SetPropertyDouble</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_SetPropertyUInt64">XML_SetPropertyUInt64</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -391,10 +445,6 @@
|
||||
<a href="#XML_GetIdAttributeIndex">XML_GetIdAttributeIndex</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_GetAttributeInfo">XML_GetAttributeInfo</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#XML_SetEncoding">XML_SetEncoding</a>
|
||||
</li>
|
||||
@@ -751,19 +801,59 @@ make install
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
<a id="XML_LARGE_SIZE" name="XML_LARGE_SIZE">XML_LARGE_SIZE</a>
|
||||
<a id="XML_LARGE_SIZE" name="XML_LARGE_SIZE">XML_LARGE_SIZE</a> (deprecated)
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
If defined, causes the <code>XML_Size</code> and <code>XML_Index</code> integer
|
||||
types to be at least 64 bits in size. This is intended to support processing of
|
||||
very large input streams, where the return values of <code><a href=
|
||||
"#XML_GetCurrentByteIndex">XML_GetCurrentByteIndex</a></code>, <code><a href=
|
||||
"#XML_GetCurrentLineNumber">XML_GetCurrentLineNumber</a></code> and
|
||||
<code><a href=
|
||||
"#XML_GetCurrentColumnNumber">XML_GetCurrentColumnNumber</a></code> could
|
||||
overflow. It may not be supported by all compilers, and is turned off by
|
||||
default.
|
||||
<p>
|
||||
If defined, causes the <code>XML_Size</code> and <code>XML_Index</code>
|
||||
integer types to be at least 64 bits in size. This is intended to support
|
||||
processing of very large input streams, where the return values of
|
||||
<code><a href="#XML_GetCurrentByteIndex">XML_GetCurrentByteIndex</a></code>,
|
||||
<code><a href="#XML_GetCurrentLineNumber">XML_GetCurrentLineNumber</a></code>
|
||||
and <code><a href=
|
||||
"#XML_GetCurrentColumnNumber">XML_GetCurrentColumnNumber</a></code> could
|
||||
overflow. It may not be supported by all compilers, and is turned off by
|
||||
default.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Starting with Expat 2.9.0, there are 64bit versions of these functions, so
|
||||
that relying on (non-default and uncommon) macro <code>XML_LARGE_SIZE</code>
|
||||
is no longer needed. These functions are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code><a href=
|
||||
"#XML_GetCurrentByteIndex64">XML_GetCurrentByteIndex64</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href=
|
||||
"#XML_GetCurrentColumnNumber64">XML_GetCurrentColumnNumber64</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href=
|
||||
"#XML_GetCurrentLineNumber64">XML_GetCurrentLineNumber64</a></code>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
And there are two more that <code>XML_LARGE_SIZE</code> was not covering:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code><a href=
|
||||
"#XML_GetCurrentByteCount64">XML_GetCurrentByteCount64</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href="#XML_GetInputContext64">XML_GetInputContext64</a></code>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
@@ -790,16 +880,6 @@ make install
|
||||
the code that calls it; this is required to get all the right MSVC magic
|
||||
annotations correct. This is ignored on other platforms.
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
<a id="XML_ATTR_INFO" name="XML_ATTR_INFO">XML_ATTR_INFO</a>
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
If defined, makes the additional function <code><a href=
|
||||
"#XML_GetAttributeInfo">XML_GetAttributeInfo</a></code> available for reporting
|
||||
attribute byte offsets.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<hr />
|
||||
@@ -1707,6 +1787,17 @@ XML_ParseBuffer(XML_Parser p,
|
||||
application can avoid double copying of the input.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> It is the responsibility of the application code to pass
|
||||
a value for <code>len</code> that does not exceed the length of the remaining
|
||||
unparsed XML content that was previously copied into the buffer obtained from
|
||||
<code><a href="#XML_GetBuffer">XML_GetBuffer</a></code>. The documentation of
|
||||
<code><a href="#XML_GetBuffer">XML_GetBuffer</a></code> below has an <a href=
|
||||
"#XML_GetBuffer">example of typical use</a> of functions <code><a href=
|
||||
"#XML_GetBuffer">XML_GetBuffer</a></code> and <code><a href=
|
||||
"#XML_ParseBuffer">XML_ParseBuffer</a></code> in tandem.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Negative values for <code>len</code> are rejected since Expat 2.6.3.
|
||||
</p>
|
||||
@@ -2889,7 +2980,40 @@ enum XML_Error XMLCALL
|
||||
XML_GetErrorCode(XML_Parser p);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
Return what type of error has occurred.
|
||||
<p>
|
||||
Return what type of error has occurred inside the main Expat parsing machinery.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Only the following functions record the type of error for retrivial via
|
||||
<code>XML_GetErrorCode</code>:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code><a href="#XML_GetBuffer">XML_GetBuffer</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href="#XML_Parse">XML_Parse</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href="#XML_ParseBuffer">XML_ParseBuffer</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href="#XML_ParserReset">XML_ParserReset</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href="#XML_ResumeParser">XML_ResumeParser</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href="#XML_StopParser">XML_StopParser</a></code>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h4 id="XML_ErrorString">
|
||||
@@ -2907,13 +3031,18 @@ XML_ErrorString(enum XML_Error code);
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetCurrentByteIndex">
|
||||
XML_GetCurrentByteIndex
|
||||
XML_GetCurrentByteIndex (deprecated)
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
XML_Index XMLCALL
|
||||
XML_GetCurrentByteIndex(XML_Parser p);
|
||||
</pre>
|
||||
<p>
|
||||
<b>Note:</b> This function is deprecated, please use function <code><a href=
|
||||
"#XML_GetCurrentByteIndex64">XML_GetCurrentByteIndex64</a></code>, instead.
|
||||
</p>
|
||||
|
||||
<div class="fcndef">
|
||||
Return the byte offset of the position. This always corresponds to the values
|
||||
returned by <code><a href=
|
||||
@@ -2928,14 +3057,36 @@ XML_GetCurrentByteIndex(XML_Parser p);
|
||||
"#XML_LARGE_SIZE">XML_LARGE_SIZE</a></code>.
|
||||
</p>
|
||||
|
||||
<h4 id="XML_GetCurrentByteIndex64">
|
||||
XML_GetCurrentByteIndex64
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
int64_t XMLCALL
|
||||
XML_GetCurrentByteIndex64(XML_Parser p);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
Return the byte offset of the position. This always corresponds to the values
|
||||
returned by <code><a href=
|
||||
"#XML_GetCurrentLineNumber64">XML_GetCurrentLineNumber64</a></code> and
|
||||
<code><a href=
|
||||
"#XML_GetCurrentColumnNumber64">XML_GetCurrentColumnNumber64</a></code>.
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetCurrentLineNumber">
|
||||
XML_GetCurrentLineNumber
|
||||
XML_GetCurrentLineNumber (deprecated)
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
XML_Size XMLCALL
|
||||
XML_GetCurrentLineNumber(XML_Parser p);
|
||||
</pre>
|
||||
<p>
|
||||
<b>Note:</b> This function is deprecated, please use function <code><a href=
|
||||
"#XML_GetCurrentLineNumber64">XML_GetCurrentLineNumber64</a></code>, instead.
|
||||
</p>
|
||||
|
||||
<div class="fcndef">
|
||||
Return the line number of the position. The first line is reported as
|
||||
<code>1</code>.
|
||||
@@ -2948,14 +3099,33 @@ XML_GetCurrentLineNumber(XML_Parser p);
|
||||
"#XML_LARGE_SIZE">XML_LARGE_SIZE</a></code>.
|
||||
</p>
|
||||
|
||||
<h4 id="XML_GetCurrentLineNumber64">
|
||||
XML_GetCurrentLineNumber64
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
uint64_t XMLCALL
|
||||
XML_GetCurrentLineNumber64(XML_Parser p);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
Return the line number of the position. The first line is reported as
|
||||
<code>1</code>.
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetCurrentColumnNumber">
|
||||
XML_GetCurrentColumnNumber
|
||||
XML_GetCurrentColumnNumber (deprecated)
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
XML_Size XMLCALL
|
||||
XML_GetCurrentColumnNumber(XML_Parser p);
|
||||
</pre>
|
||||
<p>
|
||||
<b>Note:</b> This function is deprecated, please use function <code><a href=
|
||||
"#XML_GetCurrentColumnNumber64">XML_GetCurrentColumnNumber64</a></code>, instead.
|
||||
</p>
|
||||
|
||||
<div class="fcndef">
|
||||
Return the <em>offset</em>, from the beginning of the current line, of the
|
||||
position. The first column is reported as <code>0</code>.
|
||||
@@ -2968,13 +3138,53 @@ XML_GetCurrentColumnNumber(XML_Parser p);
|
||||
"#XML_LARGE_SIZE">XML_LARGE_SIZE</a></code>.
|
||||
</p>
|
||||
|
||||
<h4 id="XML_GetCurrentColumnNumber64">
|
||||
XML_GetCurrentColumnNumber64
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
uint64_t XMLCALL
|
||||
XML_GetCurrentColumnNumber64(XML_Parser p);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
Return the <em>offset</em>, from the beginning of the current line, of the
|
||||
position. The first column is reported as <code>0</code>.
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetCurrentByteCount">
|
||||
XML_GetCurrentByteCount
|
||||
XML_GetCurrentByteCount (deprecated)
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
int XMLCALL
|
||||
XML_GetCurrentByteCount(XML_Parser p);
|
||||
</pre>
|
||||
<p>
|
||||
<b>Note:</b> This function is deprecated, please use function <code><a href=
|
||||
"#XML_GetCurrentByteCount64">XML_GetCurrentByteCount64</a></code>, instead.
|
||||
</p>
|
||||
|
||||
<div class="fcndef">
|
||||
Return the number of bytes in the current event. Returns <code>0</code> if the
|
||||
event is inside a reference to an internal entity and for the end-tag event for
|
||||
empty element tags (the later can be used to distinguish empty-element tags from
|
||||
empty elements using separate start and end tags).
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> Type <code>int</code> is known to wrap around (on both
|
||||
32bit platforms and 64bit platforms).
|
||||
</p>
|
||||
|
||||
<h4 id="XML_GetCurrentByteCount64">
|
||||
XML_GetCurrentByteCount64
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
uint64_t XMLCALL
|
||||
XML_GetCurrentByteCount64(XML_Parser p);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
Return the number of bytes in the current event. Returns <code>0</code> if the
|
||||
@@ -2984,7 +3194,7 @@ XML_GetCurrentByteCount(XML_Parser p);
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetInputContext">
|
||||
XML_GetInputContext
|
||||
XML_GetInputContext (deprecated)
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
@@ -2992,6 +3202,53 @@ const char * XMLCALL
|
||||
XML_GetInputContext(XML_Parser p,
|
||||
int *offset,
|
||||
int *size);
|
||||
</pre>
|
||||
<p>
|
||||
<b>Note:</b> This function is deprecated, please use function <code><a href=
|
||||
"#XML_GetInputContext64">XML_GetInputContext64</a></code>, instead.
|
||||
</p>
|
||||
|
||||
<div class="fcndef">
|
||||
<p>
|
||||
Returns the parser's input buffer, sets the integer pointed at by
|
||||
<code>offset</code> to the offset within this buffer of the current parse
|
||||
position, and set the integer pointed at by <code>size</code> to the size of
|
||||
the returned buffer.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This should only be called from within a handler during an active parse and the
|
||||
returned buffer should only be referred to from within the handler that made
|
||||
the call. This input buffer contains the untranslated bytes of the input.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Only a limited amount of context is kept, so if the event triggering a call
|
||||
spans over a very large amount of input, the actual parse position may be
|
||||
before the beginning of the buffer.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If <code>XML_CONTEXT_BYTES</code> is zero, this will always return
|
||||
<code>NULL</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> Type <code>int</code> is known to wrap around (on both
|
||||
32bit platforms and 64bit platforms).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetInputContext64">
|
||||
XML_GetInputContext64
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
const char * XMLCALL
|
||||
XML_GetInputContext64(XML_Parser p,
|
||||
int64_t *offset,
|
||||
zint64_t *size);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
<p>
|
||||
@@ -3019,11 +3276,390 @@ XML_GetInputContext(XML_Parser p,
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h3>
|
||||
<a id="properties" name="properties">Properties / Security Tuning</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Expat 2.9.0 introduced a new Properties API. Think of properties as the control
|
||||
knobs of a parser. The key motivations behind its introduction are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>to allow Expat to add more properties — both security-related and non-
|
||||
security ones — in the future (without need to also add new related getter and
|
||||
setter functions for each of them as was the case in the past),
|
||||
</li>
|
||||
|
||||
<li>to allow users to read (not just to set) the current values, and
|
||||
</li>
|
||||
|
||||
<li>to allow users to distinuish the different sources of error beyond a mere
|
||||
"did not work".
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
There is one setter function and one getter function — a pair — per supported
|
||||
data type:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>For <code>XML_Bool</code>:
|
||||
<ul>
|
||||
<li>
|
||||
<code><a href="#XML_GetPropertyBool">XML_GetPropertyBool</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href="#XML_SetPropertyBool">XML_SetPropertyBool</a></code>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>For <code>double</code>:
|
||||
<ul>
|
||||
<li>
|
||||
<code><a href="#XML_GetPropertyDouble">XML_GetPropertyDouble</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href="#XML_SetPropertyDouble">XML_SetPropertyDouble</a></code>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>For <code>uint64_t</code>:
|
||||
<ul>
|
||||
<li>
|
||||
<code><a href="#XML_GetPropertyUInt64">XML_GetPropertyUInt64</a></code>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code><a href="#XML_SetPropertyUInt64">XML_SetPropertyUInt64</a></code>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
They all share these two key enums:
|
||||
</p>
|
||||
|
||||
<h4 id="XML_Parser_Property">
|
||||
XML_Parser_Property
|
||||
</h4>
|
||||
|
||||
<pre>
|
||||
/* Added in Expat 2.9.0. */
|
||||
enum XML_Parser_Property {
|
||||
# if XML_GE == 1
|
||||
XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD = 1, // of type `uint64_t`
|
||||
XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION = 2, // of type `double`
|
||||
XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD = 3, // of type `uint64_t`
|
||||
XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION = 4, // of type `double`
|
||||
# endif
|
||||
XML_PROP_REPARSE_DEFERRAL_ENABLED = 5, // of type `XML_Bool`
|
||||
/* more properties upcoming here */
|
||||
};</pre>
|
||||
<h4 id="XML_Prop_Error">
|
||||
XML_Prop_Error
|
||||
</h4>
|
||||
|
||||
<pre>
|
||||
/* Added in 2.9.0. */
|
||||
enum XML_Prop_Error {
|
||||
XML_PROP_ERROR_NONE = 0, // i.e. success
|
||||
|
||||
XML_PROP_ERROR_INVALID_KEY = 1, // i.e. the property is not known at all
|
||||
XML_PROP_ERROR_INVALID_TYPE = 2, // i.e. the property is known but expects a
|
||||
// different type (so a different
|
||||
// getter/setter would need to be called)
|
||||
XML_PROP_ERROR_INVALID_VALUE = 3, // i.e. the value is invalid (with a setter
|
||||
// function) or a NULL-pointer (with a
|
||||
// getter function)
|
||||
|
||||
XML_PROP_ERROR_PARSER_NULL = 4, // i.e. the parser argument is NULL
|
||||
XML_PROP_ERROR_PARSER_NOT_ROOT = 5, // i.e. the parser is not a root parser
|
||||
// but a subparser (and a root parser is
|
||||
// needed)
|
||||
|
||||
/* potentially more error codes upcoming here */
|
||||
};</pre>
|
||||
<p>
|
||||
Let us look at these functions in more detail:
|
||||
</p>
|
||||
|
||||
<h4 id="XML_GetPropertyBool">
|
||||
XML_GetPropertyBool
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
enum XML_Prop_Error
|
||||
XML_GetPropertyBool(XML_Parser parser, enum XML_Parser_Property property,
|
||||
XML_Bool *value);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
<p>
|
||||
Writes the current value of boolean property <code>property</code> of parser
|
||||
<code>parser</code> to output variable <code>value</code>. Supported properties
|
||||
are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code>XML_PROP_REPARSE_DEFERRAL_ENABLED</code> — whether <a href=
|
||||
"#XML_SetReparseDeferralEnabled">reparse deferral</a> is active or not
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Both parameters <code>parser</code> and <code>value</code> must be
|
||||
non-<code>NULL</code>. On success <code>XML_PROP_ERROR_NONE</code> is returned;
|
||||
on error one of the other variants of <a href=
|
||||
"#XML_Prop_Error">XML_Prop_Error</a> is returned.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> There may be more error codes introduced into <a href=
|
||||
"#XML_Prop_Error">XML_Prop_Error</a> in the future, so user code must be robust
|
||||
towards error codes from the future at runtime that were not known at compile
|
||||
time.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetPropertyDouble">
|
||||
XML_GetPropertyDouble
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
enum XML_Prop_Error
|
||||
XML_GetPropertyDouble(XML_Parser parser, enum XML_Parser_Property property,
|
||||
double *value);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
<p>
|
||||
Writes the current value of floating point property <code>property</code> of
|
||||
parser <code>parser</code> to output variable <code>value</code>. Supported
|
||||
properties are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code>XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION</code> — the maximum
|
||||
tolerated amplification with the <a href=
|
||||
"#XML_SetAllocTrackerMaximumAmplification">allocation tracker</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code>XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION</code> — the maximum
|
||||
tolerated amplification with <a href=
|
||||
"#XML_SetBillionLaughsAttackProtectionMaximumAmplification">billion laughs
|
||||
attack protection</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Both parameters <code>parser</code> and <code>value</code> must be
|
||||
non-<code>NULL</code>. On success <code>XML_PROP_ERROR_NONE</code> is returned;
|
||||
on error one of the other variants of <a href=
|
||||
"#XML_Prop_Error">XML_Prop_Error</a> is returned.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> There may be more error codes introduced into <a href=
|
||||
"#XML_Prop_Error">XML_Prop_Error</a> in the future, so user code must be robust
|
||||
towards error codes from the future at runtime that were not known at compile
|
||||
time.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetPropertyUInt64">
|
||||
XML_GetPropertyUInt64
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
enum XML_Prop_Error
|
||||
XML_GetPropertyUInt64(XML_Parser parser, enum XML_Parser_Property property,
|
||||
uint64_t *value);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
<p>
|
||||
Writes the current value of integral property <code>property</code> of parser
|
||||
<code>parser</code> to output variable <code>value</code>. Supported properties
|
||||
are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code>XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD</code> — the activation
|
||||
threshold in bytes with the <a href=
|
||||
"#XML_SetAllocTrackerActivationThreshold">allocation tracker</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code>XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD</code> — the activation
|
||||
threshold in bytes with <a href=
|
||||
"#XML_SetBillionLaughsAttackProtectionActivationThreshold">billion laughs
|
||||
attack protection</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Both parameters <code>parser</code> and <code>value</code> must be
|
||||
non-<code>NULL</code>. On success <code>XML_PROP_ERROR_NONE</code> is returned;
|
||||
on error one of the other variants of <a href=
|
||||
"#XML_Prop_Error">XML_Prop_Error</a> is returned.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> There may be more error codes introduced into <a href=
|
||||
"#XML_Prop_Error">XML_Prop_Error</a> in the future, so user code must be robust
|
||||
towards error codes from the future at runtime that were not known at compile
|
||||
time.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h3>
|
||||
<a id="attack-protection" name="attack-protection">Attack Protection</a><a id=
|
||||
"billion-laughs" name="billion-laughs"></a>
|
||||
</h3>
|
||||
|
||||
<h4 id="XML_SetPropertyBool">
|
||||
XML_SetPropertyBool
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
enum XML_Prop_Error
|
||||
XML_SetPropertyBool(XML_Parser parser, enum XML_Parser_Property property,
|
||||
XML_Bool value);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
<p>
|
||||
Applies the given value <code>value</code> to boolean property
|
||||
<code>property</code> of parser <code>parser</code>. Supported properties are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code>XML_PROP_REPARSE_DEFERRAL_ENABLED</code> — whether <a href=
|
||||
"#XML_SetReparseDeferralEnabled">reparse deferral</a> is active or not
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Parameter <code>parser</code> must be non-<code>NULL</code>. On success
|
||||
<code>XML_PROP_ERROR_NONE</code> is returned; on error one of the other
|
||||
variants of <a href="#XML_Prop_Error">XML_Prop_Error</a> is returned.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> There may be more error codes introduced into <a href=
|
||||
"#XML_Prop_Error">XML_Prop_Error</a> in the future, so user code must be robust
|
||||
towards error codes from the future at runtime that were not known at compile
|
||||
time.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h4 id="XML_SetPropertyDouble">
|
||||
XML_SetPropertyDouble
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
enum XML_Prop_Error
|
||||
XML_SetPropertyDouble(XML_Parser parser, enum XML_Parser_Property property,
|
||||
double value);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
<p>
|
||||
Applies the given value <code>value</code> to floating point property
|
||||
<code>property</code> of parser <code>parser</code>. Supported properties are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code>XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION</code> — the maximum
|
||||
tolerated amplification with the <a href=
|
||||
"#XML_SetAllocTrackerMaximumAmplification">allocation tracker</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code>XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION</code> — the maximum
|
||||
tolerated amplification with <a href=
|
||||
"#XML_SetBillionLaughsAttackProtectionMaximumAmplification">billion laughs
|
||||
attack protection</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Value <code>value</code> may or may not be cast to <code>float</code>
|
||||
internally.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Parameter <code>parser</code> must be non-<code>NULL</code>. On success
|
||||
<code>XML_PROP_ERROR_NONE</code> is returned; on error one of the other
|
||||
variants of <a href="#XML_Prop_Error">XML_Prop_Error</a> is returned.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> There may be more error codes introduced into <a href=
|
||||
"#XML_Prop_Error">XML_Prop_Error</a> in the future, so user code must be robust
|
||||
towards error codes from the future at runtime that were not known at compile
|
||||
time.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h4 id="XML_SetPropertyUInt64">
|
||||
XML_SetPropertyUInt64
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
/* Added in Expat 2.9.0. */
|
||||
enum XML_Prop_Error
|
||||
XML_SetPropertyUInt64(XML_Parser parser, enum XML_Parser_Property property,
|
||||
uint64_t value);
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
<p>
|
||||
Applies the given value <code>value</code> to integral property
|
||||
<code>property</code> of parser <code>parser</code>. Supported properties are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code>XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD</code> — the activation
|
||||
threshold in bytes with the <a href=
|
||||
"#XML_SetAllocTrackerActivationThreshold">allocation tracker</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<code>XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD</code> — the activation
|
||||
threshold in bytes with <a href=
|
||||
"#XML_SetBillionLaughsAttackProtectionActivationThreshold">billion laughs
|
||||
attack protection</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Parameter <code>parser</code> must be non-<code>NULL</code>. On success
|
||||
<code>XML_PROP_ERROR_NONE</code> is returned; on error one of the other
|
||||
variants of <a href="#XML_Prop_Error">XML_Prop_Error</a> is returned.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> There may be more error codes introduced into <a href=
|
||||
"#XML_Prop_Error">XML_Prop_Error</a> in the future, so user code must be robust
|
||||
towards error codes from the future at runtime that were not known at compile
|
||||
time.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h4 id="XML_SetBillionLaughsAttackProtectionMaximumAmplification">
|
||||
XML_SetBillionLaughsAttackProtectionMaximumAmplification
|
||||
</h4>
|
||||
@@ -3405,38 +4041,6 @@ XML_GetIdAttributeIndex(XML_Parser p);
|
||||
means the current call.
|
||||
</div>
|
||||
|
||||
<h4 id="XML_GetAttributeInfo">
|
||||
XML_GetAttributeInfo
|
||||
</h4>
|
||||
|
||||
<pre class="fcndec">
|
||||
const XML_AttrInfo * XMLCALL
|
||||
XML_GetAttributeInfo(XML_Parser parser);
|
||||
</pre>
|
||||
|
||||
<pre class="signature">
|
||||
typedef struct {
|
||||
XML_Index nameStart; /* Offset to beginning of the attribute name. */
|
||||
XML_Index nameEnd; /* Offset after the attribute name's last byte. */
|
||||
XML_Index valueStart; /* Offset to beginning of the attribute value. */
|
||||
XML_Index valueEnd; /* Offset after the attribute value's last byte. */
|
||||
} XML_AttrInfo;
|
||||
</pre>
|
||||
<div class="fcndef">
|
||||
Returns an array of <code>XML_AttrInfo</code> structures for the attribute/value
|
||||
pairs passed in the last call to the <code>XML_StartElementHandler</code> that
|
||||
were specified in the start-tag rather than defaulted. Each attribute/value pair
|
||||
counts as 1; thus the number of entries in the array is
|
||||
<code>XML_GetSpecifiedAttributeCount(parser) / 2</code>.
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<strong>Note:</strong> Type <code>XML_Index</code> is known to wrap around on
|
||||
32bit platforms and 64bit Windows unless Expat has been compiled with
|
||||
(non-default and uncommon) macro <code><a href=
|
||||
"#XML_LARGE_SIZE">XML_LARGE_SIZE</a></code>.
|
||||
</p>
|
||||
|
||||
<h4 id="XML_SetEncoding">
|
||||
XML_SetEncoding
|
||||
</h4>
|
||||
@@ -3495,6 +4099,11 @@ int XMLCALL
|
||||
XML_SetHashSalt(XML_Parser parser,
|
||||
unsigned long hash_salt);
|
||||
</pre>
|
||||
<p>
|
||||
<b>Note:</b> This function is deprecated, please use function <code><a href=
|
||||
"#XML_SetHashSalt16Bytes">XML_SetHashSalt16Bytes</a></code>, instead.
|
||||
</p>
|
||||
|
||||
<div class="fcndef">
|
||||
Sets the hash salt to use for internal hash calculations. Helps in preventing DoS
|
||||
attacks based on predicting hash function behavior. In order to have an effect
|
||||
@@ -3502,15 +4111,13 @@ XML_SetHashSalt(XML_Parser parser,
|
||||
called after <code>XML_Parse</code> or <code>XML_ParseBuffer</code> or when
|
||||
<code>parser</code> is <code>NULL</code>.
|
||||
<p>
|
||||
<b>Note:</b> Function <code>XML_SetHashSalt</code> is
|
||||
<strong>deprecated</strong>. Please use function <code><a href=
|
||||
"#XML_SetHashSalt16Bytes">XML_SetHashSalt16Bytes</a></code> instead for better
|
||||
security. <code>XML_SetHashSalt</code> only provides 4 to 8 bytes of entropy
|
||||
(depending on the size of type <code>unsigned long</code>) while the SipHash
|
||||
implementation used by Expat can leverage up to 16 bytes of entropy — at least
|
||||
twice as much. Function <code><a href=
|
||||
<b>Note:</b> Function <code>XML_SetHashSalt</code> only provides 4 to 8 bytes
|
||||
of entropy (depending on the size of type <code>unsigned long</code>) while the
|
||||
SipHash implementation used by Expat can leverage up to 16 bytes of entropy —
|
||||
at least twice as much. Function <code><a href=
|
||||
"#XML_SetHashSalt16Bytes">XML_SetHashSalt16Bytes</a></code> of Expat >=2.8.0
|
||||
(and where backported) matches the amount of entropy supported by SipHash.
|
||||
(and where backported) with better security matches the amount of entropy
|
||||
supported by SipHash.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -3710,6 +4317,7 @@ enum XML_FeatureEnum {
|
||||
XML_FEATURE_UNICODE_WCHAR_T,
|
||||
XML_FEATURE_DTD,
|
||||
XML_FEATURE_CONTEXT_BYTES,
|
||||
/* Added in Expat 1.95.5, removed in Expat 2.9.0. */
|
||||
XML_FEATURE_MIN_SIZE,
|
||||
XML_FEATURE_SIZEOF_XML_CHAR,
|
||||
XML_FEATURE_SIZEOF_XML_LCHAR,
|
||||
@@ -3717,7 +4325,7 @@ enum XML_FeatureEnum {
|
||||
XML_FEATURE_NS,
|
||||
/* Added in Expat 2.0.1. */
|
||||
XML_FEATURE_LARGE_SIZE,
|
||||
/* Added in Expat 2.1.0. */
|
||||
/* Added in Expat 2.1.0, removed in Expat 2.9.0. */
|
||||
XML_FEATURE_ATTR_INFO,
|
||||
/* Added in Expat 2.4.0. */
|
||||
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
\\$2 \(la\\$1\(ra\\$3
|
||||
..
|
||||
.if \n(.g .mso www.tmac
|
||||
.TH XMLWF 1 "September 22, 2026" "" ""
|
||||
.TH XMLWF 1 "October 5, 2026" "" ""
|
||||
.SH NAME
|
||||
xmlwf \- Determines if an XML document is well-formed
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
<!ENTITY dhfirstname "<firstname>Scott</firstname>">
|
||||
<!ENTITY dhsurname "<surname>Bronson</surname>">
|
||||
<!ENTITY dhdate "<date>September 22, 2026</date>">
|
||||
<!ENTITY dhdate "<date>October 5, 2026</date>">
|
||||
<!-- Please adjust this^^ date whenever cutting a new release. -->
|
||||
<!ENTITY dhsection "<manvolnum>1</manvolnum>">
|
||||
<!ENTITY dhemail "<email>[email protected]</email>">
|
||||
|
||||
@@ -262,12 +262,10 @@ ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXPAT_ATTR_INFO = @EXPAT_ATTR_INFO@
|
||||
EXPAT_CHAR_TYPE = @EXPAT_CHAR_TYPE@
|
||||
EXPAT_CONTEXT_BYTES = @EXPAT_CONTEXT_BYTES@
|
||||
EXPAT_DTD = @EXPAT_DTD@
|
||||
EXPAT_LARGE_SIZE = @EXPAT_LARGE_SIZE@
|
||||
EXPAT_MIN_SIZE = @EXPAT_MIN_SIZE@
|
||||
EXPAT_NS = @EXPAT_NS@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
@@ -322,7 +320,6 @@ SO_PATCH = @SO_PATCH@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
VSCRIPT_LDFLAGS = @VSCRIPT_LDFLAGS@
|
||||
_EXPAT_COMMENT_ATTR_INFO = @_EXPAT_COMMENT_ATTR_INFO@
|
||||
_EXPAT_COMMENT_DTD_OR_GE = @_EXPAT_COMMENT_DTD_OR_GE@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
||||
Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net>
|
||||
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
||||
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||
Copyright (c) 2019 Zhongyuan Zhou <zhouzhongyuan@huawei.com>
|
||||
Copyright (c) 2024 Hanno Böck <hanno@gentoo.org>
|
||||
@@ -41,17 +41,12 @@
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <inttypes.h> // PRIu64
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <expat.h>
|
||||
|
||||
#ifdef XML_LARGE_SIZE
|
||||
# define XML_FMT_INT_MOD "ll"
|
||||
#else
|
||||
# define XML_FMT_INT_MOD "l"
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
# define XML_FMT_STR "ls"
|
||||
#else
|
||||
@@ -225,9 +220,8 @@ main(void) {
|
||||
if (errorCode == XML_ERROR_ABORTED) {
|
||||
errorCode = XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
|
||||
XML_GetCurrentLineNumber(parser), XML_ErrorString(errorCode));
|
||||
fprintf(stderr, "Parse error at line %" PRIu64 ":\n%" XML_FMT_STR "\n",
|
||||
XML_GetCurrentLineNumber64(parser), XML_ErrorString(errorCode));
|
||||
XML_ParserFree(parser);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
||||
Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net>
|
||||
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
||||
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||
Copyright (c) 2019 Zhongyuan Zhou <zhouzhongyuan@huawei.com>
|
||||
Licensed under the MIT license:
|
||||
@@ -41,15 +41,10 @@
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <inttypes.h> // PRIu64
|
||||
#include <stdio.h>
|
||||
#include <expat.h>
|
||||
|
||||
#ifdef XML_LARGE_SIZE
|
||||
# define XML_FMT_INT_MOD "ll"
|
||||
#else
|
||||
# define XML_FMT_INT_MOD "l"
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
# define XML_FMT_STR "ls"
|
||||
#else
|
||||
@@ -109,9 +104,8 @@ main(void) {
|
||||
done = feof(stdin);
|
||||
|
||||
if (XML_ParseBuffer(parser, (int)len, done) == XML_STATUS_ERROR) {
|
||||
fprintf(stderr,
|
||||
"Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
|
||||
XML_GetCurrentLineNumber(parser),
|
||||
fprintf(stderr, "Parse error at line %" PRIu64 ":\n%" XML_FMT_STR "\n",
|
||||
XML_GetCurrentLineNumber64(parser),
|
||||
XML_ErrorString(XML_GetErrorCode(parser)));
|
||||
XML_ParserFree(parser);
|
||||
return 1;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
||||
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
||||
Copyright (c) 2005-2006 Karl Waclawek <karl@waclawek.net>
|
||||
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||
Licensed under the MIT license:
|
||||
|
||||
@@ -38,15 +38,10 @@
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <inttypes.h> // PRIu64
|
||||
#include <stdio.h>
|
||||
#include <expat.h>
|
||||
|
||||
#ifdef XML_LARGE_SIZE
|
||||
# define XML_FMT_INT_MOD "ll"
|
||||
#else
|
||||
# define XML_FMT_INT_MOD "l"
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
# define XML_FMT_STR "ls"
|
||||
#else
|
||||
@@ -112,9 +107,8 @@ main(void) {
|
||||
done = feof(stdin);
|
||||
|
||||
if (XML_ParseBuffer(parser, (int)len, done) == XML_STATUS_ERROR) {
|
||||
fprintf(stderr,
|
||||
"Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
|
||||
XML_GetCurrentLineNumber(parser),
|
||||
fprintf(stderr, "Parse error at line %" PRIu64 ":\n%" XML_FMT_STR "\n",
|
||||
XML_GetCurrentLineNumber64(parser),
|
||||
XML_ErrorString(XML_GetErrorCode(parser)));
|
||||
XML_ParserFree(parser);
|
||||
return 1;
|
||||
|
||||
@@ -113,10 +113,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define to allow retrieving the byte offsets for attribute names and values.
|
||||
*/
|
||||
#undef XML_ATTR_INFO
|
||||
|
||||
/* Define to specify how much context to retain around the current parse
|
||||
point, 0 to disable. */
|
||||
#undef XML_CONTEXT_BYTES
|
||||
|
||||
@@ -79,7 +79,7 @@ ParseOneInput(XML_Parser p, const uint8_t *data, size_t size) {
|
||||
if (XML_Parse(p, (const XML_Char *)data, (int)size, 1) == XML_STATUS_ERROR) {
|
||||
XML_ErrorString(XML_GetErrorCode(p));
|
||||
}
|
||||
XML_GetCurrentLineNumber(p);
|
||||
XML_GetCurrentLineNumber64(p);
|
||||
if (size % 2) {
|
||||
XML_ParserReset(p, NULL);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ ParseOneInput(XML_Parser p, const uint8_t *data, size_t size) {
|
||||
if (XML_ParseBuffer(p, (int)size, 1) == XML_STATUS_ERROR) {
|
||||
XML_ErrorString(XML_GetErrorCode(p));
|
||||
}
|
||||
XML_GetCurrentLineNumber(p);
|
||||
XML_GetCurrentLineNumber64(p);
|
||||
if (size % 2) {
|
||||
XML_ParserReset(p, NULL);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ libexpat_la_LDFLAGS += $(VSCRIPT_LDFLAGS),@builddir@/libexpat.map
|
||||
endif
|
||||
|
||||
libexpat_la_SOURCES = \
|
||||
xcs.c \
|
||||
xmlparse.c \
|
||||
xmltok.c \
|
||||
xmlrole.c
|
||||
@@ -125,7 +126,7 @@ EXTRA_DIST = \
|
||||
siphash.h \
|
||||
utf8tab.h \
|
||||
winconfig.h \
|
||||
xcsinc.c \
|
||||
xcs.h \
|
||||
xmlrole.h \
|
||||
xmltok.h \
|
||||
xmltok_impl.c \
|
||||
|
||||
@@ -206,7 +206,7 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(docdir)" \
|
||||
"$(DESTDIR)$(includedir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
|
||||
libexpat_la_LIBADD =
|
||||
am__libexpat_la_SOURCES_DIST = xmlparse.c xmltok.c xmlrole.c \
|
||||
am__libexpat_la_SOURCES_DIST = xcs.c xmlparse.c xmltok.c xmlrole.c \
|
||||
random_arc4random.c random_arc4random.h \
|
||||
random_arc4random_buf.c random_arc4random_buf.h \
|
||||
random_dev_urandom.c random_dev_urandom.h random_getentropy.c \
|
||||
@@ -218,7 +218,7 @@ am__libexpat_la_SOURCES_DIST = xmlparse.c xmltok.c xmlrole.c \
|
||||
@WITH_GETENTROPY_TRUE@am__objects_4 = random_getentropy.lo
|
||||
@WITH_EITHER_GETRANDOM_TRUE@am__objects_5 = random_getrandom.lo
|
||||
@MINGW_TRUE@am__objects_6 = random_rand_s.lo
|
||||
am_libexpat_la_OBJECTS = xmlparse.lo xmltok.lo xmlrole.lo \
|
||||
am_libexpat_la_OBJECTS = xcs.lo xmlparse.lo xmltok.lo xmlrole.lo \
|
||||
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||
$(am__objects_4) $(am__objects_5) $(am__objects_6)
|
||||
libexpat_la_OBJECTS = $(am_libexpat_la_OBJECTS)
|
||||
@@ -230,7 +230,7 @@ libexpat_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(libexpat_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
libtestpat_la_LIBADD =
|
||||
am__libtestpat_la_SOURCES_DIST = xmlparse.c xmltok.c xmlrole.c \
|
||||
am__libtestpat_la_SOURCES_DIST = xcs.c xmlparse.c xmltok.c xmlrole.c \
|
||||
random_arc4random.c random_arc4random.h \
|
||||
random_arc4random_buf.c random_arc4random_buf.h \
|
||||
random_dev_urandom.c random_dev_urandom.h random_getentropy.c \
|
||||
@@ -245,10 +245,10 @@ am__libtestpat_la_SOURCES_DIST = xmlparse.c xmltok.c xmlrole.c \
|
||||
@WITH_EITHER_GETRANDOM_TRUE@am__objects_11 = \
|
||||
@WITH_EITHER_GETRANDOM_TRUE@ libtestpat_la-random_getrandom.lo
|
||||
@MINGW_TRUE@am__objects_12 = libtestpat_la-random_rand_s.lo
|
||||
am__objects_13 = libtestpat_la-xmlparse.lo libtestpat_la-xmltok.lo \
|
||||
libtestpat_la-xmlrole.lo $(am__objects_7) $(am__objects_8) \
|
||||
$(am__objects_9) $(am__objects_10) $(am__objects_11) \
|
||||
$(am__objects_12)
|
||||
am__objects_13 = libtestpat_la-xcs.lo libtestpat_la-xmlparse.lo \
|
||||
libtestpat_la-xmltok.lo libtestpat_la-xmlrole.lo \
|
||||
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
|
||||
$(am__objects_10) $(am__objects_11) $(am__objects_12)
|
||||
@WITH_TESTS_TRUE@am_libtestpat_la_OBJECTS = $(am__objects_13)
|
||||
libtestpat_la_OBJECTS = $(am_libtestpat_la_OBJECTS)
|
||||
@WITH_TESTS_TRUE@am_libtestpat_la_rpath =
|
||||
@@ -273,6 +273,7 @@ am__depfiles_remade = ./$(DEPDIR)/libtestpat_la-random_arc4random.Plo \
|
||||
./$(DEPDIR)/libtestpat_la-random_getentropy.Plo \
|
||||
./$(DEPDIR)/libtestpat_la-random_getrandom.Plo \
|
||||
./$(DEPDIR)/libtestpat_la-random_rand_s.Plo \
|
||||
./$(DEPDIR)/libtestpat_la-xcs.Plo \
|
||||
./$(DEPDIR)/libtestpat_la-xmlparse.Plo \
|
||||
./$(DEPDIR)/libtestpat_la-xmlrole.Plo \
|
||||
./$(DEPDIR)/libtestpat_la-xmltok.Plo \
|
||||
@@ -281,8 +282,8 @@ am__depfiles_remade = ./$(DEPDIR)/libtestpat_la-random_arc4random.Plo \
|
||||
./$(DEPDIR)/random_dev_urandom.Plo \
|
||||
./$(DEPDIR)/random_getentropy.Plo \
|
||||
./$(DEPDIR)/random_getrandom.Plo ./$(DEPDIR)/random_rand_s.Plo \
|
||||
./$(DEPDIR)/xmlparse.Plo ./$(DEPDIR)/xmlrole.Plo \
|
||||
./$(DEPDIR)/xmltok.Plo
|
||||
./$(DEPDIR)/xcs.Plo ./$(DEPDIR)/xmlparse.Plo \
|
||||
./$(DEPDIR)/xmlrole.Plo ./$(DEPDIR)/xmltok.Plo
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
@@ -369,12 +370,10 @@ ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXPAT_ATTR_INFO = @EXPAT_ATTR_INFO@
|
||||
EXPAT_CHAR_TYPE = @EXPAT_CHAR_TYPE@
|
||||
EXPAT_CONTEXT_BYTES = @EXPAT_CONTEXT_BYTES@
|
||||
EXPAT_DTD = @EXPAT_DTD@
|
||||
EXPAT_LARGE_SIZE = @EXPAT_LARGE_SIZE@
|
||||
EXPAT_MIN_SIZE = @EXPAT_MIN_SIZE@
|
||||
EXPAT_NS = @EXPAT_NS@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
@@ -429,7 +428,6 @@ SO_PATCH = @SO_PATCH@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
VSCRIPT_LDFLAGS = @VSCRIPT_LDFLAGS@
|
||||
_EXPAT_COMMENT_ATTR_INFO = @_EXPAT_COMMENT_ATTR_INFO@
|
||||
_EXPAT_COMMENT_DTD_OR_GE = @_EXPAT_COMMENT_DTD_OR_GE@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
@@ -497,9 +495,9 @@ lib_LTLIBRARIES = libexpat.la
|
||||
@WITH_TESTS_TRUE@noinst_LTLIBRARIES = libtestpat.la
|
||||
libexpat_la_LDFLAGS = @AM_LDFLAGS@ @LIBM@ -no-undefined -version-info \
|
||||
@LIBCURRENT@:@LIBREVISION@:@LIBAGE@ $(am__append_1)
|
||||
libexpat_la_SOURCES = xmlparse.c xmltok.c xmlrole.c $(am__append_2) \
|
||||
$(am__append_3) $(am__append_4) $(am__append_5) \
|
||||
$(am__append_6) $(am__append_7)
|
||||
libexpat_la_SOURCES = xcs.c xmlparse.c xmltok.c xmlrole.c \
|
||||
$(am__append_2) $(am__append_3) $(am__append_4) \
|
||||
$(am__append_5) $(am__append_6) $(am__append_7)
|
||||
@WITH_TESTS_TRUE@libtestpat_la_CPPFLAGS = -DXML_TESTING
|
||||
@WITH_TESTS_TRUE@libtestpat_la_SOURCES = $(libexpat_la_SOURCES)
|
||||
doc_DATA = \
|
||||
@@ -522,7 +520,7 @@ EXTRA_DIST = \
|
||||
siphash.h \
|
||||
utf8tab.h \
|
||||
winconfig.h \
|
||||
xcsinc.c \
|
||||
xcs.h \
|
||||
xmlrole.h \
|
||||
xmltok.h \
|
||||
xmltok_impl.c \
|
||||
@@ -625,6 +623,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-random_getentropy.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-random_getrandom.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-random_rand_s.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-xcs.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-xmlparse.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-xmlrole.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtestpat_la-xmltok.Plo@am__quote@ # am--include-marker
|
||||
@@ -634,6 +633,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random_getentropy.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random_getrandom.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random_rand_s.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcs.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlparse.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlrole.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltok.Plo@am__quote@ # am--include-marker
|
||||
@@ -668,6 +668,13 @@ am--depfiles: $(am__depfiles_remade)
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
libtestpat_la-xcs.lo: xcs.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestpat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtestpat_la-xcs.lo -MD -MP -MF $(DEPDIR)/libtestpat_la-xcs.Tpo -c -o libtestpat_la-xcs.lo `test -f 'xcs.c' || echo '$(srcdir)/'`xcs.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtestpat_la-xcs.Tpo $(DEPDIR)/libtestpat_la-xcs.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xcs.c' object='libtestpat_la-xcs.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestpat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtestpat_la-xcs.lo `test -f 'xcs.c' || echo '$(srcdir)/'`xcs.c
|
||||
|
||||
libtestpat_la-xmlparse.lo: xmlparse.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtestpat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtestpat_la-xmlparse.lo -MD -MP -MF $(DEPDIR)/libtestpat_la-xmlparse.Tpo -c -o libtestpat_la-xmlparse.lo `test -f 'xmlparse.c' || echo '$(srcdir)/'`xmlparse.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtestpat_la-xmlparse.Tpo $(DEPDIR)/libtestpat_la-xmlparse.Plo
|
||||
@@ -914,6 +921,7 @@ distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-random_getentropy.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-random_getrandom.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-random_rand_s.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-xcs.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-xmlparse.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-xmlrole.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-xmltok.Plo
|
||||
@@ -923,6 +931,7 @@ distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/random_getentropy.Plo
|
||||
-rm -f ./$(DEPDIR)/random_getrandom.Plo
|
||||
-rm -f ./$(DEPDIR)/random_rand_s.Plo
|
||||
-rm -f ./$(DEPDIR)/xcs.Plo
|
||||
-rm -f ./$(DEPDIR)/xmlparse.Plo
|
||||
-rm -f ./$(DEPDIR)/xmlrole.Plo
|
||||
-rm -f ./$(DEPDIR)/xmltok.Plo
|
||||
@@ -978,6 +987,7 @@ maintainer-clean: maintainer-clean-am
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-random_getentropy.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-random_getrandom.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-random_rand_s.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-xcs.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-xmlparse.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-xmlrole.Plo
|
||||
-rm -f ./$(DEPDIR)/libtestpat_la-xmltok.Plo
|
||||
@@ -987,6 +997,7 @@ maintainer-clean: maintainer-clean-am
|
||||
-rm -f ./$(DEPDIR)/random_getentropy.Plo
|
||||
-rm -f ./$(DEPDIR)/random_getrandom.Plo
|
||||
-rm -f ./$(DEPDIR)/random_rand_s.Plo
|
||||
-rm -f ./$(DEPDIR)/xcs.Plo
|
||||
-rm -f ./$(DEPDIR)/xmlparse.Plo
|
||||
-rm -f ./$(DEPDIR)/xmlrole.Plo
|
||||
-rm -f ./$(DEPDIR)/xmltok.Plo
|
||||
|
||||
+72
-27
@@ -48,7 +48,7 @@
|
||||
#ifndef Expat_INCLUDED
|
||||
# define Expat_INCLUDED 1
|
||||
|
||||
# include <stdint.h> // for uint8_t
|
||||
# include <stdint.h> // for int64_t, uint8_t, uint64_t
|
||||
# include <stdlib.h>
|
||||
# include "expat_external.h"
|
||||
|
||||
@@ -140,6 +140,26 @@ enum XML_Error {
|
||||
XML_ERROR_NOT_STARTED,
|
||||
};
|
||||
|
||||
/* Added in 2.9.0. */
|
||||
enum XML_Prop_Error {
|
||||
XML_PROP_ERROR_NONE = 0, // i.e. success
|
||||
|
||||
XML_PROP_ERROR_INVALID_KEY = 1, // i.e. the property is not known at all
|
||||
XML_PROP_ERROR_INVALID_TYPE = 2, // i.e. the property is known but expects a
|
||||
// different type (so a different
|
||||
// getter/setter would need to be called)
|
||||
XML_PROP_ERROR_INVALID_VALUE = 3, // i.e. the value is invalid (with a setter
|
||||
// function) or a NULL-pointer (with a
|
||||
// getter function)
|
||||
|
||||
XML_PROP_ERROR_PARSER_NULL = 4, // i.e. the parser argument is NULL
|
||||
XML_PROP_ERROR_PARSER_NOT_ROOT = 5, // i.e. the parser is not a root parser
|
||||
// but a subparser (and a root parser is
|
||||
// needed)
|
||||
|
||||
/* potentially more error codes upcoming here */
|
||||
};
|
||||
|
||||
enum XML_Content_Type {
|
||||
XML_CTYPE_EMPTY = 1,
|
||||
XML_CTYPE_ANY,
|
||||
@@ -757,29 +777,6 @@ XML_GetSpecifiedAttributeCount(XML_Parser parser);
|
||||
XMLPARSEAPI(int)
|
||||
XML_GetIdAttributeIndex(XML_Parser parser);
|
||||
|
||||
# ifdef XML_ATTR_INFO
|
||||
/* Source file byte offsets for the start and end of attribute names and values.
|
||||
The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
|
||||
file an attribute value of "blah" will yield:
|
||||
info->valueEnd - info->valueStart = 4 bytes.
|
||||
*/
|
||||
typedef struct {
|
||||
XML_Index nameStart; /* Offset to beginning of the attribute name. */
|
||||
XML_Index nameEnd; /* Offset after the attribute name's last byte. */
|
||||
XML_Index valueStart; /* Offset to beginning of the attribute value. */
|
||||
XML_Index valueEnd; /* Offset after the attribute value's last byte. */
|
||||
} XML_AttrInfo;
|
||||
|
||||
/* Returns an array of XML_AttrInfo structures for the attribute/value pairs
|
||||
passed in last call to the XML_StartElementHandler that were specified
|
||||
in the start-tag rather than defaulted. Each attribute/value pair counts
|
||||
as 1; thus the number of entries in the array is
|
||||
XML_GetSpecifiedAttributeCount(parser) / 2.
|
||||
*/
|
||||
XMLPARSEAPI(const XML_AttrInfo *)
|
||||
XML_GetAttributeInfo(XML_Parser parser);
|
||||
# endif
|
||||
|
||||
/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
|
||||
detected. The last call to XML_Parse must have isFinal true; len
|
||||
may be zero for this call (or any other).
|
||||
@@ -964,15 +961,24 @@ XML_GetErrorCode(XML_Parser parser);
|
||||
return 0 to indicate an error.
|
||||
Note: XML_GetCurrentByteIndex returns -1 to indicate an error.
|
||||
*/
|
||||
XML_ATTR_DEPRECATED("please use XML_GetCurrentLineNumber64 instead")
|
||||
XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
|
||||
XMLPARSEAPI(uint64_t) XML_GetCurrentLineNumber64(XML_Parser parser);
|
||||
XML_ATTR_DEPRECATED("please use XML_GetCurrentColumnNumber64 instead")
|
||||
XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
|
||||
XMLPARSEAPI(uint64_t) XML_GetCurrentColumnNumber64(XML_Parser parser);
|
||||
XML_ATTR_DEPRECATED("please use XML_GetCurrentByteIndex64 instead")
|
||||
XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
|
||||
XMLPARSEAPI(int64_t) XML_GetCurrentByteIndex64(XML_Parser parser);
|
||||
|
||||
/* Return the number of bytes in the current event.
|
||||
Returns 0 if the event is in an internal entity.
|
||||
*/
|
||||
XML_ATTR_DEPRECATED("please use XML_GetCurrentByteCount64 instead")
|
||||
XMLPARSEAPI(int)
|
||||
XML_GetCurrentByteCount(XML_Parser parser);
|
||||
XMLPARSEAPI(uint64_t)
|
||||
XML_GetCurrentByteCount64(XML_Parser parser);
|
||||
|
||||
/* If XML_CONTEXT_BYTES is >=1, returns the input buffer, sets
|
||||
the integer pointed to by offset to the offset within this buffer
|
||||
@@ -984,8 +990,11 @@ XML_GetCurrentByteCount(XML_Parser parser);
|
||||
NOTE: The character pointer returned should not be used outside
|
||||
the handler that makes the call.
|
||||
*/
|
||||
XML_ATTR_DEPRECATED("please use XML_GetInputContext64 instead")
|
||||
XMLPARSEAPI(const char *)
|
||||
XML_GetInputContext(XML_Parser parser, int *offset, int *size);
|
||||
XMLPARSEAPI(const char *)
|
||||
XML_GetInputContext64(XML_Parser parser, int64_t *offset, uint64_t *size);
|
||||
|
||||
/* For backwards compatibility with previous versions. */
|
||||
# define XML_GetErrorLineNumber XML_GetCurrentLineNumber
|
||||
@@ -1040,6 +1049,7 @@ enum XML_FeatureEnum {
|
||||
XML_FEATURE_UNICODE_WCHAR_T,
|
||||
XML_FEATURE_DTD,
|
||||
XML_FEATURE_CONTEXT_BYTES,
|
||||
/* Added in Expat 1.95.5, removed in Expat 2.9.0. */
|
||||
XML_FEATURE_MIN_SIZE,
|
||||
XML_FEATURE_SIZEOF_XML_CHAR,
|
||||
XML_FEATURE_SIZEOF_XML_LCHAR,
|
||||
@@ -1047,7 +1057,7 @@ enum XML_FeatureEnum {
|
||||
XML_FEATURE_NS,
|
||||
/* Added in Expat 2.0.1. */
|
||||
XML_FEATURE_LARGE_SIZE,
|
||||
/* Added in Expat 2.1.0. */
|
||||
/* Added in Expat 2.1.0, removed in Expat 2.9.0. */
|
||||
XML_FEATURE_ATTR_INFO,
|
||||
/* Added in Expat 2.4.0. */
|
||||
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
|
||||
@@ -1069,6 +1079,41 @@ typedef struct {
|
||||
XMLPARSEAPI(const XML_Feature *)
|
||||
XML_GetFeatureList(void);
|
||||
|
||||
/* Added in Expat 2.9.0. */
|
||||
enum XML_Parser_Property {
|
||||
# if defined(XML_TESTING)
|
||||
XML_PROP_INVALID = 0,
|
||||
# endif
|
||||
# if XML_GE == 1
|
||||
XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD = 1, // of type `uint64_t`
|
||||
XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION = 2, // of type `double`
|
||||
XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD = 3, // of type `uint64_t`
|
||||
XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION = 4, // of type `double`
|
||||
# endif
|
||||
XML_PROP_REPARSE_DEFERRAL_ENABLED = 5, // of type `XML_Bool`
|
||||
/* more properties upcoming here */
|
||||
};
|
||||
|
||||
/* Added in Expat 2.9.0. */
|
||||
XMLPARSEAPI(enum XML_Prop_Error)
|
||||
XML_GetPropertyBool(XML_Parser parser, enum XML_Parser_Property property,
|
||||
XML_Bool *value);
|
||||
XMLPARSEAPI(enum XML_Prop_Error)
|
||||
XML_GetPropertyDouble(XML_Parser parser, enum XML_Parser_Property property,
|
||||
double *value);
|
||||
XMLPARSEAPI(enum XML_Prop_Error)
|
||||
XML_GetPropertyUInt64(XML_Parser parser, enum XML_Parser_Property property,
|
||||
uint64_t *value);
|
||||
XMLPARSEAPI(enum XML_Prop_Error)
|
||||
XML_SetPropertyBool(XML_Parser parser, enum XML_Parser_Property property,
|
||||
XML_Bool value);
|
||||
XMLPARSEAPI(enum XML_Prop_Error)
|
||||
XML_SetPropertyDouble(XML_Parser parser, enum XML_Parser_Property property,
|
||||
double value);
|
||||
XMLPARSEAPI(enum XML_Prop_Error)
|
||||
XML_SetPropertyUInt64(XML_Parser parser, enum XML_Parser_Property property,
|
||||
uint64_t value);
|
||||
|
||||
# if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1)
|
||||
/* Added in Expat 2.4.0 for XML_DTD defined and
|
||||
* added in Expat 2.6.0 for XML_GE == 1. */
|
||||
@@ -1101,8 +1146,8 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
|
||||
See https://semver.org
|
||||
*/
|
||||
# define XML_MAJOR_VERSION 2
|
||||
# define XML_MINOR_VERSION 8
|
||||
# define XML_MICRO_VERSION 5
|
||||
# define XML_MINOR_VERSION 9
|
||||
# define XML_MICRO_VERSION 0
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -166,6 +166,9 @@ typedef char XML_LChar;
|
||||
# endif /* XML_UNICODE */
|
||||
|
||||
# ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
|
||||
# if defined(__clang__) || defined(__GNUC__)
|
||||
# warning Macro XML_LARGE_SIZE is deprecated, please use the 64bit location API functions instead.
|
||||
# endif
|
||||
typedef long long XML_Index;
|
||||
typedef unsigned long long XML_Size;
|
||||
# else
|
||||
|
||||
@@ -56,13 +56,11 @@
|
||||
#if ! defined(INTERNAL_H)
|
||||
# define INTERNAL_H 1
|
||||
|
||||
# ifndef XML_MIN_SIZE
|
||||
# if ! defined(inline)
|
||||
# ifdef __GNUC__
|
||||
# define inline __inline
|
||||
# endif /* __GNUC__ */
|
||||
# endif
|
||||
# endif /* XML_MIN_SIZE */
|
||||
# if ! defined(inline)
|
||||
# ifdef __GNUC__
|
||||
# define inline __inline
|
||||
# endif /* __GNUC__ */
|
||||
# endif
|
||||
|
||||
# ifndef inline
|
||||
# define inline
|
||||
|
||||
@@ -97,7 +97,7 @@ LIBEXPAT_1.95.8 {
|
||||
|
||||
LIBEXPAT_2.1.0 {
|
||||
global:
|
||||
@_EXPAT_COMMENT_ATTR_INFO@ XML_GetAttributeInfo;
|
||||
# XML_GetAttributeInfo;
|
||||
XML_SetHashSalt;
|
||||
} LIBEXPAT_1.95.8;
|
||||
|
||||
@@ -122,3 +122,18 @@ LIBEXPAT_2.8.0 {
|
||||
global:
|
||||
XML_SetHashSalt16Bytes;
|
||||
} LIBEXPAT_2.7.2;
|
||||
|
||||
LIBEXPAT_2.9.0 {
|
||||
global:
|
||||
XML_GetCurrentByteCount64;
|
||||
XML_GetCurrentByteIndex64;
|
||||
XML_GetCurrentColumnNumber64;
|
||||
XML_GetCurrentLineNumber64;
|
||||
XML_GetInputContext64;
|
||||
XML_GetPropertyBool;
|
||||
XML_GetPropertyDouble;
|
||||
XML_GetPropertyUInt64;
|
||||
XML_SetPropertyBool;
|
||||
XML_SetPropertyDouble;
|
||||
XML_SetPropertyUInt64;
|
||||
} LIBEXPAT_2.8.0;
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 2022-2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "xcs.h"
|
||||
|
||||
#if defined(XML_UNICODE)
|
||||
# if defined(XML_UNICODE_WCHAR_T)
|
||||
# include <wchar.h> // for wcscmp, wcslen, wcsncmp
|
||||
# endif
|
||||
#else
|
||||
# include <string.h> // for strcmp, strlen, strncmp
|
||||
#endif
|
||||
|
||||
size_t
|
||||
xcslen(const XML_Char *s) {
|
||||
#ifdef XML_UNICODE
|
||||
# ifdef XML_UNICODE_WCHAR_T
|
||||
return wcslen(s);
|
||||
# else
|
||||
// XML_Char is unsigned short
|
||||
size_t len = 0;
|
||||
while (s[len]) {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
# endif
|
||||
#else
|
||||
return strlen(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
xcscmp(const XML_Char *a, const XML_Char *b) {
|
||||
#if defined(XML_UNICODE)
|
||||
# if defined(XML_UNICODE_WCHAR_T)
|
||||
return wcscmp(a, b);
|
||||
# else
|
||||
for (; a[0] && b[0] && a[0] == b[0]; a++, b++)
|
||||
;
|
||||
return a[0] - b[0];
|
||||
# endif
|
||||
#else
|
||||
return strcmp(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
xcsncmp(const XML_Char *a, const XML_Char *b, size_t len) {
|
||||
#if defined(XML_UNICODE)
|
||||
# if defined(XML_UNICODE_WCHAR_T)
|
||||
return wcsncmp(a, b, len);
|
||||
# else
|
||||
for (; len > 0 && a[0] && b[0] && a[0] == b[0]; len--, a++, b++) {
|
||||
}
|
||||
return (len == 0) ? 0 : (a[0] - b[0]);
|
||||
# endif
|
||||
#else
|
||||
return strncmp(a, b, len);
|
||||
#endif
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is included from other .c files!
|
||||
/*
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
@@ -6,7 +6,7 @@
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 2022-2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
@@ -31,24 +31,14 @@
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#if defined(XML_UNICODE) && defined(XML_UNICODE_WCHAR_T)
|
||||
# include <wchar.h>
|
||||
#endif
|
||||
#if ! defined(EXPAT_XCS_H)
|
||||
|
||||
static size_t
|
||||
xcslen(const XML_Char *s) {
|
||||
#ifdef XML_UNICODE
|
||||
# ifdef XML_UNICODE_WCHAR_T
|
||||
return wcslen(s);
|
||||
# else
|
||||
// XML_Char is unsigned short
|
||||
size_t len = 0;
|
||||
while (s[len]) {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
# endif
|
||||
#else
|
||||
return strlen(s);
|
||||
#endif
|
||||
}
|
||||
# include <stddef.h> // size_t
|
||||
# include "expat_external.h" // for XML_Char
|
||||
|
||||
extern size_t xcslen(const XML_Char *s);
|
||||
|
||||
extern int xcscmp(const XML_Char *a, const XML_Char *b);
|
||||
extern int xcsncmp(const XML_Char *a, const XML_Char *b, size_t len);
|
||||
|
||||
#endif // ! defined(EXPAT_XCS_H)
|
||||
+413
-154
@@ -1,4 +1,4 @@
|
||||
/* 0864fe2d216f47b742263b698bc051c865b342e8b820e42c234717098ea507e3 (2.8.5+)
|
||||
/* e3ca845466942140c9af531ac57808c4650116df5d6dbeda3b6546d2548a586e (2.9.0+)
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
@@ -56,6 +56,8 @@
|
||||
Copyright (c) 2026 Zeyou Liu <zeyouliu@tencent.com>
|
||||
Copyright (c) 2026 Stan Ulbrych <stan@python.org>
|
||||
Copyright (c) 2026 Braian Plaku <braianplaku@gmail.com>
|
||||
Copyright (c) 2026 Filippo Tedeschi <filippotedeschi98@gmail.com>
|
||||
Copyright (c) 2026 Junki Lee <junkilee80@gmail.com>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
@@ -107,6 +109,7 @@
|
||||
#include <stdint.h> /* SIZE_MAX, UINT64_MAX, uint64_t, uintptr_t */
|
||||
#include <math.h> /* isnan */
|
||||
#include <errno.h>
|
||||
#include <wchar.h> /* wcsncmp */
|
||||
|
||||
#ifdef _WIN32
|
||||
# define getpid GetCurrentProcessId
|
||||
@@ -125,7 +128,7 @@
|
||||
#include "ascii.h"
|
||||
#include "expat.h"
|
||||
#include "siphash.h"
|
||||
#include "xcsinc.c"
|
||||
#include "xcs.h"
|
||||
|
||||
#if defined(HAVE_ARC4RANDOM)
|
||||
# include "random_arc4random.h"
|
||||
@@ -462,8 +465,8 @@ typedef struct accounting {
|
||||
} ACCOUNTING;
|
||||
|
||||
typedef struct MALLOC_TRACKER {
|
||||
XmlBigCount bytesAllocated;
|
||||
XmlBigCount peakBytesAllocated; // updated live only for debug level >=2
|
||||
size_t bytesAllocated;
|
||||
size_t peakBytesAllocated; // updated live only for debug level >=2
|
||||
unsigned long debugLevel;
|
||||
float maximumAmplificationFactor; // >=1.0
|
||||
XmlBigCount activationThresholdBytes;
|
||||
@@ -646,6 +649,25 @@ static bool poolAppendChar(STRING_POOL *pool, XML_Char c);
|
||||
|
||||
static bool poolAppendChars(STRING_POOL *pool, const XML_Char *s, size_t len);
|
||||
|
||||
#if XML_GE == 1
|
||||
static enum XML_Prop_Error setBillionLaughsAttackProtectionMaximumAmplification(
|
||||
XML_Parser parser, float maximumAmplificationFactor);
|
||||
|
||||
static enum XML_Prop_Error setBillionLaughsAttackProtectionActivationThreshold(
|
||||
XML_Parser parser, unsigned long long activationThresholdBytes);
|
||||
|
||||
static enum XML_Prop_Error
|
||||
setAllocTrackerMaximumAmplification(XML_Parser parser,
|
||||
float maximumAmplificationFactor);
|
||||
|
||||
static enum XML_Prop_Error
|
||||
setAllocTrackerActivationThreshold(XML_Parser parser,
|
||||
unsigned long long activationThresholdBytes);
|
||||
#endif /* XML_GE == 1 */
|
||||
|
||||
static enum XML_Prop_Error setReparseDeferralEnabled(XML_Parser parser,
|
||||
XML_Bool enabled);
|
||||
|
||||
#define poolStart(pool) ((pool)->start)
|
||||
#define poolLength(pool) ((pool)->ptr - (pool)->start)
|
||||
#define poolChop(pool) ((void)--(pool->ptr))
|
||||
@@ -785,9 +807,6 @@ struct XML_ParserStruct {
|
||||
NS_ATT *m_nsAtts;
|
||||
unsigned long m_nsAttsVersion;
|
||||
unsigned char m_nsAttsPower;
|
||||
#ifdef XML_ATTR_INFO
|
||||
XML_AttrInfo *m_attInfo;
|
||||
#endif
|
||||
POSITION m_position;
|
||||
STRING_POOL m_tempPool;
|
||||
STRING_POOL m_temp2Pool;
|
||||
@@ -824,30 +843,30 @@ struct XML_ParserStruct {
|
||||
|
||||
#if XML_GE == 1
|
||||
static void
|
||||
expat_heap_stat(XML_Parser rootParser, char operator, XmlBigCount absDiff,
|
||||
XmlBigCount newTotal, XmlBigCount peakTotal, int sourceLine) {
|
||||
expat_heap_stat(XML_Parser rootParser, char operator, size_t absDiff,
|
||||
size_t newTotal, size_t peakTotal, int sourceLine) {
|
||||
// NOTE: This can be +infinity or -nan
|
||||
const float amplification
|
||||
= (float)newTotal / (float)rootParser->m_accounting.countBytesDirect;
|
||||
fprintf(
|
||||
stderr,
|
||||
"expat: Allocations(%p): Direct " EXPAT_FMT_ULL("10") ", allocated %c" EXPAT_FMT_ULL(
|
||||
"10") " to " EXPAT_FMT_ULL("10") " (" EXPAT_FMT_ULL("10") " peak), amplification %8.2f (xmlparse.c:%d)\n",
|
||||
"expat: Allocations(%p): Direct " EXPAT_FMT_ULL("10") ", allocated %c" EXPAT_FMT_SIZE_T(
|
||||
"10") " to " EXPAT_FMT_SIZE_T("10") " (" EXPAT_FMT_SIZE_T("10") " peak), amplification %8.2f (xmlparse.c:%d)\n",
|
||||
(void *)rootParser, rootParser->m_accounting.countBytesDirect, operator,
|
||||
absDiff, newTotal, peakTotal, (double)amplification, sourceLine);
|
||||
}
|
||||
|
||||
static bool
|
||||
expat_heap_increase_tolerable(XML_Parser rootParser, XmlBigCount increase,
|
||||
expat_heap_increase_tolerable(XML_Parser rootParser, size_t increase,
|
||||
int sourceLine) {
|
||||
assert(rootParser != NULL);
|
||||
assert(increase > 0);
|
||||
|
||||
XmlBigCount newTotal = 0;
|
||||
size_t newTotal = 0;
|
||||
bool tolerable = true;
|
||||
|
||||
// Detect integer overflow
|
||||
if ((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated < increase) {
|
||||
if (SIZE_MAX - rootParser->m_alloc_tracker.bytesAllocated < increase) {
|
||||
tolerable = false;
|
||||
} else {
|
||||
newTotal = rootParser->m_alloc_tracker.bytesAllocated + increase;
|
||||
@@ -887,8 +906,7 @@ expat_malloc(XML_Parser parser, size_t size, int sourceLine) {
|
||||
|
||||
const size_t bytesToAllocate = sizeof(size_t) + EXPAT_MALLOC_PADDING + size;
|
||||
|
||||
if ((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated
|
||||
< bytesToAllocate) {
|
||||
if (SIZE_MAX - rootParser->m_alloc_tracker.bytesAllocated < bytesToAllocate) {
|
||||
return NULL; // i.e. signal integer overflow as out-of-memory
|
||||
}
|
||||
|
||||
@@ -998,9 +1016,10 @@ expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine) {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Integer overflow detection has already been done for us
|
||||
// by expat_heap_increase_tolerable(..) above
|
||||
assert(SIZE_MAX - sizeof(size_t) - EXPAT_MALLOC_PADDING >= size);
|
||||
// Detect and prevent integer overflow
|
||||
if (size > SIZE_MAX - sizeof(size_t) - EXPAT_MALLOC_PADDING) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Actually allocate
|
||||
mallocedPtr = parser->m_mem.realloc_fcn(
|
||||
@@ -1012,8 +1031,7 @@ expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine) {
|
||||
|
||||
// Update accounting
|
||||
if (isIncrease) {
|
||||
assert((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated
|
||||
>= absDiff);
|
||||
assert(SIZE_MAX - rootParser->m_alloc_tracker.bytesAllocated >= absDiff);
|
||||
rootParser->m_alloc_tracker.bytesAllocated += absDiff;
|
||||
} else { // i.e. decrease
|
||||
assert(rootParser->m_alloc_tracker.bytesAllocated >= absDiff);
|
||||
@@ -1389,20 +1407,9 @@ parserCreate(const XML_Char *encodingName,
|
||||
FREE(parser, parser);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef XML_ATTR_INFO
|
||||
parser->m_attInfo = MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo));
|
||||
if (parser->m_attInfo == NULL) {
|
||||
FREE(parser, parser->m_atts);
|
||||
FREE(parser, parser);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
parser->m_dataBuf = MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
|
||||
if (parser->m_dataBuf == NULL) {
|
||||
FREE(parser, parser->m_atts);
|
||||
#ifdef XML_ATTR_INFO
|
||||
FREE(parser, parser->m_attInfo);
|
||||
#endif
|
||||
FREE(parser, parser);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1415,9 +1422,6 @@ parserCreate(const XML_Char *encodingName,
|
||||
if (parser->m_dtd == NULL) {
|
||||
FREE(parser, parser->m_dataBuf);
|
||||
FREE(parser, parser->m_atts);
|
||||
#ifdef XML_ATTR_INFO
|
||||
FREE(parser, parser->m_attInfo);
|
||||
#endif
|
||||
FREE(parser, parser);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1596,6 +1600,10 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
|
||||
|
||||
if (parser->m_parentParser)
|
||||
return XML_FALSE;
|
||||
// The application-defined release callback may access the parser, so it
|
||||
// must run before any parser state is freed.
|
||||
if (parser->m_unknownEncodingRelease)
|
||||
callUnknownEncodingRelease(parser);
|
||||
/* move m_tagStack to m_freeTagList */
|
||||
tStk = parser->m_tagStack;
|
||||
while (tStk) {
|
||||
@@ -1616,14 +1624,16 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
|
||||
moveEntityList(&parser->m_freeEntities, &parser->m_openValueEntities);
|
||||
moveToFreeBindingList(parser, parser->m_inheritedBindings);
|
||||
FREE(parser, parser->m_unknownEncodingMem);
|
||||
if (parser->m_unknownEncodingRelease)
|
||||
callUnknownEncodingRelease(parser);
|
||||
poolClear(&parser->m_tempPool);
|
||||
poolClear(&parser->m_temp2Pool);
|
||||
FREE(parser, (void *)parser->m_protocolEncodingName);
|
||||
parser->m_protocolEncodingName = NULL;
|
||||
parserInit(parser, encodingName);
|
||||
dtdReset(parser->m_dtd, parser);
|
||||
if (encodingName && ! parser->m_protocolEncodingName) {
|
||||
parser->m_errorCode = XML_ERROR_NO_MEMORY;
|
||||
return XML_FALSE;
|
||||
}
|
||||
return XML_TRUE;
|
||||
}
|
||||
|
||||
@@ -1856,6 +1866,10 @@ XML_ParserFree(XML_Parser parser) {
|
||||
TAG *tagList;
|
||||
if ((parser == NULL) || isCalledFromInsideHandler(parser))
|
||||
return;
|
||||
// The application-defined release callback may access the parser, so it
|
||||
// must run before any parser state is freed.
|
||||
if (parser->m_unknownEncodingRelease)
|
||||
callUnknownEncodingRelease(parser);
|
||||
/* free m_tagStack and m_freeTagList */
|
||||
tagList = parser->m_tagStack;
|
||||
for (;;) {
|
||||
@@ -1916,9 +1930,6 @@ XML_ParserFree(XML_Parser parser) {
|
||||
#endif /* XML_DTD */
|
||||
dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, parser);
|
||||
FREE(parser, parser->m_atts);
|
||||
#ifdef XML_ATTR_INFO
|
||||
FREE(parser, parser->m_attInfo);
|
||||
#endif
|
||||
FREE(parser, parser->m_groupConnector);
|
||||
// NOTE: We are avoiding FREE(..) here because parser->m_buffer
|
||||
// is not being allocated with MALLOC(..) but with plain
|
||||
@@ -1927,8 +1938,6 @@ XML_ParserFree(XML_Parser parser) {
|
||||
FREE(parser, parser->m_dataBuf);
|
||||
FREE(parser, parser->m_nsAtts);
|
||||
FREE(parser, parser->m_unknownEncodingMem);
|
||||
if (parser->m_unknownEncodingRelease)
|
||||
callUnknownEncodingRelease(parser);
|
||||
FREE(parser, parser);
|
||||
}
|
||||
|
||||
@@ -2009,15 +2018,6 @@ XML_GetIdAttributeIndex(XML_Parser parser) {
|
||||
return parser->m_idAttIndex;
|
||||
}
|
||||
|
||||
#ifdef XML_ATTR_INFO
|
||||
const XML_AttrInfo *XMLCALL
|
||||
XML_GetAttributeInfo(XML_Parser parser) {
|
||||
if (parser == NULL)
|
||||
return NULL;
|
||||
return parser->m_attInfo;
|
||||
}
|
||||
#endif
|
||||
|
||||
void XMLCALL
|
||||
XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
|
||||
XML_EndElementHandler end) {
|
||||
@@ -2446,6 +2446,11 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
|
||||
parser->m_parsingStatus.parsing = XML_PARSING;
|
||||
}
|
||||
|
||||
if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
|
||||
parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
|
||||
return XML_STATUS_ERROR;
|
||||
}
|
||||
|
||||
// Detect and avoid integer overflow
|
||||
if ((uint64_t)len > UINT64_MAX - parser->m_parseEndByteIndex) {
|
||||
parser->m_errorCode = XML_ERROR_NO_MEMORY;
|
||||
@@ -2705,41 +2710,57 @@ XML_GetErrorCode(XML_Parser parser) {
|
||||
return parser->m_errorCode;
|
||||
}
|
||||
|
||||
XML_Index XMLCALL
|
||||
XML_GetCurrentByteIndex(XML_Parser parser) {
|
||||
int64_t XMLCALL
|
||||
XML_GetCurrentByteIndex64(XML_Parser parser) {
|
||||
if (parser == NULL)
|
||||
return -1;
|
||||
if (parser->m_eventPtr) {
|
||||
// NOTE: XML_Index is known to wrap around for >2 GiB content
|
||||
// on 32bit machines and 64bit Windows, unless (non-default and
|
||||
// uncommon) XML_LARGE_SIZE is defined.
|
||||
// That's a bug and it only lives on because we cannot break
|
||||
// ABI compatibility of public API.
|
||||
return (XML_Index)(parser->m_parseEndByteIndex
|
||||
- (parser->m_parseEndPtr - parser->m_eventPtr));
|
||||
return (int64_t)(parser->m_parseEndByteIndex
|
||||
- (parser->m_parseEndPtr - parser->m_eventPtr));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int XMLCALL
|
||||
XML_GetCurrentByteCount(XML_Parser parser) {
|
||||
// DEPRECATED since Expat 2.9.0.
|
||||
XML_Index XMLCALL
|
||||
XML_GetCurrentByteIndex(XML_Parser parser) {
|
||||
// NOTE: XML_Index is known to wrap around for >2 GiB content
|
||||
// on 32bit machines and 64bit Windows, unless (non-default and
|
||||
// uncommon) XML_LARGE_SIZE is defined.
|
||||
// That's a bug and it only lives on because we cannot break
|
||||
// ABI compatibility of public API.
|
||||
return (XML_Index)XML_GetCurrentByteIndex64(parser);
|
||||
}
|
||||
|
||||
uint64_t XMLCALL
|
||||
XML_GetCurrentByteCount64(XML_Parser parser) {
|
||||
if (parser == NULL)
|
||||
return 0;
|
||||
if (parser->m_eventEndPtr && parser->m_eventPtr)
|
||||
return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
|
||||
if (parser->m_eventEndPtr && parser->m_eventPtr) {
|
||||
return parser->m_eventEndPtr - parser->m_eventPtr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// DEPRECATED since Expat 2.9.0.
|
||||
int XMLCALL
|
||||
XML_GetCurrentByteCount(XML_Parser parser) {
|
||||
// NOTE: int is known to wrap around for >2 GiB content.
|
||||
// That's a bug and it only lives on because we cannot break
|
||||
// ABI compatibility of public API.
|
||||
return (int)XML_GetCurrentByteCount64(parser);
|
||||
}
|
||||
|
||||
const char *XMLCALL
|
||||
XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
|
||||
XML_GetInputContext64(XML_Parser parser, int64_t *offset, uint64_t *size) {
|
||||
#if XML_CONTEXT_BYTES > 0
|
||||
if (parser == NULL)
|
||||
return NULL;
|
||||
if (parser->m_eventPtr && parser->m_buffer) {
|
||||
if (offset != NULL)
|
||||
*offset = (int)(parser->m_eventPtr - parser->m_buffer);
|
||||
*offset = parser->m_eventPtr - parser->m_buffer;
|
||||
if (size != NULL)
|
||||
*size = (int)(parser->m_bufferEnd - parser->m_buffer);
|
||||
*size = parser->m_bufferEnd - parser->m_buffer;
|
||||
return parser->m_buffer;
|
||||
}
|
||||
#else
|
||||
@@ -2750,25 +2771,41 @@ XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XML_Size XMLCALL
|
||||
XML_GetCurrentLineNumber(XML_Parser parser) {
|
||||
// DEPRECATED since Expat 2.9.0.
|
||||
const char *XMLCALL
|
||||
XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
|
||||
#if XML_CONTEXT_BYTES > 0
|
||||
if (parser == NULL)
|
||||
return 0;
|
||||
if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
|
||||
XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
|
||||
parser->m_eventPtr, &parser->m_position);
|
||||
parser->m_positionPtr = parser->m_eventPtr;
|
||||
}
|
||||
// NOTE: XML_Size is known to wrap around for >4 GiB content
|
||||
// on 32bit machines and 64bit Windows, unless (non-default and
|
||||
// uncommon) XML_LARGE_SIZE is defined.
|
||||
return NULL;
|
||||
|
||||
int64_t offset64;
|
||||
uint64_t size64;
|
||||
|
||||
const char *const buffer = XML_GetInputContext64(parser, &offset64, &size64);
|
||||
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
// NOTE: int is known to wrap around for >2 GiB content.
|
||||
// That's a bug and it only lives on because we cannot break
|
||||
// ABI compatibility of public API.
|
||||
return (XML_Size)(parser->m_position.lineNumber + 1);
|
||||
if (offset != NULL)
|
||||
*offset = (int)offset64;
|
||||
|
||||
if (size != NULL)
|
||||
*size = (int)size64;
|
||||
|
||||
return buffer;
|
||||
#else
|
||||
(void)parser;
|
||||
(void)offset;
|
||||
(void)size;
|
||||
#endif /* XML_CONTEXT_BYTES > 0 */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XML_Size XMLCALL
|
||||
XML_GetCurrentColumnNumber(XML_Parser parser) {
|
||||
uint64_t XMLCALL
|
||||
XML_GetCurrentLineNumber64(XML_Parser parser) {
|
||||
if (parser == NULL)
|
||||
return 0;
|
||||
if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
|
||||
@@ -2776,12 +2813,41 @@ XML_GetCurrentColumnNumber(XML_Parser parser) {
|
||||
parser->m_eventPtr, &parser->m_position);
|
||||
parser->m_positionPtr = parser->m_eventPtr;
|
||||
}
|
||||
return parser->m_position.lineNumber + 1;
|
||||
}
|
||||
|
||||
// DEPRECATED since Expat 2.9.0.
|
||||
XML_Size XMLCALL
|
||||
XML_GetCurrentLineNumber(XML_Parser parser) {
|
||||
// NOTE: XML_Size is known to wrap around for >4 GiB content
|
||||
// on 32bit machines and 64bit Windows, unless (non-default and
|
||||
// uncommon) XML_LARGE_SIZE is defined.
|
||||
// That's a bug and it only lives on because we cannot break
|
||||
// ABI compatibility of public API.
|
||||
return (XML_Size)parser->m_position.columnNumber;
|
||||
return (XML_Size)XML_GetCurrentLineNumber64(parser);
|
||||
}
|
||||
|
||||
uint64_t XMLCALL
|
||||
XML_GetCurrentColumnNumber64(XML_Parser parser) {
|
||||
if (parser == NULL)
|
||||
return 0;
|
||||
if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
|
||||
XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
|
||||
parser->m_eventPtr, &parser->m_position);
|
||||
parser->m_positionPtr = parser->m_eventPtr;
|
||||
}
|
||||
return parser->m_position.columnNumber;
|
||||
}
|
||||
|
||||
// DEPRECATED since Expat 2.9.0.
|
||||
XML_Size XMLCALL
|
||||
XML_GetCurrentColumnNumber(XML_Parser parser) {
|
||||
// NOTE: XML_Size is known to wrap around for >4 GiB content
|
||||
// on 32bit machines and 64bit Windows, unless (non-default and
|
||||
// uncommon) XML_LARGE_SIZE is defined.
|
||||
// That's a bug and it only lives on because we cannot break
|
||||
// ABI compatibility of public API.
|
||||
return (XML_Size)XML_GetCurrentColumnNumber64(parser);
|
||||
}
|
||||
|
||||
void XMLCALL
|
||||
@@ -2827,7 +2893,7 @@ XML_MemFree(XML_Parser parser, void *ptr) {
|
||||
|
||||
void XMLCALL
|
||||
XML_DefaultCurrent(XML_Parser parser) {
|
||||
if (parser == NULL)
|
||||
if (parser == NULL || ! isCalledFromInsideHandler(parser))
|
||||
return;
|
||||
if (parser->m_defaultHandler) {
|
||||
if (parser->m_openInternalEntities)
|
||||
@@ -2998,18 +3064,12 @@ XML_GetFeatureList(void) {
|
||||
{XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
|
||||
XML_CONTEXT_BYTES},
|
||||
#endif
|
||||
#ifdef XML_MIN_SIZE
|
||||
{XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
|
||||
#endif
|
||||
#ifdef XML_NS
|
||||
{XML_FEATURE_NS, XML_L("XML_NS"), 0},
|
||||
#endif
|
||||
#ifdef XML_LARGE_SIZE
|
||||
{XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
|
||||
#endif
|
||||
#ifdef XML_ATTR_INFO
|
||||
{XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
|
||||
#endif
|
||||
#if XML_GE == 1
|
||||
/* Added in Expat 2.4.0 for XML_DTD defined and
|
||||
* added in Expat 2.6.0 for XML_GE == 1. */
|
||||
@@ -3036,59 +3096,294 @@ XML_GetFeatureList(void) {
|
||||
}
|
||||
|
||||
#if XML_GE == 1
|
||||
static enum XML_Prop_Error
|
||||
setBillionLaughsAttackProtectionMaximumAmplification(
|
||||
XML_Parser parser, float maximumAmplificationFactor) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
if (parser->m_parentParser != NULL)
|
||||
return XML_PROP_ERROR_PARSER_NOT_ROOT;
|
||||
|
||||
if (isnan(maximumAmplificationFactor) || (maximumAmplificationFactor < 1.0f))
|
||||
return XML_PROP_ERROR_INVALID_VALUE;
|
||||
|
||||
parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor;
|
||||
|
||||
return XML_PROP_ERROR_NONE;
|
||||
}
|
||||
|
||||
XML_Bool XMLCALL
|
||||
XML_SetBillionLaughsAttackProtectionMaximumAmplification(
|
||||
XML_Parser parser, float maximumAmplificationFactor) {
|
||||
if ((parser == NULL) || (parser->m_parentParser != NULL)
|
||||
|| isnan(maximumAmplificationFactor)
|
||||
|| (maximumAmplificationFactor < 1.0f)) {
|
||||
return XML_FALSE;
|
||||
}
|
||||
parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor;
|
||||
return XML_TRUE;
|
||||
return (setBillionLaughsAttackProtectionMaximumAmplification(
|
||||
parser, maximumAmplificationFactor)
|
||||
== XML_PROP_ERROR_NONE)
|
||||
? XML_TRUE
|
||||
: XML_FALSE;
|
||||
}
|
||||
|
||||
static enum XML_Prop_Error
|
||||
setBillionLaughsAttackProtectionActivationThreshold(
|
||||
XML_Parser parser, unsigned long long activationThresholdBytes) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
if (parser->m_parentParser != NULL)
|
||||
return XML_PROP_ERROR_PARSER_NOT_ROOT;
|
||||
|
||||
parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
|
||||
|
||||
return XML_PROP_ERROR_NONE;
|
||||
}
|
||||
|
||||
XML_Bool XMLCALL
|
||||
XML_SetBillionLaughsAttackProtectionActivationThreshold(
|
||||
XML_Parser parser, unsigned long long activationThresholdBytes) {
|
||||
if ((parser == NULL) || (parser->m_parentParser != NULL)) {
|
||||
return XML_FALSE;
|
||||
}
|
||||
parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
|
||||
return XML_TRUE;
|
||||
return (setBillionLaughsAttackProtectionActivationThreshold(
|
||||
parser, activationThresholdBytes)
|
||||
== XML_PROP_ERROR_NONE)
|
||||
? XML_TRUE
|
||||
: XML_FALSE;
|
||||
}
|
||||
|
||||
static enum XML_Prop_Error
|
||||
setAllocTrackerMaximumAmplification(XML_Parser parser,
|
||||
float maximumAmplificationFactor) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
if (parser->m_parentParser != NULL)
|
||||
return XML_PROP_ERROR_PARSER_NOT_ROOT;
|
||||
|
||||
if (isnan(maximumAmplificationFactor) || (maximumAmplificationFactor < 1.0f))
|
||||
return XML_PROP_ERROR_INVALID_VALUE;
|
||||
|
||||
parser->m_alloc_tracker.maximumAmplificationFactor
|
||||
= maximumAmplificationFactor;
|
||||
|
||||
return XML_PROP_ERROR_NONE;
|
||||
}
|
||||
|
||||
XML_Bool XMLCALL
|
||||
XML_SetAllocTrackerMaximumAmplification(XML_Parser parser,
|
||||
float maximumAmplificationFactor) {
|
||||
if ((parser == NULL) || (parser->m_parentParser != NULL)
|
||||
|| isnan(maximumAmplificationFactor)
|
||||
|| (maximumAmplificationFactor < 1.0f)) {
|
||||
return XML_FALSE;
|
||||
}
|
||||
parser->m_alloc_tracker.maximumAmplificationFactor
|
||||
= maximumAmplificationFactor;
|
||||
return XML_TRUE;
|
||||
return (setAllocTrackerMaximumAmplification(parser,
|
||||
maximumAmplificationFactor)
|
||||
== XML_PROP_ERROR_NONE)
|
||||
? XML_TRUE
|
||||
: XML_FALSE;
|
||||
}
|
||||
|
||||
static enum XML_Prop_Error
|
||||
setAllocTrackerActivationThreshold(
|
||||
XML_Parser parser, unsigned long long activationThresholdBytes) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
if (parser->m_parentParser != NULL)
|
||||
return XML_PROP_ERROR_PARSER_NOT_ROOT;
|
||||
|
||||
parser->m_alloc_tracker.activationThresholdBytes = activationThresholdBytes;
|
||||
|
||||
return XML_PROP_ERROR_NONE;
|
||||
}
|
||||
|
||||
XML_Bool XMLCALL
|
||||
XML_SetAllocTrackerActivationThreshold(
|
||||
XML_Parser parser, unsigned long long activationThresholdBytes) {
|
||||
if ((parser == NULL) || (parser->m_parentParser != NULL)) {
|
||||
return XML_FALSE;
|
||||
}
|
||||
parser->m_alloc_tracker.activationThresholdBytes = activationThresholdBytes;
|
||||
return XML_TRUE;
|
||||
return (setAllocTrackerActivationThreshold(parser, activationThresholdBytes)
|
||||
== XML_PROP_ERROR_NONE)
|
||||
? XML_TRUE
|
||||
: XML_FALSE;
|
||||
}
|
||||
#endif /* XML_GE == 1 */
|
||||
|
||||
static enum XML_Prop_Error
|
||||
setReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
if (enabled != XML_TRUE && enabled != XML_FALSE)
|
||||
return XML_PROP_ERROR_INVALID_VALUE;
|
||||
|
||||
parser->m_reparseDeferralEnabled = enabled;
|
||||
|
||||
return XML_PROP_ERROR_NONE;
|
||||
}
|
||||
|
||||
XML_Bool XMLCALL
|
||||
XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled) {
|
||||
if (parser != NULL && (enabled == XML_TRUE || enabled == XML_FALSE)) {
|
||||
parser->m_reparseDeferralEnabled = enabled;
|
||||
return XML_TRUE;
|
||||
return (setReparseDeferralEnabled(parser, enabled) == XML_PROP_ERROR_NONE)
|
||||
? XML_TRUE
|
||||
: XML_FALSE;
|
||||
}
|
||||
|
||||
enum XML_Prop_Error XMLCALL
|
||||
XML_SetPropertyBool(XML_Parser parser, enum XML_Parser_Property property,
|
||||
XML_Bool value) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
switch (property) {
|
||||
#if XML_GE == 1
|
||||
case XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD:
|
||||
case XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION:
|
||||
case XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD:
|
||||
case XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION:
|
||||
return XML_PROP_ERROR_INVALID_TYPE;
|
||||
#endif /* XML_GE == 1 */
|
||||
case XML_PROP_REPARSE_DEFERRAL_ENABLED:
|
||||
return setReparseDeferralEnabled(parser, value);
|
||||
default:
|
||||
return XML_PROP_ERROR_INVALID_KEY;
|
||||
}
|
||||
return XML_FALSE;
|
||||
|
||||
assert(0 && "considered unreachable");
|
||||
}
|
||||
|
||||
enum XML_Prop_Error XMLCALL
|
||||
XML_SetPropertyDouble(XML_Parser parser, enum XML_Parser_Property property,
|
||||
double value) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
#if XML_GE == 0
|
||||
UNUSED_P(value);
|
||||
#endif
|
||||
|
||||
switch (property) {
|
||||
#if XML_GE == 1
|
||||
case XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION:
|
||||
return setAllocTrackerMaximumAmplification(parser, (float)value);
|
||||
case XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION:
|
||||
return setBillionLaughsAttackProtectionMaximumAmplification(parser,
|
||||
(float)value);
|
||||
case XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD:
|
||||
case XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD:
|
||||
#endif /* XML_GE == 1 */
|
||||
case XML_PROP_REPARSE_DEFERRAL_ENABLED:
|
||||
return XML_PROP_ERROR_INVALID_TYPE;
|
||||
default:
|
||||
return XML_PROP_ERROR_INVALID_KEY;
|
||||
}
|
||||
|
||||
assert(0 && "considered unreachable");
|
||||
}
|
||||
|
||||
enum XML_Prop_Error XMLCALL
|
||||
XML_SetPropertyUInt64(XML_Parser parser, enum XML_Parser_Property property,
|
||||
uint64_t value) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
#if XML_GE == 0
|
||||
UNUSED_P(value);
|
||||
#endif
|
||||
|
||||
switch (property) {
|
||||
#if XML_GE == 1
|
||||
case XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD:
|
||||
return setAllocTrackerActivationThreshold(parser,
|
||||
(unsigned long long)value);
|
||||
case XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD:
|
||||
return setBillionLaughsAttackProtectionActivationThreshold(
|
||||
parser, (unsigned long long)value);
|
||||
case XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION:
|
||||
case XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION:
|
||||
#endif /* XML_GE == 1 */
|
||||
case XML_PROP_REPARSE_DEFERRAL_ENABLED:
|
||||
return XML_PROP_ERROR_INVALID_TYPE;
|
||||
default:
|
||||
return XML_PROP_ERROR_INVALID_KEY;
|
||||
}
|
||||
|
||||
assert(0 && "considered unreachable");
|
||||
}
|
||||
|
||||
enum XML_Prop_Error XMLCALL
|
||||
XML_GetPropertyBool(XML_Parser parser, enum XML_Parser_Property property,
|
||||
XML_Bool *value) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
if (value == NULL)
|
||||
return XML_PROP_ERROR_INVALID_VALUE;
|
||||
|
||||
switch (property) {
|
||||
#if XML_GE == 1
|
||||
case XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD:
|
||||
case XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION:
|
||||
case XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD:
|
||||
case XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION:
|
||||
return XML_PROP_ERROR_INVALID_TYPE;
|
||||
#endif /* XML_GE == 1 */
|
||||
case XML_PROP_REPARSE_DEFERRAL_ENABLED:
|
||||
*value = parser->m_reparseDeferralEnabled;
|
||||
break;
|
||||
default:
|
||||
return XML_PROP_ERROR_INVALID_KEY;
|
||||
}
|
||||
|
||||
return XML_PROP_ERROR_NONE;
|
||||
}
|
||||
|
||||
enum XML_Prop_Error XMLCALL
|
||||
XML_GetPropertyDouble(XML_Parser parser, enum XML_Parser_Property property,
|
||||
double *value) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
if (value == NULL)
|
||||
return XML_PROP_ERROR_INVALID_VALUE;
|
||||
|
||||
switch (property) {
|
||||
#if XML_GE == 1
|
||||
case XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION:
|
||||
*value = (double)parser->m_accounting.maximumAmplificationFactor;
|
||||
break;
|
||||
case XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION:
|
||||
*value = (double)parser->m_alloc_tracker.maximumAmplificationFactor;
|
||||
break;
|
||||
case XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD:
|
||||
case XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD:
|
||||
#endif /* XML_GE == 1 */
|
||||
case XML_PROP_REPARSE_DEFERRAL_ENABLED:
|
||||
return XML_PROP_ERROR_INVALID_TYPE;
|
||||
default:
|
||||
return XML_PROP_ERROR_INVALID_KEY;
|
||||
}
|
||||
|
||||
return XML_PROP_ERROR_NONE;
|
||||
}
|
||||
|
||||
enum XML_Prop_Error XMLCALL
|
||||
XML_GetPropertyUInt64(XML_Parser parser, enum XML_Parser_Property property,
|
||||
uint64_t *value) {
|
||||
if (parser == NULL)
|
||||
return XML_PROP_ERROR_PARSER_NULL;
|
||||
|
||||
if (value == NULL)
|
||||
return XML_PROP_ERROR_INVALID_VALUE;
|
||||
|
||||
switch (property) {
|
||||
#if XML_GE == 1
|
||||
case XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD:
|
||||
*value = parser->m_accounting.activationThresholdBytes;
|
||||
break;
|
||||
case XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD:
|
||||
*value = parser->m_alloc_tracker.activationThresholdBytes;
|
||||
break;
|
||||
case XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION:
|
||||
case XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION:
|
||||
#endif /* XML_GE == 1 */
|
||||
case XML_PROP_REPARSE_DEFERRAL_ENABLED:
|
||||
return XML_PROP_ERROR_INVALID_TYPE;
|
||||
default:
|
||||
return XML_PROP_ERROR_INVALID_KEY;
|
||||
}
|
||||
|
||||
return XML_PROP_ERROR_NONE;
|
||||
}
|
||||
|
||||
/* Initially tag->rawName always points into the parse buffer;
|
||||
@@ -3901,21 +4196,6 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
parser->m_atts = temp;
|
||||
#ifdef XML_ATTR_INFO
|
||||
/* Detect and prevent integer overflow. */
|
||||
if (parser->m_attsSize > SIZE_MAX / sizeof(XML_AttrInfo)) {
|
||||
parser->m_attsSize = oldAttsSize;
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
XML_AttrInfo *const temp2 = REALLOC(
|
||||
parser, parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo));
|
||||
if (temp2 == NULL) {
|
||||
parser->m_attsSize = oldAttsSize;
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
parser->m_attInfo = temp2;
|
||||
#endif
|
||||
if (n > oldAttsSize) {
|
||||
/* Detect and prevent integer overflow. */
|
||||
if (n > (size_t)INT_MAX)
|
||||
@@ -3928,33 +4208,12 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
|
||||
const XML_Char **const appAtts = (const XML_Char **)parser->m_atts;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
ATTRIBUTE *currAtt = &parser->m_atts[i];
|
||||
#ifdef XML_ATTR_INFO
|
||||
XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
|
||||
#endif
|
||||
/* add the name and value to the attribute list */
|
||||
ATTRIBUTE_ID *attId
|
||||
= getAttributeId(parser, enc, currAtt->name,
|
||||
currAtt->name + XmlNameLength(enc, currAtt->name));
|
||||
if (! attId)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
#ifdef XML_ATTR_INFO
|
||||
// NOTE: XML_Index is known to wrap around for >2 GiB content
|
||||
// on 32bit machines and 64bit Windows, unless (non-default and
|
||||
// uncommon) XML_LARGE_SIZE is defined.
|
||||
// That's a bug and it only lives on because we cannot break
|
||||
// ABI compatibility of public API.
|
||||
currAttInfo->nameStart
|
||||
= (XML_Index)(parser->m_parseEndByteIndex
|
||||
- (parser->m_parseEndPtr - currAtt->name));
|
||||
currAttInfo->nameEnd
|
||||
= currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
|
||||
currAttInfo->valueStart
|
||||
= (XML_Index)(parser->m_parseEndByteIndex
|
||||
- (parser->m_parseEndPtr - currAtt->valuePtr));
|
||||
currAttInfo->valueEnd
|
||||
= (XML_Index)(parser->m_parseEndByteIndex
|
||||
- (parser->m_parseEndPtr - currAtt->valueEnd));
|
||||
#endif
|
||||
/* Detect duplicate attributes by their QNames. This does not work when
|
||||
namespace processing is turned on and different prefixes for the same
|
||||
namespace are used. For this case we have a check further down.
|
||||
|
||||
+56
-220
@@ -193,13 +193,6 @@ utf8_isInvalid4(const ENCODING *enc, const char *p) {
|
||||
struct normal_encoding {
|
||||
ENCODING enc;
|
||||
unsigned char type[256];
|
||||
#ifdef XML_MIN_SIZE
|
||||
int (*byteType)(const ENCODING *, const char *);
|
||||
int (*isNameMin)(const ENCODING *, const char *);
|
||||
int (*isNmstrtMin)(const ENCODING *, const char *);
|
||||
int (*byteToAscii)(const ENCODING *, const char *);
|
||||
int (*charMatches)(const ENCODING *, const char *, int);
|
||||
#endif /* XML_MIN_SIZE */
|
||||
int (*isName2)(const ENCODING *, const char *);
|
||||
int (*isName3)(const ENCODING *, const char *);
|
||||
int (*isName4)(const ENCODING *, const char *);
|
||||
@@ -213,16 +206,7 @@ struct normal_encoding {
|
||||
|
||||
#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc))
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
|
||||
# define STANDARD_VTABLE(E) \
|
||||
E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches,
|
||||
|
||||
#else
|
||||
|
||||
# define STANDARD_VTABLE(E) /* as nothing */
|
||||
|
||||
#endif
|
||||
#define STANDARD_VTABLE(E) /* as nothing */
|
||||
|
||||
#define NORMAL_VTABLE(E) \
|
||||
E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3, \
|
||||
@@ -233,93 +217,33 @@ struct normal_encoding {
|
||||
/* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \
|
||||
/* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL
|
||||
|
||||
/* Like NULL_VTABLE but with a real isInvalid4 so the UTF-16 encodings reject a
|
||||
high surrogate that is not followed by a low surrogate. Only needed for the
|
||||
XML_MIN_SIZE build, where the shared tokenizer dispatches through the vtable;
|
||||
the regular build inlines the same check via IS_INVALID_CHAR. */
|
||||
#ifdef XML_MIN_SIZE
|
||||
# define UTF16_NULL_VTABLE(E) \
|
||||
/* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \
|
||||
/* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \
|
||||
/* isInvalid2 */ NULL, /* isInvalid3 */ NULL, E##isInvalid4
|
||||
#else
|
||||
# define UTF16_NULL_VTABLE(E) NULL_VTABLE
|
||||
#endif
|
||||
#define UTF16_NULL_VTABLE(E) NULL_VTABLE
|
||||
|
||||
static int checkCharRefNumber(int result);
|
||||
|
||||
#include "xmltok_impl.h"
|
||||
#include "ascii.h"
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
# define sb_isNameMin isNever
|
||||
# define sb_isNmstrtMin isNever
|
||||
#endif
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
# define MINBPC(enc) ((enc)->minBytesPerChar)
|
||||
#else
|
||||
/* minimum bytes per character */
|
||||
# define MINBPC(enc) 1
|
||||
#endif
|
||||
#define MINBPC(enc) 1
|
||||
|
||||
#define SB_BYTE_TYPE(enc, p) \
|
||||
(((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
static int
|
||||
sb_byteType(const ENCODING *enc, const char *p) {
|
||||
return SB_BYTE_TYPE(enc, p);
|
||||
}
|
||||
# define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
|
||||
#else
|
||||
# define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
|
||||
#endif
|
||||
#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
# define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
|
||||
static int
|
||||
sb_byteToAscii(const ENCODING *enc, const char *p) {
|
||||
UNUSED_P(enc);
|
||||
return *p;
|
||||
}
|
||||
#else
|
||||
# define BYTE_TO_ASCII(enc, p) (*(p))
|
||||
#endif
|
||||
#define BYTE_TO_ASCII(enc, p) (*(p))
|
||||
|
||||
#define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p))
|
||||
#define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p))
|
||||
#ifdef XML_MIN_SIZE
|
||||
# define IS_INVALID_CHAR(enc, p, n) \
|
||||
(AS_NORMAL_ENCODING(enc)->isInvalid##n \
|
||||
&& AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
|
||||
#else
|
||||
# define IS_INVALID_CHAR(enc, p, n) \
|
||||
(AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
|
||||
#endif
|
||||
#define IS_INVALID_CHAR(enc, p, n) \
|
||||
(AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
# define IS_NAME_CHAR_MINBPC(enc, p) \
|
||||
(AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
|
||||
# define IS_NMSTRT_CHAR_MINBPC(enc, p) \
|
||||
(AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
|
||||
#else
|
||||
# define IS_NAME_CHAR_MINBPC(enc, p) (0)
|
||||
# define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
|
||||
#endif
|
||||
#define IS_NAME_CHAR_MINBPC(enc, p) (0)
|
||||
#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
# define CHAR_MATCHES(enc, p, c) \
|
||||
(AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
|
||||
static int
|
||||
sb_charMatches(const ENCODING *enc, const char *p, int c) {
|
||||
UNUSED_P(enc);
|
||||
return *p == c;
|
||||
}
|
||||
#else
|
||||
/* c is an ASCII character */
|
||||
# define CHAR_MATCHES(enc, p, c) (*(p) == (c))
|
||||
#endif
|
||||
#define CHAR_MATCHES(enc, p, c) (*(p) == (c))
|
||||
|
||||
#define PREFIX(ident) normal_##ident
|
||||
#define XML_TOK_IMPL_C
|
||||
@@ -769,76 +693,32 @@ DEFINE_UTF16_TO_UTF16(big2_)
|
||||
#define LITTLE2_IS_INVALID_CHAR(p, n) \
|
||||
((n) == 4 && ((unsigned char)(p)[3] & 0xFC) != 0xDC)
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
|
||||
static int
|
||||
little2_byteType(const ENCODING *enc, const char *p) {
|
||||
return LITTLE2_BYTE_TYPE(enc, p);
|
||||
}
|
||||
|
||||
static int
|
||||
little2_byteToAscii(const ENCODING *enc, const char *p) {
|
||||
UNUSED_P(enc);
|
||||
return LITTLE2_BYTE_TO_ASCII(p);
|
||||
}
|
||||
|
||||
static int
|
||||
little2_charMatches(const ENCODING *enc, const char *p, int c) {
|
||||
UNUSED_P(enc);
|
||||
return LITTLE2_CHAR_MATCHES(p, c);
|
||||
}
|
||||
|
||||
static int
|
||||
little2_isNameMin(const ENCODING *enc, const char *p) {
|
||||
UNUSED_P(enc);
|
||||
return LITTLE2_IS_NAME_CHAR_MINBPC(p);
|
||||
}
|
||||
|
||||
static int
|
||||
little2_isNmstrtMin(const ENCODING *enc, const char *p) {
|
||||
UNUSED_P(enc);
|
||||
return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p);
|
||||
}
|
||||
|
||||
static int
|
||||
little2_isInvalid4(const ENCODING *enc, const char *p) {
|
||||
UNUSED_P(enc);
|
||||
return LITTLE2_IS_INVALID_CHAR(p, 4);
|
||||
}
|
||||
|
||||
# undef VTABLE
|
||||
# define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
|
||||
|
||||
#else /* not XML_MIN_SIZE */
|
||||
|
||||
# undef PREFIX
|
||||
# define PREFIX(ident) little2_##ident
|
||||
# define MINBPC(enc) 2
|
||||
#undef PREFIX
|
||||
#define PREFIX(ident) little2_##ident
|
||||
#define MINBPC(enc) 2
|
||||
/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
|
||||
# define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
|
||||
# define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p)
|
||||
# define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c)
|
||||
# define IS_NAME_CHAR(enc, p, n) 0
|
||||
# define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p)
|
||||
# define IS_NMSTRT_CHAR(enc, p, n) (0)
|
||||
# define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)
|
||||
# define IS_INVALID_CHAR(enc, p, n) LITTLE2_IS_INVALID_CHAR(p, n)
|
||||
#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
|
||||
#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p)
|
||||
#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c)
|
||||
#define IS_NAME_CHAR(enc, p, n) 0
|
||||
#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p)
|
||||
#define IS_NMSTRT_CHAR(enc, p, n) (0)
|
||||
#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)
|
||||
#define IS_INVALID_CHAR(enc, p, n) LITTLE2_IS_INVALID_CHAR(p, n)
|
||||
|
||||
# define XML_TOK_IMPL_C
|
||||
# include "xmltok_impl.c"
|
||||
# undef XML_TOK_IMPL_C
|
||||
#define XML_TOK_IMPL_C
|
||||
#include "xmltok_impl.c"
|
||||
#undef XML_TOK_IMPL_C
|
||||
|
||||
# undef MINBPC
|
||||
# undef BYTE_TYPE
|
||||
# undef BYTE_TO_ASCII
|
||||
# undef CHAR_MATCHES
|
||||
# undef IS_NAME_CHAR
|
||||
# undef IS_NAME_CHAR_MINBPC
|
||||
# undef IS_NMSTRT_CHAR
|
||||
# undef IS_NMSTRT_CHAR_MINBPC
|
||||
# undef IS_INVALID_CHAR
|
||||
|
||||
#endif /* not XML_MIN_SIZE */
|
||||
#undef MINBPC
|
||||
#undef BYTE_TYPE
|
||||
#undef BYTE_TO_ASCII
|
||||
#undef CHAR_MATCHES
|
||||
#undef IS_NAME_CHAR
|
||||
#undef IS_NAME_CHAR_MINBPC
|
||||
#undef IS_NMSTRT_CHAR
|
||||
#undef IS_NMSTRT_CHAR_MINBPC
|
||||
#undef IS_INVALID_CHAR
|
||||
|
||||
#ifdef XML_NS
|
||||
|
||||
@@ -914,76 +794,32 @@ static const struct normal_encoding internal_little2_encoding
|
||||
#define BIG2_IS_INVALID_CHAR(p, n) \
|
||||
((n) == 4 && ((unsigned char)(p)[2] & 0xFC) != 0xDC)
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
|
||||
static int
|
||||
big2_byteType(const ENCODING *enc, const char *p) {
|
||||
return BIG2_BYTE_TYPE(enc, p);
|
||||
}
|
||||
|
||||
static int
|
||||
big2_byteToAscii(const ENCODING *enc, const char *p) {
|
||||
UNUSED_P(enc);
|
||||
return BIG2_BYTE_TO_ASCII(p);
|
||||
}
|
||||
|
||||
static int
|
||||
big2_charMatches(const ENCODING *enc, const char *p, int c) {
|
||||
UNUSED_P(enc);
|
||||
return BIG2_CHAR_MATCHES(p, c);
|
||||
}
|
||||
|
||||
static int
|
||||
big2_isNameMin(const ENCODING *enc, const char *p) {
|
||||
UNUSED_P(enc);
|
||||
return BIG2_IS_NAME_CHAR_MINBPC(p);
|
||||
}
|
||||
|
||||
static int
|
||||
big2_isNmstrtMin(const ENCODING *enc, const char *p) {
|
||||
UNUSED_P(enc);
|
||||
return BIG2_IS_NMSTRT_CHAR_MINBPC(p);
|
||||
}
|
||||
|
||||
static int
|
||||
big2_isInvalid4(const ENCODING *enc, const char *p) {
|
||||
UNUSED_P(enc);
|
||||
return BIG2_IS_INVALID_CHAR(p, 4);
|
||||
}
|
||||
|
||||
# undef VTABLE
|
||||
# define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
|
||||
|
||||
#else /* not XML_MIN_SIZE */
|
||||
|
||||
# undef PREFIX
|
||||
# define PREFIX(ident) big2_##ident
|
||||
# define MINBPC(enc) 2
|
||||
#undef PREFIX
|
||||
#define PREFIX(ident) big2_##ident
|
||||
#define MINBPC(enc) 2
|
||||
/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
|
||||
# define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
|
||||
# define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p)
|
||||
# define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c)
|
||||
# define IS_NAME_CHAR(enc, p, n) 0
|
||||
# define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p)
|
||||
# define IS_NMSTRT_CHAR(enc, p, n) (0)
|
||||
# define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p)
|
||||
# define IS_INVALID_CHAR(enc, p, n) BIG2_IS_INVALID_CHAR(p, n)
|
||||
#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
|
||||
#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p)
|
||||
#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c)
|
||||
#define IS_NAME_CHAR(enc, p, n) 0
|
||||
#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p)
|
||||
#define IS_NMSTRT_CHAR(enc, p, n) (0)
|
||||
#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p)
|
||||
#define IS_INVALID_CHAR(enc, p, n) BIG2_IS_INVALID_CHAR(p, n)
|
||||
|
||||
# define XML_TOK_IMPL_C
|
||||
# include "xmltok_impl.c"
|
||||
# undef XML_TOK_IMPL_C
|
||||
#define XML_TOK_IMPL_C
|
||||
#include "xmltok_impl.c"
|
||||
#undef XML_TOK_IMPL_C
|
||||
|
||||
# undef MINBPC
|
||||
# undef BYTE_TYPE
|
||||
# undef BYTE_TO_ASCII
|
||||
# undef CHAR_MATCHES
|
||||
# undef IS_NAME_CHAR
|
||||
# undef IS_NAME_CHAR_MINBPC
|
||||
# undef IS_NMSTRT_CHAR
|
||||
# undef IS_NMSTRT_CHAR_MINBPC
|
||||
# undef IS_INVALID_CHAR
|
||||
|
||||
#endif /* not XML_MIN_SIZE */
|
||||
#undef MINBPC
|
||||
#undef BYTE_TYPE
|
||||
#undef BYTE_TO_ASCII
|
||||
#undef CHAR_MATCHES
|
||||
#undef IS_NAME_CHAR
|
||||
#undef IS_NAME_CHAR_MINBPC
|
||||
#undef IS_NMSTRT_CHAR
|
||||
#undef IS_NMSTRT_CHAR_MINBPC
|
||||
#undef IS_INVALID_CHAR
|
||||
|
||||
#ifdef XML_NS
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is included (from xmltok.c, 1-3 times depending on XML_MIN_SIZE)!
|
||||
/* This file is included (from xmltok.c, 3 times)!
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
|
||||
@@ -55,8 +55,10 @@ runtests_SOURCES = \
|
||||
misc_tests.c \
|
||||
ns_tests.c \
|
||||
nsalloc_tests.c \
|
||||
props_tests.c \
|
||||
runtests.c \
|
||||
structdata.c
|
||||
structdata.c \
|
||||
xcs_tests.c
|
||||
|
||||
runtests_LDADD = ../lib/libtestpat.la
|
||||
|
||||
@@ -76,8 +78,10 @@ EXTRA_DIST = \
|
||||
misc_tests.h \
|
||||
ns_tests.h \
|
||||
nsalloc_tests.h \
|
||||
props_tests.h \
|
||||
README.md \
|
||||
structdata.h \
|
||||
udiffer.py \
|
||||
xcs_tests.h \
|
||||
xmltest.log.expected \
|
||||
xmltest.sh
|
||||
@@ -151,8 +151,9 @@ am_runtests_OBJECTS = acc_tests.$(OBJEXT) alloc_tests.$(OBJEXT) \
|
||||
basic_tests.$(OBJEXT) chardata.$(OBJEXT) common.$(OBJEXT) \
|
||||
dummy.$(OBJEXT) handlers.$(OBJEXT) hash_tests.$(OBJEXT) \
|
||||
memcheck.$(OBJEXT) minicheck.$(OBJEXT) misc_tests.$(OBJEXT) \
|
||||
ns_tests.$(OBJEXT) nsalloc_tests.$(OBJEXT) runtests.$(OBJEXT) \
|
||||
structdata.$(OBJEXT)
|
||||
ns_tests.$(OBJEXT) nsalloc_tests.$(OBJEXT) \
|
||||
props_tests.$(OBJEXT) runtests.$(OBJEXT) structdata.$(OBJEXT) \
|
||||
xcs_tests.$(OBJEXT)
|
||||
runtests_OBJECTS = $(am_runtests_OBJECTS)
|
||||
runtests_DEPENDENCIES = ../lib/libtestpat.la
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
@@ -184,7 +185,8 @@ am__depfiles_remade = ./$(DEPDIR)/acc_tests.Po \
|
||||
./$(DEPDIR)/hash_tests.Po ./$(DEPDIR)/memcheck.Po \
|
||||
./$(DEPDIR)/minicheck.Po ./$(DEPDIR)/misc_tests.Po \
|
||||
./$(DEPDIR)/ns_tests.Po ./$(DEPDIR)/nsalloc_tests.Po \
|
||||
./$(DEPDIR)/runtests.Po ./$(DEPDIR)/structdata.Po
|
||||
./$(DEPDIR)/props_tests.Po ./$(DEPDIR)/runtests.Po \
|
||||
./$(DEPDIR)/structdata.Po ./$(DEPDIR)/xcs_tests.Po
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
@@ -519,12 +521,10 @@ ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXPAT_ATTR_INFO = @EXPAT_ATTR_INFO@
|
||||
EXPAT_CHAR_TYPE = @EXPAT_CHAR_TYPE@
|
||||
EXPAT_CONTEXT_BYTES = @EXPAT_CONTEXT_BYTES@
|
||||
EXPAT_DTD = @EXPAT_DTD@
|
||||
EXPAT_LARGE_SIZE = @EXPAT_LARGE_SIZE@
|
||||
EXPAT_MIN_SIZE = @EXPAT_MIN_SIZE@
|
||||
EXPAT_NS = @EXPAT_NS@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
@@ -579,7 +579,6 @@ SO_PATCH = @SO_PATCH@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
VSCRIPT_LDFLAGS = @VSCRIPT_LDFLAGS@
|
||||
_EXPAT_COMMENT_ATTR_INFO = @_EXPAT_COMMENT_ATTR_INFO@
|
||||
_EXPAT_COMMENT_DTD_OR_GE = @_EXPAT_COMMENT_DTD_OR_GE@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
@@ -656,8 +655,10 @@ runtests_SOURCES = \
|
||||
misc_tests.c \
|
||||
ns_tests.c \
|
||||
nsalloc_tests.c \
|
||||
props_tests.c \
|
||||
runtests.c \
|
||||
structdata.c
|
||||
structdata.c \
|
||||
xcs_tests.c
|
||||
|
||||
runtests_LDADD = ../lib/libtestpat.la
|
||||
runtests_LDFLAGS = @AM_LDFLAGS@ @LIBM@
|
||||
@@ -675,9 +676,11 @@ EXTRA_DIST = \
|
||||
misc_tests.h \
|
||||
ns_tests.h \
|
||||
nsalloc_tests.h \
|
||||
props_tests.h \
|
||||
README.md \
|
||||
structdata.h \
|
||||
udiffer.py \
|
||||
xcs_tests.h \
|
||||
xmltest.log.expected \
|
||||
xmltest.sh
|
||||
|
||||
@@ -742,8 +745,10 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc_tests.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ns_tests.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nsalloc_tests.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/props_tests.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runtests.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/structdata.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcs_tests.Po@am__quote@ # am--include-marker
|
||||
|
||||
$(am__depfiles_remade):
|
||||
@$(MKDIR_P) $(@D)
|
||||
@@ -1186,8 +1191,10 @@ distclean: distclean-recursive
|
||||
-rm -f ./$(DEPDIR)/misc_tests.Po
|
||||
-rm -f ./$(DEPDIR)/ns_tests.Po
|
||||
-rm -f ./$(DEPDIR)/nsalloc_tests.Po
|
||||
-rm -f ./$(DEPDIR)/props_tests.Po
|
||||
-rm -f ./$(DEPDIR)/runtests.Po
|
||||
-rm -f ./$(DEPDIR)/structdata.Po
|
||||
-rm -f ./$(DEPDIR)/xcs_tests.Po
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
@@ -1246,8 +1253,10 @@ maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f ./$(DEPDIR)/misc_tests.Po
|
||||
-rm -f ./$(DEPDIR)/ns_tests.Po
|
||||
-rm -f ./$(DEPDIR)/nsalloc_tests.Po
|
||||
-rm -f ./$(DEPDIR)/props_tests.Po
|
||||
-rm -f ./$(DEPDIR)/runtests.Po
|
||||
-rm -f ./$(DEPDIR)/structdata.Po
|
||||
-rm -f ./$(DEPDIR)/xcs_tests.Po
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
|
||||
@@ -359,6 +359,41 @@ START_TEST(test_billion_laughs_attack_protection_api) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_billions_laughs_attack_protection_api_float_round_trip) {
|
||||
const float values[] = {1.0f, 1.1f, INFINITY};
|
||||
|
||||
for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
|
||||
set_subtest("float %f", (double)i);
|
||||
const float wanted = values[i];
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
// Self-Test: Original value not already at target value
|
||||
double actual = 123.456;
|
||||
assert_true((float)actual != wanted);
|
||||
# if XML_GE == 1
|
||||
assert_true(
|
||||
XML_GetPropertyDouble(
|
||||
parser, XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, &actual)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true((float)actual != wanted); // Self-Test
|
||||
|
||||
// Test: Target value applied successfully
|
||||
assert_true(
|
||||
XML_SetBillionLaughsAttackProtectionMaximumAmplification(parser, wanted)
|
||||
== XML_TRUE);
|
||||
assert_true(
|
||||
XML_GetPropertyDouble(
|
||||
parser, XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, &actual)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true((float)actual == wanted);
|
||||
# endif // XML_GE == 1
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_helper_unsigned_char_to_printable) {
|
||||
// Smoke test
|
||||
unsigned char uc = 0;
|
||||
@@ -451,6 +486,8 @@ make_accounting_test_case(Suite *s) {
|
||||
|
||||
tcase_add_test(tc_accounting, test_accounting_precision);
|
||||
tcase_add_test(tc_accounting, test_billion_laughs_attack_protection_api);
|
||||
tcase_add_test(tc_accounting,
|
||||
test_billions_laughs_attack_protection_api_float_round_trip);
|
||||
tcase_add_test(tc_accounting, test_helper_unsigned_char_to_printable);
|
||||
tcase_add_test__ifdef_xml_dtd(tc_accounting,
|
||||
test_amplification_isolated_external_parser);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
|
||||
Copyright (c) 2025 Berkay Eren Ürün <berkay.ueruen@siemens.com>
|
||||
Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com>
|
||||
Copyright (c) 2026 Filippo Tedeschi <filippotedeschi98@gmail.com>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
@@ -563,6 +564,24 @@ START_TEST(test_alloc_explicit_encoding) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* Test robustness of XML_ParserReset() with a failing allocator when setting
|
||||
* encoding */
|
||||
START_TEST(test_alloc_reset_encoding) {
|
||||
int i;
|
||||
const int max_alloc_count = 5;
|
||||
|
||||
for (i = 0; i < max_alloc_count; i++) {
|
||||
g_allocation_count = i;
|
||||
if (XML_ParserReset(g_parser, XCS("us-ascii")) == XML_TRUE)
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
fail("Reset with encoding succeeded despite failing allocator");
|
||||
else if (i == max_alloc_count)
|
||||
fail("Reset with encoding failed at max allocation count");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* Test robustness of XML_SetBase against a failing allocator */
|
||||
START_TEST(test_alloc_set_base) {
|
||||
const XML_Char *new_base = XCS("/local/file/name.xml");
|
||||
@@ -2118,6 +2137,10 @@ START_TEST(test_alloc_tracker_size_recorded) {
|
||||
assert_true(ptr != NULL);
|
||||
assert_true(sizeRecordedFor(ptr) == 10);
|
||||
|
||||
assert_true(expat_realloc(parser, ptr, SIZE_MAX, -1) == NULL);
|
||||
|
||||
assert_true(sizeRecordedFor(ptr) == 10); // i.e. unchanged
|
||||
|
||||
assert_true(expat_realloc(parser, ptr, SIZE_MAX / 2, -1) == NULL);
|
||||
|
||||
assert_true(sizeRecordedFor(ptr) == 10); // i.e. unchanged
|
||||
@@ -2273,6 +2296,40 @@ START_TEST(test_alloc_tracker_api) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_alloc_tracker_api_float_round_trip) {
|
||||
const float values[] = {1.0f, 1.1f, INFINITY};
|
||||
|
||||
for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
|
||||
set_subtest("float %f", (double)i);
|
||||
const float wanted = values[i];
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
// Self-Test: Original value not already at target value
|
||||
double actual = 123.456;
|
||||
assert_true((float)actual != wanted);
|
||||
#if XML_GE == 1
|
||||
assert_true(
|
||||
XML_GetPropertyDouble(
|
||||
parser, XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, &actual)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true((float)actual != wanted); // Self-Test
|
||||
|
||||
// Test: Target value applied successfully
|
||||
assert_true(XML_SetAllocTrackerMaximumAmplification(parser, wanted)
|
||||
== XML_TRUE);
|
||||
assert_true(
|
||||
XML_GetPropertyDouble(
|
||||
parser, XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, &actual)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true((float)actual == wanted);
|
||||
#endif // XML_GE == 1
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_mem_api_cycle) {
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
|
||||
@@ -2336,6 +2393,7 @@ make_alloc_test_case(Suite *s) {
|
||||
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(tc_alloc, test_alloc_explicit_encoding);
|
||||
tcase_add_test(tc_alloc, test_alloc_reset_encoding);
|
||||
tcase_add_test(tc_alloc, test_alloc_set_base);
|
||||
tcase_add_test(tc_alloc, test_alloc_realloc_buffer);
|
||||
tcase_add_test__if_xml_ge(tc_alloc, test_alloc_ext_entity_realloc_buffer);
|
||||
@@ -2386,6 +2444,7 @@ make_alloc_test_case(Suite *s) {
|
||||
tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_threshold);
|
||||
tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_getbuffer_unlimited);
|
||||
tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_api);
|
||||
tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_api_float_round_trip);
|
||||
|
||||
tcase_add_test(tc_alloc, test_mem_api_cycle);
|
||||
tcase_add_test__if_xml_ge(tc_alloc, test_mem_api_unlimited);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
Copyright (c) 2026 Zeyou Liu <zeyouliu@tencent.com>
|
||||
Copyright (c) 2026 Afonso Januário <afonso-januario@hotmail.com>
|
||||
Copyright (c) 2026 Braian Plaku <braianplaku@gmail.com>
|
||||
Copyright (c) 2026 Filippo Tedeschi <filippotedeschi98@gmail.com>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
@@ -57,7 +58,8 @@
|
||||
#include "expat_config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h> // ULONG_MAX
|
||||
#include <inttypes.h> // PRIu64
|
||||
#include <limits.h> // ULONG_MAX
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -72,6 +74,7 @@
|
||||
#include "handlers.h"
|
||||
#include "siphash.h"
|
||||
#include "basic_tests.h"
|
||||
#include "../lib/xcs.h"
|
||||
|
||||
#define EXPAT_TESTS_ASAN 1
|
||||
|
||||
@@ -646,16 +649,15 @@ START_TEST(test_line_number_after_parse) {
|
||||
const char *text = "<tag>\n"
|
||||
"\n"
|
||||
"\n</tag>";
|
||||
XML_Size lineno;
|
||||
uint64_t lineno;
|
||||
|
||||
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||
== XML_STATUS_ERROR)
|
||||
xml_failure(g_parser);
|
||||
lineno = XML_GetCurrentLineNumber(g_parser);
|
||||
lineno = XML_GetCurrentLineNumber64(g_parser);
|
||||
if (lineno != 4) {
|
||||
char buffer[100];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno);
|
||||
snprintf(buffer, sizeof(buffer), "expected 4 lines, saw %" PRIu64, lineno);
|
||||
fail(buffer);
|
||||
}
|
||||
}
|
||||
@@ -664,16 +666,16 @@ END_TEST
|
||||
/* Regression test #2 for SF bug #653180. */
|
||||
START_TEST(test_column_number_after_parse) {
|
||||
const char *text = "<tag></tag>";
|
||||
XML_Size colno;
|
||||
uint64_t colno;
|
||||
|
||||
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||
== XML_STATUS_ERROR)
|
||||
xml_failure(g_parser);
|
||||
colno = XML_GetCurrentColumnNumber(g_parser);
|
||||
colno = XML_GetCurrentColumnNumber64(g_parser);
|
||||
if (colno != 11) {
|
||||
char buffer[100];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno);
|
||||
snprintf(buffer, sizeof(buffer), "expected 11 columns, saw %" PRIu64,
|
||||
colno);
|
||||
fail(buffer);
|
||||
}
|
||||
}
|
||||
@@ -716,16 +718,15 @@ START_TEST(test_line_number_after_error) {
|
||||
const char *text = "<a>\n"
|
||||
" <b>\n"
|
||||
" </a>"; /* missing </b> */
|
||||
XML_Size lineno;
|
||||
uint64_t lineno;
|
||||
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||
!= XML_STATUS_ERROR)
|
||||
fail("Expected a parse error");
|
||||
|
||||
lineno = XML_GetCurrentLineNumber(g_parser);
|
||||
lineno = XML_GetCurrentLineNumber64(g_parser);
|
||||
if (lineno != 3) {
|
||||
char buffer[100];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno);
|
||||
snprintf(buffer, sizeof(buffer), "expected 3 lines, saw %" PRIu64, lineno);
|
||||
fail(buffer);
|
||||
}
|
||||
}
|
||||
@@ -736,16 +737,15 @@ START_TEST(test_column_number_after_error) {
|
||||
const char *text = "<a>\n"
|
||||
" <b>\n"
|
||||
" </a>"; /* missing </b> */
|
||||
XML_Size colno;
|
||||
uint64_t colno;
|
||||
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||
!= XML_STATUS_ERROR)
|
||||
fail("Expected a parse error");
|
||||
|
||||
colno = XML_GetCurrentColumnNumber(g_parser);
|
||||
colno = XML_GetCurrentColumnNumber64(g_parser);
|
||||
if (colno != 4) {
|
||||
char buffer[100];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno);
|
||||
snprintf(buffer, sizeof(buffer), "expected 4 columns, saw %" PRIu64, colno);
|
||||
fail(buffer);
|
||||
}
|
||||
}
|
||||
@@ -921,9 +921,8 @@ check_attr_contains_normalized_whitespace(void *userData, const XML_Char *name,
|
||||
for (i = 0; atts[i] != NULL; i += 2) {
|
||||
const XML_Char *attrname = atts[i];
|
||||
const XML_Char *value = atts[i + 1];
|
||||
if (xcstrcmp(XCS("attr"), attrname) == 0
|
||||
|| xcstrcmp(XCS("ents"), attrname) == 0
|
||||
|| xcstrcmp(XCS("refs"), attrname) == 0) {
|
||||
if (xcscmp(XCS("attr"), attrname) == 0 || xcscmp(XCS("ents"), attrname) == 0
|
||||
|| xcscmp(XCS("refs"), attrname) == 0) {
|
||||
if (! is_whitespace_normalized(value, 0)) {
|
||||
char buffer[256];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
@@ -2598,6 +2597,57 @@ START_TEST(test_default_current) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* Test XML_DefaultCurrent does not dereference NULL when outside an event */
|
||||
START_TEST(test_default_current_outside_event) {
|
||||
struct handler_record_list handlerCalls;
|
||||
handlerCalls.count = 0;
|
||||
|
||||
set_subtest("NULL parser");
|
||||
XML_DefaultCurrent(NULL);
|
||||
|
||||
set_subtest("before parse");
|
||||
{
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
XML_SetDefaultHandler(parser, record_default_handler);
|
||||
XML_SetUserData(parser, &handlerCalls);
|
||||
|
||||
XML_DefaultCurrent(parser);
|
||||
assert_true(handlerCalls.count == 0);
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
|
||||
set_subtest("after parse");
|
||||
{
|
||||
const char *text = "<r>hello</r>";
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE)
|
||||
== XML_STATUS_ERROR)
|
||||
xml_failure(parser);
|
||||
|
||||
XML_SetDefaultHandler(parser, record_default_handler);
|
||||
XML_SetUserData(parser, &handlerCalls);
|
||||
|
||||
XML_DefaultCurrent(parser);
|
||||
assert_true(handlerCalls.count == 0);
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
|
||||
set_subtest("explicit encoding before parse");
|
||||
{
|
||||
XML_Parser parser = XML_ParserCreate(XCS("ISO-8859-1"));
|
||||
XML_SetDefaultHandler(parser, record_default_handler);
|
||||
XML_SetUserData(parser, &handlerCalls);
|
||||
|
||||
XML_DefaultCurrent(parser);
|
||||
assert_true(handlerCalls.count == 0);
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* Test DTD element parsing code paths */
|
||||
START_TEST(test_dtd_elements) {
|
||||
const char *text = "<!DOCTYPE doc [\n"
|
||||
@@ -2627,7 +2677,7 @@ element_decl_check_model(void *userData, const XML_Char *name,
|
||||
* [5] (type 4, quant 3, name "xyz")
|
||||
* [2] (type 4, quant 2, name "zebra")
|
||||
*/
|
||||
errorFlags |= ((xcstrcmp(name, XCS("junk")) == 0) ? 0 : (1u << 0));
|
||||
errorFlags |= ((xcscmp(name, XCS("junk")) == 0) ? 0 : (1u << 0));
|
||||
errorFlags |= ((model != NULL) ? 0 : (1u << 1));
|
||||
|
||||
if (model != NULL) {
|
||||
@@ -2647,26 +2697,25 @@ element_decl_check_model(void *userData, const XML_Char *name,
|
||||
errorFlags |= ((model[2].quant == XML_CQUANT_REP) ? 0 : (1u << 13));
|
||||
errorFlags |= ((model[2].numchildren == 0) ? 0 : (1u << 14));
|
||||
errorFlags |= ((model[2].children == NULL) ? 0 : (1u << 15));
|
||||
errorFlags
|
||||
|= ((xcstrcmp(model[2].name, XCS("zebra")) == 0) ? 0 : (1u << 16));
|
||||
errorFlags |= ((xcscmp(model[2].name, XCS("zebra")) == 0) ? 0 : (1u << 16));
|
||||
|
||||
errorFlags |= ((model[3].type == XML_CTYPE_NAME) ? 0 : (1u << 17));
|
||||
errorFlags |= ((model[3].quant == XML_CQUANT_NONE) ? 0 : (1u << 18));
|
||||
errorFlags |= ((model[3].numchildren == 0) ? 0 : (1u << 19));
|
||||
errorFlags |= ((model[3].children == NULL) ? 0 : (1u << 20));
|
||||
errorFlags |= ((xcstrcmp(model[3].name, XCS("bar")) == 0) ? 0 : (1u << 21));
|
||||
errorFlags |= ((xcscmp(model[3].name, XCS("bar")) == 0) ? 0 : (1u << 21));
|
||||
|
||||
errorFlags |= ((model[4].type == XML_CTYPE_NAME) ? 0 : (1u << 22));
|
||||
errorFlags |= ((model[4].quant == XML_CQUANT_NONE) ? 0 : (1u << 23));
|
||||
errorFlags |= ((model[4].numchildren == 0) ? 0 : (1u << 24));
|
||||
errorFlags |= ((model[4].children == NULL) ? 0 : (1u << 25));
|
||||
errorFlags |= ((xcstrcmp(model[4].name, XCS("foo")) == 0) ? 0 : (1u << 26));
|
||||
errorFlags |= ((xcscmp(model[4].name, XCS("foo")) == 0) ? 0 : (1u << 26));
|
||||
|
||||
errorFlags |= ((model[5].type == XML_CTYPE_NAME) ? 0 : (1u << 27));
|
||||
errorFlags |= ((model[5].quant == XML_CQUANT_PLUS) ? 0 : (1u << 28));
|
||||
errorFlags |= ((model[5].numchildren == 0) ? 0 : (1u << 29));
|
||||
errorFlags |= ((model[5].children == NULL) ? 0 : (1u << 30));
|
||||
errorFlags |= ((xcstrcmp(model[5].name, XCS("xyz")) == 0) ? 0 : (1u << 31));
|
||||
errorFlags |= ((xcscmp(model[5].name, XCS("xyz")) == 0) ? 0 : (1u << 31));
|
||||
}
|
||||
|
||||
XML_SetUserData(g_parser, (void *)(uintptr_t)errorFlags);
|
||||
@@ -2833,7 +2882,7 @@ START_TEST(test_set_base) {
|
||||
old_base = XML_GetBase(g_parser);
|
||||
if (XML_SetBase(g_parser, new_base) != XML_STATUS_OK)
|
||||
fail("Unable to set base");
|
||||
if (xcstrcmp(XML_GetBase(g_parser), new_base) != 0)
|
||||
if (xcscmp(XML_GetBase(g_parser), new_base) != 0)
|
||||
fail("Base setting not correct");
|
||||
if (XML_SetBase(g_parser, NULL) != XML_STATUS_OK)
|
||||
fail("Unable to NULL base");
|
||||
@@ -3160,12 +3209,12 @@ check_second_attr_normalization(void *userData, const XML_Char *name,
|
||||
for (size_t i = 0; atts[i] != NULL; i += 2) {
|
||||
const XML_Char *const key = atts[i];
|
||||
const XML_Char *const value = atts[i + 1];
|
||||
if (xcstrcmp(key, XCS("second")) != 0)
|
||||
if (xcscmp(key, XCS("second")) != 0)
|
||||
continue;
|
||||
*seen_second = 1;
|
||||
/* Attribute "second" is not of type CDATA, so leading, trailing and
|
||||
* repeated whitespace is to be normalized away. */
|
||||
if (xcstrcmp(value, XCS("a b")) != 0)
|
||||
if (xcscmp(value, XCS("a b")) != 0)
|
||||
fail("Attribute of non-CDATA type was not whitespace-normalized");
|
||||
}
|
||||
}
|
||||
@@ -3725,6 +3774,46 @@ START_TEST(test_negative_len_parse_buffer) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* Test XML_ParseBuffer rejects calls where len exceeds available buffer */
|
||||
START_TEST(test_parse_buffer_exceeds_buffer) {
|
||||
for (int isFinal = 0; isFinal < 2; isFinal++) {
|
||||
set_subtest("isFinal=%d", isFinal);
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
|
||||
/* Calling XML_ParseBuffer without any prior XML_GetBuffer call */
|
||||
if (XML_ParseBuffer(parser, 10, isFinal) != XML_STATUS_ERROR)
|
||||
fail("XML_ParseBuffer without XML_GetBuffer was expected to fail.");
|
||||
if (XML_GetErrorCode(parser) != XML_ERROR_NO_BUFFER)
|
||||
fail("Expected XML_ERROR_NO_BUFFER.");
|
||||
|
||||
/* Acquire a small buffer */
|
||||
void *const buffer = XML_GetBuffer(parser, 10);
|
||||
if (buffer == NULL)
|
||||
fail("XML_GetBuffer failed.");
|
||||
|
||||
/* Calling XML_ParseBuffer with len exceeding available buffer capacity */
|
||||
if (XML_ParseBuffer(parser, 10000, isFinal) != XML_STATUS_ERROR)
|
||||
fail("XML_ParseBuffer with len > capacity was expected to fail.");
|
||||
if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
|
||||
fail("Expected XML_ERROR_INVALID_ARGUMENT.");
|
||||
|
||||
/* Valid parse */
|
||||
memcpy(buffer, "<r></r>", 7);
|
||||
if (XML_ParseBuffer(parser, 7, XML_FALSE) != XML_STATUS_OK)
|
||||
xml_failure(parser);
|
||||
|
||||
/* Subsequent XML_ParseBuffer where len exceeds remaining capacity */
|
||||
if (XML_ParseBuffer(parser, 10000, isFinal) != XML_STATUS_ERROR)
|
||||
fail("XML_ParseBuffer on subsequent chunk was expected to fail.");
|
||||
if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_ARGUMENT)
|
||||
fail("Expected XML_ERROR_INVALID_ARGUMENT.");
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* Test odd corners of the XML_GetBuffer interface */
|
||||
static enum XML_Status
|
||||
get_feature(enum XML_FeatureEnum feature_id, long *presult) {
|
||||
@@ -3907,16 +3996,16 @@ END_TEST
|
||||
START_TEST(test_byte_info_at_end) {
|
||||
const char *text = "<doc></doc>";
|
||||
|
||||
if (XML_GetCurrentByteIndex(g_parser) != -1
|
||||
|| XML_GetCurrentByteCount(g_parser) != 0)
|
||||
if (XML_GetCurrentByteIndex64(g_parser) != -1
|
||||
|| XML_GetCurrentByteCount64(g_parser) != 0)
|
||||
fail("Byte index/count incorrect at start of parse");
|
||||
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||
== XML_STATUS_ERROR)
|
||||
xml_failure(g_parser);
|
||||
/* At end, the count will be zero and the index the end of string */
|
||||
if (XML_GetCurrentByteCount(g_parser) != 0)
|
||||
if (XML_GetCurrentByteCount64(g_parser) != 0)
|
||||
fail("Terminal byte count incorrect");
|
||||
if (XML_GetCurrentByteIndex(g_parser) != (XML_Index)strlen(text))
|
||||
if (XML_GetCurrentByteIndex64(g_parser) != (int64_t)strlen(text))
|
||||
fail("Terminal byte index incorrect");
|
||||
}
|
||||
END_TEST
|
||||
@@ -3930,9 +4019,9 @@ START_TEST(test_byte_info_at_error) {
|
||||
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||
== XML_STATUS_OK)
|
||||
fail("Syntax error not faulted");
|
||||
if (XML_GetCurrentByteCount(g_parser) != 0)
|
||||
if (XML_GetCurrentByteCount64(g_parser) != 0)
|
||||
fail("Error byte count incorrect");
|
||||
if (XML_GetCurrentByteIndex(g_parser) != strlen(PRE_ERROR_STR))
|
||||
if (XML_GetCurrentByteIndex64(g_parser) != strlen(PRE_ERROR_STR))
|
||||
fail("Error byte index incorrect");
|
||||
}
|
||||
END_TEST
|
||||
@@ -3945,11 +4034,12 @@ END_TEST
|
||||
#define END_ELEMENT "</e>"
|
||||
START_TEST(test_byte_info_at_cdata) {
|
||||
const char *text = START_ELEMENT CDATA_TEXT END_ELEMENT;
|
||||
int offset, size;
|
||||
int64_t offset;
|
||||
uint64_t size;
|
||||
ByteTestData data;
|
||||
|
||||
/* Check initial context is empty */
|
||||
if (XML_GetInputContext(g_parser, &offset, &size) != NULL)
|
||||
if (XML_GetInputContext64(g_parser, &offset, &size) != NULL)
|
||||
fail("Unexpected context at start of parse");
|
||||
|
||||
data.start_element_len = (int)strlen(START_ELEMENT);
|
||||
@@ -4150,7 +4240,7 @@ external_bom_checker(XML_Parser parser, const XML_Char *context,
|
||||
if (ext_parser == NULL)
|
||||
fail("Could not create external entity parser");
|
||||
|
||||
if (! xcstrcmp(systemId, XCS("004-2.ent"))) {
|
||||
if (! xcscmp(systemId, XCS("004-2.ent"))) {
|
||||
struct bom_testdata *const testdata = XML_GetUserData(parser);
|
||||
const char *const external = testdata->external;
|
||||
const int split = testdata->split;
|
||||
@@ -4161,7 +4251,7 @@ external_bom_checker(XML_Parser parser, const XML_Char *context,
|
||||
xml_failure(ext_parser);
|
||||
}
|
||||
text = external + split; // the parse below will continue where we left off.
|
||||
} else if (! xcstrcmp(systemId, XCS("004-1.ent"))) {
|
||||
} else if (! xcscmp(systemId, XCS("004-1.ent"))) {
|
||||
text = "<!ELEMENT doc EMPTY>\n"
|
||||
"<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
|
||||
"<!ENTITY % e2 '%e1;'>\n";
|
||||
@@ -7139,6 +7229,7 @@ make_basic_test_case(Suite *s) {
|
||||
tcase_add_test(tc_basic, test_suspend_parser_between_cdata_calls);
|
||||
tcase_add_test(tc_basic, test_memory_allocation);
|
||||
tcase_add_test__if_xml_ge(tc_basic, test_default_current);
|
||||
tcase_add_test(tc_basic, test_default_current_outside_event);
|
||||
tcase_add_test(tc_basic, test_dtd_elements);
|
||||
tcase_add_test(tc_basic, test_dtd_elements_nesting);
|
||||
tcase_add_test__ifdef_xml_dtd(tc_basic, test_set_foreign_dtd);
|
||||
@@ -7181,6 +7272,7 @@ make_basic_test_case(Suite *s) {
|
||||
tcase_add_test(tc_basic, test_empty_parse);
|
||||
tcase_add_test(tc_basic, test_negative_len_parse);
|
||||
tcase_add_test(tc_basic, test_negative_len_parse_buffer);
|
||||
tcase_add_test(tc_basic, test_parse_buffer_exceeds_buffer);
|
||||
tcase_add_test(tc_basic, test_get_buffer_1);
|
||||
tcase_add_test(tc_basic, test_get_buffer_2);
|
||||
#if XML_CONTEXT_BYTES > 0
|
||||
|
||||
@@ -252,12 +252,10 @@ ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXPAT_ATTR_INFO = @EXPAT_ATTR_INFO@
|
||||
EXPAT_CHAR_TYPE = @EXPAT_CHAR_TYPE@
|
||||
EXPAT_CONTEXT_BYTES = @EXPAT_CONTEXT_BYTES@
|
||||
EXPAT_DTD = @EXPAT_DTD@
|
||||
EXPAT_LARGE_SIZE = @EXPAT_LARGE_SIZE@
|
||||
EXPAT_MIN_SIZE = @EXPAT_MIN_SIZE@
|
||||
EXPAT_NS = @EXPAT_NS@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
@@ -312,7 +310,6 @@ SO_PATCH = @SO_PATCH@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
VSCRIPT_LDFLAGS = @VSCRIPT_LDFLAGS@
|
||||
_EXPAT_COMMENT_ATTR_INFO = @_EXPAT_COMMENT_ATTR_INFO@
|
||||
_EXPAT_COMMENT_DTD_OR_GE = @_EXPAT_COMMENT_DTD_OR_GE@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
Copyright (c) 2003-2006 Karl Waclawek <karl@waclawek.net>
|
||||
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
||||
Copyright (c) 2017-2025 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2017-2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||
Licensed under the MIT license:
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
# include <unistd.h> // close
|
||||
#endif
|
||||
|
||||
#include <fcntl.h> // open
|
||||
#include <inttypes.h> // PRIu64
|
||||
#include <fcntl.h> // open
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
#include <stddef.h> // ptrdiff_t
|
||||
@@ -48,12 +49,6 @@
|
||||
#include <time.h>
|
||||
#include "expat.h"
|
||||
|
||||
#ifdef XML_LARGE_SIZE
|
||||
# define XML_FMT_INT_MOD "ll"
|
||||
#else
|
||||
# define XML_FMT_INT_MOD "l"
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
# define XML_FMT_STR "ls"
|
||||
#else
|
||||
@@ -148,11 +143,11 @@ main(int argc, char *argv[]) {
|
||||
assert(parseBufferSize <= (ptrdiff_t)bufferSize);
|
||||
if (! XML_Parse(parser, XMLBufPtr, (int)parseBufferSize, isFinal)) {
|
||||
fprintf(stderr,
|
||||
"error '%" XML_FMT_STR "' at line %" XML_FMT_INT_MOD
|
||||
"u character %" XML_FMT_INT_MOD "u\n",
|
||||
"error '%" XML_FMT_STR "' at line %" PRIu64
|
||||
" character %" PRIu64 "\n",
|
||||
XML_ErrorString(XML_GetErrorCode(parser)),
|
||||
XML_GetCurrentLineNumber(parser),
|
||||
XML_GetCurrentColumnNumber(parser));
|
||||
XML_GetCurrentLineNumber64(parser),
|
||||
XML_GetCurrentColumnNumber64(parser));
|
||||
free(XMLBuf);
|
||||
XML_ParserFree(parser);
|
||||
return 4;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
Copyright (c) 2002-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
||||
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
|
||||
Copyright (c) 2016 Gilles Espinasse <g.esp@free.fr>
|
||||
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
|
||||
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
|
||||
@@ -49,7 +49,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "chardata.h"
|
||||
#include "../lib/xcsinc.c"
|
||||
#include "../lib/xcs.h"
|
||||
|
||||
void
|
||||
CharData_Init(CharData *storage) {
|
||||
|
||||
@@ -48,7 +48,8 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h> // for SIZE_MAX
|
||||
#include <inttypes.h> // for PRIu64
|
||||
#include <stdint.h> // for SIZE_MAX
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -188,10 +189,10 @@ _xml_failure(XML_Parser parser, const char *file, int line) {
|
||||
char buffer[1024];
|
||||
enum XML_Error err = XML_GetErrorCode(parser);
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
" %d: %" XML_FMT_STR " (line %" XML_FMT_INT_MOD
|
||||
"u, offset %" XML_FMT_INT_MOD "u)\n reported from %s, line %d\n",
|
||||
err, XML_ErrorString(err), XML_GetCurrentLineNumber(parser),
|
||||
XML_GetCurrentColumnNumber(parser), file, line);
|
||||
" %d: %" XML_FMT_STR " (line %" PRIu64 ", offset %" PRIu64
|
||||
")\n reported from %s, line %d\n",
|
||||
err, XML_ErrorString(err), XML_GetCurrentLineNumber64(parser),
|
||||
XML_GetCurrentColumnNumber64(parser), file, line);
|
||||
_fail(file, line, buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,9 +59,6 @@
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
# define XML_FMT_STR "ls"
|
||||
# include <wchar.h>
|
||||
# define xcstrlen(s) wcslen(s)
|
||||
# define xcstrcmp(s, t) wcscmp((s), (t))
|
||||
# define xcstrncmp(s, t, n) wcsncmp((s), (t), (n))
|
||||
# define XCS(s) _XCS(s)
|
||||
# define _XCS(s) L##s
|
||||
#else
|
||||
@@ -69,9 +66,6 @@
|
||||
# error "No support for UTF-16 character without wchar_t in tests"
|
||||
# else
|
||||
# define XML_FMT_STR "s"
|
||||
# define xcstrlen(s) strlen(s)
|
||||
# define xcstrcmp(s, t) strcmp((s), (t))
|
||||
# define xcstrncmp(s, t, n) strncmp((s), (t), (n))
|
||||
# define XCS(s) s
|
||||
# endif /* XML_UNICODE */
|
||||
#endif /* XML_UNICODE_WCHAR_T */
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "structdata.h"
|
||||
#include "common.h"
|
||||
#include "handlers.h"
|
||||
#include "../lib/xcs.h"
|
||||
|
||||
/* Global variables for user parameter settings tests */
|
||||
/* Variable holding the expected handler userData */
|
||||
@@ -95,15 +96,16 @@ start_element_event_handler2(void *userData, const XML_Char *name,
|
||||
const XML_Char **attr) {
|
||||
StructData *storage = (StructData *)userData;
|
||||
UNUSED_P(attr);
|
||||
StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
|
||||
(int)XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG);
|
||||
StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber64(g_parser),
|
||||
(int)XML_GetCurrentLineNumber64(g_parser),
|
||||
STRUCT_START_TAG);
|
||||
}
|
||||
|
||||
void XMLCALL
|
||||
end_element_event_handler2(void *userData, const XML_Char *name) {
|
||||
StructData *storage = (StructData *)userData;
|
||||
StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
|
||||
(int)XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG);
|
||||
StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber64(g_parser),
|
||||
(int)XML_GetCurrentLineNumber64(g_parser), STRUCT_END_TAG);
|
||||
}
|
||||
|
||||
void XMLCALL
|
||||
@@ -116,7 +118,7 @@ counting_start_element_handler(void *userData, const XML_Char *name,
|
||||
int count, id, i;
|
||||
|
||||
while (info->name != NULL) {
|
||||
if (! xcstrcmp(name, info->name))
|
||||
if (! xcscmp(name, info->name))
|
||||
break;
|
||||
info++;
|
||||
}
|
||||
@@ -138,14 +140,14 @@ counting_start_element_handler(void *userData, const XML_Char *name,
|
||||
fail("ID not present");
|
||||
return;
|
||||
}
|
||||
if (id != -1 && xcstrcmp(atts[id], info->id_name) != 0) {
|
||||
if (id != -1 && xcscmp(atts[id], info->id_name) != 0) {
|
||||
fail("ID does not have the correct name");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < info->attr_count + info->default_attr_count; i++) {
|
||||
attr = info->attributes;
|
||||
while (attr->name != NULL) {
|
||||
if (! xcstrcmp(atts[0], attr->name))
|
||||
if (! xcscmp(atts[0], attr->name))
|
||||
break;
|
||||
attr++;
|
||||
}
|
||||
@@ -153,7 +155,7 @@ counting_start_element_handler(void *userData, const XML_Char *name,
|
||||
fail("Attribute not recognised");
|
||||
return;
|
||||
}
|
||||
if (xcstrcmp(atts[1], attr->value) != 0) {
|
||||
if (xcscmp(atts[1], attr->value) != 0) {
|
||||
fail("Attribute has wrong value");
|
||||
return;
|
||||
}
|
||||
@@ -176,9 +178,9 @@ start_element_suspender(void *userData, const XML_Char *name,
|
||||
const XML_Char **atts) {
|
||||
UNUSED_P(userData);
|
||||
UNUSED_P(atts);
|
||||
if (! xcstrcmp(name, XCS("suspend")))
|
||||
if (! xcscmp(name, XCS("suspend")))
|
||||
XML_StopParser(g_parser, XML_TRUE);
|
||||
if (! xcstrcmp(name, XCS("abort")))
|
||||
if (! xcscmp(name, XCS("abort")))
|
||||
XML_StopParser(g_parser, XML_FALSE);
|
||||
}
|
||||
|
||||
@@ -195,12 +197,12 @@ triplet_start_checker(void *userData, const XML_Char *name,
|
||||
const XML_Char **atts) {
|
||||
XML_Char **elemstr = (XML_Char **)userData;
|
||||
char buffer[1024];
|
||||
if (xcstrcmp(elemstr[0], name) != 0) {
|
||||
if (xcscmp(elemstr[0], name) != 0) {
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"unexpected start string: '%" XML_FMT_STR "'", name);
|
||||
fail(buffer);
|
||||
}
|
||||
if (xcstrcmp(elemstr[1], atts[0]) != 0) {
|
||||
if (xcscmp(elemstr[1], atts[0]) != 0) {
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"unexpected attribute string: '%" XML_FMT_STR "'", atts[0]);
|
||||
fail(buffer);
|
||||
@@ -215,7 +217,7 @@ triplet_start_checker(void *userData, const XML_Char *name,
|
||||
void XMLCALL
|
||||
triplet_end_checker(void *userData, const XML_Char *name) {
|
||||
XML_Char **elemstr = (XML_Char **)userData;
|
||||
if (xcstrcmp(elemstr[0], name) != 0) {
|
||||
if (xcscmp(elemstr[0], name) != 0) {
|
||||
char buffer[1024];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"unexpected end string: '%" XML_FMT_STR "'", name);
|
||||
@@ -291,7 +293,7 @@ int XMLCALL
|
||||
UnknownEncodingHandler(void *data, const XML_Char *encoding,
|
||||
XML_Encoding *info) {
|
||||
UNUSED_P(data);
|
||||
if (xcstrcmp(encoding, XCS("unsupported-encoding")) == 0) {
|
||||
if (xcscmp(encoding, XCS("unsupported-encoding")) == 0) {
|
||||
int i;
|
||||
for (i = 0; i < 256; ++i)
|
||||
info->map[i] = i;
|
||||
@@ -323,7 +325,7 @@ int XMLCALL
|
||||
unknown_released_encoding_handler(void *data, const XML_Char *encoding,
|
||||
XML_Encoding *info) {
|
||||
UNUSED_P(data);
|
||||
if (! xcstrcmp(encoding, XCS("unsupported-encoding"))) {
|
||||
if (! xcscmp(encoding, XCS("unsupported-encoding"))) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
@@ -359,12 +361,12 @@ MiscEncodingHandler(void *data, const XML_Char *encoding, XML_Encoding *info) {
|
||||
int i;
|
||||
int high_map = -2; /* Assume a 2-byte sequence */
|
||||
|
||||
if (! xcstrcmp(encoding, XCS("invalid-9"))
|
||||
|| ! xcstrcmp(encoding, XCS("ascii-like"))
|
||||
|| ! xcstrcmp(encoding, XCS("invalid-len"))
|
||||
|| ! xcstrcmp(encoding, XCS("invalid-a"))
|
||||
|| ! xcstrcmp(encoding, XCS("invalid-surrogate"))
|
||||
|| ! xcstrcmp(encoding, XCS("invalid-high")))
|
||||
if (! xcscmp(encoding, XCS("invalid-9"))
|
||||
|| ! xcscmp(encoding, XCS("ascii-like"))
|
||||
|| ! xcscmp(encoding, XCS("invalid-len"))
|
||||
|| ! xcscmp(encoding, XCS("invalid-a"))
|
||||
|| ! xcscmp(encoding, XCS("invalid-surrogate"))
|
||||
|| ! xcscmp(encoding, XCS("invalid-high")))
|
||||
high_map = -1;
|
||||
|
||||
for (i = 0; i < 128; ++i)
|
||||
@@ -373,28 +375,28 @@ MiscEncodingHandler(void *data, const XML_Char *encoding, XML_Encoding *info) {
|
||||
info->map[i] = high_map;
|
||||
|
||||
/* If required, put an invalid value in the ASCII entries */
|
||||
if (! xcstrcmp(encoding, XCS("invalid-9")))
|
||||
if (! xcscmp(encoding, XCS("invalid-9")))
|
||||
info->map[9] = 5;
|
||||
/* If required, have a top-bit set character starts a 5-byte sequence */
|
||||
if (! xcstrcmp(encoding, XCS("invalid-len")))
|
||||
if (! xcscmp(encoding, XCS("invalid-len")))
|
||||
info->map[0x81] = -5;
|
||||
/* If required, make a top-bit set character a valid ASCII character */
|
||||
if (! xcstrcmp(encoding, XCS("invalid-a")))
|
||||
if (! xcscmp(encoding, XCS("invalid-a")))
|
||||
info->map[0x82] = 'a';
|
||||
/* If required, give a top-bit set character a forbidden value,
|
||||
* what would otherwise be the first of a surrogate pair.
|
||||
*/
|
||||
if (! xcstrcmp(encoding, XCS("invalid-surrogate")))
|
||||
if (! xcscmp(encoding, XCS("invalid-surrogate")))
|
||||
info->map[0x83] = 0xd801;
|
||||
/* If required, give a top-bit set character too high a value */
|
||||
if (! xcstrcmp(encoding, XCS("invalid-high")))
|
||||
if (! xcscmp(encoding, XCS("invalid-high")))
|
||||
info->map[0x84] = 0x010101;
|
||||
|
||||
info->data = data;
|
||||
info->release = NULL;
|
||||
if (! xcstrcmp(encoding, XCS("failing-conv")))
|
||||
if (! xcscmp(encoding, XCS("failing-conv")))
|
||||
info->convert = failing_converter;
|
||||
else if (! xcstrcmp(encoding, XCS("prefix-conv")))
|
||||
else if (! xcscmp(encoding, XCS("prefix-conv")))
|
||||
info->convert = prefix_converter;
|
||||
else
|
||||
info->convert = NULL;
|
||||
@@ -437,7 +439,7 @@ external_entity_optioner(XML_Parser parser, const XML_Char *context,
|
||||
UNUSED_P(base);
|
||||
UNUSED_P(publicId);
|
||||
while (options->parse_text != NULL) {
|
||||
if (! xcstrcmp(systemId, options->system_id)) {
|
||||
if (! xcscmp(systemId, options->system_id)) {
|
||||
enum XML_Status rc;
|
||||
ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
|
||||
if (ext_parser == NULL)
|
||||
@@ -874,13 +876,13 @@ external_entity_param(XML_Parser parser, const XML_Char *context,
|
||||
if (ext_parser == NULL)
|
||||
fail("Could not create external entity parser");
|
||||
|
||||
if (! xcstrcmp(systemId, XCS("004-1.ent"))) {
|
||||
if (! xcscmp(systemId, XCS("004-1.ent"))) {
|
||||
if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE)
|
||||
!= XML_STATUS_ERROR)
|
||||
fail("Inner DTD with invalid tag not rejected");
|
||||
if (XML_GetErrorCode(ext_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
|
||||
xml_failure(ext_parser);
|
||||
} else if (! xcstrcmp(systemId, XCS("004-2.ent"))) {
|
||||
} else if (! xcscmp(systemId, XCS("004-2.ent"))) {
|
||||
if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE)
|
||||
!= XML_STATUS_ERROR)
|
||||
fail("Invalid tag in external param not rejected");
|
||||
@@ -984,11 +986,11 @@ external_entity_valuer(XML_Parser parser, const XML_Char *context,
|
||||
ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
|
||||
if (ext_parser == NULL)
|
||||
fail("Could not create external entity parser");
|
||||
if (! xcstrcmp(systemId, XCS("004-1.ent"))) {
|
||||
if (! xcscmp(systemId, XCS("004-1.ent"))) {
|
||||
if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE)
|
||||
== XML_STATUS_ERROR)
|
||||
xml_failure(ext_parser);
|
||||
} else if (! xcstrcmp(systemId, XCS("004-2.ent"))) {
|
||||
} else if (! xcscmp(systemId, XCS("004-2.ent"))) {
|
||||
ExtFaults *fault = XML_GetUserData(parser);
|
||||
enum XML_Status status;
|
||||
enum XML_Error error;
|
||||
@@ -1030,7 +1032,7 @@ external_entity_not_standalone(XML_Parser parser, const XML_Char *context,
|
||||
ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
|
||||
if (ext_parser == NULL)
|
||||
fail("Could not create external entity parser");
|
||||
if (! xcstrcmp(systemId, XCS("foo"))) {
|
||||
if (! xcscmp(systemId, XCS("foo"))) {
|
||||
XML_SetNotStandaloneHandler(ext_parser, reject_not_standalone_handler);
|
||||
if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE)
|
||||
!= XML_STATUS_ERROR)
|
||||
@@ -1040,7 +1042,7 @@ external_entity_not_standalone(XML_Parser parser, const XML_Char *context,
|
||||
XML_SetNotStandaloneHandler(ext_parser, NULL);
|
||||
XML_ParserFree(ext_parser);
|
||||
return XML_STATUS_ERROR;
|
||||
} else if (! xcstrcmp(systemId, XCS("bar"))) {
|
||||
} else if (! xcscmp(systemId, XCS("bar"))) {
|
||||
if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE)
|
||||
== XML_STATUS_ERROR)
|
||||
xml_failure(ext_parser);
|
||||
@@ -1068,12 +1070,12 @@ external_entity_value_aborter(XML_Parser parser, const XML_Char *context,
|
||||
ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
|
||||
if (ext_parser == NULL)
|
||||
fail("Could not create external entity parser");
|
||||
if (! xcstrcmp(systemId, XCS("004-1.ent"))) {
|
||||
if (! xcscmp(systemId, XCS("004-1.ent"))) {
|
||||
if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE)
|
||||
== XML_STATUS_ERROR)
|
||||
xml_failure(ext_parser);
|
||||
}
|
||||
if (! xcstrcmp(systemId, XCS("004-2.ent"))) {
|
||||
if (! xcscmp(systemId, XCS("004-2.ent"))) {
|
||||
XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
|
||||
XML_SetUserData(ext_parser, ext_parser);
|
||||
if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE)
|
||||
@@ -1101,9 +1103,9 @@ external_entity_public(XML_Parser parser, const XML_Char *context,
|
||||
ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
|
||||
if (ext_parser == NULL)
|
||||
return XML_STATUS_ERROR;
|
||||
if (systemId != NULL && ! xcstrcmp(systemId, XCS("http://example.org/"))) {
|
||||
if (systemId != NULL && ! xcscmp(systemId, XCS("http://example.org/"))) {
|
||||
text = text1;
|
||||
} else if (publicId != NULL && ! xcstrcmp(publicId, XCS("foo"))) {
|
||||
} else if (publicId != NULL && ! xcscmp(publicId, XCS("foo"))) {
|
||||
text = text2;
|
||||
} else
|
||||
fail("Unexpected parameters to external entity parser");
|
||||
@@ -1126,9 +1128,9 @@ external_entity_devaluer(XML_Parser parser, const XML_Char *context,
|
||||
|
||||
UNUSED_P(base);
|
||||
UNUSED_P(publicId);
|
||||
if (systemId == NULL || ! xcstrcmp(systemId, XCS("bar")))
|
||||
if (systemId == NULL || ! xcscmp(systemId, XCS("bar")))
|
||||
return XML_STATUS_OK;
|
||||
if (xcstrcmp(systemId, XCS("foo")) != 0)
|
||||
if (xcscmp(systemId, XCS("foo")) != 0)
|
||||
fail("Unexpected system ID");
|
||||
ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
|
||||
if (ext_parser == NULL)
|
||||
@@ -1527,9 +1529,9 @@ accounting_external_entity_ref_handler(XML_Parser parser,
|
||||
const struct AccountingTestCase *const testCase = XML_GetUserData(parser);
|
||||
|
||||
const char *externalText = NULL;
|
||||
if (xcstrcmp(systemId, XCS("first.ent")) == 0) {
|
||||
if (xcscmp(systemId, XCS("first.ent")) == 0) {
|
||||
externalText = testCase->firstExternalText;
|
||||
} else if (xcstrcmp(systemId, XCS("second.ent")) == 0) {
|
||||
} else if (xcscmp(systemId, XCS("second.ent")) == 0) {
|
||||
externalText = testCase->secondExternalText;
|
||||
} else {
|
||||
assert(! "systemId is neither \"first.ent\" nor \"second.ent\"");
|
||||
@@ -1569,16 +1571,16 @@ verify_attlist_decl_handler(void *userData, const XML_Char *element_name,
|
||||
const XML_Char *default_value, int is_required) {
|
||||
AttTest *at = (AttTest *)userData;
|
||||
|
||||
if (xcstrcmp(element_name, at->element_name) != 0)
|
||||
if (xcscmp(element_name, at->element_name) != 0)
|
||||
fail("Unexpected element name in attribute declaration");
|
||||
if (xcstrcmp(attr_name, at->attr_name) != 0)
|
||||
if (xcscmp(attr_name, at->attr_name) != 0)
|
||||
fail("Unexpected attribute name in attribute declaration");
|
||||
if (xcstrcmp(attr_type, at->attr_type) != 0)
|
||||
if (xcscmp(attr_type, at->attr_type) != 0)
|
||||
fail("Unexpected attribute type in attribute declaration");
|
||||
if ((default_value == NULL && at->default_value != NULL)
|
||||
|| (default_value != NULL && at->default_value == NULL)
|
||||
|| (default_value != NULL
|
||||
&& xcstrcmp(default_value, at->default_value) != 0))
|
||||
&& xcscmp(default_value, at->default_value) != 0))
|
||||
fail("Unexpected default value in attribute declaration");
|
||||
if (is_required != at->is_required)
|
||||
fail("Requirement mismatch in attribute declaration");
|
||||
@@ -1649,23 +1651,24 @@ rsqb_handler(void *userData, const XML_Char *s, int len) {
|
||||
void XMLCALL
|
||||
byte_character_handler(void *userData, const XML_Char *s, int len) {
|
||||
#if XML_CONTEXT_BYTES > 0
|
||||
int offset, size;
|
||||
int64_t offset;
|
||||
uint64_t size;
|
||||
const char *buffer;
|
||||
ByteTestData *data = (ByteTestData *)userData;
|
||||
|
||||
UNUSED_P(s);
|
||||
buffer = XML_GetInputContext(g_parser, &offset, &size);
|
||||
buffer = XML_GetInputContext64(g_parser, &offset, &size);
|
||||
if (buffer == NULL)
|
||||
fail("Failed to get context buffer");
|
||||
if (offset != data->start_element_len)
|
||||
fail("Context offset in unexpected position");
|
||||
if (len != data->cdata_len)
|
||||
fail("CDATA length reported incorrectly");
|
||||
if (size != data->total_string_len)
|
||||
if (size != (uint64_t)data->total_string_len)
|
||||
fail("Context size is not full buffer");
|
||||
if (XML_GetCurrentByteIndex(g_parser) != offset)
|
||||
if (XML_GetCurrentByteIndex64(g_parser) != offset)
|
||||
fail("Character byte index incorrect");
|
||||
if (XML_GetCurrentByteCount(g_parser) != len)
|
||||
if (XML_GetCurrentByteCount64(g_parser) != (uint64_t)len)
|
||||
fail("Character byte count incorrect");
|
||||
#else
|
||||
UNUSED_P(s);
|
||||
@@ -1723,7 +1726,7 @@ void XMLCALL
|
||||
record_element_start_handler(void *userData, const XML_Char *name,
|
||||
const XML_Char **atts) {
|
||||
UNUSED_P(atts);
|
||||
CharData_AppendXMLChars((CharData *)userData, name, (int)xcstrlen(name));
|
||||
CharData_AppendXMLChars((CharData *)userData, name, (int)xcslen(name));
|
||||
}
|
||||
|
||||
void XMLCALL
|
||||
@@ -1763,13 +1766,13 @@ param_entity_match_handler(void *userData, const XML_Char *entityName,
|
||||
|| entity_value_to_match == NULL) {
|
||||
return;
|
||||
}
|
||||
if (! xcstrcmp(entityName, entity_name_to_match)) {
|
||||
if (! xcscmp(entityName, entity_name_to_match)) {
|
||||
/* The cast here is safe because we control the horizontal and
|
||||
* the vertical, and we therefore know our strings are never
|
||||
* going to overflow an int.
|
||||
*/
|
||||
if (value_length != (int)xcstrlen(entity_value_to_match)
|
||||
|| xcstrncmp(value, entity_value_to_match, value_length) != 0) {
|
||||
if (value_length != (int)xcslen(entity_value_to_match)
|
||||
|| xcsncmp(value, entity_value_to_match, value_length) != 0) {
|
||||
entity_match_flag = ENTITY_MATCH_FAIL;
|
||||
} else {
|
||||
entity_match_flag = ENTITY_MATCH_SUCCESS;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
Copyright (c) 2026 Kartik Kenchi <netliomax25@gmail.com>
|
||||
Copyright (c) 2026 Evgeny Kotkov <kotkov@apache.org>
|
||||
Copyright (c) 2026 Darren Carreras <carrerasdarren@gmail.com>
|
||||
Copyright (c) 2026 Junki Lee <junkilee80@gmail.com>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
@@ -55,6 +56,8 @@
|
||||
#include "expat_config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "expat.h"
|
||||
@@ -65,6 +68,7 @@
|
||||
#include "ascii.h" /* for ASCII_xxx */
|
||||
#include "handlers.h"
|
||||
#include "misc_tests.h"
|
||||
#include "../lib/xcs.h"
|
||||
|
||||
void XMLCALL accumulate_characters_ext_handler(void *userData,
|
||||
const XML_Char *s, int len);
|
||||
@@ -218,7 +222,7 @@ START_TEST(test_misc_version) {
|
||||
if (! versions_equal(&read_version, &parsed_version))
|
||||
fail("Version mismatch");
|
||||
|
||||
if (xcstrcmp(version_text, XCS("expat_2.8.5"))
|
||||
if (xcscmp(version_text, XCS("expat_2.9.0"))
|
||||
!= 0) /* needs bump on releases */
|
||||
fail("XML_*_VERSION in expat.h out of sync?\n");
|
||||
}
|
||||
@@ -394,8 +398,8 @@ START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) {
|
||||
XML_Parser parser;
|
||||
enum XML_Status parseResult;
|
||||
int setParamEntityResult;
|
||||
XML_Size lineNumber;
|
||||
XML_Size columnNumber;
|
||||
uint64_t lineNumber;
|
||||
uint64_t columnNumber;
|
||||
|
||||
parser = XML_ParserCreate(NULL);
|
||||
setParamEntityResult
|
||||
@@ -444,13 +448,13 @@ START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) {
|
||||
if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
|
||||
fail("Error code does not match XML_ERROR_INVALID_TOKEN");
|
||||
|
||||
lineNumber = XML_GetCurrentLineNumber(parser);
|
||||
lineNumber = XML_GetCurrentLineNumber64(parser);
|
||||
if (lineNumber != 6)
|
||||
fail("XML_GetCurrentLineNumber does not work as expected.");
|
||||
fail("XML_GetCurrentLineNumber64 does not work as expected.");
|
||||
|
||||
columnNumber = XML_GetCurrentColumnNumber(parser);
|
||||
columnNumber = XML_GetCurrentColumnNumber64(parser);
|
||||
if (columnNumber != 0)
|
||||
fail("XML_GetCurrentColumnNumber does not work as expected.");
|
||||
fail("XML_GetCurrentColumnNumber64 does not work as expected.");
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
@@ -629,22 +633,23 @@ END_TEST
|
||||
// Inspired by function XML_OriginalString of Perl's XML::Parser
|
||||
static char *
|
||||
dup_original_string(XML_Parser parser) {
|
||||
const int byte_count = XML_GetCurrentByteCount(parser);
|
||||
const uint64_t byte_count = XML_GetCurrentByteCount64(parser);
|
||||
|
||||
assert_true(byte_count >= 0);
|
||||
int64_t offset64 = -1;
|
||||
uint64_t size64 = UINT64_MAX;
|
||||
|
||||
int offset = -1;
|
||||
int size = -1;
|
||||
|
||||
const char *const context = XML_GetInputContext(parser, &offset, &size);
|
||||
const char *const context64
|
||||
= XML_GetInputContext64(parser, &offset64, &size64);
|
||||
|
||||
#if XML_CONTEXT_BYTES > 0
|
||||
assert_true(context != NULL);
|
||||
assert_true(offset >= 0);
|
||||
assert_true(size >= 0);
|
||||
return portable_strndup(context + offset, byte_count);
|
||||
assert_true(context64 != NULL);
|
||||
assert_true(offset64 != -1);
|
||||
assert_true(size64 != UINT64_MAX);
|
||||
|
||||
return portable_strndup(context64 + offset64, byte_count);
|
||||
#else
|
||||
assert_true(context == NULL);
|
||||
UNUSED_P(byte_count);
|
||||
assert_true(context64 == NULL);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
@@ -709,8 +714,8 @@ START_TEST(test_misc_async_entity_rejected) {
|
||||
const char *doc;
|
||||
enum XML_Status expectedStatusNoGE;
|
||||
enum XML_Error expectedErrorNoGE;
|
||||
XML_Size expectedErrorLine;
|
||||
XML_Size expectedErrorColumn;
|
||||
uint64_t expectedErrorLine;
|
||||
uint16_t expectedErrorColumn;
|
||||
};
|
||||
const struct test_case cases[] = {
|
||||
// Opened by one entity, closed by another
|
||||
@@ -769,8 +774,9 @@ START_TEST(test_misc_async_entity_rejected) {
|
||||
== expectedStatus);
|
||||
assert_true(XML_GetErrorCode(parser) == expectedError);
|
||||
#if XML_GE == 1
|
||||
assert_true(XML_GetCurrentLineNumber(parser) == testCase.expectedErrorLine);
|
||||
assert_true(XML_GetCurrentColumnNumber(parser)
|
||||
assert_true(XML_GetCurrentLineNumber64(parser)
|
||||
== testCase.expectedErrorLine);
|
||||
assert_true(XML_GetCurrentColumnNumber64(parser)
|
||||
== testCase.expectedErrorColumn);
|
||||
#endif
|
||||
XML_ParserFree(parser);
|
||||
@@ -894,6 +900,66 @@ START_TEST(test_misc_unknown_encoding_callbacks_protected) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
typedef struct {
|
||||
XML_Parser parser;
|
||||
int releaseCallCount;
|
||||
uint64_t lineAtRelease;
|
||||
} EncodingReleaseData;
|
||||
|
||||
static void XMLCALL
|
||||
position_reading_encoding_release(void *userData) {
|
||||
EncodingReleaseData *const data = userData;
|
||||
data->releaseCallCount++;
|
||||
data->lineAtRelease = XML_GetCurrentLineNumber64(data->parser);
|
||||
}
|
||||
|
||||
static int XMLCALL
|
||||
position_reading_encoding_handler(void *userData, const XML_Char *name,
|
||||
XML_Encoding *info) {
|
||||
UNUSED_P(name);
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
info->map[i] = i;
|
||||
info->data = userData;
|
||||
info->convert = NULL;
|
||||
info->release = position_reading_encoding_release;
|
||||
return XML_STATUS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
run_unknown_encoding_release_getter_test(bool resetParser) {
|
||||
const char *const doc = "<?xml version='1.0' encoding='release-order'?>\n"
|
||||
"<root>\n"
|
||||
" <unclosed>\n"
|
||||
"</root>\n";
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
EncodingReleaseData data = {parser, 0, 0};
|
||||
|
||||
assert_true(parser != NULL);
|
||||
XML_SetUnknownEncodingHandler(parser, position_reading_encoding_handler,
|
||||
&data);
|
||||
assert_true(XML_Parse(parser, doc, (int)strlen(doc), /*isFinal=*/XML_TRUE)
|
||||
== XML_STATUS_ERROR);
|
||||
assert_true(XML_GetErrorCode(parser) == XML_ERROR_TAG_MISMATCH);
|
||||
|
||||
if (resetParser)
|
||||
assert_true(XML_ParserReset(parser, NULL) == XML_TRUE);
|
||||
XML_ParserFree(parser);
|
||||
|
||||
assert_true(data.releaseCallCount == 1);
|
||||
assert_true(data.lineAtRelease == 4);
|
||||
}
|
||||
|
||||
START_TEST(test_misc_unknown_encoding_release_getter_parser_free) {
|
||||
run_unknown_encoding_release_getter_test(false);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_misc_unknown_encoding_release_getter_parser_reset) {
|
||||
run_unknown_encoding_release_getter_test(true);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
// General attack payload idea by Jason Kratzer of Mozilla
|
||||
START_TEST(test_misc_low_surrogate_mozilla_bug_2053153) {
|
||||
const char doc_before[] = "<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n\0"
|
||||
@@ -992,6 +1058,10 @@ make_miscellaneous_test_case(Suite *s) {
|
||||
tcase_add_test(tc_misc, test_misc_calls_forbidden_from_handlers);
|
||||
tcase_add_test(tc_misc, test_misc_resume_parser_forbidden_from_handler);
|
||||
tcase_add_test(tc_misc, test_misc_unknown_encoding_callbacks_protected);
|
||||
tcase_add_test(tc_misc,
|
||||
test_misc_unknown_encoding_release_getter_parser_free);
|
||||
tcase_add_test(tc_misc,
|
||||
test_misc_unknown_encoding_release_getter_parser_reset);
|
||||
tcase_add_test(tc_misc, test_misc_input_2gb);
|
||||
tcase_add_test(tc_misc, test_misc_low_surrogate_mozilla_bug_2053153);
|
||||
}
|
||||
@@ -0,0 +1,790 @@
|
||||
/* Tests related to the public properties API of Expat
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "expat_config.h"
|
||||
|
||||
#include "props_tests.h"
|
||||
|
||||
#include "common.h" // for g_chunkSize
|
||||
#include "expat.h"
|
||||
#include "internal.h" // for e.g. EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
enum ExpectedType {
|
||||
TYPE_BOOL,
|
||||
TYPE_DOUBLE,
|
||||
TYPE_UINT64,
|
||||
};
|
||||
|
||||
START_TEST(test_props_getter_defaults) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
#if XML_GE == 1
|
||||
// Case XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD
|
||||
{
|
||||
uint64_t actionThresholdBytes1 = 123;
|
||||
assert_true(XML_GetPropertyUInt64(
|
||||
parser, XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD,
|
||||
&actionThresholdBytes1)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true(actionThresholdBytes1
|
||||
== EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT);
|
||||
}
|
||||
|
||||
// Case XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION
|
||||
{
|
||||
double maximumAmplification1 = 123.456;
|
||||
assert_true(XML_GetPropertyDouble(
|
||||
parser, XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION,
|
||||
&maximumAmplification1)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true(maximumAmplification1
|
||||
== (double)EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT);
|
||||
}
|
||||
|
||||
// Case XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD
|
||||
{
|
||||
uint64_t actionThresholdBytes2 = 123;
|
||||
assert_true(XML_GetPropertyUInt64(
|
||||
parser, XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD,
|
||||
&actionThresholdBytes2)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true(
|
||||
actionThresholdBytes2
|
||||
== EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT);
|
||||
}
|
||||
|
||||
// Case XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION
|
||||
{
|
||||
double maximumAmplification2 = 123.456;
|
||||
assert_true(XML_GetPropertyDouble(
|
||||
parser, XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION,
|
||||
&maximumAmplification2)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true(
|
||||
maximumAmplification2
|
||||
== (double)
|
||||
EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Case XML_PROP_REPARSE_DEFERRAL_ENABLED
|
||||
XML_Bool reparseDeferralEnabled = XML_FALSE;
|
||||
assert_true(XML_GetPropertyBool(parser, XML_PROP_REPARSE_DEFERRAL_ENABLED,
|
||||
&reparseDeferralEnabled)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true(reparseDeferralEnabled == g_reparseDeferralEnabledDefault);
|
||||
|
||||
// Case XML_PROP_INVALID
|
||||
XML_Bool dummyBool = XML_FALSE;
|
||||
double dummyDouble = 123.456;
|
||||
uint64_t dummyUInt64 = 123;
|
||||
assert_true(XML_GetPropertyBool(parser, XML_PROP_INVALID, &dummyBool)
|
||||
== XML_PROP_ERROR_INVALID_KEY);
|
||||
assert_true(XML_GetPropertyDouble(parser, XML_PROP_INVALID, &dummyDouble)
|
||||
== XML_PROP_ERROR_INVALID_KEY);
|
||||
assert_true(XML_GetPropertyUInt64(parser, XML_PROP_INVALID, &dummyUInt64)
|
||||
== XML_PROP_ERROR_INVALID_KEY);
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_getter_error_parser_null) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
XML_Parser parserNonNull = XML_ParserCreate(NULL);
|
||||
XML_Parser parsers[] = {parserNonNull, NULL};
|
||||
assert_true(parserNonNull != NULL);
|
||||
|
||||
for (size_t i = 0; i < sizeof(parsers) / sizeof(parsers[0]); i++) {
|
||||
XML_Parser parser = parsers[i];
|
||||
const enum XML_Prop_Error validKeyExpectedError
|
||||
= (parser == NULL) ? XML_PROP_ERROR_PARSER_NULL : XML_PROP_ERROR_NONE;
|
||||
// NOTE: Currently the parser is checked for being `NULL` before the key is
|
||||
// being checked for being valid.
|
||||
// That precedence among errors is not considered part of the API
|
||||
// contract: either error would be fine to return.
|
||||
const enum XML_Prop_Error invalidKeyExpectedError
|
||||
= (parser == NULL) ? XML_PROP_ERROR_PARSER_NULL
|
||||
: XML_PROP_ERROR_INVALID_KEY;
|
||||
|
||||
XML_Bool dummyBool = XML_FALSE;
|
||||
double dummyDouble = 123.456;
|
||||
uint64_t dummyUInt64 = 123;
|
||||
|
||||
#if XML_GE == 1
|
||||
assert_true(
|
||||
XML_GetPropertyUInt64(
|
||||
parser, XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD, &dummyUInt64)
|
||||
== validKeyExpectedError);
|
||||
assert_true(
|
||||
XML_GetPropertyDouble(
|
||||
parser, XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, &dummyDouble)
|
||||
== validKeyExpectedError);
|
||||
assert_true(
|
||||
XML_GetPropertyUInt64(
|
||||
parser, XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD, &dummyUInt64)
|
||||
== validKeyExpectedError);
|
||||
assert_true(
|
||||
XML_GetPropertyDouble(
|
||||
parser, XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, &dummyDouble)
|
||||
== validKeyExpectedError);
|
||||
#endif
|
||||
assert_true(XML_GetPropertyBool(parser, XML_PROP_REPARSE_DEFERRAL_ENABLED,
|
||||
&dummyBool)
|
||||
== validKeyExpectedError);
|
||||
|
||||
assert_true(XML_GetPropertyBool(parser, XML_PROP_INVALID, &dummyBool)
|
||||
== invalidKeyExpectedError);
|
||||
assert_true(XML_GetPropertyDouble(parser, XML_PROP_INVALID, &dummyDouble)
|
||||
== invalidKeyExpectedError);
|
||||
assert_true(XML_GetPropertyUInt64(parser, XML_PROP_INVALID, &dummyUInt64)
|
||||
== invalidKeyExpectedError);
|
||||
}
|
||||
|
||||
XML_ParserFree(parserNonNull);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_getter_error_invalid_key) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
XML_Bool dummyBool = XML_FALSE;
|
||||
double dummyDouble = 123.456;
|
||||
uint64_t dummyUInt64 = 123;
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
assert_true(XML_GetPropertyBool(parser, XML_PROP_INVALID, &dummyBool)
|
||||
== XML_PROP_ERROR_INVALID_KEY);
|
||||
assert_true(XML_GetPropertyDouble(parser, XML_PROP_INVALID, &dummyDouble)
|
||||
== XML_PROP_ERROR_INVALID_KEY);
|
||||
assert_true(XML_GetPropertyUInt64(parser, XML_PROP_INVALID, &dummyUInt64)
|
||||
== XML_PROP_ERROR_INVALID_KEY);
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_getter_error_invalid_type) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
struct TestCase {
|
||||
enum XML_Parser_Property key;
|
||||
enum ExpectedType expectedType;
|
||||
};
|
||||
|
||||
struct TestCase cases[] = {
|
||||
#if XML_GE == 1
|
||||
{XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
{XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
#endif
|
||||
{XML_PROP_REPARSE_DEFERRAL_ENABLED, TYPE_BOOL},
|
||||
};
|
||||
|
||||
XML_Bool dummyBool = XML_FALSE;
|
||||
double dummyDouble = 123.456;
|
||||
uint64_t dummyUInt64 = 123;
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
struct TestCase *const testCase = cases + i;
|
||||
set_subtest("property %d", (int)testCase->key);
|
||||
|
||||
const enum XML_Prop_Error expectedBoolError
|
||||
= (testCase->expectedType == TYPE_BOOL) ? XML_PROP_ERROR_NONE
|
||||
: XML_PROP_ERROR_INVALID_TYPE;
|
||||
const enum XML_Prop_Error expectedDoubleError
|
||||
= (testCase->expectedType == TYPE_DOUBLE) ? XML_PROP_ERROR_NONE
|
||||
: XML_PROP_ERROR_INVALID_TYPE;
|
||||
const enum XML_Prop_Error expectedUInt64Error
|
||||
= (testCase->expectedType == TYPE_UINT64) ? XML_PROP_ERROR_NONE
|
||||
: XML_PROP_ERROR_INVALID_TYPE;
|
||||
|
||||
assert_true(XML_GetPropertyBool(parser, testCase->key, &dummyBool)
|
||||
== expectedBoolError);
|
||||
assert_true(XML_GetPropertyDouble(parser, testCase->key, &dummyDouble)
|
||||
== expectedDoubleError);
|
||||
assert_true(XML_GetPropertyUInt64(parser, testCase->key, &dummyUInt64)
|
||||
== expectedUInt64Error);
|
||||
}
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_getter_error_invalid_value) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
enum XML_Parser_Property keys[] = {
|
||||
#if XML_GE == 1
|
||||
XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD,
|
||||
XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION,
|
||||
XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD,
|
||||
XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION,
|
||||
#endif
|
||||
XML_PROP_REPARSE_DEFERRAL_ENABLED,
|
||||
};
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
for (size_t i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
|
||||
const enum XML_Parser_Property key = keys[i];
|
||||
set_subtest("property %d", (int)key);
|
||||
|
||||
// NOTE: Currently the value output pointer is checked for being `NULL`
|
||||
// before the key is being checked for being valid.
|
||||
// That precedence among errors is not considered part of the API
|
||||
// contract: either error would be fine to return.
|
||||
assert_true(XML_GetPropertyBool(parser, key, NULL)
|
||||
== XML_PROP_ERROR_INVALID_VALUE);
|
||||
assert_true(XML_GetPropertyDouble(parser, key, NULL)
|
||||
== XML_PROP_ERROR_INVALID_VALUE);
|
||||
assert_true(XML_GetPropertyUInt64(parser, key, NULL)
|
||||
== XML_PROP_ERROR_INVALID_VALUE);
|
||||
}
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_setter_effective) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
struct TestCase {
|
||||
enum XML_Parser_Property key;
|
||||
enum ExpectedType expectedType;
|
||||
};
|
||||
|
||||
struct TestCase cases[] = {
|
||||
#if XML_GE == 1
|
||||
{XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
{XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
#endif
|
||||
{XML_PROP_REPARSE_DEFERRAL_ENABLED, TYPE_BOOL},
|
||||
};
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
struct TestCase *const testCase = cases + i;
|
||||
set_subtest("property %d", (int)testCase->key);
|
||||
|
||||
switch (testCase->expectedType) {
|
||||
case TYPE_BOOL: {
|
||||
// Get original value
|
||||
XML_Bool valueOne = ! g_reparseDeferralEnabledDefault;
|
||||
assert_true(XML_GetPropertyBool(parser, testCase->key, &valueOne)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
const XML_Bool valueTwo = ((valueOne == XML_TRUE) ? XML_FALSE : XML_TRUE);
|
||||
assert_true(valueTwo != valueOne); // self-test
|
||||
|
||||
// Test: Set with reported success
|
||||
assert_true(XML_SetPropertyBool(parser, testCase->key, valueTwo)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
XML_Bool valueThree = valueOne;
|
||||
assert_true(valueThree != valueTwo); // self-test
|
||||
|
||||
// Test: Whether the new value has become effective
|
||||
assert_true(XML_GetPropertyBool(parser, testCase->key, &valueThree)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true(valueThree == valueTwo);
|
||||
break;
|
||||
}
|
||||
case TYPE_DOUBLE: {
|
||||
// Get original value
|
||||
double valueOne = 1.23;
|
||||
assert_true(XML_GetPropertyDouble(parser, testCase->key, &valueOne)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
const double valueTwo = 4.56;
|
||||
assert_true(valueTwo != valueOne); // self-test
|
||||
|
||||
// Test: Set with reported success
|
||||
assert_true(XML_SetPropertyDouble(parser, testCase->key, valueTwo)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
double valueThree = 7.89;
|
||||
assert_true(valueThree != valueTwo); // self-test
|
||||
|
||||
// Test: Whether the new value has become effective
|
||||
assert_true(XML_GetPropertyDouble(parser, testCase->key, &valueThree)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true((float)valueThree == (float)valueTwo);
|
||||
break;
|
||||
}
|
||||
case TYPE_UINT64: {
|
||||
// Get original value
|
||||
uint64_t valueOne = 123;
|
||||
assert_true(XML_GetPropertyUInt64(parser, testCase->key, &valueOne)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
const uint64_t valueTwo = 456;
|
||||
assert_true(valueTwo != valueOne); // self-test
|
||||
|
||||
// Test: Set with reported success
|
||||
assert_true(XML_SetPropertyUInt64(parser, testCase->key, valueTwo)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
uint64_t valueThree = 789;
|
||||
assert_true(valueThree != valueTwo); // self-test
|
||||
|
||||
// Test: Whether the new value has become effective
|
||||
assert_true(XML_GetPropertyUInt64(parser, testCase->key, &valueThree)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true(valueThree == valueTwo);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fail("unsupported type");
|
||||
}
|
||||
}
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_setter_error_parser_null) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
struct TestCase {
|
||||
enum XML_Parser_Property key;
|
||||
enum ExpectedType expectedType;
|
||||
};
|
||||
|
||||
struct TestCase cases[] = {
|
||||
#if XML_GE == 1
|
||||
{XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
{XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
#endif
|
||||
{XML_PROP_REPARSE_DEFERRAL_ENABLED, TYPE_BOOL},
|
||||
};
|
||||
|
||||
XML_Parser parserNonNull = XML_ParserCreate(NULL);
|
||||
XML_Parser parsers[] = {parserNonNull, NULL};
|
||||
assert_true(parserNonNull != NULL);
|
||||
|
||||
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
struct TestCase *const testCase = cases + i;
|
||||
for (size_t j = 0; j < sizeof(parsers) / sizeof(parsers[0]); j++) {
|
||||
XML_Parser parser = parsers[j];
|
||||
set_subtest("property %d, parser %s", (int)testCase->key,
|
||||
(parser == NULL) ? "NULL" : "non-NULL");
|
||||
|
||||
const enum XML_Prop_Error expected
|
||||
= ((parser == NULL) ? XML_PROP_ERROR_PARSER_NULL
|
||||
: XML_PROP_ERROR_NONE);
|
||||
|
||||
enum XML_Prop_Error actual
|
||||
= XML_PROP_ERROR_INVALID_TYPE; // i.e. some value unequal to
|
||||
// `expected`
|
||||
// above
|
||||
assert_true(actual != expected); // self-test
|
||||
|
||||
switch (testCase->expectedType) {
|
||||
case TYPE_BOOL:
|
||||
actual = XML_SetPropertyBool(parser, testCase->key,
|
||||
! g_reparseDeferralEnabledDefault);
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
actual = XML_SetPropertyDouble(parser, testCase->key, 456.789);
|
||||
break;
|
||||
case TYPE_UINT64:
|
||||
actual = XML_SetPropertyUInt64(parser, testCase->key, 456);
|
||||
break;
|
||||
default:
|
||||
fail("unsupported type");
|
||||
}
|
||||
assert_true(actual == expected);
|
||||
}
|
||||
}
|
||||
|
||||
XML_ParserFree(parserNonNull);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_setter_error_parser_not_root) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
struct TestCase {
|
||||
enum XML_Parser_Property key;
|
||||
enum ExpectedType expectedType;
|
||||
bool needsRootParser;
|
||||
};
|
||||
|
||||
struct TestCase cases[] = {
|
||||
#if XML_GE == 1
|
||||
{XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD, TYPE_UINT64, true},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE, true},
|
||||
{XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD, TYPE_UINT64, true},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE, true},
|
||||
#endif
|
||||
{XML_PROP_REPARSE_DEFERRAL_ENABLED, TYPE_BOOL, false},
|
||||
};
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
XML_Parser subParser = XML_ExternalEntityParserCreate(parser, NULL, NULL);
|
||||
#if defined(XML_DTD)
|
||||
assert_true(subParser != NULL);
|
||||
|
||||
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
struct TestCase *const testCase = cases + i;
|
||||
set_subtest("property %d", (int)testCase->key);
|
||||
|
||||
const enum XML_Prop_Error expected
|
||||
= (testCase->needsRootParser ? XML_PROP_ERROR_PARSER_NOT_ROOT
|
||||
: XML_PROP_ERROR_NONE);
|
||||
|
||||
enum XML_Prop_Error actual
|
||||
= XML_PROP_ERROR_INVALID_TYPE; // i.e. some value unequal to `expected`
|
||||
// above
|
||||
assert_true(actual != expected); // self-test
|
||||
|
||||
switch (testCase->expectedType) {
|
||||
case TYPE_BOOL:
|
||||
actual = XML_SetPropertyBool(subParser, testCase->key,
|
||||
! g_reparseDeferralEnabledDefault);
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
actual = XML_SetPropertyDouble(subParser, testCase->key, 456.789);
|
||||
break;
|
||||
case TYPE_UINT64:
|
||||
actual = XML_SetPropertyUInt64(subParser, testCase->key, 456);
|
||||
break;
|
||||
default:
|
||||
fail("unsupported type");
|
||||
}
|
||||
|
||||
assert_true(actual == expected);
|
||||
}
|
||||
|
||||
XML_ParserFree(subParser);
|
||||
#else // ! defined(XML_DTD)
|
||||
assert_true(subParser == NULL);
|
||||
UNUSED_P(cases);
|
||||
#endif
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_setter_error_parser_started) {
|
||||
// The test is not doing any (real) parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
struct TestCase {
|
||||
enum XML_Parser_Property key;
|
||||
enum ExpectedType expectedType;
|
||||
};
|
||||
|
||||
struct TestCase cases[] = {
|
||||
#if XML_GE == 1
|
||||
{XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
{XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
#endif
|
||||
{XML_PROP_REPARSE_DEFERRAL_ENABLED, TYPE_BOOL},
|
||||
};
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
// Get the parser into state "parsing started"
|
||||
XML_ParsingStatus parsingStatus;
|
||||
XML_GetParsingStatus(parser, &parsingStatus);
|
||||
assert_true(parsingStatus.parsing == XML_INITIALIZED); // Self-test
|
||||
assert_true(_XML_Parse_SINGLE_BYTES(parser, "", 0, /*isFInal=*/XML_FALSE)
|
||||
== XML_STATUS_OK);
|
||||
XML_GetParsingStatus(parser, &parsingStatus);
|
||||
assert_true(parsingStatus.parsing == XML_PARSING);
|
||||
|
||||
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
struct TestCase *const testCase = cases + i;
|
||||
set_subtest("property %d", (int)testCase->key);
|
||||
|
||||
switch (testCase->expectedType) {
|
||||
case TYPE_BOOL: {
|
||||
// Get original value
|
||||
XML_Bool valueOne = ! g_reparseDeferralEnabledDefault;
|
||||
assert_true(XML_GetPropertyBool(parser, testCase->key, &valueOne)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
const XML_Bool valueTwo = ((valueOne == XML_TRUE) ? XML_FALSE : XML_TRUE);
|
||||
assert_true(valueTwo != valueOne); // self-test
|
||||
|
||||
// Test: Set with reported success
|
||||
assert_true(XML_SetPropertyBool(parser, testCase->key, valueTwo)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
XML_Bool valueThree = valueOne;
|
||||
assert_true(valueThree != valueTwo); // self-test
|
||||
|
||||
// Test: Whether the new value has become effective
|
||||
assert_true(XML_GetPropertyBool(parser, testCase->key, &valueThree)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true(valueThree == valueTwo); // i.e. new value applied
|
||||
break;
|
||||
}
|
||||
case TYPE_DOUBLE: {
|
||||
// Get original value
|
||||
double valueOne = 1.23;
|
||||
assert_true(XML_GetPropertyDouble(parser, testCase->key, &valueOne)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
const double valueTwo = 4.56;
|
||||
assert_true(valueTwo != valueOne); // self-test
|
||||
|
||||
// Test: Set with reported success
|
||||
assert_true(XML_SetPropertyDouble(parser, testCase->key, valueTwo)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
double valueThree = 7.89;
|
||||
assert_true(valueThree != valueTwo); // self-test
|
||||
|
||||
// Test: Whether the new value has become effective
|
||||
assert_true(XML_GetPropertyDouble(parser, testCase->key, &valueThree)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true((float)valueThree
|
||||
== (float)valueTwo); // i.e. new value applied
|
||||
break;
|
||||
}
|
||||
case TYPE_UINT64: {
|
||||
// Get original value
|
||||
uint64_t valueOne = 123;
|
||||
assert_true(XML_GetPropertyUInt64(parser, testCase->key, &valueOne)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
const uint64_t valueTwo = 456;
|
||||
assert_true(valueTwo != valueOne); // self-test
|
||||
|
||||
// Test: Set with reported success
|
||||
assert_true(XML_SetPropertyUInt64(parser, testCase->key, valueTwo)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
uint64_t valueThree = 789;
|
||||
assert_true(valueThree != valueTwo); // self-test
|
||||
|
||||
// Test: Whether the new value has become effective
|
||||
assert_true(XML_GetPropertyUInt64(parser, testCase->key, &valueThree)
|
||||
== XML_PROP_ERROR_NONE);
|
||||
assert_true(valueThree == valueTwo); // i.e. new value applied
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fail("unsupported type");
|
||||
}
|
||||
}
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_setter_error_invalid_key) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
assert_true(XML_SetPropertyBool(parser, XML_PROP_INVALID,
|
||||
! g_reparseDeferralEnabledDefault)
|
||||
== XML_PROP_ERROR_INVALID_KEY);
|
||||
assert_true(XML_SetPropertyDouble(parser, XML_PROP_INVALID, 123.456)
|
||||
== XML_PROP_ERROR_INVALID_KEY);
|
||||
assert_true(XML_SetPropertyUInt64(parser, XML_PROP_INVALID, 123)
|
||||
== XML_PROP_ERROR_INVALID_KEY);
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_setter_error_invalid_type) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
struct TestCase {
|
||||
enum XML_Parser_Property key;
|
||||
enum ExpectedType expectedType;
|
||||
};
|
||||
|
||||
struct TestCase cases[] = {
|
||||
#if XML_GE == 1
|
||||
{XML_PROP_ALLOC_TRACKER_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
{XML_PROP_BILLION_LAUGHS_ACTIVATION_THRESHOLD, TYPE_UINT64},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, TYPE_DOUBLE},
|
||||
#endif
|
||||
{XML_PROP_REPARSE_DEFERRAL_ENABLED, TYPE_BOOL},
|
||||
};
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
struct TestCase *const testCase = cases + i;
|
||||
set_subtest("property %d", (int)testCase->key);
|
||||
|
||||
const enum XML_Prop_Error expectedErrorBool
|
||||
= ((testCase->expectedType == TYPE_BOOL) ? XML_PROP_ERROR_NONE
|
||||
: XML_PROP_ERROR_INVALID_TYPE);
|
||||
const enum XML_Prop_Error expectedErrorDouble
|
||||
= ((testCase->expectedType == TYPE_DOUBLE)
|
||||
? XML_PROP_ERROR_NONE
|
||||
: XML_PROP_ERROR_INVALID_TYPE);
|
||||
const enum XML_Prop_Error expectedErrorUInt64
|
||||
= ((testCase->expectedType == TYPE_UINT64)
|
||||
? XML_PROP_ERROR_NONE
|
||||
: XML_PROP_ERROR_INVALID_TYPE);
|
||||
|
||||
assert_true(XML_SetPropertyBool(parser, testCase->key,
|
||||
! g_reparseDeferralEnabledDefault)
|
||||
== expectedErrorBool);
|
||||
assert_true(XML_SetPropertyDouble(parser, testCase->key, 456.789)
|
||||
== expectedErrorDouble);
|
||||
assert_true(XML_SetPropertyUInt64(parser, testCase->key, 456)
|
||||
== expectedErrorUInt64);
|
||||
}
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_props_setter_error_invalid_value) {
|
||||
// The test is not doing any parsing, so a single run
|
||||
// (with `g_chunkSize == 0`) is enough
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
XML_Parser parser = XML_ParserCreate(NULL);
|
||||
assert_true(parser != NULL);
|
||||
|
||||
#if XML_GE == 1
|
||||
struct TestCase {
|
||||
enum XML_Parser_Property key;
|
||||
// NOTE: Neither `uint64_t`- nor `XML_Bool`-based properties have any
|
||||
// invalid in-dimension values, so we are only testing `double`-based
|
||||
// property values here.
|
||||
double value;
|
||||
bool valueValid;
|
||||
};
|
||||
|
||||
struct TestCase cases[] = {
|
||||
// XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, -HUGE_VAL, false},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, -1.0, false},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, -0.9, false},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, 0.0, false},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, 0.9, false},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, 1.0, true},
|
||||
{XML_PROP_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION, HUGE_VAL, true},
|
||||
// XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, -HUGE_VAL, false},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, -1.0, false},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, -0.9, false},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, 0.0, false},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, 0.9, false},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, 1.0, true},
|
||||
{XML_PROP_BILLION_LAUGHS_MAXIMUM_AMPLIFICATION, HUGE_VAL, true},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
struct TestCase *const testCase = cases + i;
|
||||
const enum XML_Prop_Error expected
|
||||
= (testCase->valueValid ? XML_PROP_ERROR_NONE
|
||||
: XML_PROP_ERROR_INVALID_VALUE);
|
||||
assert_true(XML_SetPropertyDouble(parser, testCase->key, testCase->value)
|
||||
== expected);
|
||||
}
|
||||
#endif
|
||||
|
||||
XML_ParserFree(parser);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
make_props_test_case(Suite *s) {
|
||||
TCase *const tc_props = tcase_create("properties tests");
|
||||
suite_add_tcase(s, tc_props);
|
||||
|
||||
tcase_add_test(tc_props, test_props_getter_defaults);
|
||||
tcase_add_test(tc_props, test_props_getter_error_parser_null);
|
||||
tcase_add_test(tc_props, test_props_getter_error_invalid_key);
|
||||
tcase_add_test(tc_props, test_props_getter_error_invalid_type);
|
||||
tcase_add_test(tc_props, test_props_getter_error_invalid_value);
|
||||
|
||||
tcase_add_test(tc_props, test_props_setter_effective);
|
||||
tcase_add_test(tc_props, test_props_setter_error_parser_null);
|
||||
tcase_add_test(tc_props, test_props_setter_error_parser_not_root);
|
||||
tcase_add_test(tc_props, test_props_setter_error_parser_started);
|
||||
tcase_add_test(tc_props, test_props_setter_error_invalid_key);
|
||||
tcase_add_test(tc_props, test_props_setter_error_invalid_type);
|
||||
tcase_add_test(tc_props, test_props_setter_error_invalid_value);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Tests related to the public properties API of Expat
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef XML_PROPS_TESTS_H
|
||||
#define XML_PROPS_TESTS_H
|
||||
|
||||
#include "minicheck.h"
|
||||
|
||||
extern void make_props_test_case(Suite *s);
|
||||
|
||||
#endif /* XML_PROPS_TESTS_H */
|
||||
@@ -54,13 +54,15 @@
|
||||
#include "minicheck.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "acc_tests.h"
|
||||
#include "alloc_tests.h"
|
||||
#include "basic_tests.h"
|
||||
#include "hash_tests.h"
|
||||
#include "ns_tests.h"
|
||||
#include "misc_tests.h"
|
||||
#include "alloc_tests.h"
|
||||
#include "ns_tests.h"
|
||||
#include "nsalloc_tests.h"
|
||||
#include "acc_tests.h"
|
||||
#include "props_tests.h"
|
||||
#include "xcs_tests.h"
|
||||
|
||||
XML_Parser g_parser = NULL;
|
||||
|
||||
@@ -68,15 +70,17 @@ static Suite *
|
||||
make_suite(void) {
|
||||
Suite *s = suite_create("basic");
|
||||
|
||||
make_basic_test_case(s);
|
||||
make_hash_test_case(s);
|
||||
make_namespace_test_case(s);
|
||||
make_miscellaneous_test_case(s);
|
||||
make_alloc_test_case(s);
|
||||
make_nsalloc_test_case(s);
|
||||
#if XML_GE == 1
|
||||
make_accounting_test_case(s);
|
||||
#endif
|
||||
make_alloc_test_case(s);
|
||||
make_basic_test_case(s);
|
||||
make_hash_test_case(s);
|
||||
make_miscellaneous_test_case(s);
|
||||
make_namespace_test_case(s);
|
||||
make_nsalloc_test_case(s);
|
||||
make_props_test_case(s);
|
||||
make_xcs_test_case(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||
Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2017-2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
|
||||
Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com>
|
||||
Licensed under the MIT license:
|
||||
@@ -47,23 +47,20 @@
|
||||
|
||||
#include "structdata.h"
|
||||
#include "minicheck.h"
|
||||
#include "../lib/xcs.h"
|
||||
|
||||
#define STRUCT_EXTENSION_COUNT 8
|
||||
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
# include <wchar.h>
|
||||
# define XML_FMT_STR "ls"
|
||||
# define xcstrlen(s) wcslen(s)
|
||||
# define xcstrcmp(s, t) wcscmp((s), (t))
|
||||
#else
|
||||
# define XML_FMT_STR "s"
|
||||
# define xcstrlen(s) strlen(s)
|
||||
# define xcstrcmp(s, t) strcmp((s), (t))
|
||||
#endif
|
||||
|
||||
static XML_Char *
|
||||
xmlstrdup(const XML_Char *s) {
|
||||
size_t byte_count = (xcstrlen(s) + 1) * sizeof(XML_Char);
|
||||
size_t byte_count = (xcslen(s) + 1) * sizeof(XML_Char);
|
||||
XML_Char *const dup = malloc(byte_count);
|
||||
|
||||
assert(dup != NULL);
|
||||
@@ -128,7 +125,7 @@ StructData_CheckItems(StructData *storage, const StructDataEntry *expected,
|
||||
assert(got != NULL);
|
||||
assert(want != NULL);
|
||||
|
||||
if (xcstrcmp(got->str, want->str) != 0) {
|
||||
if (xcscmp(got->str, want->str) != 0) {
|
||||
StructData_Dispose(storage);
|
||||
fail("structure got bad string");
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/* Tests related to the XCS (XML character string) functionality
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "xcs_tests.h"
|
||||
|
||||
#include "ascii.h"
|
||||
#include "common.h" // for g_chunkSize
|
||||
#include "xcs.h" // for xcslen, xcscmp, xcsncmp
|
||||
|
||||
static const XML_Char empty[] = {'\0'};
|
||||
static const XML_Char test[] = {ASCII_T, ASCII_E, ASCII_S, ASCII_T, '\0'};
|
||||
static const XML_Char testing[]
|
||||
= {ASCII_T, ASCII_E, ASCII_S, ASCII_T, ASCII_I, ASCII_N, ASCII_G, '\0'};
|
||||
|
||||
START_TEST(test_xcs_len) {
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
assert_true(xcslen(empty) == 0);
|
||||
assert_true(xcslen(test) == 4);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_xcs_cmp) {
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
assert_true(xcscmp(test, test) == 0);
|
||||
assert_true(xcscmp(test, testing) < 0);
|
||||
assert_true(xcscmp(testing, test) > 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_xcs_ncmp) {
|
||||
if (g_chunkSize != 0)
|
||||
return;
|
||||
|
||||
assert_true(xcsncmp(test, test, 0) == 0);
|
||||
assert_true(xcsncmp(test, test, 4) == 0);
|
||||
|
||||
assert_true(xcsncmp(test, testing, 4) == 0);
|
||||
assert_true(xcsncmp(testing, test, 4) == 0);
|
||||
|
||||
assert_true(xcsncmp(test, testing, 5) < 0);
|
||||
assert_true(xcsncmp(testing, test, 5) > 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
make_xcs_test_case(Suite *s) {
|
||||
TCase *const tc_xcs = tcase_create("xcs tests");
|
||||
suite_add_tcase(s, tc_xcs);
|
||||
tcase_add_test(tc_xcs, test_xcs_len);
|
||||
tcase_add_test(tc_xcs, test_xcs_cmp);
|
||||
tcase_add_test(tc_xcs, test_xcs_ncmp);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Tests related to the XCS (XML character string) functionality
|
||||
__ __ _
|
||||
___\ \/ /_ __ __ _| |_
|
||||
/ _ \\ /| '_ \ / _` | __|
|
||||
| __// \| |_) | (_| | |_
|
||||
\___/_/\_\ .__/ \__,_|\__|
|
||||
|_| XML parser
|
||||
|
||||
Copyright (c) 2026 Sebastian Pipping <sebastian@pipping.org>
|
||||
Licensed under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef XML_XCS_TESTS_H
|
||||
#define XML_XCS_TESTS_H
|
||||
|
||||
#include "minicheck.h"
|
||||
|
||||
extern void make_xcs_test_case(Suite *s);
|
||||
|
||||
#endif /* XML_XCS_TESTS_H */
|
||||
@@ -6,7 +6,7 @@
|
||||
# \___/_/\_\ .__/ \__,_|\__|
|
||||
# |_| XML parser
|
||||
#
|
||||
# Copyright (c) 2017-2021 Sebastian Pipping <[email protected]>
|
||||
# Copyright (c) 2017-2026 Sebastian Pipping <[email protected]>
|
||||
# Licensed under the MIT license:
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
@@ -32,6 +32,7 @@ bin_PROGRAMS = xmlwf
|
||||
|
||||
xmlwf_LDADD = ../lib/libexpat.la
|
||||
xmlwf_SOURCES = \
|
||||
../lib/xcs.c \
|
||||
xmlwf.c \
|
||||
xmlfile.c \
|
||||
codepage.c \
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
# \___/_/\_\ .__/ \__,_|\__|
|
||||
# |_| XML parser
|
||||
#
|
||||
# Copyright (c) 2017-2021 Sebastian Pipping <[email protected]>
|
||||
# Copyright (c) 2017-2026 Sebastian Pipping <[email protected]>
|
||||
# Licensed under the MIT license:
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
@@ -148,8 +148,10 @@ CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
am_xmlwf_OBJECTS = xmlwf-xmlwf.$(OBJEXT) xmlwf-xmlfile.$(OBJEXT) \
|
||||
xmlwf-codepage.$(OBJEXT) xmlwf-@FILEMAP@.$(OBJEXT)
|
||||
am__dirstamp = $(am__leading_dot)dirstamp
|
||||
am_xmlwf_OBJECTS = ../lib/xmlwf-xcs.$(OBJEXT) xmlwf-xmlwf.$(OBJEXT) \
|
||||
xmlwf-xmlfile.$(OBJEXT) xmlwf-codepage.$(OBJEXT) \
|
||||
xmlwf-@FILEMAP@.$(OBJEXT)
|
||||
xmlwf_OBJECTS = $(am_xmlwf_OBJECTS)
|
||||
xmlwf_DEPENDENCIES = ../lib/libexpat.la
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
@@ -174,9 +176,9 @@ am__v_at_1 =
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/conftools/depcomp
|
||||
am__maybe_remake_depfiles = depfiles
|
||||
am__depfiles_remade = ./$(DEPDIR)/xmlwf-@FILEMAP@.Po \
|
||||
./$(DEPDIR)/xmlwf-codepage.Po ./$(DEPDIR)/xmlwf-xmlfile.Po \
|
||||
./$(DEPDIR)/xmlwf-xmlwf.Po
|
||||
am__depfiles_remade = ../lib/$(DEPDIR)/xmlwf-xcs.Po \
|
||||
./$(DEPDIR)/xmlwf-@FILEMAP@.Po ./$(DEPDIR)/xmlwf-codepage.Po \
|
||||
./$(DEPDIR)/xmlwf-xmlfile.Po ./$(DEPDIR)/xmlwf-xmlwf.Po
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
@@ -260,12 +262,10 @@ ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXPAT_ATTR_INFO = @EXPAT_ATTR_INFO@
|
||||
EXPAT_CHAR_TYPE = @EXPAT_CHAR_TYPE@
|
||||
EXPAT_CONTEXT_BYTES = @EXPAT_CONTEXT_BYTES@
|
||||
EXPAT_DTD = @EXPAT_DTD@
|
||||
EXPAT_LARGE_SIZE = @EXPAT_LARGE_SIZE@
|
||||
EXPAT_MIN_SIZE = @EXPAT_MIN_SIZE@
|
||||
EXPAT_NS = @EXPAT_NS@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
@@ -320,7 +320,6 @@ SO_PATCH = @SO_PATCH@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
VSCRIPT_LDFLAGS = @VSCRIPT_LDFLAGS@
|
||||
_EXPAT_COMMENT_ATTR_INFO = @_EXPAT_COMMENT_ATTR_INFO@
|
||||
_EXPAT_COMMENT_DTD_OR_GE = @_EXPAT_COMMENT_DTD_OR_GE@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
@@ -381,6 +380,7 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
xmlwf_LDADD = ../lib/libexpat.la
|
||||
xmlwf_SOURCES = \
|
||||
../lib/xcs.c \
|
||||
xmlwf.c \
|
||||
xmlfile.c \
|
||||
codepage.c \
|
||||
@@ -477,6 +477,14 @@ uninstall-binPROGRAMS:
|
||||
clean-binPROGRAMS:
|
||||
$(am__rm_f) $(bin_PROGRAMS)
|
||||
test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=)
|
||||
../lib/$(am__dirstamp):
|
||||
@$(MKDIR_P) ../lib
|
||||
@: >>../lib/$(am__dirstamp)
|
||||
../lib/$(DEPDIR)/$(am__dirstamp):
|
||||
@$(MKDIR_P) ../lib/$(DEPDIR)
|
||||
@: >>../lib/$(DEPDIR)/$(am__dirstamp)
|
||||
../lib/xmlwf-xcs.$(OBJEXT): ../lib/$(am__dirstamp) \
|
||||
../lib/$(DEPDIR)/$(am__dirstamp)
|
||||
|
||||
xmlwf$(EXEEXT): $(xmlwf_OBJECTS) $(xmlwf_DEPENDENCIES) $(EXTRA_xmlwf_DEPENDENCIES)
|
||||
@rm -f xmlwf$(EXEEXT)
|
||||
@@ -484,10 +492,12 @@ xmlwf$(EXEEXT): $(xmlwf_OBJECTS) $(xmlwf_DEPENDENCIES) $(EXTRA_xmlwf_DEPENDENCIE
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
-rm -f ../lib/*.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/xmlwf-xcs.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlwf-@FILEMAP@.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlwf-codepage.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmlwf-xmlfile.Po@am__quote@ # am--include-marker
|
||||
@@ -523,6 +533,20 @@ am--depfiles: $(am__depfiles_remade)
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
../lib/xmlwf-xcs.o: ../lib/xcs.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xmlwf_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ../lib/xmlwf-xcs.o -MD -MP -MF ../lib/$(DEPDIR)/xmlwf-xcs.Tpo -c -o ../lib/xmlwf-xcs.o `test -f '../lib/xcs.c' || echo '$(srcdir)/'`../lib/xcs.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/xmlwf-xcs.Tpo ../lib/$(DEPDIR)/xmlwf-xcs.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/xcs.c' object='../lib/xmlwf-xcs.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xmlwf_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ../lib/xmlwf-xcs.o `test -f '../lib/xcs.c' || echo '$(srcdir)/'`../lib/xcs.c
|
||||
|
||||
../lib/xmlwf-xcs.obj: ../lib/xcs.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xmlwf_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ../lib/xmlwf-xcs.obj -MD -MP -MF ../lib/$(DEPDIR)/xmlwf-xcs.Tpo -c -o ../lib/xmlwf-xcs.obj `if test -f '../lib/xcs.c'; then $(CYGPATH_W) '../lib/xcs.c'; else $(CYGPATH_W) '$(srcdir)/../lib/xcs.c'; fi`
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/xmlwf-xcs.Tpo ../lib/$(DEPDIR)/xmlwf-xcs.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/xcs.c' object='../lib/xmlwf-xcs.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xmlwf_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ../lib/xmlwf-xcs.obj `if test -f '../lib/xcs.c'; then $(CYGPATH_W) '../lib/xcs.c'; else $(CYGPATH_W) '$(srcdir)/../lib/xcs.c'; fi`
|
||||
|
||||
xmlwf-xmlwf.o: xmlwf.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xmlwf_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xmlwf-xmlwf.o -MD -MP -MF $(DEPDIR)/xmlwf-xmlwf.Tpo -c -o xmlwf-xmlwf.o `test -f 'xmlwf.c' || echo '$(srcdir)/'`xmlwf.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xmlwf-xmlwf.Tpo $(DEPDIR)/xmlwf-xmlwf.Po
|
||||
@@ -704,6 +728,8 @@ clean-generic:
|
||||
distclean-generic:
|
||||
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
|
||||
-$(am__rm_f) ../lib/$(DEPDIR)/$(am__dirstamp)
|
||||
-$(am__rm_f) ../lib/$(am__dirstamp)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@@ -713,6 +739,7 @@ clean: clean-am
|
||||
clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f ../lib/$(DEPDIR)/xmlwf-xcs.Po
|
||||
-rm -f ./$(DEPDIR)/xmlwf-@[email protected]
|
||||
-rm -f ./$(DEPDIR)/xmlwf-codepage.Po
|
||||
-rm -f ./$(DEPDIR)/xmlwf-xmlfile.Po
|
||||
@@ -762,6 +789,7 @@ install-ps-am:
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f ../lib/$(DEPDIR)/xmlwf-xcs.Po
|
||||
-rm -f ./$(DEPDIR)/xmlwf-@[email protected]
|
||||
-rm -f ./$(DEPDIR)/xmlwf-codepage.Po
|
||||
-rm -f ./$(DEPDIR)/xmlwf-xmlfile.Po
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
|
||||
#include "expat_config.h"
|
||||
|
||||
#include <inttypes.h> // PRIu64
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -98,11 +99,9 @@ reportError(XML_Parser parser, const XML_Char *filename) {
|
||||
enum XML_Error code = XML_GetErrorCode(parser);
|
||||
const XML_Char *message = XML_ErrorString(code);
|
||||
if (message)
|
||||
ftprintf(stdout,
|
||||
T("%s") T(":%") T(XML_FMT_INT_MOD) T("u") T(":%")
|
||||
T(XML_FMT_INT_MOD) T("u") T(": %s\n"),
|
||||
filename, XML_GetCurrentLineNumber(parser),
|
||||
XML_GetCurrentColumnNumber(parser), message);
|
||||
ftprintf(stdout, T("%s") T(":%") T(PRIu64) T(":%") T(PRIu64) T(": %s\n"),
|
||||
filename, XML_GetCurrentLineNumber64(parser),
|
||||
XML_GetCurrentColumnNumber64(parser), message);
|
||||
else
|
||||
ftprintf(stderr, T("%s: (unknown message %u)\n"), filename,
|
||||
(unsigned int)code);
|
||||
|
||||
@@ -37,15 +37,11 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "expat.h" // for XML_Parser, XML_Char
|
||||
|
||||
#define XML_MAP_FILE 01
|
||||
#define XML_EXTERNAL_ENTITIES 02
|
||||
|
||||
#ifdef XML_LARGE_SIZE
|
||||
# define XML_FMT_INT_MOD "ll"
|
||||
#else
|
||||
# define XML_FMT_INT_MOD "l"
|
||||
#endif
|
||||
|
||||
extern int g_read_size_bytes;
|
||||
|
||||
extern bool XML_ProcessFile(XML_Parser parser, const XML_Char *filename,
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "expat_config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h> // for PRIu64
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -72,7 +73,7 @@
|
||||
# include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "../lib/xcsinc.c"
|
||||
#include "../lib/xcs.h"
|
||||
|
||||
enum ExitCode {
|
||||
XMLWF_EXIT_SUCCESS = 0,
|
||||
@@ -359,23 +360,6 @@ cleanupUserData(XmlwfUserData *userData) {
|
||||
freeNotations(userData);
|
||||
}
|
||||
|
||||
static int
|
||||
xcscmp(const XML_Char *xs, const XML_Char *xt) {
|
||||
while (*xs != 0 && *xt != 0) {
|
||||
if (*xs < *xt)
|
||||
return -1;
|
||||
if (*xs > *xt)
|
||||
return 1;
|
||||
xs++;
|
||||
xt++;
|
||||
}
|
||||
if (*xs < *xt)
|
||||
return -1;
|
||||
if (*xs > *xt)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
notationCmp(const void *a, const void *b) {
|
||||
const NotationList *const n1 = *(const NotationList *const *)a;
|
||||
@@ -587,12 +571,11 @@ metaLocation(XML_Parser parser) {
|
||||
puttc(T('"'), fp);
|
||||
}
|
||||
ftprintf(fp,
|
||||
T(" byte=\"%") T(XML_FMT_INT_MOD) T("d\"") T(" nbytes=\"%d\"")
|
||||
T(" line=\"%") T(XML_FMT_INT_MOD) T("u\"") T(" col=\"%")
|
||||
T(XML_FMT_INT_MOD) T("u\""),
|
||||
XML_GetCurrentByteIndex(parser), XML_GetCurrentByteCount(parser),
|
||||
XML_GetCurrentLineNumber(parser),
|
||||
XML_GetCurrentColumnNumber(parser));
|
||||
T(" byte=\"%") T(PRId64) T("\"") T(" nbytes=\"%") T(PRIu64) T("\"")
|
||||
T(" line=\"%") T(PRIu64) T("\"") T(" col=\"%") T(PRIu64) T("\""),
|
||||
XML_GetCurrentByteIndex64(parser), XML_GetCurrentByteCount64(parser),
|
||||
XML_GetCurrentLineNumber64(parser),
|
||||
XML_GetCurrentColumnNumber64(parser));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -4,7 +4,7 @@ EXPAT= ${SRCTOP}/contrib/expat
|
||||
LIB= bsdxml
|
||||
SHLIBDIR?= /lib
|
||||
SHLIB_MAJOR= 4
|
||||
SRCS= random_arc4random_buf.c xmlparse.c xmlrole.c xmltok.c
|
||||
SRCS= random_arc4random_buf.c xcs.c xmlparse.c xmlrole.c xmltok.c
|
||||
INCS= bsdxml.h bsdxml_external.h
|
||||
MAN= libbsdxml.3
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
#define PACKAGE_NAME "expat"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "expat 2.8.5"
|
||||
#define PACKAGE_STRING "expat 2.9.0"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "expat"
|
||||
@@ -98,7 +98,7 @@
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "2.8.5"
|
||||
#define PACKAGE_VERSION "2.9.0"
|
||||
|
||||
/* Define to 1 if all of the C89 standard headers exist (not just the ones
|
||||
required in a freestanding environment). This macro is provided for
|
||||
@@ -106,7 +106,7 @@
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "2.8.5"
|
||||
#define VERSION "2.9.0"
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"/
|
||||
.Dd September 22, 2026
|
||||
.Dd October 5, 2026
|
||||
.Dt LIBBSDXML 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -34,7 +34,7 @@
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
library is a verbatim copy of the eXpat XML library version 2.8.5.
|
||||
library is a verbatim copy of the eXpat XML library version 2.9.0.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
|
||||
Reference in new issue
Block a user