sync with OpenBSD -current

This commit is contained in:
purplerain 2024-02-11 23:14:53 +00:00
parent 1216bb5537
commit 3a25e8ae30
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
93 changed files with 17023 additions and 13073 deletions

View File

@ -1,5 +1,5 @@
#!/bin/ksh
# $OpenBSD: install.sub,v 1.1258 2024/01/26 16:35:58 sthen Exp $
# $OpenBSD: install.sub,v 1.1259 2024/02/11 21:56:10 kn Exp $
#
# Copyright (c) 1997-2015 Todd Miller, Theo de Raadt, Ken Westerback
# Copyright (c) 2015, Robert Peichaer <rpe@openbsd.org>
@ -917,7 +917,7 @@ ask_password() {
}
# Ask for a passphrase once showing prompt $1. Ensure input is not empty
# save it in $_passphrase.
# and save it in $_passphrase.
ask_passphrase() {
local _q=$1
@ -3109,9 +3109,6 @@ encrypt_root() {
[[ $MDBOOTSR == y ]] || return
# The interactive bioctl(8) passphrase prompt requires a TTY.
$AI && return
[[ -x /sbin/bioctl ]] || return
# Do not even try if softraid is in use already,
@ -3127,8 +3124,12 @@ encrypt_root() {
_args=-k$KEYDISK
break
;;
# Do nothing, bioctl(8) will handle the passphrase.
[pP]*) break
[pP]*) $AI || break
ask_passphrase 'New passphrase?'
PASSFILE=/tmp/i/passfile
(umask 077 && print -r -- "$_passphrase" >$PASSFILE)
_args=-p$PASSFILE
break
;;
[nN]*) return
;;
@ -3142,6 +3143,7 @@ encrypt_root() {
echo 'RAID *' | disklabel -w -A -T- $_chunk
bioctl -Cforce -cC -l${_chunk}a $_args softraid0 >/dev/null
rm -fP $PASSFILE
# No volumes existed before asking, but we just created one.
ROOTDISK=$(get_softraid_volumes)

View File

@ -726,7 +726,7 @@
./usr/lib/libelf.so.3.0
./usr/lib/libevent.so.4.1
./usr/lib/libexecinfo.so.3.0
./usr/lib/libexpat.so.14.0
./usr/lib/libexpat.so.14.1
./usr/lib/libfido2.so.7.0
./usr/lib/libform.so.7.0
./usr/lib/libformw.so.7.0

View File

@ -1,7 +1,7 @@
# $OpenBSD: ifstated.conf,v 1.2 2018/01/20 23:07:58 mpf Exp $
# $OpenBSD: ifstated.conf,v 1.3 2024/02/11 01:31:28 jsg Exp $
# This is a sample config for a pair of firewalls with three physical interfaces
#
# The two firefall interfaces are made redundant on each side using
# The two firewall interfaces are made redundant on each side using
# carp0 and carp1.
#
# A third interface em2 connects each firewall to the DMZ where it can

View File

@ -2,6 +2,120 @@ NOTE: We are looking for help with a few things:
https://github.com/libexpat/libexpat/labels/help%20wanted
If you can help, please get in touch. Thanks!
Release 2.6.0 Tue February 6 2024
Security fixes:
#789 #814 CVE-2023-52425 -- Fix quadratic runtime issues with big tokens
that can cause denial of service, in partial where
dealing with compressed XML input. Applications
that parsed a document in one go -- a single call to
functions XML_Parse or XML_ParseBuffer -- were not affected.
The smaller the chunks/buffers you use for parsing
previously, the bigger the problem prior to the fix.
Backporters should be careful to no omit parts of
pull request #789 and to include earlier pull request #771,
in order to not break the fix.
#777 CVE-2023-52426 -- Fix billion laughs attacks for users
compiling *without* XML_DTD defined (which is not common).
Users with XML_DTD defined have been protected since
Expat >=2.4.0 (and that was CVE-2013-0340 back then).
Bug fixes:
#753 Fix parse-size-dependent "invalid token" error for
external entities that start with a byte order mark
#780 Fix NULL pointer dereference in setContext via
XML_ExternalEntityParserCreate for compilation with
XML_DTD undefined
#812 #813 Protect against closing entities out of order
Other changes:
#723 Improve support for arc4random/arc4random_buf
#771 #788 Improve buffer growth in XML_GetBuffer and XML_Parse
#761 #770 xmlwf: Support --help and --version
#759 #770 xmlwf: Support custom buffer size for XML_GetBuffer and read
#744 xmlwf: Improve language and URL clickability in help output
#673 examples: Add new example "element_declarations.c"
#764 Be stricter about macro XML_CONTEXT_BYTES at build time
#765 Make inclusion to expat_config.h consistent
#726 #727 Autotools: configure.ac: Support --disable-maintainer-mode
#678 #705 ..
#706 #733 #792 Autotools: Sync CMake templates with CMake 3.26
#795 Autotools: Make installation of shipped man page doc/xmlwf.1
independent of docbook2man availability
#815 Autotools|CMake: Add missing -DXML_STATIC to pkg-config file
section "Cflags.private" in order to fix compilation
against static libexpat using pkg-config on Windows
#724 #751 Autotools|CMake: Require a C99 compiler
(a de-facto requirement already since Expat 2.2.2 of 2017)
#793 Autotools|CMake: Fix PACKAGE_BUGREPORT variable
#750 #786 Autotools|CMake: Make test suite require a C++11 compiler
#749 CMake: Require CMake >=3.5.0
#672 CMake: Lowercase off_t and size_t to help a bug in Meson
#746 CMake: Sort xmlwf sources alphabetically
#785 CMake|Windows: Fix generation of DLL file version info
#790 CMake: Build tests/benchmark/benchmark.c as well for
a build with -DEXPAT_BUILD_TESTS=ON
#745 #757 docs: Document the importance of isFinal + adjust tests
accordingly
#736 docs: Improve use of "NULL" and "null"
#713 docs: Be specific about version of XML (XML 1.0r4)
and version of C (C99); (XML 1.0r5 will need a sponsor.)
#762 docs: reference.html: Promote function XML_ParseBuffer more
#779 docs: reference.html: Add HTML anchors to XML_* macros
#760 docs: reference.html: Upgrade to OK.css 1.2.0
#763 #739 docs: Fix typos
#696 docs|CI: Use HTTPS URLs instead of HTTP at various places
#669 #670 ..
#692 #703 ..
#733 #772 Address compiler warnings
#798 #800 Address clang-tidy warnings
#775 #776 Version info bumped from 9:10:8 (libexpat*.so.1.8.10)
to 10:0:9 (libexpat*.so.1.9.0); see https://verbump.de/
for what these numbers do
Infrastructure:
#700 #701 docs: Document security policy in file SECURITY.md
#766 docs: Improve parse buffer variables in-code documentation
#674 #738 ..
#740 #747 ..
#748 #781 #782 Refactor coverage and conformance tests
#714 #716 Refactor debug level variables to unsigned long
#671 Improve handling of empty environment variable value
in function getDebugLevel (without visible user effect)
#755 #774 ..
#758 #783 ..
#784 #787 tests: Improve test coverage with regard to parse chunk size
#660 #797 #801 Fuzzing: Improve fuzzing coverage
#367 #799 Fuzzing|CI: Start running OSS-Fuzz fuzzing regression tests
#698 #721 CI: Resolve some Travis CI leftovers
#669 CI: Be robust towards absence of Git tags
#693 #694 CI: Set permissions to "contents: read" for security
#709 CI: Pin all GitHub Actions to specific commits for security
#739 CI: Reject spelling errors using codespell
#798 CI: Enforce clang-tidy clean code
#773 #808 ..
#809 #810 CI: Upgrade Clang from 15 to 18
#796 CI: Start using Clang's Control Flow Integrity sanitizer
#675 #720 #722 CI: Adapt to breaking changes in GitHub Actions Ubuntu images
#689 CI: Adapt to breaking changes in Clang/LLVM Debian packaging
#763 CI: Adapt to breaking changes in codespell
#803 CI: Adapt to breaking changes in Cppcheck
Special thanks to:
Ivan Galkin
Joyce Brum
Philippe Antoine
Rhodri James
Snild Dolkow
spookyahell
Steven Garske
and
Clang AddressSanitizer
Clang UndefinedBehaviorSanitizer
codespell
GCC Farm Project
OSS-Fuzz
Sony Mobile
Release 2.5.0 Tue October 25 2022
Security fixes:
#616 #649 #650 CVE-2022-43680 -- Fix heap use-after-free after overeager
@ -11,7 +125,7 @@ Release 2.5.0 Tue October 25 2022
arbitrary code execution.
Bug fixes:
#612 #645 Fix curruption from undefined entities
#612 #645 Fix corruption from undefined entities
#613 #654 Fix case when parsing was suspended while processing nested
entities
#616 #652 #653 Stop leaking opening tag bindings after a closing tag
@ -318,7 +432,7 @@ Release 2.4.2 Sun December 19 2021
see https://verbump.de/ for what these numbers do
Special thanks to:
Dong-hee Na
Donghee Na
Joergen Ibsen
Kai Pastor

View File

@ -1,13 +1,14 @@
[![Run Linux Travis CI tasks](https://github.com/libexpat/libexpat/actions/workflows/linux.yml/badge.svg)](https://github.com/libexpat/libexpat/actions/workflows/linux.yml)
[![Run Linux CI tasks](https://github.com/libexpat/libexpat/actions/workflows/linux.yml/badge.svg)](https://github.com/libexpat/libexpat/actions/workflows/linux.yml)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/libexpat/libexpat?svg=true)](https://ci.appveyor.com/project/libexpat/libexpat)
[![Packaging status](https://repology.org/badge/tiny-repos/expat.svg)](https://repology.org/metapackage/expat/versions)
[![Downloads SourceForge](https://img.shields.io/sourceforge/dt/expat?label=Downloads%20SourceForge)](https://sourceforge.net/projects/expat/files/)
[![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
# Expat, Release 2.5.0
# Expat, Release 2.6.0
This is Expat, a C library for parsing XML, started by
This is Expat, a C99 library for parsing
[XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by
[James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997.
Expat is a stream-oriented XML parser. This means that you register
handlers with the parser before starting the parse. These handlers

View File

@ -14,11 +14,13 @@
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2000-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2017-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Jakub Wilk <jwilk@jwilk.net>
Copyright (c) 2021 Tomas Korbar <tkorbar@redhat.com>
Copyright (c) 2021 Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
Copyright (c) 2022 Thijs Schreijer <thijs@thijsschreijer.nl>
Copyright (c) 2023 Hanno Böck <hanno@gentoo.org>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -50,7 +52,7 @@
<div>
<h1>
The Expat XML Parser
<small>Release 2.5.0</small>
<small>Release 2.6.0</small>
</h1>
</div>
<div class="content">
@ -68,11 +70,11 @@ Working Group at W3C that produced the XML specification.</p>
<p>This is free software, licensed under the <a
href="../COPYING">MIT/X Consortium license</a>. You may download it
from <a href="http://www.libexpat.org/">the Expat home page</a>.
from <a href="https://libexpat.github.io/">the Expat home page</a>.
</p>
<p>The bulk of this document was originally commissioned as an article
by <a href="http://www.xml.com/">XML.com</a>. They graciously allowed
by <a href="https://www.xml.com/">XML.com</a>. They graciously allowed
Clark Cooper to retain copyright and to distribute it with Expat.
This version has been substantially extended to include documentation
on features which have been added since the original article was
@ -151,10 +153,11 @@ interface.</p>
</ul>
</li>
<li>
<a href="#billion-laughs">Billion Laughs Attack Protection</a>
<a href="#attack-protection">Attack Protection</a>
<ul>
<li><a href="#XML_SetBillionLaughsAttackProtectionMaximumAmplification">XML_SetBillionLaughsAttackProtectionMaximumAmplification</a></li>
<li><a href="#XML_SetBillionLaughsAttackProtectionActivationThreshold">XML_SetBillionLaughsAttackProtectionActivationThreshold</a></li>
<li><a href="#XML_SetReparseDeferralEnabled">XML_SetReparseDeferralEnabled</a></li>
</ul>
</li>
<li><a href="#miscellaneous">Miscellaneous Functions</a>
@ -305,7 +308,7 @@ shoveling the document to the parser so that it can do its work.</p>
<p>The Expat distribution comes as a compressed (with GNU gzip) tar
file. You may download the latest version from <a href=
"http://sourceforge.net/projects/expat/" >Source Forge</a>. After
"https://sourceforge.net/projects/expat/" >Source Forge</a>. After
unpacking this, cd into the directory. Then follow either the Win32
directions or Unix directions below.</p>
@ -359,37 +362,64 @@ and the definition of character types in the case of
<code>XML_UNICODE_WCHAR_T</code>. The symbols are:</p>
<dl class="cpp-symbols">
<dt>XML_DTD</dt>
<dt><a name="XML_GE">XML_GE</a></dt>
<dd>
Added in Expat 2.6.0.
Include support for
<a href="https://www.w3.org/TR/2006/REC-xml-20060816/#sec-physical-struct">general entities</a>
(syntax <code>&amp;e1;</code> to reference and
syntax <code>&lt;!ENTITY e1 'value1'&gt;</code> (an internal general entity) or
<code>&lt;!ENTITY e2 SYSTEM 'file2'&gt;</code> (an external general entity) to declare).
With <code>XML_GE</code> enabled, general entities will be replaced by their declared replacement text;
for this to work for <em>external</em> general entities, in addition an
<code><a href="#XML_SetExternalEntityRefHandler">XML_ExternalEntityRefHandler</a></code> must be set using
<code><a href="#XML_SetExternalEntityRefHandler">XML_SetExternalEntityRefHandler</a></code>.
Also, enabling <code>XML_GE</code> makes
the functions <code><a href="#XML_SetBillionLaughsAttackProtectionMaximumAmplification">
XML_SetBillionLaughsAttackProtectionMaximumAmplification</a></code> and <code>
<a href="#XML_SetBillionLaughsAttackProtectionActivationThreshold">
XML_SetBillionLaughsAttackProtectionActivationThreshold</a></code> available.
<br/>
With <code>XML_GE</code> disabled, Expat has a smaller memory footprint and can be faster, but will
not load external general entities and will replace all general entities
(except the <a href="https://www.w3.org/TR/2006/REC-xml-20060816/#sec-predefined-ent">predefined five</a>:
<code>amp</code>, <code>apos</code>, <code>gt</code>, <code>lt</code>, <code>quot</code>)
with a self-reference:
for example, referencing an entity <code>e1</code> via <code>&amp;e1;</code> will be replaced
by text <code>&amp;e1;</code>.
</dd>
<dt><a name="XML_DTD">XML_DTD</a></dt>
<dd>Include support for using and reporting DTD-based content. If
this is defined, default attribute values from an external DTD subset
are reported and attribute value normalization occurs based on the
type of attributes defined in the external subset. Without
this, Expat has a smaller memory footprint and can be faster, but will
not load external entities or process conditional sections. If defined, makes
not load external parameter entities or process conditional sections. If defined, makes
the functions <code><a
href="#XML_SetBillionLaughsAttackProtectionMaximumAmplification">
XML_SetBillionLaughsAttackProtectionMaximumAmplification</a></code> and <code>
<a href="#XML_SetBillionLaughsAttackProtectionActivationThreshold">
XML_SetBillionLaughsAttackProtectionActivationThreshold</a></code> available.</dd>
<dt>XML_NS</dt>
<dt><a name="XML_NS">XML_NS</a></dt>
<dd>When defined, support for the <cite><a href=
"http://www.w3.org/TR/REC-xml-names/" >Namespaces in XML</a></cite>
"https://www.w3.org/TR/REC-xml-names/" >Namespaces in XML</a></cite>
specification is included.</dd>
<dt>XML_UNICODE</dt>
<dt><a name="XML_UNICODE">XML_UNICODE</a></dt>
<dd>When defined, character data reported to the application is
encoded in UTF-16 using wide characters of the type
<code>XML_Char</code>. This is implied if
<code>XML_UNICODE_WCHAR_T</code> is defined.</dd>
<dt>XML_UNICODE_WCHAR_T</dt>
<dt><a name="XML_UNICODE_WCHAR_T">XML_UNICODE_WCHAR_T</a></dt>
<dd>If defined, causes the <code>XML_Char</code> character type to be
defined using the <code>wchar_t</code> type; otherwise, <code>unsigned
short</code> is used. Defining this implies
<code>XML_UNICODE</code>.</dd>
<dt>XML_LARGE_SIZE</dt>
<dt><a name="XML_LARGE_SIZE">XML_LARGE_SIZE</a></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
@ -399,23 +429,23 @@ processing of very large input streams, where the return values of
could overflow. It may not be supported by all compilers, and is turned
off by default.</dd>
<dt>XML_CONTEXT_BYTES</dt>
<dt><a name="XML_CONTEXT_BYTES">XML_CONTEXT_BYTES</a></dt>
<dd>The number of input bytes of markup context which the parser will
ensure are available for reporting via <code><a href=
"#XML_GetInputContext" >XML_GetInputContext</a></code>. This is
normally set to 1024, and must be set to a positive integer. If this
is not defined, the input context will not be available and <code><a
normally set to 1024, and must be set to a positive integer to enable.
If this is set to zero, the input context will not be available and <code><a
href= "#XML_GetInputContext" >XML_GetInputContext</a></code> will
always report NULL. Without this, Expat has a smaller memory
always report <code>NULL</code>. Without this, Expat has a smaller memory
footprint and can be faster.</dd>
<dt>XML_STATIC</dt>
<dt><a name="XML_STATIC">XML_STATIC</a></dt>
<dd>On Windows, this should be set if Expat is going to be linked
statically with 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>XML_ATTR_INFO</dt>
<dt><a 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>
@ -669,8 +699,9 @@ function. The StartNamespaceDeclHandler is called prior to the start
tag handler and the EndNamespaceDeclHandler is called after the
corresponding end tag that ends the namespace's scope. The namespace
start handler gets passed the prefix and URI for the namespace. For a
default namespace declaration (xmlns='...'), the prefix will be null.
The URI will be null for the case where the default namespace is being
default namespace declaration (xmlns='...'), the prefix will be
<code>NULL</code>.
The URI will be <code>NULL</code> for the case where the default namespace is being
unset. The namespace end handler just gets the prefix for the closing
scope.</p>
@ -799,7 +830,7 @@ has already been passed into the parser. Applications for this
include</p>
<ul>
<li>Supporting the <a href= "http://www.w3.org/TR/xinclude/"
<li>Supporting the <a href= "https://www.w3.org/TR/xinclude/"
>XInclude</a> specification.</li>
<li>Delaying further processing until additional information is
@ -947,16 +978,20 @@ XML_Parser XMLCALL
XML_ParserCreate(const XML_Char *encoding);
</pre>
<div class="fcndef">
Construct a new parser. If encoding is non-null, it specifies a
<p>
Construct a new parser. If encoding is non-<code>NULL</code>, it specifies a
character encoding to use for the document. This overrides the document
encoding declaration. There are four built-in encodings:
</p>
<ul>
<li>US-ASCII</li>
<li>UTF-8</li>
<li>UTF-16</li>
<li>ISO-8859-1</li>
</ul>
<p>
Any other value will invoke a call to the UnknownEncodingHandler.
</p>
</div>
<h4 id="XML_ParserCreateNS">XML_ParserCreateNS</h4>
@ -1003,9 +1038,9 @@ typedef struct {
</pre>
<div class="fcndef">
<p>Construct a new parser using the suite of memory handling functions
specified in <code>ms</code>. If <code>ms</code> is NULL, then use the
specified in <code>ms</code>. If <code>ms</code> is <code>NULL</code>, then use the
standard set of memory management functions. If <code>sep</code> is
non NULL, then namespace processing is enabled in the created parser
non-<code>NULL</code>, then namespace processing is enabled in the created parser
and the character pointed at by sep is used as the separator between
the namespace URI and the local part of the name.</p>
</div>
@ -1077,6 +1112,11 @@ exceed the maximum integer value. Input data at the end of a buffer
will remain unprocessed if it is part of an XML token for which the
end is not part of that buffer.</p>
<p><a name="isFinal"></a>The application <em>must</em> make a concluding
<code><a href="#XML_Parse">XML_Parse</a></code> or
<code><a href="#XML_ParseBuffer">XML_ParseBuffer</a></code> call
with <code>isFinal</code> set to <code>XML_TRUE</code>.</p>
<h4 id="XML_Parse">XML_Parse</h4>
<pre class="fcndec">
enum XML_Status XMLCALL
@ -1092,17 +1132,50 @@ enum XML_Status {
};
</pre>
<div class="fcndef">
<p>
Parse some more of the document. The string <code>s</code> is a buffer
containing part (or perhaps all) of the document. The number of bytes of s
that are part of the document is indicated by <code>len</code>. This means
that <code>s</code> doesn't have to be null terminated. It also means that
that <code>s</code> doesn't have to be null-terminated. It also means that
if <code>len</code> is larger than the number of bytes in the block of
memory that <code>s</code> points at, then a memory fault is likely. The
<code>isFinal</code> parameter informs the parser that this is the last
piece of the document. Frequently, the last piece is empty (i.e.
<code>len</code> is zero.)
</p>
<p>
If a parse error occurred, it returns <code>XML_STATUS_ERROR</code>.
Otherwise it returns <code>XML_STATUS_OK</code> value.
Note that regardless of the return value, there is no guarantee that all
provided input has been parsed; only after <a href="#isFinal">the
concluding call</a> will all handler callbacks and parsing errors have
happened.
</p>
<p>
Simplified, <code>XML_Parse</code> can be considered a convenience wrapper
that is pairing calls
to <code><a href="#XML_GetBuffer">XML_GetBuffer</a></code>
and <code><a href="#XML_ParseBuffer">XML_ParseBuffer</a></code>
(when Expat is built with macro <code>XML_CONTEXT_BYTES</code>
defined to a positive value, which is both common and default).
<code>XML_Parse</code> is then functionally equivalent to calling
<code><a href="#XML_GetBuffer">XML_GetBuffer</a></code>,
<code>memcpy</code>, and
<code><a href="#XML_ParseBuffer">XML_ParseBuffer</a></code>.
</p>
<p>
To avoid double copying of the input, direct use of functions
<code><a href="#XML_GetBuffer">XML_GetBuffer</a></code> and
<code><a href="#XML_ParseBuffer">XML_ParseBuffer</a></code> is advised
for most production use, e.g.
if you're using <code>read</code> or similar functionality to fill your
buffers, fill directly into the buffer from
<code><a href="#XML_GetBuffer">XML_GetBuffer</a></code>,
then parse with <code><a href="#XML_ParseBuffer">XML_ParseBuffer</a></code>.
</p>
</div>
<h4 id="XML_ParseBuffer">XML_ParseBuffer</h4>
@ -1128,8 +1201,8 @@ XML_GetBuffer(XML_Parser p,
</pre>
<div class="fcndef">
Obtain a buffer of size <code>len</code> to read a piece of the document
into. A NULL value is returned if Expat can't allocate enough memory for
this buffer. A NULL value may also be returned if <code>len</code> is zero.
into. A <code>NULL</code> value is returned if Expat can't allocate enough memory for
this buffer. A <code>NULL</code> value may also be returned if <code>len</code> is zero.
This has to be called prior to every call to
<code><a href= "#XML_ParseBuffer" >XML_ParseBuffer</a></code>. A
typical use would look like this:
@ -1275,7 +1348,7 @@ typedef struct {
<p>Returns status of parser with respect to being initialized,
parsing, finished, or suspended, and whether the final buffer is being
processed. The <code>status</code> parameter <em>must not</em> be
NULL.</p>
<code>NULL</code>.</p>
<p>New in Expat 1.95.8.</p>
</div>
@ -1290,7 +1363,7 @@ to ignore all text not descended from a <code>para</code> element. One
way it could do this is to set the character handler when a para start tag
is seen, and unset it for the corresponding end tag.</p>
<p>A handler may be <em>unset</em> by providing a NULL pointer to the
<p>A handler may be <em>unset</em> by providing a <code>NULL</code> pointer to the
appropriate handler setter. None of the handler setting functions have
a return value.</p>
@ -1318,7 +1391,7 @@ typedef void
handler as a pointer to a vector of char pointers. Each attribute seen in
a start (or empty) tag occupies 2 consecutive places in this vector: the
attribute name followed by the attribute value. These pairs are terminated
by a null pointer.</p>
by a <code>NULL</code> pointer.</p>
<p>Note that an empty tag generates a call to both start and end handlers
(in that order).</p>
</div>
@ -1368,7 +1441,7 @@ is <em>NOT null-terminated</em>. You have to use the length argument
to deal with the end of the string. A single block of contiguous text
free of markup may still result in a sequence of calls to this handler.
In other words, if you're searching for a pattern in the text, it may
be split across calls to this handler. Note: Setting this handler to NULL
be split across calls to this handler. Note: Setting this handler to <code>NULL</code>
may <em>NOT immediately</em> terminate call-backs if the parser is currently
processing such a single block of contiguous markup-free text, as the parser
will continue calling back until the end of the block is reached.</p>
@ -1526,16 +1599,16 @@ the format expected by the <code>context</code> argument to <code><a
href="#XML_ExternalEntityParserCreate"
>XML_ExternalEntityParserCreate</a></code>. <code>code</code> is
valid only until the handler returns, so if the referenced entity is
to be parsed later, it must be copied. <code>context</code> is NULL
to be parsed later, it must be copied. <code>context</code> is <code>NULL</code>
only when the entity is a parameter entity, which is how one can
differentiate between general and parameter entities.</p>
<p>The <code>base</code> parameter is the base to use for relative
system identifiers. It is set by <code><a
href="#XML_SetBase">XML_SetBase</a></code> and may be NULL. The
href="#XML_SetBase">XML_SetBase</a></code> and may be <code>NULL</code>. The
<code>publicId</code> parameter is the public id given in the entity
declaration and may be NULL. <code>systemId</code> is the system
identifier specified in the entity declaration and is never NULL.</p>
declaration and may be <code>NULL</code>. <code>systemId</code> is the system
identifier specified in the entity declaration and is never <code>NULL</code>.</p>
<p>There are a couple of ways in which this handler differs from
others. First, this handler returns a status indicator (an
@ -1564,10 +1637,10 @@ XML_SetExternalEntityRefHandlerArg(XML_Parser p,
</pre>
<div class="fcndef">
<p>Set the argument passed to the ExternalEntityRefHandler. If
<code>arg</code> is not NULL, it is the new value passed to the
<code>arg</code> is not <code>NULL</code>, it is the new value passed to the
handler set using <code><a href="#XML_SetExternalEntityRefHandler"
>XML_SetExternalEntityRefHandler</a></code>; if <code>arg</code> is
NULL, the argument passed to the handler function will be the parser
<code>NULL</code>, the argument passed to the handler function will be the parser
object itself.</p>
<p><strong>Note:</strong>
@ -1650,14 +1723,14 @@ value is -1, then that byte is invalid as the initial byte in a sequence.
If the value is -n, where n is an integer &gt; 1, then n is the number of
bytes in the sequence and the actual conversion is accomplished by a
call to the function pointed at by convert. This function may return -1
if the sequence itself is invalid. The convert pointer may be null if
if the sequence itself is invalid. The convert pointer may be <code>NULL</code> if
there are only single byte codes. The data parameter passed to the convert
function is the data pointer from <code>XML_Encoding</code>. The
string s is <em>NOT</em> null-terminated and points at the sequence of
bytes to be converted.</p>
<p>The function pointed at by <code>release</code> is called by the
parser when it is finished with the encoding. It may be NULL.</p>
parser when it is finished with the encoding. It may be <code>NULL</code>.</p>
</div>
<div class="handler">
@ -1724,8 +1797,8 @@ typedef void
</pre>
<p>Sets a handler that is called for XML declarations and also for
text declarations discovered in external entities. The way to
distinguish is that the <code>version</code> parameter will be NULL
for text declarations. The <code>encoding</code> parameter may be NULL
distinguish is that the <code>version</code> parameter will be <code>NULL</code>
for text declarations. The <code>encoding</code> parameter may be <code>NULL</code>
for an XML declaration. The <code>standalone</code> argument will
contain -1, 0, or 1 indicating respectively that there was no
standalone parameter in the declaration, that it was given as no, or
@ -1749,7 +1822,7 @@ typedef void
</pre>
<p>Set a handler that is called at the start of a DOCTYPE declaration,
before any external or internal subset is parsed. Both <code>sysid</code>
and <code>pubid</code> may be NULL. The <code>has_internal_subset</code>
and <code>pubid</code> may be <code>NULL</code>. The <code>has_internal_subset</code>
will be non-zero if the DOCTYPE declaration has an internal subset.</p>
</div>
@ -1831,7 +1904,7 @@ around and freed at a later stage.</p>
<code>XML_Content</code> nodes. If <code>type</code> equals
<code>XML_CTYPE_EMPTY</code> or <code>XML_CTYPE_ANY</code>, then
<code>quant</code> will be <code>XML_CQUANT_NONE</code>, and the other
fields will be zero or NULL. If <code>type</code> is
fields will be zero or <code>NULL</code>. If <code>type</code> is
<code>XML_CTYPE_MIXED</code>, then <code>quant</code> will be
<code>XML_CQUANT_NONE</code> or <code>XML_CQUANT_REP</code> and
<code>numchildren</code> will contain the number of elements that are
@ -1843,7 +1916,7 @@ XML_CTYPE_NAME with no quantification. Only the root node can be type
<p>For type <code>XML_CTYPE_NAME</code>, the <code>name</code> field
points to the name and the <code>numchildren</code> and
<code>children</code> fields will be zero and NULL. The
<code>children</code> fields will be zero and <code>NULL</code>. The
<code>quant</code> field will indicate any quantifiers placed on the
name.</p>
@ -1879,11 +1952,11 @@ is in the <code>attname</code> parameter. The attribute type is in the
type in the declaration with whitespace removed.</p>
<p>The <code>dflt</code> parameter holds the default value. It will be
NULL in the case of "#IMPLIED" or "#REQUIRED" attributes. You can
<code>NULL</code> in the case of "#IMPLIED" or "#REQUIRED" attributes. You can
distinguish these two cases by checking the <code>isrequired</code>
parameter, which will be true in the case of "#REQUIRED" attributes.
Attributes which are "#FIXED" will have also have a true
<code>isrequired</code>, but they will have the non-NULL fixed value
<code>isrequired</code>, but they will have the non-<code>NULL</code> fixed value
in the <code>dflt</code> parameter.</p>
</div>
@ -1911,14 +1984,14 @@ The <code>is_parameter_entity</code> argument will be non-zero in the
case of parameter entities and zero otherwise.</p>
<p>For internal entities (<code>&lt;!ENTITY foo "bar"&gt;</code>),
<code>value</code> will be non-NULL and <code>systemId</code>,
<code>publicId</code>, and <code>notationName</code> will all be NULL.
The value string is <em>not</em> NULL terminated; the length is
<code>value</code> will be non-<code>NULL</code> and <code>systemId</code>,
<code>publicId</code>, and <code>notationName</code> will all be <code>NULL</code>.
The value string is <em>not</em> null-terminated; the length is
provided in the <code>value_length</code> parameter. Do not use
<code>value_length</code> to test for internal entities, since it is
legal to have zero-length values. Instead check for whether or not
<code>value</code> is NULL.</p> <p>The <code>notationName</code>
argument will have a non-NULL value only for unparsed entity
<code>value</code> is <code>NULL</code>.</p> <p>The <code>notationName</code>
argument will have a non-<code>NULL</code> value only for unparsed entity
declarations.</p>
</div>
@ -2092,15 +2165,11 @@ untranslated bytes of the input.</p>
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 not defined, this will always
return NULL.</p>
<p>If <code>XML_CONTEXT_BYTES</code> is zero, this will always
return <code>NULL</code>.</p>
</div>
<h3><a name="billion-laughs">Billion Laughs Attack Protection</a></h3>
<p>The functions in this section configure the built-in
protection against various forms of
<a href="https://en.wikipedia.org/wiki/Billion_laughs_attack">billion laughs attacks</a>.</p>
<h3><a name="attack-protection">Attack Protection</a><a name="billion-laughs"></a></h3>
<h4 id="XML_SetBillionLaughsAttackProtectionMaximumAmplification">XML_SetBillionLaughsAttackProtectionMaximumAmplification</h4>
<pre class="fcndec">
@ -2188,6 +2257,27 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(XML_Parser p,
</p>
</div>
<h4 id="XML_SetReparseDeferralEnabled">XML_SetReparseDeferralEnabled</h4>
<pre class="fcndec">
/* Added in Expat 2.6.0. */
XML_Bool XMLCALL
XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
</pre>
<div class="fcndef">
<p>
Large tokens may require many parse calls before enough data is available for Expat to parse it in full.
If Expat retried parsing the token on every parse call, parsing could take quadratic time.
To avoid this, Expat only retries once a significant amount of new data is available.
This function allows disabling this behavior.
</p>
<p>
The <code>enabled</code> argument should be <code>XML_TRUE</code> or <code>XML_FALSE</code>.
</p>
<p>
Returns <code>XML_TRUE</code> on success, and <code>XML_FALSE</code> on error.
</p>
</div>
<h3><a name="miscellaneous">Miscellaneous functions</a></h3>
<p>The functions in this section either obtain state information from
@ -2313,7 +2403,7 @@ XML_SetEncoding(XML_Parser p,
</pre>
<div class="fcndef">
Set the encoding to be used by the parser. It is equivalent to
passing a non-null encoding argument to the parser creation functions.
passing a non-<code>NULL</code> encoding argument to the parser creation functions.
It must not be called after <code><a href= "#XML_Parse"
>XML_Parse</a></code> or <code><a href= "#XML_ParseBuffer"
>XML_ParseBuffer</a></code> have been called on the given parser.
@ -2385,7 +2475,7 @@ called. The setting of parameter entity parsing, controlled using
external entity reference handler set via <code><a href=
"#XML_SetExternalEntityRefHandler"
>XML_SetExternalEntityRefHandler</a></code> with both
<code>publicId</code> and <code>systemId</code> set to NULL.</p>
<code>publicId</code> and <code>systemId</code> set to <code>NULL</code>.</p>
<p>If this function is called after parsing has begun, it returns
<code>XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING</code> and ignores
@ -2506,7 +2596,7 @@ check these features to do so at runtime.</p>
<p>The return value is an array of <code>XML_Feature</code>,
terminated by a record with a <code>feature</code> of
<code>XML_FEATURE_END</code> and <code>name</code> of NULL,
<code>XML_FEATURE_END</code> and <code>name</code> of <code>NULL</code>,
identifying the feature-test macros Expat was compiled with. Since an
application that requires this kind of information needs to determine
the type of character the <code>name</code> points to, records for the
@ -2562,7 +2652,7 @@ XML_MemMalloc(XML_Parser parser, size_t size);
<div class="fcndef">
Allocate <code>size</code> bytes of memory using the allocator the
<code>parser</code> object has been configured to use. Returns a
pointer to the memory or NULL on failure. Memory allocated in this
pointer to the memory or <code>NULL</code> on failure. Memory allocated in this
way must be freed using <code><a href="#XML_MemFree"
>XML_MemFree</a></code>.
</div>
@ -2577,9 +2667,9 @@ Allocate <code>size</code> bytes of memory using the allocator the
<code>parser</code> object has been configured to use.
<code>ptr</code> must point to a block of memory allocated by <code><a
href="#XML_MemMalloc" >XML_MemMalloc</a></code> or
<code>XML_MemRealloc</code>, or be NULL. This function tries to
<code>XML_MemRealloc</code>, or be <code>NULL</code>. This function tries to
expand the block pointed to by <code>ptr</code> if possible. Returns
a pointer to the memory or NULL on failure. On success, the original
a pointer to the memory or <code>NULL</code> on failure. On success, the original
block has either been expanded or freed. On failure, the original
block has not been freed; the caller is responsible for freeing the
original block. Memory allocated in this way must be freed using
@ -2595,7 +2685,7 @@ XML_MemFree(XML_Parser parser, void *ptr);
<div class="fcndef">
Free a block of memory pointed to by <code>ptr</code>. The block must
have been allocated by <code><a href="#XML_MemMalloc"
>XML_MemMalloc</a></code> or <code>XML_MemRealloc</code>, or be NULL.
>XML_MemMalloc</a></code> or <code>XML_MemRealloc</code>, or be <code>NULL</code>.
</div>
<hr />

View File

@ -0,0 +1,234 @@
/* Read an XML document from standard input and print
element declarations (if any) to standard output.
It must be used with Expat compiled for UTF-8 output.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
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) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2019 Zhongyuan Zhou <zhouzhongyuan@huawei.com>
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.
*/
#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
# define XML_FMT_STR "s"
#endif
// While traversing the XML_Content tree, we avoid recursion
// to not be vulnerable to a denial of service attack.
typedef struct StackStruct {
const XML_Content *model;
unsigned level;
struct StackStruct *prev;
} Stack;
static Stack *
stackPushMalloc(Stack *stackTop, const XML_Content *model, unsigned level) {
Stack *const newStackTop = malloc(sizeof(Stack));
if (! newStackTop) {
return NULL;
}
newStackTop->model = model;
newStackTop->level = level;
newStackTop->prev = stackTop;
return newStackTop;
}
static Stack *
stackPopFree(Stack *stackTop) {
Stack *const newStackTop = stackTop->prev;
free(stackTop);
return newStackTop;
}
static char *
contentTypeName(enum XML_Content_Type contentType) {
switch (contentType) {
case XML_CTYPE_EMPTY:
return "EMPTY";
case XML_CTYPE_ANY:
return "ANY";
case XML_CTYPE_MIXED:
return "MIXED";
case XML_CTYPE_NAME:
return "NAME";
case XML_CTYPE_CHOICE:
return "CHOICE";
case XML_CTYPE_SEQ:
return "SEQ";
default:
return "???";
}
}
static char *
contentQuantName(enum XML_Content_Quant contentQuant) {
switch (contentQuant) {
case XML_CQUANT_NONE:
return "NONE";
case XML_CQUANT_OPT:
return "OPT";
case XML_CQUANT_REP:
return "REP";
case XML_CQUANT_PLUS:
return "PLUS";
default:
return "???";
}
}
static void
dumpContentModelElement(const XML_Content *model, unsigned level,
const XML_Content *root) {
// Indent
unsigned u = 0;
for (; u < level; u++) {
printf(" ");
}
// Node
printf("[%u] type=%s(%d), quant=%s(%d)", (unsigned)(model - root),
contentTypeName(model->type), model->type,
contentQuantName(model->quant), model->quant);
if (model->name) {
printf(", name=\"%" XML_FMT_STR "\"", model->name);
} else {
printf(", name=NULL");
}
printf(", numchildren=%d", model->numchildren);
printf("\n");
}
static bool
dumpContentModel(const XML_Char *name, const XML_Content *root) {
printf("Element \"%" XML_FMT_STR "\":\n", name);
Stack *stackTop = stackPushMalloc(NULL, root, 1);
if (! stackTop) {
return false;
}
while (stackTop) {
const XML_Content *const model = stackTop->model;
const unsigned level = stackTop->level;
dumpContentModelElement(model, level, root);
stackTop = stackPopFree(stackTop);
for (size_t u = model->numchildren; u >= 1; u--) {
Stack *const newStackTop
= stackPushMalloc(stackTop, model->children + (u - 1), level + 1);
if (! newStackTop) {
// We ran out of memory, so let's free all memory allocated
// earlier in this function, to be leak-clean:
while (stackTop != NULL) {
stackTop = stackPopFree(stackTop);
}
return false;
}
stackTop = newStackTop;
}
}
printf("\n");
return true;
}
static void XMLCALL
handleElementDeclaration(void *userData, const XML_Char *name,
XML_Content *model) {
XML_Parser parser = (XML_Parser)userData;
const bool success = dumpContentModel(name, model);
XML_FreeContentModel(parser, model);
if (! success) {
XML_StopParser(parser, /* resumable= */ XML_FALSE);
}
}
int
main(void) {
XML_Parser parser = XML_ParserCreate(NULL);
int done;
if (! parser) {
fprintf(stderr, "Couldn't allocate memory for parser\n");
return 1;
}
XML_SetUserData(parser, parser);
XML_SetElementDeclHandler(parser, handleElementDeclaration);
do {
void *const buf = XML_GetBuffer(parser, BUFSIZ);
if (! buf) {
fprintf(stderr, "Couldn't allocate memory for buffer\n");
XML_ParserFree(parser);
return 1;
}
const size_t len = fread(buf, 1, BUFSIZ, stdin);
if (ferror(stdin)) {
fprintf(stderr, "Read error\n");
XML_ParserFree(parser);
return 1;
}
done = feof(stdin);
if (XML_ParseBuffer(parser, (int)len, done) == XML_STATUS_ERROR) {
enum XML_Error errorCode = XML_GetErrorCode(parser);
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));
XML_ParserFree(parser);
return 1;
}
} while (! done);
XML_ParserFree(parser);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: expat_config.h,v 1.5 2019/06/29 00:33:59 bluhm Exp $ */
/* $OpenBSD: expat_config.h,v 1.6 2024/02/11 00:56:28 bluhm Exp $ */
/* quick and dirty conf for OpenBSD */
@ -6,6 +6,7 @@
#define HAVE_ARC4RANDOM_BUF 1
#define XML_CONTEXT_BYTES 1024
#define XML_DTD 1
#define XML_GE 1
#define XML_NS 1
#include <endian.h>

View File

@ -11,11 +11,13 @@
Copyright (c) 2000-2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2022 Thijs Schreijer <thijs@thijsschreijer.nl>
Copyright (c) 2023 Hanno Böck <hanno@gentoo.org>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -269,7 +271,7 @@ XML_ParserCreate_MM(const XML_Char *encoding,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *namespaceSeparator);
/* Prepare a parser object to be re-used. This is particularly
/* Prepare a parser object to be reused. This is particularly
valuable when memory allocation overhead is disproportionately high,
such as when a large number of small documnents need to be parsed.
All handlers are cleared from the parser, except for the
@ -951,7 +953,7 @@ XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
XMLPARSEAPI(int)
XML_GetCurrentByteCount(XML_Parser parser);
/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
/* If XML_CONTEXT_BYTES is >=1, returns the input buffer, sets
the integer pointed to by offset to the offset within this buffer
of the current parse position, and sets the integer pointed to by size
to the size of this buffer (the number of input bytes). Otherwise
@ -1025,7 +1027,9 @@ enum XML_FeatureEnum {
XML_FEATURE_ATTR_INFO,
/* Added in Expat 2.4.0. */
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT
XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
/* Added in Expat 2.6.0. */
XML_FEATURE_GE
/* Additional features must be added to the end of this enum. */
};
@ -1038,23 +1042,29 @@ typedef struct {
XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void);
#ifdef XML_DTD
/* Added in Expat 2.4.0. */
#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. */
XMLPARSEAPI(XML_Bool)
XML_SetBillionLaughsAttackProtectionMaximumAmplification(
XML_Parser parser, float maximumAmplificationFactor);
/* Added in Expat 2.4.0. */
/* Added in Expat 2.4.0 for XML_DTD defined and
* added in Expat 2.6.0 for XML_GE == 1. */
XMLPARSEAPI(XML_Bool)
XML_SetBillionLaughsAttackProtectionActivationThreshold(
XML_Parser parser, unsigned long long activationThresholdBytes);
#endif
/* Added in Expat 2.6.0. */
XMLPARSEAPI(XML_Bool)
XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled);
/* Expat follows the semantic versioning convention.
See http://semver.org.
See https://semver.org
*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 5
#define XML_MINOR_VERSION 6
#define XML_MICRO_VERSION 0
#ifdef __cplusplus

View File

@ -28,9 +28,10 @@
Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -154,12 +155,15 @@ extern "C" {
void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
const char **fromLimRef);
#if defined(XML_DTD)
#if XML_GE == 1
unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
const char *unsignedCharToPrintable(unsigned char c);
#endif
extern XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
extern unsigned int g_parseAttempts; // used for testing only
#ifdef __cplusplus
}
#endif

View File

@ -106,7 +106,7 @@
* if this code is included and compiled as C++; related GCC warning is:
* warning: use of C++11 long long integer constant [-Wlong-long]
*/
#define _SIP_ULL(high, low) ((((uint64_t)high) << 32) | (low))
#define SIP_ULL(high, low) ((((uint64_t)high) << 32) | (low))
#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
@ -190,10 +190,10 @@ sip_round(struct siphash *H, const int rounds) {
static struct siphash *
sip24_init(struct siphash *H, const struct sipkey *key) {
H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0];
H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1];
H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0];
H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1];
H->v0 = SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0];
H->v1 = SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1];
H->v2 = SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0];
H->v3 = SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1];
H->p = H->buf;
H->c = 0;

View File

@ -9,7 +9,8 @@
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2023 Orgad Shaneh <orgad.shaneh@audiocodes.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -35,7 +36,9 @@
#ifndef WINCONFIG_H
#define WINCONFIG_H
#define WIN32_LEAN_AND_MEAN
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

File diff suppressed because it is too large Load Diff

View File

@ -12,10 +12,10 @@
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2005-2009 Steven Solie <steven@solie.ca>
Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -38,7 +38,7 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <expat_config.h>
#include "expat_config.h"
#include <stddef.h>

View File

@ -10,7 +10,7 @@
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2024 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -127,9 +127,9 @@ typedef struct prolog_state {
#endif /* XML_DTD */
} PROLOG_STATE;
void XmlPrologStateInit(PROLOG_STATE *);
void XmlPrologStateInit(PROLOG_STATE *state);
#ifdef XML_DTD
void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
void XmlPrologStateInitExternalEntity(PROLOG_STATE *state);
#endif /* XML_DTD */
#define XmlTokenRole(state, tok, ptr, end, enc) \

View File

@ -12,7 +12,7 @@
Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2005-2009 Steven Solie <steven@solie.ca>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com>
Copyright (c) 2016 Don Lewis <truckman@apache.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
@ -20,8 +20,10 @@
Copyright (c) 2017 Benbuck Nason <bnason@netflix.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
Copyright (c) 2022 Martin Ettl <ettl.martin78@googlemail.com>
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
Copyright (c) 2023 Hanno Böck <hanno@gentoo.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -44,7 +46,7 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <expat_config.h>
#include "expat_config.h"
#include <stddef.h>
#include <string.h> /* memcpy */
@ -76,7 +78,7 @@
#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
#define UCS2_GET_NAMING(pages, hi, lo) \
(namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo)&0x1F)))
(namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F)))
/* A 2 byte UTF-8 representation splits the characters 11 bits between
the bottom 5 and 6 bits of the bytes. We need 8 bits to index into
@ -100,7 +102,7 @@
& (1u << (((byte)[2]) & 0x1F)))
/* Detection of invalid UTF-8 sequences is based on Table 3.1B
of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
of Unicode 3.2: https://www.unicode.org/unicode/reports/tr28/
with the additional restriction of not allowing the Unicode
code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
Implementation details:
@ -225,7 +227,7 @@ struct normal_encoding {
/* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \
/* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL
static int FASTCALL checkCharRefNumber(int);
static int FASTCALL checkCharRefNumber(int result);
#include "xmltok_impl.h"
#include "ascii.h"
@ -243,7 +245,7 @@ static int FASTCALL checkCharRefNumber(int);
#endif
#define SB_BYTE_TYPE(enc, p) \
(((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
(((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
#ifdef XML_MIN_SIZE
static int PTRFASTCALL
@ -407,7 +409,7 @@ utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
unsigned short *to = *toP;
const char *from = *fromP;
while (from < fromLim && to < toLim) {
switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
switch (SB_BYTE_TYPE(enc, from)) {
case BT_LEAD2:
if (fromLim - from < 2) {
res = XML_CONVERT_INPUT_INCOMPLETE;
@ -715,31 +717,26 @@ unicode_byte_type(char hi, char lo) {
return res; \
}
#define SET2(ptr, ch) (((ptr)[0] = ((ch)&0xff)), ((ptr)[1] = ((ch) >> 8)))
#define GET_LO(ptr) ((unsigned char)(ptr)[0])
#define GET_HI(ptr) ((unsigned char)(ptr)[1])
DEFINE_UTF16_TO_UTF8(little2_)
DEFINE_UTF16_TO_UTF16(little2_)
#undef SET2
#undef GET_LO
#undef GET_HI
#define SET2(ptr, ch) (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch)&0xFF)))
#define GET_LO(ptr) ((unsigned char)(ptr)[1])
#define GET_HI(ptr) ((unsigned char)(ptr)[0])
DEFINE_UTF16_TO_UTF8(big2_)
DEFINE_UTF16_TO_UTF16(big2_)
#undef SET2
#undef GET_LO
#undef GET_HI
#define LITTLE2_BYTE_TYPE(enc, p) \
((p)[1] == 0 ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
: unicode_byte_type((p)[1], (p)[0]))
((p)[1] == 0 ? SB_BYTE_TYPE(enc, p) : unicode_byte_type((p)[1], (p)[0]))
#define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1)
#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == (c))
#define LITTLE2_IS_NAME_CHAR_MINBPC(p) \
@ -872,9 +869,7 @@ static const struct normal_encoding internal_little2_encoding
#endif
#define BIG2_BYTE_TYPE(enc, p) \
((p)[0] == 0 \
? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
: unicode_byte_type((p)[0], (p)[1]))
((p)[0] == 0 ? SB_BYTE_TYPE(enc, p + 1) : unicode_byte_type((p)[0], (p)[1]))
#define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1)
#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == (c))
#define BIG2_IS_NAME_CHAR_MINBPC(p) \

View File

@ -10,7 +10,7 @@
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2005 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Licensed under the MIT license:
@ -289,7 +289,8 @@ int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc,
const char **encodingNamePtr,
const ENCODING **namedEncodingPtr, int *standalonePtr);
int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
int XmlInitEncoding(INIT_ENCODING *p, const ENCODING **encPtr,
const char *name);
const ENCODING *XmlGetUtf8InternalEncoding(void);
const ENCODING *XmlGetUtf16InternalEncoding(void);
int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
@ -307,7 +308,8 @@ int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc,
const char **encodingNamePtr,
const ENCODING **namedEncodingPtr, int *standalonePtr);
int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
int XmlInitEncodingNS(INIT_ENCODING *p, const ENCODING **encPtr,
const char *name);
const ENCODING *XmlGetUtf8InternalEncodingNS(void);
const ENCODING *XmlGetUtf16InternalEncodingNS(void);
ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,

View File

@ -126,7 +126,7 @@
# endif
# define HAS_CHARS(enc, ptr, end, count) \
((end) - (ptr) >= ((count)*MINBPC(enc)))
((end) - (ptr) >= ((count) * MINBPC(enc)))
# define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1)

View File

@ -1,2 +1,2 @@
major=14
minor=0
minor=1

View File

@ -0,0 +1,396 @@
/* Tests in the "accounting" test case for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
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.
*/
#include <math.h> /* NAN, INFINITY */
#include <stdio.h>
#include <string.h>
#include "expat_config.h"
#include "expat.h"
#include "internal.h"
#include "common.h"
#include "minicheck.h"
#include "chardata.h"
#include "handlers.h"
#include "acc_tests.h"
#if XML_GE == 1
START_TEST(test_accounting_precision) {
struct AccountingTestCase cases[] = {
{"<e/>", NULL, NULL, 0},
{"<e></e>", NULL, NULL, 0},
/* Attributes */
{"<e k1=\"v2\" k2=\"v2\"/>", NULL, NULL, 0},
{"<e k1=\"v2\" k2=\"v2\"></e>", NULL, NULL, 0},
{"<p:e xmlns:p=\"https://domain.invalid/\" />", NULL, NULL, 0},
{"<e k=\"&amp;&apos;&gt;&lt;&quot;\" />", NULL, NULL,
sizeof(XML_Char) * 5 /* number of predefined entities */},
{"<e1 xmlns='https://example.org/'>\n"
" <e2 xmlns=''/>\n"
"</e1>",
NULL, NULL, 0},
/* Text */
{"<e>text</e>", NULL, NULL, 0},
{"<e1><e2>text1<e3/>text2</e2></e1>", NULL, NULL, 0},
{"<e>&amp;&apos;&gt;&lt;&quot;</e>", NULL, NULL,
sizeof(XML_Char) * 5 /* number of predefined entities */},
{"<e>&#65;&#41;</e>", NULL, NULL, 0},
/* Prolog */
{"<?xml version=\"1.0\"?><root/>", NULL, NULL, 0},
/* Whitespace */
{" <e1> <e2> </e2> </e1> ", NULL, NULL, 0},
{"<e1 ><e2 /></e1 >", NULL, NULL, 0},
{"<e1><e2 k = \"v\"/><e3 k = 'v'/></e1>", NULL, NULL, 0},
/* Comments */
{"<!-- Comment --><e><!-- Comment --></e>", NULL, NULL, 0},
/* Processing instructions */
{"<?xml-stylesheet type=\"text/xsl\" href=\"https://domain.invalid/\" media=\"all\"?><e/>",
NULL, NULL, 0},
{"<?pi0?><?pi1 ?><?pi2 ?><r/><?pi4?>", NULL, NULL, 0},
# ifdef XML_DTD
{"<?pi0?><?pi1 ?><?pi2 ?><!DOCTYPE r SYSTEM 'first.ent'><r/>",
"<?pi3?><!ENTITY % e1 SYSTEM 'second.ent'><?pi4?>%e1;<?pi5?>", "<?pi6?>",
0},
# endif /* XML_DTD */
/* CDATA */
{"<e><![CDATA[one two three]]></e>", NULL, NULL, 0},
/* The following is the essence of this OSS-Fuzz finding:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=34302
https://oss-fuzz.com/testcase-detail/4860575394955264
*/
{"<!DOCTYPE r [\n"
"<!ENTITY e \"111<![CDATA[2 <= 2]]>333\">\n"
"]>\n"
"<r>&e;</r>\n",
NULL, NULL, sizeof(XML_Char) * strlen("111<![CDATA[2 <= 2]]>333")},
# ifdef XML_DTD
/* Conditional sections */
{"<!DOCTYPE r [\n"
"<!ENTITY % draft 'INCLUDE'>\n"
"<!ENTITY % final 'IGNORE'>\n"
"<!ENTITY % import SYSTEM \"first.ent\">\n"
"%import;\n"
"]>\n"
"<r/>\n",
"<![%draft;[<!--1-->]]>\n"
"<![%final;[<!--22-->]]>",
NULL, sizeof(XML_Char) * (strlen("INCLUDE") + strlen("IGNORE"))},
# endif /* XML_DTD */
/* General entities */
{"<!DOCTYPE root [\n"
"<!ENTITY nine \"123456789\">\n"
"]>\n"
"<root>&nine;</root>",
NULL, NULL, sizeof(XML_Char) * strlen("123456789")},
{"<!DOCTYPE root [\n"
"<!ENTITY nine \"123456789\">\n"
"]>\n"
"<root k1=\"&nine;\"/>",
NULL, NULL, sizeof(XML_Char) * strlen("123456789")},
{"<!DOCTYPE root [\n"
"<!ENTITY nine \"123456789\">\n"
"<!ENTITY nine2 \"&nine;&nine;\">\n"
"]>\n"
"<root>&nine2;&nine2;&nine2;</root>",
NULL, NULL,
sizeof(XML_Char) * 3 /* calls to &nine2; */ * 2 /* calls to &nine; */
* (strlen("&nine;") + strlen("123456789"))},
{"<!DOCTYPE r [\n"
" <!ENTITY five SYSTEM 'first.ent'>\n"
"]>\n"
"<r>&five;</r>",
"12345", NULL, 0},
{"<!DOCTYPE r [\n"
" <!ENTITY five SYSTEM 'first.ent'>\n"
"]>\n"
"<r>&five;</r>",
"\xEF\xBB\xBF" /* UTF-8 BOM */, NULL, 0},
# ifdef XML_DTD
/* Parameter entities */
{"<!DOCTYPE r [\n"
"<!ENTITY % comment \"<!---->\">\n"
"%comment;\n"
"]>\n"
"<r/>",
NULL, NULL, sizeof(XML_Char) * strlen("<!---->")},
{"<!DOCTYPE r [\n"
"<!ENTITY % ninedef \"&#60;!ENTITY nine &#34;123456789&#34;&#62;\">\n"
"%ninedef;\n"
"]>\n"
"<r>&nine;</r>",
NULL, NULL,
sizeof(XML_Char)
* (strlen("<!ENTITY nine \"123456789\">") + strlen("123456789"))},
{"<!DOCTYPE r [\n"
"<!ENTITY % comment \"<!--1-->\">\n"
"<!ENTITY % comment2 \"&#37;comment;<!--22-->&#37;comment;\">\n"
"%comment2;\n"
"]>\n"
"<r/>\n",
NULL, NULL,
sizeof(XML_Char)
* (strlen("%comment;<!--22-->%comment;") + 2 * strlen("<!--1-->"))},
{"<!DOCTYPE r [\n"
" <!ENTITY % five \"12345\">\n"
" <!ENTITY % five2def \"&#60;!ENTITY five2 &#34;[&#37;five;][&#37;five;]]]]&#34;&#62;\">\n"
" %five2def;\n"
"]>\n"
"<r>&five2;</r>",
NULL, NULL, /* from "%five2def;": */
sizeof(XML_Char)
* (strlen("<!ENTITY five2 \"[%five;][%five;]]]]\">")
+ 2 /* calls to "%five;" */ * strlen("12345")
+ /* from "&five2;": */ strlen("[12345][12345]]]]"))},
{"<!DOCTYPE r SYSTEM \"first.ent\">\n"
"<r/>",
"<!ENTITY % comment '<!--1-->'>\n"
"<!ENTITY % comment2 '<!--22-->%comment;<!--22-->%comment;<!--22-->'>\n"
"%comment2;",
NULL,
sizeof(XML_Char)
* (strlen("<!--22-->%comment;<!--22-->%comment;<!--22-->")
+ 2 /* calls to "%comment;" */ * strlen("<!---->"))},
{"<!DOCTYPE r SYSTEM 'first.ent'>\n"
"<r/>",
"<!ENTITY % e1 PUBLIC 'foo' 'second.ent'>\n"
"<!ENTITY % e2 '<!--22-->%e1;<!--22-->'>\n"
"%e2;\n",
"<!--1-->", sizeof(XML_Char) * strlen("<!--22--><!--1--><!--22-->")},
{
"<!DOCTYPE r SYSTEM 'first.ent'>\n"
"<r/>",
"<!ENTITY % e1 SYSTEM 'second.ent'>\n"
"<!ENTITY % e2 '%e1;'>",
"<?xml version='1.0' encoding='utf-8'?>\n"
"hello\n"
"xml" /* without trailing newline! */,
0,
},
{
"<!DOCTYPE r SYSTEM 'first.ent'>\n"
"<r/>",
"<!ENTITY % e1 SYSTEM 'second.ent'>\n"
"<!ENTITY % e2 '%e1;'>",
"<?xml version='1.0' encoding='utf-8'?>\n"
"hello\n"
"xml\n" /* with trailing newline! */,
0,
},
{"<!DOCTYPE doc SYSTEM 'first.ent'>\n"
"<doc></doc>\n",
"<!ELEMENT doc EMPTY>\n"
"<!ENTITY % e1 SYSTEM 'second.ent'>\n"
"<!ENTITY % e2 '%e1;'>\n"
"%e1;\n",
"\xEF\xBB\xBF<!ATTLIST doc a1 CDATA 'value'>" /* UTF-8 BOM */,
strlen("\xEF\xBB\xBF<!ATTLIST doc a1 CDATA 'value'>")},
# endif /* XML_DTD */
};
const size_t countCases = sizeof(cases) / sizeof(cases[0]);
size_t u = 0;
for (; u < countCases; u++) {
const unsigned long long expectedCountBytesDirect
= strlen(cases[u].primaryText);
const unsigned long long expectedCountBytesIndirect
= (cases[u].firstExternalText ? strlen(cases[u].firstExternalText) : 0)
+ (cases[u].secondExternalText ? strlen(cases[u].secondExternalText)
: 0)
+ cases[u].expectedCountBytesIndirectExtra;
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
if (cases[u].firstExternalText) {
XML_SetExternalEntityRefHandler(parser,
accounting_external_entity_ref_handler);
XML_SetUserData(parser, (void *)&cases[u]);
}
enum XML_Status status
= _XML_Parse_SINGLE_BYTES(parser, cases[u].primaryText,
(int)strlen(cases[u].primaryText), XML_TRUE);
if (status != XML_STATUS_OK) {
_xml_failure(parser, __FILE__, __LINE__);
}
const unsigned long long actualCountBytesDirect
= testingAccountingGetCountBytesDirect(parser);
const unsigned long long actualCountBytesIndirect
= testingAccountingGetCountBytesIndirect(parser);
XML_ParserFree(parser);
if (actualCountBytesDirect != expectedCountBytesDirect) {
fprintf(
stderr,
"Document " EXPAT_FMT_SIZE_T("") " of " EXPAT_FMT_SIZE_T("") ": Expected " EXPAT_FMT_ULL(
"") " count direct bytes, got " EXPAT_FMT_ULL("") " instead.\n",
u + 1, countCases, expectedCountBytesDirect, actualCountBytesDirect);
fail("Count of direct bytes is off");
}
if (actualCountBytesIndirect != expectedCountBytesIndirect) {
fprintf(
stderr,
"Document " EXPAT_FMT_SIZE_T("") " of " EXPAT_FMT_SIZE_T("") ": Expected " EXPAT_FMT_ULL(
"") " count indirect bytes, got " EXPAT_FMT_ULL("") " instead.\n",
u + 1, countCases, expectedCountBytesIndirect,
actualCountBytesIndirect);
fail("Count of indirect bytes is off");
}
}
}
END_TEST
START_TEST(test_billion_laughs_attack_protection_api) {
XML_Parser parserWithoutParent = XML_ParserCreate(NULL);
XML_Parser parserWithParent = XML_ExternalEntityParserCreate(
parserWithoutParent, XCS("entity123"), NULL);
if (parserWithoutParent == NULL)
fail("parserWithoutParent is NULL");
if (parserWithParent == NULL)
fail("parserWithParent is NULL");
// XML_SetBillionLaughsAttackProtectionMaximumAmplification, error cases
if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(NULL, 123.0f)
== XML_TRUE)
fail("Call with NULL parser is NOT supposed to succeed");
if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(parserWithParent,
123.0f)
== XML_TRUE)
fail("Call with non-root parser is NOT supposed to succeed");
if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
parserWithoutParent, NAN)
== XML_TRUE)
fail("Call with NaN limit is NOT supposed to succeed");
if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
parserWithoutParent, -1.0f)
== XML_TRUE)
fail("Call with negative limit is NOT supposed to succeed");
if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
parserWithoutParent, 0.9f)
== XML_TRUE)
fail("Call with positive limit <1.0 is NOT supposed to succeed");
// XML_SetBillionLaughsAttackProtectionMaximumAmplification, success cases
if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
parserWithoutParent, 1.0f)
== XML_FALSE)
fail("Call with positive limit >=1.0 is supposed to succeed");
if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
parserWithoutParent, 123456.789f)
== XML_FALSE)
fail("Call with positive limit >=1.0 is supposed to succeed");
if (XML_SetBillionLaughsAttackProtectionMaximumAmplification(
parserWithoutParent, INFINITY)
== XML_FALSE)
fail("Call with positive limit >=1.0 is supposed to succeed");
// XML_SetBillionLaughsAttackProtectionActivationThreshold, error cases
if (XML_SetBillionLaughsAttackProtectionActivationThreshold(NULL, 123)
== XML_TRUE)
fail("Call with NULL parser is NOT supposed to succeed");
if (XML_SetBillionLaughsAttackProtectionActivationThreshold(parserWithParent,
123)
== XML_TRUE)
fail("Call with non-root parser is NOT supposed to succeed");
// XML_SetBillionLaughsAttackProtectionActivationThreshold, success cases
if (XML_SetBillionLaughsAttackProtectionActivationThreshold(
parserWithoutParent, 123)
== XML_FALSE)
fail("Call with non-NULL parentless parser is supposed to succeed");
XML_ParserFree(parserWithParent);
XML_ParserFree(parserWithoutParent);
}
END_TEST
START_TEST(test_helper_unsigned_char_to_printable) {
// Smoke test
unsigned char uc = 0;
for (; uc < (unsigned char)-1; uc++) {
set_subtest("char %u", (unsigned)uc);
const char *const printable = unsignedCharToPrintable(uc);
if (printable == NULL)
fail("unsignedCharToPrintable returned NULL");
else if (strlen(printable) < (size_t)1)
fail("unsignedCharToPrintable returned empty string");
}
// Two concrete samples
set_subtest("char 'A'");
if (strcmp(unsignedCharToPrintable('A'), "A") != 0)
fail("unsignedCharToPrintable result mistaken");
set_subtest("char '\\'");
if (strcmp(unsignedCharToPrintable('\\'), "\\\\") != 0)
fail("unsignedCharToPrintable result mistaken");
}
END_TEST
#endif // XML_GE == 1
void
make_accounting_test_case(Suite *s) {
#if XML_GE == 1
TCase *tc_accounting = tcase_create("accounting tests");
suite_add_tcase(s, tc_accounting);
tcase_add_test(tc_accounting, test_accounting_precision);
tcase_add_test(tc_accounting, test_billion_laughs_attack_protection_api);
tcase_add_test(tc_accounting, test_helper_unsigned_char_to_printable);
#else
UNUSED_P(s);
#endif /* XML_GE == 1 */
}

View File

@ -0,0 +1,56 @@
/* Tests in the "accounting" test case for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.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.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_ACC_TESTS_H
# define XML_ACC_TESTS_H
extern void make_accounting_test_case(Suite *s);
#endif /* XML_ACC_TESTS_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "acc_tests.c"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
/* Tests in the "allocation" test case for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.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.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_ALLOC_TESTS_H
# define XML_ALLOC_TESTS_H
extern void make_alloc_test_case(Suite *s);
#endif /* XML_ALLOC_TESTS_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "alloc_tests.c"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
/* Tests in the "basic" test case for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.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.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_BASIC_TESTS_H
# define XML_BASIC_TESTS_H
extern void make_basic_test_case(Suite *s);
#endif /* XML_BASIC_TESTS_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "basic_tests.c"

View File

@ -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 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Licensed under the MIT license:
@ -33,6 +33,8 @@
*/
#include <sys/stat.h>
#include <assert.h>
#include <stddef.h> // ptrdiff_t
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
@ -62,7 +64,8 @@ main(int argc, char *argv[]) {
char *XMLBuf, *XMLBufEnd, *XMLBufPtr;
FILE *fd;
struct stat fileAttr;
int nrOfLoops, bufferSize, fileSize, i, isFinal;
int nrOfLoops, bufferSize, i, isFinal;
size_t fileSize;
int j = 0, ns = 0;
clock_t tstart, tend;
double cpuTime = 0.0;
@ -114,12 +117,13 @@ main(int argc, char *argv[]) {
isFinal = 0;
tstart = clock();
do {
int parseBufferSize = XMLBufEnd - XMLBufPtr;
if (parseBufferSize <= bufferSize)
ptrdiff_t parseBufferSize = XMLBufEnd - XMLBufPtr;
if (parseBufferSize <= (ptrdiff_t)bufferSize)
isFinal = 1;
else
parseBufferSize = bufferSize;
if (! XML_Parse(parser, XMLBufPtr, parseBufferSize, isFinal)) {
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",

View File

@ -9,9 +9,10 @@
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-2021 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2023 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>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -34,7 +35,11 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <expat_config.h>
#if defined(NDEBUG)
# undef NDEBUG /* because test suite relies on assert(...) at the moment */
#endif
#include "expat_config.h"
#include "minicheck.h"
#include <assert.h>
@ -80,15 +85,16 @@ CharData_AppendXMLChars(CharData *storage, const XML_Char *s, int len) {
int
CharData_CheckXMLChars(CharData *storage, const XML_Char *expected) {
char buffer[1024];
int len = xmlstrlen(expected);
int count;
assert(storage != NULL);
count = (storage->count < 0) ? 0 : storage->count;
if (len != count) {
sprintf(buffer, "wrong number of data characters: got %d, expected %d",
count, len);
char buffer[1024];
snprintf(buffer, sizeof(buffer),
"wrong number of data characters: got %d, expected %d", count,
len);
fail(buffer);
return 0;
}

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "chardata.c"

325
lib/libexpat/tests/common.c Normal file
View File

@ -0,0 +1,325 @@
/* Commonly used functions for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
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.
*/
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "expat_config.h"
#include "expat.h"
#include "internal.h"
#include "chardata.h"
#include "minicheck.h"
#include "common.h"
/* Common test data */
const char *long_character_data_text
= "<?xml version='1.0' encoding='iso-8859-1'?><s>"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"</s>";
const char *long_cdata_text
= "<s><![CDATA["
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"012345678901234567890123456789012345678901234567890123456789"
"]]></s>";
/* Having an element name longer than 1024 characters exercises some
* of the pool allocation code in the parser that otherwise does not
* get executed. The count at the end of the line is the number of
* characters (bytes) in the element name by that point.x
*/
const char *get_buffer_test_text
= "<documentwitharidiculouslylongelementnametotease" /* 0x030 */
"aparticularcorneroftheallocationinXML_GetBuffers" /* 0x060 */
"othatwecanimprovethecoverageyetagain012345678901" /* 0x090 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0c0 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0f0 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x120 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x150 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x180 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1b0 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1e0 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x210 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x240 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x270 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2a0 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2d0 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x300 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x330 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x360 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x390 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3c0 */
"123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3f0 */
"123456789abcdef0123456789abcdef0123456789>\n<ef0"; /* 0x420 */
/* Test control globals */
/* Used as the "resumable" parameter to XML_StopParser by some tests */
XML_Bool g_resumable = XML_FALSE;
/* Used to control abort checks in some tests */
XML_Bool g_abortable = XML_FALSE;
/* Used to control _XML_Parse_SINGLE_BYTES() chunk size */
int g_chunkSize = 1;
/* Common test functions */
void
tcase_add_test__ifdef_xml_dtd(TCase *tc, tcase_test_function test) {
#ifdef XML_DTD
tcase_add_test(tc, test);
#else
UNUSED_P(tc);
UNUSED_P(test);
#endif
}
void
tcase_add_test__if_xml_ge(TCase *tc, tcase_test_function test) {
#if XML_GE == 1
tcase_add_test(tc, test);
#else
UNUSED_P(tc);
UNUSED_P(test);
#endif
}
void
basic_teardown(void) {
if (g_parser != NULL) {
XML_ParserFree(g_parser);
g_parser = NULL;
}
}
/* Generate a failure using the parser state to create an error message;
this should be used when the parser reports an error we weren't
expecting.
*/
void
_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);
_fail(file, line, buffer);
}
enum XML_Status
_XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len,
int isFinal) {
// This ensures that tests have to run pathological parse cases
// (e.g. when `s` is NULL) against plain XML_Parse rather than
// chunking _XML_Parse_SINGLE_BYTES.
assert((parser != NULL) && (s != NULL) && (len >= 0));
const int chunksize = g_chunkSize;
if (chunksize > 0) {
// parse in chunks of `chunksize` bytes as long as not exhausting
for (; len > chunksize; len -= chunksize, s += chunksize) {
enum XML_Status res = XML_Parse(parser, s, chunksize, XML_FALSE);
if (res != XML_STATUS_OK) {
return res;
}
}
}
// parse the final chunk, the size of which will be <= chunksize
return XML_Parse(parser, s, len, isFinal);
}
void
_expect_failure(const char *text, enum XML_Error errorCode,
const char *errorMessage, const char *file, int lineno) {
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_OK)
/* Hackish use of _fail() macro, but lets us report
the right filename and line number. */
_fail(file, lineno, errorMessage);
if (XML_GetErrorCode(g_parser) != errorCode)
_xml_failure(g_parser, file, lineno);
}
/* Character data support for handlers, built on top of the code in
* chardata.c
*/
void XMLCALL
accumulate_characters(void *userData, const XML_Char *s, int len) {
CharData_AppendXMLChars((CharData *)userData, s, len);
}
void XMLCALL
accumulate_attribute(void *userData, const XML_Char *name,
const XML_Char **atts) {
CharData *storage = (CharData *)userData;
UNUSED_P(name);
/* Check there are attributes to deal with */
if (atts == NULL)
return;
while (storage->count < 0 && atts[0] != NULL) {
/* "accumulate" the value of the first attribute we see */
CharData_AppendXMLChars(storage, atts[1], -1);
atts += 2;
}
}
void
_run_character_check(const char *text, const XML_Char *expected,
const char *file, int line) {
CharData storage;
CharData_Init(&storage);
XML_SetUserData(g_parser, &storage);
XML_SetCharacterDataHandler(g_parser, accumulate_characters);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
_xml_failure(g_parser, file, line);
CharData_CheckXMLChars(&storage, expected);
}
void
_run_attribute_check(const char *text, const XML_Char *expected,
const char *file, int line) {
CharData storage;
CharData_Init(&storage);
XML_SetUserData(g_parser, &storage);
XML_SetStartElementHandler(g_parser, accumulate_attribute);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
_xml_failure(g_parser, file, line);
CharData_CheckXMLChars(&storage, expected);
}
void XMLCALL
ext_accumulate_characters(void *userData, const XML_Char *s, int len) {
ExtTest *test_data = (ExtTest *)userData;
accumulate_characters(test_data->storage, s, len);
}
void
_run_ext_character_check(const char *text, ExtTest *test_data,
const XML_Char *expected, const char *file, int line) {
CharData *const storage = (CharData *)malloc(sizeof(CharData));
CharData_Init(storage);
test_data->storage = storage;
XML_SetUserData(g_parser, test_data);
XML_SetCharacterDataHandler(g_parser, ext_accumulate_characters);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
_xml_failure(g_parser, file, line);
CharData_CheckXMLChars(storage, expected);
free(storage);
}
/* Control variable; the number of times duff_allocator() will successfully
* allocate */
#define ALLOC_ALWAYS_SUCCEED (-1)
#define REALLOC_ALWAYS_SUCCEED (-1)
int g_allocation_count = ALLOC_ALWAYS_SUCCEED;
int g_reallocation_count = REALLOC_ALWAYS_SUCCEED;
/* Crocked allocator for allocation failure tests */
void *
duff_allocator(size_t size) {
if (g_allocation_count == 0)
return NULL;
if (g_allocation_count != ALLOC_ALWAYS_SUCCEED)
g_allocation_count--;
return malloc(size);
}
/* Crocked reallocator for allocation failure tests */
void *
duff_reallocator(void *ptr, size_t size) {
if (g_reallocation_count == 0)
return NULL;
if (g_reallocation_count != REALLOC_ALWAYS_SUCCEED)
g_reallocation_count--;
return realloc(ptr, size);
}

162
lib/libexpat/tests/common.h Normal file
View File

@ -0,0 +1,162 @@
/* Commonly used functions for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
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.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_COMMON_H
# define XML_COMMON_H
# include "expat_config.h"
# include "minicheck.h"
# include "chardata.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"
# 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
# ifdef XML_UNICODE
# 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 */
extern XML_Parser g_parser;
extern XML_Bool g_resumable;
extern XML_Bool g_abortable;
extern int g_chunkSize;
extern const char *long_character_data_text;
extern const char *long_cdata_text;
extern const char *get_buffer_test_text;
extern void tcase_add_test__ifdef_xml_dtd(TCase *tc, tcase_test_function test);
extern void tcase_add_test__if_xml_ge(TCase *tc, tcase_test_function test);
extern void basic_teardown(void);
extern void _xml_failure(XML_Parser parser, const char *file, int line);
# define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
extern enum XML_Status _XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s,
int len, int isFinal);
extern void _expect_failure(const char *text, enum XML_Error errorCode,
const char *errorMessage, const char *file,
int lineno);
# define expect_failure(text, errorCode, errorMessage) \
_expect_failure((text), (errorCode), (errorMessage), __FILE__, __LINE__)
/* Support functions for handlers to collect up character and attribute data.
*/
extern void XMLCALL accumulate_characters(void *userData, const XML_Char *s,
int len);
extern void XMLCALL accumulate_attribute(void *userData, const XML_Char *name,
const XML_Char **atts);
extern void _run_character_check(const char *text, const XML_Char *expected,
const char *file, int line);
# define run_character_check(text, expected) \
_run_character_check(text, expected, __FILE__, __LINE__)
extern void _run_attribute_check(const char *text, const XML_Char *expected,
const char *file, int line);
# define run_attribute_check(text, expected) \
_run_attribute_check(text, expected, __FILE__, __LINE__)
typedef struct ExtTest {
const char *parse_text;
const XML_Char *encoding;
CharData *storage;
} ExtTest;
extern void XMLCALL ext_accumulate_characters(void *userData, const XML_Char *s,
int len);
extern void _run_ext_character_check(const char *text, ExtTest *test_data,
const XML_Char *expected, const char *file,
int line);
# define run_ext_character_check(text, test_data, expected) \
_run_ext_character_check(text, test_data, expected, __FILE__, __LINE__)
# define ALLOC_ALWAYS_SUCCEED (-1)
# define REALLOC_ALWAYS_SUCCEED (-1)
extern int g_allocation_count;
extern int g_reallocation_count;
extern void *duff_allocator(size_t size);
extern void *duff_reallocator(void *ptr, size_t size);
#endif /* XML_COMMON_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "common.c"

261
lib/libexpat/tests/dummy.c Normal file
View File

@ -0,0 +1,261 @@
/* Dummy handler functions for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.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.
*/
#include "expat.h"
#include "internal.h"
#include "common.h"
#include "dummy.h"
/* Dummy handlers for when we need to set a handler to tickle a bug,
but it doesn't need to do anything.
*/
static unsigned long dummy_handler_flags = 0;
void
init_dummy_handlers(void) {
dummy_handler_flags = 0;
}
unsigned long
get_dummy_handler_flags(void) {
return dummy_handler_flags;
}
void XMLCALL
dummy_xdecl_handler(void *userData, const XML_Char *version,
const XML_Char *encoding, int standalone) {
UNUSED_P(userData);
UNUSED_P(version);
UNUSED_P(encoding);
UNUSED_P(standalone);
}
void XMLCALL
dummy_start_doctype_handler(void *userData, const XML_Char *doctypeName,
const XML_Char *sysid, const XML_Char *pubid,
int has_internal_subset) {
UNUSED_P(userData);
UNUSED_P(doctypeName);
UNUSED_P(sysid);
UNUSED_P(pubid);
UNUSED_P(has_internal_subset);
dummy_handler_flags |= DUMMY_START_DOCTYPE_HANDLER_FLAG;
}
void XMLCALL
dummy_end_doctype_handler(void *userData) {
UNUSED_P(userData);
dummy_handler_flags |= DUMMY_END_DOCTYPE_HANDLER_FLAG;
}
void XMLCALL
dummy_entity_decl_handler(void *userData, const XML_Char *entityName,
int is_parameter_entity, const XML_Char *value,
int value_length, const XML_Char *base,
const XML_Char *systemId, const XML_Char *publicId,
const XML_Char *notationName) {
UNUSED_P(userData);
UNUSED_P(entityName);
UNUSED_P(is_parameter_entity);
UNUSED_P(value);
UNUSED_P(value_length);
UNUSED_P(base);
UNUSED_P(systemId);
UNUSED_P(publicId);
UNUSED_P(notationName);
dummy_handler_flags |= DUMMY_ENTITY_DECL_HANDLER_FLAG;
}
void XMLCALL
dummy_notation_decl_handler(void *userData, const XML_Char *notationName,
const XML_Char *base, const XML_Char *systemId,
const XML_Char *publicId) {
UNUSED_P(userData);
UNUSED_P(notationName);
UNUSED_P(base);
UNUSED_P(systemId);
UNUSED_P(publicId);
dummy_handler_flags |= DUMMY_NOTATION_DECL_HANDLER_FLAG;
}
void XMLCALL
dummy_element_decl_handler(void *userData, const XML_Char *name,
XML_Content *model) {
UNUSED_P(userData);
UNUSED_P(name);
/* The content model must be freed by the handler. Unfortunately
* we cannot pass the parser as the userData because this is used
* with other handlers that require other userData.
*/
XML_FreeContentModel(g_parser, model);
dummy_handler_flags |= DUMMY_ELEMENT_DECL_HANDLER_FLAG;
}
void XMLCALL
dummy_attlist_decl_handler(void *userData, const XML_Char *elname,
const XML_Char *attname, const XML_Char *att_type,
const XML_Char *dflt, int isrequired) {
UNUSED_P(userData);
UNUSED_P(elname);
UNUSED_P(attname);
UNUSED_P(att_type);
UNUSED_P(dflt);
UNUSED_P(isrequired);
dummy_handler_flags |= DUMMY_ATTLIST_DECL_HANDLER_FLAG;
}
void XMLCALL
dummy_comment_handler(void *userData, const XML_Char *data) {
UNUSED_P(userData);
UNUSED_P(data);
dummy_handler_flags |= DUMMY_COMMENT_HANDLER_FLAG;
}
void XMLCALL
dummy_pi_handler(void *userData, const XML_Char *target, const XML_Char *data) {
UNUSED_P(userData);
UNUSED_P(target);
UNUSED_P(data);
dummy_handler_flags |= DUMMY_PI_HANDLER_FLAG;
}
void XMLCALL
dummy_start_element(void *userData, const XML_Char *name,
const XML_Char **atts) {
UNUSED_P(userData);
UNUSED_P(name);
UNUSED_P(atts);
dummy_handler_flags |= DUMMY_START_ELEMENT_HANDLER_FLAG;
}
void XMLCALL
dummy_end_element(void *userData, const XML_Char *name) {
UNUSED_P(userData);
UNUSED_P(name);
}
void XMLCALL
dummy_start_cdata_handler(void *userData) {
UNUSED_P(userData);
dummy_handler_flags |= DUMMY_START_CDATA_HANDLER_FLAG;
}
void XMLCALL
dummy_end_cdata_handler(void *userData) {
UNUSED_P(userData);
dummy_handler_flags |= DUMMY_END_CDATA_HANDLER_FLAG;
}
void XMLCALL
dummy_cdata_handler(void *userData, const XML_Char *s, int len) {
UNUSED_P(userData);
UNUSED_P(s);
UNUSED_P(len);
}
void XMLCALL
dummy_start_namespace_decl_handler(void *userData, const XML_Char *prefix,
const XML_Char *uri) {
UNUSED_P(userData);
UNUSED_P(prefix);
UNUSED_P(uri);
dummy_handler_flags |= DUMMY_START_NS_DECL_HANDLER_FLAG;
}
void XMLCALL
dummy_end_namespace_decl_handler(void *userData, const XML_Char *prefix) {
UNUSED_P(userData);
UNUSED_P(prefix);
dummy_handler_flags |= DUMMY_END_NS_DECL_HANDLER_FLAG;
}
/* This handler is obsolete, but while the code exists we should
* ensure that dealing with the handler is covered by tests.
*/
void XMLCALL
dummy_unparsed_entity_decl_handler(void *userData, const XML_Char *entityName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId,
const XML_Char *notationName) {
UNUSED_P(userData);
UNUSED_P(entityName);
UNUSED_P(base);
UNUSED_P(systemId);
UNUSED_P(publicId);
UNUSED_P(notationName);
dummy_handler_flags |= DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG;
}
void XMLCALL
dummy_default_handler(void *userData, const XML_Char *s, int len) {
UNUSED_P(userData);
UNUSED_P(s);
UNUSED_P(len);
}
void XMLCALL
dummy_start_doctype_decl_handler(void *userData, const XML_Char *doctypeName,
const XML_Char *sysid, const XML_Char *pubid,
int has_internal_subset) {
UNUSED_P(userData);
UNUSED_P(doctypeName);
UNUSED_P(sysid);
UNUSED_P(pubid);
UNUSED_P(has_internal_subset);
dummy_handler_flags |= DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG;
}
void XMLCALL
dummy_end_doctype_decl_handler(void *userData) {
UNUSED_P(userData);
dummy_handler_flags |= DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG;
}
void XMLCALL
dummy_skip_handler(void *userData, const XML_Char *entityName,
int is_parameter_entity) {
UNUSED_P(userData);
UNUSED_P(entityName);
UNUSED_P(is_parameter_entity);
dummy_handler_flags |= DUMMY_SKIP_HANDLER_FLAG;
}

150
lib/libexpat/tests/dummy.h Normal file
View File

@ -0,0 +1,150 @@
/* Dummy handler functions for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.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.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_DUMMY_H
# define XML_DUMMY_H
# define DUMMY_START_DOCTYPE_HANDLER_FLAG (1UL << 0)
# define DUMMY_END_DOCTYPE_HANDLER_FLAG (1UL << 1)
# define DUMMY_ENTITY_DECL_HANDLER_FLAG (1UL << 2)
# define DUMMY_NOTATION_DECL_HANDLER_FLAG (1UL << 3)
# define DUMMY_ELEMENT_DECL_HANDLER_FLAG (1UL << 4)
# define DUMMY_ATTLIST_DECL_HANDLER_FLAG (1UL << 5)
# define DUMMY_COMMENT_HANDLER_FLAG (1UL << 6)
# define DUMMY_PI_HANDLER_FLAG (1UL << 7)
# define DUMMY_START_ELEMENT_HANDLER_FLAG (1UL << 8)
# define DUMMY_START_CDATA_HANDLER_FLAG (1UL << 9)
# define DUMMY_END_CDATA_HANDLER_FLAG (1UL << 10)
# define DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG (1UL << 11)
# define DUMMY_START_NS_DECL_HANDLER_FLAG (1UL << 12)
# define DUMMY_END_NS_DECL_HANDLER_FLAG (1UL << 13)
# define DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG (1UL << 14)
# define DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG (1UL << 15)
# define DUMMY_SKIP_HANDLER_FLAG (1UL << 16)
# define DUMMY_DEFAULT_HANDLER_FLAG (1UL << 17)
extern void init_dummy_handlers(void);
extern unsigned long get_dummy_handler_flags(void);
extern void XMLCALL dummy_xdecl_handler(void *userData, const XML_Char *version,
const XML_Char *encoding,
int standalone);
extern void XMLCALL dummy_start_doctype_handler(void *userData,
const XML_Char *doctypeName,
const XML_Char *sysid,
const XML_Char *pubid,
int has_internal_subset);
extern void XMLCALL dummy_end_doctype_handler(void *userData);
extern void XMLCALL dummy_entity_decl_handler(
void *userData, const XML_Char *entityName, int is_parameter_entity,
const XML_Char *value, int value_length, const XML_Char *base,
const XML_Char *systemId, const XML_Char *publicId,
const XML_Char *notationName);
extern void XMLCALL dummy_notation_decl_handler(void *userData,
const XML_Char *notationName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern void XMLCALL dummy_element_decl_handler(void *userData,
const XML_Char *name,
XML_Content *model);
extern void XMLCALL dummy_attlist_decl_handler(
void *userData, const XML_Char *elname, const XML_Char *attname,
const XML_Char *att_type, const XML_Char *dflt, int isrequired);
extern void XMLCALL dummy_comment_handler(void *userData, const XML_Char *data);
extern void XMLCALL dummy_pi_handler(void *userData, const XML_Char *target,
const XML_Char *data);
extern void XMLCALL dummy_start_element(void *userData, const XML_Char *name,
const XML_Char **atts);
extern void XMLCALL dummy_end_element(void *userData, const XML_Char *name);
extern void XMLCALL dummy_start_cdata_handler(void *userData);
extern void XMLCALL dummy_end_cdata_handler(void *userData);
extern void XMLCALL dummy_cdata_handler(void *userData, const XML_Char *s,
int len);
extern void XMLCALL dummy_start_namespace_decl_handler(void *userData,
const XML_Char *prefix,
const XML_Char *uri);
extern void XMLCALL dummy_end_namespace_decl_handler(void *userData,
const XML_Char *prefix);
extern void XMLCALL dummy_unparsed_entity_decl_handler(
void *userData, const XML_Char *entityName, const XML_Char *base,
const XML_Char *systemId, const XML_Char *publicId,
const XML_Char *notationName);
extern void XMLCALL dummy_default_handler(void *userData, const XML_Char *s,
int len);
extern void XMLCALL dummy_start_doctype_decl_handler(
void *userData, const XML_Char *doctypeName, const XML_Char *sysid,
const XML_Char *pubid, int has_internal_subset);
extern void XMLCALL dummy_end_doctype_decl_handler(void *userData);
extern void XMLCALL dummy_skip_handler(void *userData,
const XML_Char *entityName,
int is_parameter_entity);
#endif /* XML_DUMMY_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "dummy.c"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,595 @@
/* XML handler functions for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
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.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_HANDLERS_H
# define XML_HANDLERS_H
# include "expat_config.h"
# include "expat.h"
/* Variable holding the expected handler userData */
extern const void *g_handler_data;
/* Count of the number of times the comment handler has been invoked */
extern int g_comment_count;
/* Count of the number of skipped entities */
extern int g_skip_count;
/* Count of the number of times the XML declaration handler is invoked */
extern int g_xdecl_count;
/* Start/End Element Handlers */
extern void XMLCALL start_element_event_handler(void *userData,
const XML_Char *name,
const XML_Char **atts);
extern void XMLCALL end_element_event_handler(void *userData,
const XML_Char *name);
# define STRUCT_START_TAG 0
# define STRUCT_END_TAG 1
extern void XMLCALL start_element_event_handler2(void *userData,
const XML_Char *name,
const XML_Char **attr);
extern void XMLCALL end_element_event_handler2(void *userData,
const XML_Char *name);
typedef struct attrInfo {
const XML_Char *name;
const XML_Char *value;
} AttrInfo;
typedef struct elementInfo {
const XML_Char *name;
int attr_count;
const XML_Char *id_name;
AttrInfo *attributes;
} ElementInfo;
extern void XMLCALL counting_start_element_handler(void *userData,
const XML_Char *name,
const XML_Char **atts);
extern void XMLCALL suspending_end_handler(void *userData, const XML_Char *s);
extern void XMLCALL start_element_suspender(void *userData,
const XML_Char *name,
const XML_Char **atts);
extern int g_triplet_start_flag;
extern int g_triplet_end_flag;
extern void XMLCALL triplet_start_checker(void *userData, const XML_Char *name,
const XML_Char **atts);
extern void XMLCALL triplet_end_checker(void *userData, const XML_Char *name);
extern void XMLCALL overwrite_start_checker(void *userData,
const XML_Char *name,
const XML_Char **atts);
extern void XMLCALL overwrite_end_checker(void *userData, const XML_Char *name);
extern void XMLCALL start_element_fail(void *userData, const XML_Char *name,
const XML_Char **atts);
extern void XMLCALL start_ns_clearing_start_element(void *userData,
const XML_Char *prefix,
const XML_Char *uri);
typedef struct {
XML_Parser parser;
int deep;
} DataIssue240;
extern void XMLCALL start_element_issue_240(void *userData,
const XML_Char *name,
const XML_Char **atts);
extern void XMLCALL end_element_issue_240(void *userData, const XML_Char *name);
/* Text encoding handlers */
extern int XMLCALL UnknownEncodingHandler(void *data, const XML_Char *encoding,
XML_Encoding *info);
extern int XMLCALL UnrecognisedEncodingHandler(void *data,
const XML_Char *encoding,
XML_Encoding *info);
extern int XMLCALL unknown_released_encoding_handler(void *data,
const XML_Char *encoding,
XML_Encoding *info);
extern int XMLCALL MiscEncodingHandler(void *data, const XML_Char *encoding,
XML_Encoding *info);
extern int XMLCALL long_encoding_handler(void *userData,
const XML_Char *encoding,
XML_Encoding *info);
/* External Entity Handlers */
typedef struct ExtOption {
const XML_Char *system_id;
const char *parse_text;
} ExtOption;
extern int XMLCALL external_entity_optioner(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_loader(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
typedef struct ext_faults {
const char *parse_text;
const char *fail_text;
const XML_Char *encoding;
enum XML_Error error;
} ExtFaults;
extern int XMLCALL external_entity_faulter(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_failer__if_not_xml_ge(
XML_Parser parser, const XML_Char *context, const XML_Char *base,
const XML_Char *systemId, const XML_Char *publicId);
extern int XMLCALL external_entity_null_loader(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_resetter(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_suspender(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_suspend_xmldecl(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_suspending_faulter(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_cr_catcher(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_bad_cr_catcher(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_rsqb_catcher(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_good_cdata_ascii(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
/* Entity declaration handlers */
extern void XMLCALL entity_suspending_decl_handler(void *userData,
const XML_Char *name,
XML_Content *model);
extern void XMLCALL entity_suspending_xdecl_handler(void *userData,
const XML_Char *version,
const XML_Char *encoding,
int standalone);
extern int XMLCALL external_entity_param_checker(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_ref_param_checker(XML_Parser parameter,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_param(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_load_ignore(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_load_ignore_utf16(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_load_ignore_utf16_be(
XML_Parser parser, const XML_Char *context, const XML_Char *base,
const XML_Char *systemId, const XML_Char *publicId);
extern int XMLCALL external_entity_valuer(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_not_standalone(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_value_aborter(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_public(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_devaluer(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
typedef struct ext_hdlr_data {
const char *parse_text;
XML_ExternalEntityRefHandler handler;
} ExtHdlrData;
extern int XMLCALL external_entity_oneshot_loader(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
typedef struct ExtTest2 {
const char *parse_text;
int parse_len;
const XML_Char *encoding;
CharData *storage;
} ExtTest2;
extern int XMLCALL external_entity_loader2(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
typedef struct ExtFaults2 {
const char *parse_text;
int parse_len;
const char *fail_text;
const XML_Char *encoding;
enum XML_Error error;
} ExtFaults2;
extern int XMLCALL external_entity_faulter2(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_unfinished_attlist(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_handler(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_duff_loader(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_dbl_handler(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_dbl_handler_2(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_alloc_set_encoding(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_reallocator(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_alloc(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
extern int XMLCALL external_entity_parser_create_alloc_fail_handler(
XML_Parser parser, const XML_Char *context, const XML_Char *base,
const XML_Char *systemId, const XML_Char *publicId);
struct AccountingTestCase {
const char *primaryText;
const char *firstExternalText; /* often NULL */
const char *secondExternalText; /* often NULL */
const unsigned long long expectedCountBytesIndirectExtra;
};
extern int accounting_external_entity_ref_handler(XML_Parser parser,
const XML_Char *context,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
/* NotStandalone handlers */
extern int XMLCALL reject_not_standalone_handler(void *userData);
extern int XMLCALL accept_not_standalone_handler(void *userData);
/* Attribute List handlers */
typedef struct AttTest {
const char *definition;
const XML_Char *element_name;
const XML_Char *attr_name;
const XML_Char *attr_type;
const XML_Char *default_value;
int is_required;
} AttTest;
extern void XMLCALL verify_attlist_decl_handler(
void *userData, const XML_Char *element_name, const XML_Char *attr_name,
const XML_Char *attr_type, const XML_Char *default_value, int is_required);
/* Character data handlers */
extern void XMLCALL clearing_aborting_character_handler(void *userData,
const XML_Char *s,
int len);
extern void XMLCALL parser_stop_character_handler(void *userData,
const XML_Char *s, int len);
extern void XMLCALL cr_cdata_handler(void *userData, const XML_Char *s,
int len);
extern void XMLCALL rsqb_handler(void *userData, const XML_Char *s, int len);
typedef struct ByteTestData {
int start_element_len;
int cdata_len;
int total_string_len;
} ByteTestData;
extern void XMLCALL byte_character_handler(void *userData, const XML_Char *s,
int len);
extern void XMLCALL ext2_accumulate_characters(void *userData,
const XML_Char *s, int len);
/* Handlers that record their `len` arg and a single identifying character */
struct handler_record_entry {
const char *name;
int arg;
};
struct handler_record_list {
int count;
struct handler_record_entry entries[50]; // arbitrary big-enough max count
};
extern void XMLCALL record_default_handler(void *userData, const XML_Char *s,
int len);
extern void XMLCALL record_cdata_handler(void *userData, const XML_Char *s,
int len);
extern void XMLCALL record_cdata_nodefault_handler(void *userData,
const XML_Char *s, int len);
extern void XMLCALL record_skip_handler(void *userData,
const XML_Char *entityName,
int is_parameter_entity);
extern void XMLCALL record_element_start_handler(void *userData,
const XML_Char *name,
const XML_Char **atts);
extern void XMLCALL record_element_end_handler(void *userData,
const XML_Char *name);
extern const struct handler_record_entry *
_handler_record_get(const struct handler_record_list *storage, int index,
const char *file, int line);
# define handler_record_get(storage, index) \
_handler_record_get((storage), (index), __FILE__, __LINE__)
# define assert_record_handler_called(storage, index, expected_name, \
expected_arg) \
do { \
const struct handler_record_entry *e \
= handler_record_get(storage, index); \
assert_true(strcmp(e->name, expected_name) == 0); \
assert_true(e->arg == (expected_arg)); \
} while (0)
/* Entity Declaration Handlers */
# define ENTITY_MATCH_FAIL (-1)
# define ENTITY_MATCH_NOT_FOUND (0)
# define ENTITY_MATCH_SUCCESS (1)
extern void XMLCALL param_entity_match_handler(
void *userData, const XML_Char *entityName, int is_parameter_entity,
const XML_Char *value, int value_length, const XML_Char *base,
const XML_Char *systemId, const XML_Char *publicId,
const XML_Char *notationName);
extern void param_entity_match_init(const XML_Char *name,
const XML_Char *value);
extern int get_param_entity_match_flag(void);
/* Misc handlers */
extern void XMLCALL xml_decl_handler(void *userData, const XML_Char *version,
const XML_Char *encoding, int standalone);
extern void XMLCALL param_check_skip_handler(void *userData,
const XML_Char *entityName,
int is_parameter_entity);
extern void XMLCALL data_check_comment_handler(void *userData,
const XML_Char *data);
extern void XMLCALL selective_aborting_default_handler(void *userData,
const XML_Char *s,
int len);
extern void XMLCALL suspending_comment_handler(void *userData,
const XML_Char *data);
extern void XMLCALL element_decl_suspender(void *userData, const XML_Char *name,
XML_Content *model);
extern void XMLCALL accumulate_pi_characters(void *userData,
const XML_Char *target,
const XML_Char *data);
extern void XMLCALL accumulate_comment(void *userData, const XML_Char *data);
extern void XMLCALL accumulate_entity_decl(
void *userData, const XML_Char *entityName, int is_parameter_entity,
const XML_Char *value, int value_length, const XML_Char *base,
const XML_Char *systemId, const XML_Char *publicId,
const XML_Char *notationName);
extern void XMLCALL accumulate_char_data(void *userData, const XML_Char *s,
int len);
extern void XMLCALL accumulate_start_element(void *userData,
const XML_Char *name,
const XML_Char **atts);
typedef struct default_check {
const XML_Char *expected;
const int expectedLen;
XML_Bool seen;
} DefaultCheck;
void XMLCALL checking_default_handler(void *userData, const XML_Char *s,
int len);
typedef struct {
XML_Parser parser;
CharData *storage;
} ParserPlusStorage;
extern void XMLCALL
accumulate_and_suspend_comment_handler(void *userData, const XML_Char *data);
#endif /* XML_HANDLERS_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "handlers.c"

View File

@ -6,8 +6,9 @@
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -49,12 +50,13 @@ typedef struct allocation_entry {
static AllocationEntry *alloc_head = NULL;
static AllocationEntry *alloc_tail = NULL;
static AllocationEntry *find_allocation(void *ptr);
static AllocationEntry *find_allocation(const void *ptr);
/* Allocate some memory and keep track of it. */
void *
tracking_malloc(size_t size) {
AllocationEntry *entry = malloc(sizeof(AllocationEntry));
AllocationEntry *const entry
= (AllocationEntry *)malloc(sizeof(AllocationEntry));
if (entry == NULL) {
printf("Allocator failure\n");
@ -82,7 +84,7 @@ tracking_malloc(size_t size) {
}
static AllocationEntry *
find_allocation(void *ptr) {
find_allocation(const void *ptr) {
AllocationEntry *entry;
for (entry = alloc_head; entry != NULL; entry = entry->next) {
@ -140,7 +142,7 @@ tracking_realloc(void *ptr, size_t size) {
entry = find_allocation(ptr);
if (entry == NULL) {
printf("Attempting to realloc unallocated memory at %p\n", ptr);
entry = malloc(sizeof(AllocationEntry));
entry = (AllocationEntry *)malloc(sizeof(AllocationEntry));
if (entry == NULL) {
printf("Reallocator failure\n");
return NULL;
@ -162,12 +164,11 @@ tracking_realloc(void *ptr, size_t size) {
alloc_tail = entry;
}
} else {
entry->allocation = realloc(ptr, size);
if (entry->allocation == NULL) {
/* Realloc semantics say the original is still allocated */
entry->allocation = ptr;
void *const reallocated = realloc(ptr, size);
if (reallocated == NULL) {
return NULL;
}
entry->allocation = reallocated;
}
entry->num_bytes = size;

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "memcheck.c"

View File

@ -11,10 +11,11 @@
|_| XML parser
Copyright (c) 2004-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2016-2020 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -37,6 +38,11 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if defined(NDEBUG)
# undef NDEBUG /* because test suite relies on assert(...) at the moment */
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
@ -88,7 +94,8 @@ tcase_add_test(TCase *tc, tcase_test_function test) {
if (tc->allocated == tc->ntests) {
int nalloc = tc->allocated + 100;
size_t new_size = sizeof(tcase_test_function) * nalloc;
tcase_test_function *new_tests = realloc(tc->tests, new_size);
tcase_test_function *const new_tests
= (tcase_test_function *)realloc(tc->tests, new_size);
assert(new_tests != NULL);
tc->tests = new_tests;
tc->allocated = nalloc;
@ -123,7 +130,7 @@ suite_free(Suite *suite) {
SRunner *
srunner_create(Suite *suite) {
SRunner *runner = calloc(1, sizeof(SRunner));
SRunner *const runner = (SRunner *)calloc(1, sizeof(SRunner));
if (runner != NULL) {
runner->suite = suite;
}
@ -132,17 +139,35 @@ srunner_create(Suite *suite) {
static jmp_buf env;
#define SUBTEST_LEN (50) // informative, but not too long
static char const *_check_current_function = NULL;
static char _check_current_subtest[SUBTEST_LEN];
static int _check_current_lineno = -1;
static char const *_check_current_filename = NULL;
void
_check_set_test_info(char const *function, char const *filename, int lineno) {
_check_current_function = function;
set_subtest("%s", "");
_check_current_lineno = lineno;
_check_current_filename = filename;
}
void
set_subtest(char const *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vsnprintf(_check_current_subtest, SUBTEST_LEN, fmt, ap);
va_end(ap);
// replace line feeds with spaces, for nicer error logs
for (size_t i = 0; i < SUBTEST_LEN; ++i) {
if (_check_current_subtest[i] == '\n') {
_check_current_subtest[i] = ' ';
}
}
_check_current_subtest[SUBTEST_LEN - 1] = '\0'; // ensure termination
}
static void
handle_success(int verbosity) {
if (verbosity >= CK_VERBOSE) {
@ -151,16 +176,20 @@ handle_success(int verbosity) {
}
static void
handle_failure(SRunner *runner, int verbosity, const char *phase_info) {
handle_failure(SRunner *runner, int verbosity, const char *context,
const char *phase_info) {
runner->nfailures++;
if (verbosity != CK_SILENT) {
printf("FAIL: %s (%s at %s:%d)\n", _check_current_function, phase_info,
_check_current_filename, _check_current_lineno);
if (strlen(_check_current_subtest) != 0) {
phase_info = _check_current_subtest;
}
printf("FAIL [%s]: %s (%s at %s:%d)\n", context, _check_current_function,
phase_info, _check_current_filename, _check_current_lineno);
}
}
void
srunner_run_all(SRunner *runner, int verbosity) {
srunner_run_all(SRunner *runner, const char *context, int verbosity) {
Suite *suite;
TCase *volatile tc;
assert(runner != NULL);
@ -170,26 +199,28 @@ srunner_run_all(SRunner *runner, int verbosity) {
volatile int i;
for (i = 0; i < tc->ntests; ++i) {
runner->nchecks++;
set_subtest("%s", "");
if (tc->setup != NULL) {
/* setup */
if (setjmp(env)) {
handle_failure(runner, verbosity, "during setup");
handle_failure(runner, verbosity, context, "during setup");
continue;
}
tc->setup();
}
/* test */
if (setjmp(env)) {
handle_failure(runner, verbosity, "during actual test");
handle_failure(runner, verbosity, context, "during actual test");
continue;
}
(tc->tests[i])();
set_subtest("%s", "");
/* teardown */
if (tc->teardown != NULL) {
if (setjmp(env)) {
handle_failure(runner, verbosity, "during teardown");
handle_failure(runner, verbosity, context, "during teardown");
continue;
}
tc->teardown();
@ -199,6 +230,10 @@ srunner_run_all(SRunner *runner, int verbosity) {
}
tc = tc->next_tcase;
}
}
void
srunner_summarize(SRunner *runner, int verbosity) {
if (verbosity != CK_SILENT) {
int passed = runner->nchecks - runner->nfailures;
double percentage = ((double)passed) / runner->nchecks;
@ -209,12 +244,11 @@ srunner_run_all(SRunner *runner, int verbosity) {
}
void
_fail_unless(int condition, const char *file, int line, const char *msg) {
_fail(const char *file, int line, const char *msg) {
/* Always print the error message so it isn't lost. In this case,
we have a failure, so there's no reason to be quiet about what
it is.
*/
UNUSED_P(condition);
_check_current_filename = file;
_check_current_lineno = line;
if (msg != NULL) {

View File

@ -14,7 +14,9 @@
Copyright (c) 2004-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2006-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -41,30 +43,54 @@
extern "C" {
#endif
#define CK_NOFORK 0
#define CK_FORK 1
#ifndef XML_MINICHECK_H
# define XML_MINICHECK_H
#define CK_SILENT 0
#define CK_NORMAL 1
#define CK_VERBOSE 2
# define CK_NOFORK 0
# define CK_FORK 1
# define CK_SILENT 0
# define CK_NORMAL 1
# define CK_VERBOSE 2
/* Workaround for Microsoft's compiler and Tru64 Unix systems where the
C compiler has a working __func__, but the C++ compiler only has a
working __FUNCTION__. This could be fixed in configure.in, but it's
not worth it right now. */
#if defined(_MSC_VER) || (defined(__osf__) && defined(__cplusplus))
# define __func__ __FUNCTION__
#endif
# if defined(_MSC_VER) || (defined(__osf__) && defined(__cplusplus))
# define __func__ __FUNCTION__
# endif
#define START_TEST(testname) \
static void testname(void) { \
_check_set_test_info(__func__, __FILE__, __LINE__); \
{
#define END_TEST \
} \
}
/* PRINTF_LIKE has two effects:
1. Make clang's -Wformat-nonliteral stop warning about non-literal format
strings in annotated functions' code.
2. Make both clang and gcc's -Wformat-nonliteral warn about *callers* of
the annotated function that use a non-literal format string.
*/
# if defined(__GNUC__)
# define PRINTF_LIKE(fmtpos, argspos) \
__attribute__((format(printf, fmtpos, argspos)))
# else
# define PRINTF_LIKE(fmtpos, argspos)
# endif
#define fail(msg) _fail_unless(0, __FILE__, __LINE__, msg)
# define START_TEST(testname) \
static void testname(void) { \
_check_set_test_info(__func__, __FILE__, __LINE__); \
{
# define END_TEST \
} \
}
void PRINTF_LIKE(1, 2) set_subtest(char const *fmt, ...);
# define fail(msg) _fail(__FILE__, __LINE__, msg)
# define assert_true(cond) \
do { \
if (! (cond)) { \
_fail(__FILE__, __LINE__, "check failed: " #cond); \
} \
} while (0)
typedef void (*tcase_setup_function)(void);
typedef void (*tcase_teardown_function)(void);
@ -103,18 +129,25 @@ void _check_set_test_info(char const *function, char const *filename,
* Prototypes for the actual implementation.
*/
void _fail_unless(int condition, const char *file, int line, const char *msg);
# if defined(__GNUC__)
__attribute__((noreturn))
# endif
void
_fail(const char *file, int line, const char *msg);
Suite *suite_create(const char *name);
TCase *tcase_create(const char *name);
void suite_add_tcase(Suite *suite, TCase *tc);
void tcase_add_checked_fixture(TCase *, tcase_setup_function,
tcase_teardown_function);
void tcase_add_checked_fixture(TCase *tc, tcase_setup_function setup,
tcase_teardown_function teardown);
void tcase_add_test(TCase *tc, tcase_test_function test);
SRunner *srunner_create(Suite *suite);
void srunner_run_all(SRunner *runner, int verbosity);
void srunner_run_all(SRunner *runner, const char *context, int verbosity);
void srunner_summarize(SRunner *runner, int verbosity);
int srunner_ntests_failed(SRunner *runner);
void srunner_free(SRunner *runner);
#endif /* XML_MINICHECK_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "minicheck.c"

View File

@ -0,0 +1,523 @@
/* Tests in the "miscellaneous" test case for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
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.
*/
#if defined(NDEBUG)
# undef NDEBUG /* because test suite relies on assert(...) at the moment */
#endif
#include <assert.h>
#include <string.h>
#include "expat_config.h"
#include "expat.h"
#include "internal.h"
#include "minicheck.h"
#include "memcheck.h"
#include "common.h"
#include "ascii.h" /* for ASCII_xxx */
#include "handlers.h"
#include "misc_tests.h"
/* Test that a failure to allocate the parser structure fails gracefully */
START_TEST(test_misc_alloc_create_parser) {
XML_Memory_Handling_Suite memsuite = {duff_allocator, realloc, free};
unsigned int i;
const unsigned int max_alloc_count = 10;
/* Something this simple shouldn't need more than 10 allocations */
for (i = 0; i < max_alloc_count; i++) {
g_allocation_count = i;
g_parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
if (g_parser != NULL)
break;
}
if (i == 0)
fail("Parser unexpectedly ignored failing allocator");
else if (i == max_alloc_count)
fail("Parser not created with max allocation count");
}
END_TEST
/* Test memory allocation failures for a parser with an encoding */
START_TEST(test_misc_alloc_create_parser_with_encoding) {
XML_Memory_Handling_Suite memsuite = {duff_allocator, realloc, free};
unsigned int i;
const unsigned int max_alloc_count = 10;
/* Try several levels of allocation */
for (i = 0; i < max_alloc_count; i++) {
g_allocation_count = i;
g_parser = XML_ParserCreate_MM(XCS("us-ascii"), &memsuite, NULL);
if (g_parser != NULL)
break;
}
if (i == 0)
fail("Parser ignored failing allocator");
else if (i == max_alloc_count)
fail("Parser not created with max allocation count");
}
END_TEST
/* Test that freeing a NULL parser doesn't cause an explosion.
* (Not actually tested anywhere else)
*/
START_TEST(test_misc_null_parser) {
XML_ParserFree(NULL);
}
END_TEST
#if defined(__has_feature)
# if __has_feature(undefined_behavior_sanitizer)
# define EXPAT_TESTS_UBSAN 1
# else
# define EXPAT_TESTS_UBSAN 0
# endif
#else
# define EXPAT_TESTS_UBSAN 0
#endif
/* Test that XML_ErrorString rejects out-of-range codes */
START_TEST(test_misc_error_string) {
#if ! EXPAT_TESTS_UBSAN // because this would trigger UBSan
union {
enum XML_Error xml_error;
int integer;
} trickery;
assert_true(sizeof(enum XML_Error) == sizeof(int)); // self-test
trickery.integer = -1;
if (XML_ErrorString(trickery.xml_error) != NULL)
fail("Negative error code not rejected");
trickery.integer = 100;
if (XML_ErrorString(trickery.xml_error) != NULL)
fail("Large error code not rejected");
#endif
}
END_TEST
/* Test the version information is consistent */
/* Since we are working in XML_LChars (potentially 16-bits), we
* can't use the standard C library functions for character
* manipulation and have to roll our own.
*/
static int
parse_version(const XML_LChar *version_text,
XML_Expat_Version *version_struct) {
if (! version_text)
return XML_FALSE;
while (*version_text != 0x00) {
if (*version_text >= ASCII_0 && *version_text <= ASCII_9)
break;
version_text++;
}
if (*version_text == 0x00)
return XML_FALSE;
/* version_struct->major = strtoul(version_text, 10, &version_text) */
version_struct->major = 0;
while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
version_struct->major
= 10 * version_struct->major + (*version_text++ - ASCII_0);
}
if (*version_text++ != ASCII_PERIOD)
return XML_FALSE;
/* Now for the minor version number */
version_struct->minor = 0;
while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
version_struct->minor
= 10 * version_struct->minor + (*version_text++ - ASCII_0);
}
if (*version_text++ != ASCII_PERIOD)
return XML_FALSE;
/* Finally the micro version number */
version_struct->micro = 0;
while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
version_struct->micro
= 10 * version_struct->micro + (*version_text++ - ASCII_0);
}
if (*version_text != 0x00)
return XML_FALSE;
return XML_TRUE;
}
static int
versions_equal(const XML_Expat_Version *first,
const XML_Expat_Version *second) {
return (first->major == second->major && first->minor == second->minor
&& first->micro == second->micro);
}
START_TEST(test_misc_version) {
XML_Expat_Version read_version = XML_ExpatVersionInfo();
/* Silence compiler warning with the following assignment */
XML_Expat_Version parsed_version = {0, 0, 0};
const XML_LChar *version_text = XML_ExpatVersion();
if (version_text == NULL)
fail("Could not obtain version text");
assert(version_text != NULL);
if (! parse_version(version_text, &parsed_version))
fail("Unable to parse version text");
if (! versions_equal(&read_version, &parsed_version))
fail("Version mismatch");
if (xcstrcmp(version_text, XCS("expat_2.6.0"))) /* needs bump on releases */
fail("XML_*_VERSION in expat.h out of sync?\n");
}
END_TEST
/* Test feature information */
START_TEST(test_misc_features) {
const XML_Feature *features = XML_GetFeatureList();
/* Prevent problems with double-freeing parsers */
g_parser = NULL;
if (features == NULL) {
fail("Failed to get feature information");
} else {
/* Loop through the features checking what we can */
while (features->feature != XML_FEATURE_END) {
switch (features->feature) {
case XML_FEATURE_SIZEOF_XML_CHAR:
if (features->value != sizeof(XML_Char))
fail("Incorrect size of XML_Char");
break;
case XML_FEATURE_SIZEOF_XML_LCHAR:
if (features->value != sizeof(XML_LChar))
fail("Incorrect size of XML_LChar");
break;
default:
break;
}
features++;
}
}
}
END_TEST
/* Regression test for GitHub Issue #17: memory leak parsing attribute
* values with mixed bound and unbound namespaces.
*/
START_TEST(test_misc_attribute_leak) {
const char *text = "<D xmlns:L=\"D\" l:a='' L:a=''/>";
XML_Memory_Handling_Suite memsuite
= {tracking_malloc, tracking_realloc, tracking_free};
g_parser = XML_ParserCreate_MM(XCS("UTF-8"), &memsuite, XCS("\n"));
expect_failure(text, XML_ERROR_UNBOUND_PREFIX, "Unbound prefixes not found");
XML_ParserFree(g_parser);
/* Prevent the teardown trying to double free */
g_parser = NULL;
if (! tracking_report())
fail("Memory leak found");
}
END_TEST
/* Test parser created for UTF-16LE is successful */
START_TEST(test_misc_utf16le) {
const char text[] =
/* <?xml version='1.0'?><q>Hi</q> */
"<\0?\0x\0m\0l\0 \0"
"v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0?\0>\0"
"<\0q\0>\0H\0i\0<\0/\0q\0>\0";
const XML_Char *expected = XCS("Hi");
CharData storage;
g_parser = XML_ParserCreate(XCS("UTF-16LE"));
if (g_parser == NULL)
fail("Parser not created");
CharData_Init(&storage);
XML_SetUserData(g_parser, &storage);
XML_SetCharacterDataHandler(g_parser, accumulate_characters);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)sizeof(text) - 1, XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, expected);
}
END_TEST
START_TEST(test_misc_stop_during_end_handler_issue_240_1) {
XML_Parser parser;
DataIssue240 *mydata;
enum XML_Status result;
const char *const doc1 = "<doc><e1/><e><foo/></e></doc>";
parser = XML_ParserCreate(NULL);
XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
mydata->parser = parser;
mydata->deep = 0;
XML_SetUserData(parser, mydata);
result = _XML_Parse_SINGLE_BYTES(parser, doc1, (int)strlen(doc1), 1);
XML_ParserFree(parser);
free(mydata);
if (result != XML_STATUS_ERROR)
fail("Stopping the parser did not work as expected");
}
END_TEST
START_TEST(test_misc_stop_during_end_handler_issue_240_2) {
XML_Parser parser;
DataIssue240 *mydata;
enum XML_Status result;
const char *const doc2 = "<doc><elem/></doc>";
parser = XML_ParserCreate(NULL);
XML_SetElementHandler(parser, start_element_issue_240, end_element_issue_240);
mydata = (DataIssue240 *)malloc(sizeof(DataIssue240));
mydata->parser = parser;
mydata->deep = 0;
XML_SetUserData(parser, mydata);
result = _XML_Parse_SINGLE_BYTES(parser, doc2, (int)strlen(doc2), 1);
XML_ParserFree(parser);
free(mydata);
if (result != XML_STATUS_ERROR)
fail("Stopping the parser did not work as expected");
}
END_TEST
START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) {
const char *const inputOne = "<!DOCTYPE d [\n"
"<!ENTITY % e ']><d/>'>\n"
"\n"
"%e;";
const char *const inputTwo = "<!DOCTYPE d [\n"
"<!ENTITY % e1 ']><d/>'><!ENTITY % e2 '&e1;'>\n"
"\n"
"%e2;";
const char *const inputThree = "<!DOCTYPE d [\n"
"<!ENTITY % e ']><d'>\n"
"\n"
"%e;";
const char *const inputIssue317 = "<!DOCTYPE doc [\n"
"<!ENTITY % foo ']>\n"
"<doc>Hell<oc (#PCDATA)*>'>\n"
"%foo;\n"
"]>\n"
"<doc>Hello, world</dVc>";
const char *const inputs[] = {inputOne, inputTwo, inputThree, inputIssue317};
size_t inputIndex = 0;
for (; inputIndex < sizeof(inputs) / sizeof(inputs[0]); inputIndex++) {
set_subtest("%s", inputs[inputIndex]);
XML_Parser parser;
enum XML_Status parseResult;
int setParamEntityResult;
XML_Size lineNumber;
XML_Size columnNumber;
const char *const input = inputs[inputIndex];
parser = XML_ParserCreate(NULL);
setParamEntityResult
= XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
if (setParamEntityResult != 1)
fail("Failed to set XML_PARAM_ENTITY_PARSING_ALWAYS.");
parseResult = _XML_Parse_SINGLE_BYTES(parser, input, (int)strlen(input), 0);
if (parseResult != XML_STATUS_ERROR) {
parseResult = _XML_Parse_SINGLE_BYTES(parser, "", 0, 1);
if (parseResult != XML_STATUS_ERROR) {
fail("Parsing was expected to fail but succeeded.");
}
}
if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
fail("Error code does not match XML_ERROR_INVALID_TOKEN");
lineNumber = XML_GetCurrentLineNumber(parser);
if (lineNumber != 4)
fail("XML_GetCurrentLineNumber does not work as expected.");
columnNumber = XML_GetCurrentColumnNumber(parser);
if (columnNumber != 0)
fail("XML_GetCurrentColumnNumber does not work as expected.");
XML_ParserFree(parser);
}
}
END_TEST
START_TEST(test_misc_tag_mismatch_reset_leak) {
#ifdef XML_NS
const char *const text = "<open xmlns='https://namespace1.test'></close>";
XML_Parser parser = XML_ParserCreateNS(NULL, XCS('\n'));
if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
!= XML_STATUS_ERROR)
fail("Call to parse was expected to fail");
if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
fail("Call to parse was expected to fail from a closing tag mismatch");
XML_ParserReset(parser, NULL);
if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE)
!= XML_STATUS_ERROR)
fail("Call to parse was expected to fail");
if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
fail("Call to parse was expected to fail from a closing tag mismatch");
XML_ParserFree(parser);
#endif
}
END_TEST
START_TEST(test_misc_create_external_entity_parser_with_null_context) {
// With XML_DTD undefined, the only supported case of external entities
// is pattern "<!ENTITY entity123 SYSTEM 'filename123'>". A NULL context
// was causing a segfault through a null pointer dereference in function
// setContext, previously.
XML_Parser parser = XML_ParserCreate(NULL);
XML_Parser ext_parser = XML_ExternalEntityParserCreate(parser, NULL, NULL);
#ifdef XML_DTD
assert_true(ext_parser != NULL);
XML_ParserFree(ext_parser);
#else
assert_true(ext_parser == NULL);
#endif /* XML_DTD */
XML_ParserFree(parser);
}
END_TEST
START_TEST(test_misc_general_entities_support) {
const char *const doc
= "<!DOCTYPE r [\n"
"<!ENTITY e1 'v1'>\n"
"<!ENTITY e2 SYSTEM 'v2'>\n"
"]>\n"
"<r a1='[&e1;]'>[&e1;][&e2;][&amp;&apos;&gt;&lt;&quot;]</r>";
CharData storage;
CharData_Init(&storage);
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, &storage);
XML_SetStartElementHandler(parser, accumulate_start_element);
XML_SetExternalEntityRefHandler(parser,
external_entity_failer__if_not_xml_ge);
XML_SetEntityDeclHandler(parser, accumulate_entity_decl);
XML_SetCharacterDataHandler(parser, accumulate_char_data);
if (_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), XML_TRUE)
!= XML_STATUS_OK) {
xml_failure(parser);
}
XML_ParserFree(parser);
CharData_CheckXMLChars(&storage,
/* clang-format off */
#if XML_GE == 1
XCS("e1=v1\n")
XCS("e2=(null)\n")
XCS("(r(a1=[v1]))\n")
XCS("[v1][][&'><\"]")
#else
XCS("e1=&amp;e1;\n")
XCS("e2=(null)\n")
XCS("(r(a1=[&e1;]))\n")
XCS("[&e1;][&e2;][&'><\"]")
#endif
);
/* clang-format on */
}
END_TEST
static void XMLCALL
resumable_stopping_character_handler(void *userData, const XML_Char *s,
int len) {
UNUSED_P(s);
UNUSED_P(len);
XML_Parser parser = (XML_Parser)userData;
XML_StopParser(parser, XML_TRUE);
}
// NOTE: This test needs active LeakSanitizer to be of actual use
START_TEST(test_misc_char_handler_stop_without_leak) {
const char *const data
= "<!DOCTYPE t1[<!ENTITY e1 'angle<'><!ENTITY e2 '&e1;'>]><t1>&e2;";
XML_Parser parser = XML_ParserCreate(NULL);
assert_true(parser != NULL);
XML_SetUserData(parser, parser);
XML_SetCharacterDataHandler(parser, resumable_stopping_character_handler);
_XML_Parse_SINGLE_BYTES(parser, data, (int)strlen(data), XML_FALSE);
XML_ParserFree(parser);
}
END_TEST
void
make_miscellaneous_test_case(Suite *s) {
TCase *tc_misc = tcase_create("miscellaneous tests");
suite_add_tcase(s, tc_misc);
tcase_add_checked_fixture(tc_misc, NULL, basic_teardown);
tcase_add_test(tc_misc, test_misc_alloc_create_parser);
tcase_add_test(tc_misc, test_misc_alloc_create_parser_with_encoding);
tcase_add_test(tc_misc, test_misc_null_parser);
tcase_add_test(tc_misc, test_misc_error_string);
tcase_add_test(tc_misc, test_misc_version);
tcase_add_test(tc_misc, test_misc_features);
tcase_add_test(tc_misc, test_misc_attribute_leak);
tcase_add_test(tc_misc, test_misc_utf16le);
tcase_add_test(tc_misc, test_misc_stop_during_end_handler_issue_240_1);
tcase_add_test(tc_misc, test_misc_stop_during_end_handler_issue_240_2);
tcase_add_test__ifdef_xml_dtd(
tc_misc, test_misc_deny_internal_entity_closing_doctype_issue_317);
tcase_add_test(tc_misc, test_misc_tag_mismatch_reset_leak);
tcase_add_test(tc_misc,
test_misc_create_external_entity_parser_with_null_context);
tcase_add_test(tc_misc, test_misc_general_entities_support);
tcase_add_test(tc_misc, test_misc_char_handler_stop_without_leak);
}

View File

@ -0,0 +1,56 @@
/* Tests in the "miscellaneous" test case for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.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.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_MISC_TESTS_H
# define XML_MISC_TESTS_H
extern void make_miscellaneous_test_case(Suite *s);
#endif /* XML_MISC_TESTS_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "misc_tests.c"

View File

@ -0,0 +1,754 @@
/* Tests in the "namespace" test case for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.org>
Copyright (c) 2023 Sony Corporation / Snild Dolkow <snild@sony.com>
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.
*/
#include "expat_config.h"
#include <string.h>
#include "expat.h"
#include "internal.h"
#include "minicheck.h"
#include "common.h"
#include "dummy.h"
#include "handlers.h"
#include "ns_tests.h"
static void
namespace_setup(void) {
g_parser = XML_ParserCreateNS(NULL, XCS(' '));
if (g_parser == NULL)
fail("Parser not created.");
}
static void
namespace_teardown(void) {
basic_teardown();
}
START_TEST(test_return_ns_triplet) {
const char *text = "<foo:e xmlns:foo='http://example.org/' bar:a='12'\n"
" xmlns:bar='http://example.org/'>";
const char *epilog = "</foo:e>";
const XML_Char *elemstr[]
= {XCS("http://example.org/ e foo"), XCS("http://example.org/ a bar")};
XML_SetReturnNSTriplet(g_parser, XML_TRUE);
XML_SetUserData(g_parser, (void *)elemstr);
XML_SetElementHandler(g_parser, triplet_start_checker, triplet_end_checker);
XML_SetNamespaceDeclHandler(g_parser, dummy_start_namespace_decl_handler,
dummy_end_namespace_decl_handler);
g_triplet_start_flag = XML_FALSE;
g_triplet_end_flag = XML_FALSE;
init_dummy_handlers();
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_FALSE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
/* Check that unsetting "return triplets" fails while still parsing */
XML_SetReturnNSTriplet(g_parser, XML_FALSE);
if (_XML_Parse_SINGLE_BYTES(g_parser, epilog, (int)strlen(epilog), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
if (! g_triplet_start_flag)
fail("triplet_start_checker not invoked");
if (! g_triplet_end_flag)
fail("triplet_end_checker not invoked");
if (get_dummy_handler_flags()
!= (DUMMY_START_NS_DECL_HANDLER_FLAG | DUMMY_END_NS_DECL_HANDLER_FLAG))
fail("Namespace handlers not called");
}
END_TEST
/* Test that the parsing status is correctly reset by XML_ParserReset().
* We use test_return_ns_triplet() for our example parse to improve
* coverage of tidying up code executed.
*/
START_TEST(test_ns_parser_reset) {
XML_ParsingStatus status;
XML_GetParsingStatus(g_parser, &status);
if (status.parsing != XML_INITIALIZED)
fail("parsing status doesn't start INITIALIZED");
test_return_ns_triplet();
XML_GetParsingStatus(g_parser, &status);
if (status.parsing != XML_FINISHED)
fail("parsing status doesn't end FINISHED");
XML_ParserReset(g_parser, NULL);
XML_GetParsingStatus(g_parser, &status);
if (status.parsing != XML_INITIALIZED)
fail("parsing status doesn't reset to INITIALIZED");
}
END_TEST
static void
run_ns_tagname_overwrite_test(const char *text, const XML_Char *result) {
CharData storage;
CharData_Init(&storage);
XML_SetUserData(g_parser, &storage);
XML_SetElementHandler(g_parser, overwrite_start_checker,
overwrite_end_checker);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, result);
}
/* Regression test for SF bug #566334. */
START_TEST(test_ns_tagname_overwrite) {
const char *text = "<n:e xmlns:n='http://example.org/'>\n"
" <n:f n:attr='foo'/>\n"
" <n:g n:attr2='bar'/>\n"
"</n:e>";
const XML_Char *result = XCS("start http://example.org/ e\n")
XCS("start http://example.org/ f\n")
XCS("attribute http://example.org/ attr\n")
XCS("end http://example.org/ f\n")
XCS("start http://example.org/ g\n")
XCS("attribute http://example.org/ attr2\n")
XCS("end http://example.org/ g\n")
XCS("end http://example.org/ e\n");
run_ns_tagname_overwrite_test(text, result);
}
END_TEST
/* Regression test for SF bug #566334. */
START_TEST(test_ns_tagname_overwrite_triplet) {
const char *text = "<n:e xmlns:n='http://example.org/'>\n"
" <n:f n:attr='foo'/>\n"
" <n:g n:attr2='bar'/>\n"
"</n:e>";
const XML_Char *result = XCS("start http://example.org/ e n\n")
XCS("start http://example.org/ f n\n")
XCS("attribute http://example.org/ attr n\n")
XCS("end http://example.org/ f n\n")
XCS("start http://example.org/ g n\n")
XCS("attribute http://example.org/ attr2 n\n")
XCS("end http://example.org/ g n\n")
XCS("end http://example.org/ e n\n");
XML_SetReturnNSTriplet(g_parser, XML_TRUE);
run_ns_tagname_overwrite_test(text, result);
}
END_TEST
/* Regression test for SF bug #620343. */
START_TEST(test_start_ns_clears_start_element) {
/* This needs to use separate start/end tags; using the empty tag
syntax doesn't cause the problematic path through Expat to be
taken.
*/
const char *text = "<e xmlns='http://example.org/'></e>";
XML_SetStartElementHandler(g_parser, start_element_fail);
XML_SetStartNamespaceDeclHandler(g_parser, start_ns_clearing_start_element);
XML_SetEndNamespaceDeclHandler(g_parser, dummy_end_namespace_decl_handler);
XML_UseParserAsHandlerArg(g_parser);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Regression test for SF bug #616863. */
START_TEST(test_default_ns_from_ext_subset_and_ext_ge) {
const char *text = "<?xml version='1.0'?>\n"
"<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
" <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
"]>\n"
"<doc xmlns='http://example.org/ns1'>\n"
"&en;\n"
"</doc>";
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
XML_SetExternalEntityRefHandler(g_parser, external_entity_handler);
/* We actually need to set this handler to tickle this bug. */
XML_SetStartElementHandler(g_parser, dummy_start_element);
XML_SetUserData(g_parser, NULL);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Regression test #1 for SF bug #673791. */
START_TEST(test_ns_prefix_with_empty_uri_1) {
const char *text = "<doc xmlns:prefix='http://example.org/'>\n"
" <e xmlns:prefix=''/>\n"
"</doc>";
expect_failure(text, XML_ERROR_UNDECLARING_PREFIX,
"Did not report re-setting namespace"
" URI with prefix to ''.");
}
END_TEST
/* Regression test #2 for SF bug #673791. */
START_TEST(test_ns_prefix_with_empty_uri_2) {
const char *text = "<?xml version='1.0'?>\n"
"<docelem xmlns:pre=''/>";
expect_failure(text, XML_ERROR_UNDECLARING_PREFIX,
"Did not report setting namespace URI with prefix to ''.");
}
END_TEST
/* Regression test #3 for SF bug #673791. */
START_TEST(test_ns_prefix_with_empty_uri_3) {
const char *text = "<!DOCTYPE doc [\n"
" <!ELEMENT doc EMPTY>\n"
" <!ATTLIST doc\n"
" xmlns:prefix CDATA ''>\n"
"]>\n"
"<doc/>";
expect_failure(text, XML_ERROR_UNDECLARING_PREFIX,
"Didn't report attr default setting NS w/ prefix to ''.");
}
END_TEST
/* Regression test #4 for SF bug #673791. */
START_TEST(test_ns_prefix_with_empty_uri_4) {
const char *text = "<!DOCTYPE doc [\n"
" <!ELEMENT prefix:doc EMPTY>\n"
" <!ATTLIST prefix:doc\n"
" xmlns:prefix CDATA 'http://example.org/'>\n"
"]>\n"
"<prefix:doc/>";
/* Packaged info expected by the end element handler;
the weird structuring lets us reuse the triplet_end_checker()
function also used for another test. */
const XML_Char *elemstr[] = {XCS("http://example.org/ doc prefix")};
XML_SetReturnNSTriplet(g_parser, XML_TRUE);
XML_SetUserData(g_parser, (void *)elemstr);
XML_SetEndElementHandler(g_parser, triplet_end_checker);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Test with non-xmlns prefix */
START_TEST(test_ns_unbound_prefix) {
const char *text = "<!DOCTYPE doc [\n"
" <!ELEMENT prefix:doc EMPTY>\n"
" <!ATTLIST prefix:doc\n"
" notxmlns:prefix CDATA 'http://example.org/'>\n"
"]>\n"
"<prefix:doc/>";
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
!= XML_STATUS_ERROR)
fail("Unbound prefix incorrectly passed");
if (XML_GetErrorCode(g_parser) != XML_ERROR_UNBOUND_PREFIX)
xml_failure(g_parser);
}
END_TEST
START_TEST(test_ns_default_with_empty_uri) {
const char *text = "<doc xmlns='http://example.org/'>\n"
" <e xmlns=''/>\n"
"</doc>";
/* Add some handlers to exercise extra code paths */
XML_SetStartNamespaceDeclHandler(g_parser,
dummy_start_namespace_decl_handler);
XML_SetEndNamespaceDeclHandler(g_parser, dummy_end_namespace_decl_handler);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Regression test for SF bug #692964: two prefixes for one namespace. */
START_TEST(test_ns_duplicate_attrs_diff_prefixes) {
const char *text = "<doc xmlns:a='http://example.org/a'\n"
" xmlns:b='http://example.org/a'\n"
" a:a='v' b:a='v' />";
expect_failure(text, XML_ERROR_DUPLICATE_ATTRIBUTE,
"did not report multiple attributes with same URI+name");
}
END_TEST
START_TEST(test_ns_duplicate_hashes) {
/* The hash of an attribute is calculated as the hash of its URI
* concatenated with a space followed by its name (after the
* colon). We wish to generate attributes with the same hash
* value modulo the attribute table size so that we can check that
* the attribute hash table works correctly. The attribute hash
* table size will be the smallest power of two greater than the
* number of attributes, but at least eight. There is
* unfortunately no programmatic way of getting the hash or the
* table size at user level, but the test code coverage percentage
* will drop if the hashes cease to point to the same row.
*
* The cunning plan is to have few enough attributes to have a
* reliable table size of 8, and have the single letter attribute
* names be 8 characters apart, producing a hash which will be the
* same modulo 8.
*/
const char *text = "<doc xmlns:a='http://example.org/a'\n"
" a:a='v' a:i='w' />";
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Regression test for SF bug #695401: unbound prefix. */
START_TEST(test_ns_unbound_prefix_on_attribute) {
const char *text = "<doc a:attr=''/>";
expect_failure(text, XML_ERROR_UNBOUND_PREFIX,
"did not report unbound prefix on attribute");
}
END_TEST
/* Regression test for SF bug #695401: unbound prefix. */
START_TEST(test_ns_unbound_prefix_on_element) {
const char *text = "<a:doc/>";
expect_failure(text, XML_ERROR_UNBOUND_PREFIX,
"did not report unbound prefix on element");
}
END_TEST
/* Test that long element names with namespaces are handled correctly */
START_TEST(test_ns_long_element) {
const char *text
= "<foo:thisisalongenoughelementnametotriggerareallocation\n"
" xmlns:foo='http://example.org/' bar:a='12'\n"
" xmlns:bar='http://example.org/'>"
"</foo:thisisalongenoughelementnametotriggerareallocation>";
const XML_Char *elemstr[]
= {XCS("http://example.org/")
XCS(" thisisalongenoughelementnametotriggerareallocation foo"),
XCS("http://example.org/ a bar")};
XML_SetReturnNSTriplet(g_parser, XML_TRUE);
XML_SetUserData(g_parser, (void *)elemstr);
XML_SetElementHandler(g_parser, triplet_start_checker, triplet_end_checker);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Test mixed population of prefixed and unprefixed attributes */
START_TEST(test_ns_mixed_prefix_atts) {
const char *text = "<e a='12' bar:b='13'\n"
" xmlns:bar='http://example.org/'>"
"</e>";
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Test having a long namespaced element name inside a short one.
* This exercises some internal buffer reallocation that is shared
* across elements with the same namespace URI.
*/
START_TEST(test_ns_extend_uri_buffer) {
const char *text = "<foo:e xmlns:foo='http://example.org/'>"
" <foo:thisisalongenoughnametotriggerallocationaction"
" foo:a='12' />"
"</foo:e>";
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Test that xmlns is correctly rejected as an attribute in the xmlns
* namespace, but not in other namespaces
*/
START_TEST(test_ns_reserved_attributes) {
const char *text1
= "<foo:e xmlns:foo='http://example.org/' xmlns:xmlns='12' />";
const char *text2
= "<foo:e xmlns:foo='http://example.org/' foo:xmlns='12' />";
expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XMLNS,
"xmlns not rejected as an attribute");
XML_ParserReset(g_parser, NULL);
if (_XML_Parse_SINGLE_BYTES(g_parser, text2, (int)strlen(text2), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Test more reserved attributes */
START_TEST(test_ns_reserved_attributes_2) {
const char *text1 = "<foo:e xmlns:foo='http://example.org/'"
" xmlns:xml='http://example.org/' />";
const char *text2
= "<foo:e xmlns:foo='http://www.w3.org/XML/1998/namespace' />";
const char *text3 = "<foo:e xmlns:foo='http://www.w3.org/2000/xmlns/' />";
expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XML,
"xml not rejected as an attribute");
XML_ParserReset(g_parser, NULL);
expect_failure(text2, XML_ERROR_RESERVED_NAMESPACE_URI,
"Use of w3.org URL not faulted");
XML_ParserReset(g_parser, NULL);
expect_failure(text3, XML_ERROR_RESERVED_NAMESPACE_URI,
"Use of w3.org xmlns URL not faulted");
}
END_TEST
/* Test string pool handling of namespace names of 2048 characters */
/* Exercises a particular string pool growth path */
START_TEST(test_ns_extremely_long_prefix) {
/* C99 compilers are only required to support 4095-character
* strings, so the following needs to be split in two to be safe
* for all compilers.
*/
const char *text1
= "<doc "
/* 64 character on each line */
/* ...gives a total length of 2048 */
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
":a='12'";
const char *text2
= " xmlns:"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
"='foo'\n>"
"</doc>";
if (_XML_Parse_SINGLE_BYTES(g_parser, text1, (int)strlen(text1), XML_FALSE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
if (_XML_Parse_SINGLE_BYTES(g_parser, text2, (int)strlen(text2), XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
}
END_TEST
/* Test unknown encoding handlers in namespace setup */
START_TEST(test_ns_unknown_encoding_success) {
const char *text = "<?xml version='1.0' encoding='prefix-conv'?>\n"
"<foo:e xmlns:foo='http://example.org/'>Hi</foo:e>";
XML_SetUnknownEncodingHandler(g_parser, MiscEncodingHandler, NULL);
run_character_check(text, XCS("Hi"));
}
END_TEST
/* Test that too many colons are rejected */
START_TEST(test_ns_double_colon) {
const char *text = "<foo:e xmlns:foo='http://example.org/' foo:a:b='bar' />";
const enum XML_Status status
= _XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE);
#ifdef XML_NS
if ((status == XML_STATUS_OK)
|| (XML_GetErrorCode(g_parser) != XML_ERROR_INVALID_TOKEN)) {
fail("Double colon in attribute name not faulted"
" (despite active namespace support)");
}
#else
if (status != XML_STATUS_OK) {
fail("Double colon in attribute name faulted"
" (despite inactive namespace support");
}
#endif
}
END_TEST
START_TEST(test_ns_double_colon_element) {
const char *text = "<foo:bar:e xmlns:foo='http://example.org/' />";
const enum XML_Status status
= _XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE);
#ifdef XML_NS
if ((status == XML_STATUS_OK)
|| (XML_GetErrorCode(g_parser) != XML_ERROR_INVALID_TOKEN)) {
fail("Double colon in element name not faulted"
" (despite active namespace support)");
}
#else
if (status != XML_STATUS_OK) {
fail("Double colon in element name faulted"
" (despite inactive namespace support");
}
#endif
}
END_TEST
/* Test that non-name characters after a colon are rejected */
START_TEST(test_ns_bad_attr_leafname) {
const char *text = "<foo:e xmlns:foo='http://example.org/' foo:?ar='baz' />";
expect_failure(text, XML_ERROR_INVALID_TOKEN,
"Invalid character in leafname not faulted");
}
END_TEST
START_TEST(test_ns_bad_element_leafname) {
const char *text = "<foo:?oc xmlns:foo='http://example.org/' />";
expect_failure(text, XML_ERROR_INVALID_TOKEN,
"Invalid character in element leafname not faulted");
}
END_TEST
/* Test high-byte-set UTF-16 characters are valid in a leafname */
START_TEST(test_ns_utf16_leafname) {
const char text[] =
/* <n:e xmlns:n='URI' n:{KHO KHWAI}='a' />
* where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
*/
"<\0n\0:\0e\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0 \0"
"n\0:\0\x04\x0e=\0'\0a\0'\0 \0/\0>\0";
const XML_Char *expected = XCS("a");
CharData storage;
CharData_Init(&storage);
XML_SetStartElementHandler(g_parser, accumulate_attribute);
XML_SetUserData(g_parser, &storage);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)sizeof(text) - 1, XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, expected);
}
END_TEST
START_TEST(test_ns_utf16_element_leafname) {
const char text[] =
/* <n:{KHO KHWAI} xmlns:n='URI'/>
* where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
*/
"\0<\0n\0:\x0e\x04\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0/\0>";
#ifdef XML_UNICODE
const XML_Char *expected = XCS("URI \x0e04");
#else
const XML_Char *expected = XCS("URI \xe0\xb8\x84");
#endif
CharData storage;
CharData_Init(&storage);
XML_SetStartElementHandler(g_parser, start_element_event_handler);
XML_SetUserData(g_parser, &storage);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)sizeof(text) - 1, XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, expected);
}
END_TEST
START_TEST(test_ns_utf16_doctype) {
const char text[] =
/* <!DOCTYPE foo:{KHO KHWAI} [ <!ENTITY bar 'baz'> ]>\n
* where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
*/
"\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0f\0o\0o\0:\x0e\x04\0 "
"\0[\0 \0<\0!\0E\0N\0T\0I\0T\0Y\0 \0b\0a\0r\0 \0'\0b\0a\0z\0'\0>\0 "
"\0]\0>\0\n"
/* <foo:{KHO KHWAI} xmlns:foo='URI'>&bar;</foo:{KHO KHWAI}> */
"\0<\0f\0o\0o\0:\x0e\x04\0 "
"\0x\0m\0l\0n\0s\0:\0f\0o\0o\0=\0'\0U\0R\0I\0'\0>"
"\0&\0b\0a\0r\0;"
"\0<\0/\0f\0o\0o\0:\x0e\x04\0>";
#ifdef XML_UNICODE
const XML_Char *expected = XCS("URI \x0e04");
#else
const XML_Char *expected = XCS("URI \xe0\xb8\x84");
#endif
CharData storage;
CharData_Init(&storage);
XML_SetUserData(g_parser, &storage);
XML_SetStartElementHandler(g_parser, start_element_event_handler);
XML_SetUnknownEncodingHandler(g_parser, MiscEncodingHandler, NULL);
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)sizeof(text) - 1, XML_TRUE)
== XML_STATUS_ERROR)
xml_failure(g_parser);
CharData_CheckXMLChars(&storage, expected);
}
END_TEST
START_TEST(test_ns_invalid_doctype) {
const char *text = "<!DOCTYPE foo:!bad [ <!ENTITY bar 'baz' ]>\n"
"<foo:!bad>&bar;</foo:!bad>";
expect_failure(text, XML_ERROR_INVALID_TOKEN,
"Invalid character in document local name not faulted");
}
END_TEST
START_TEST(test_ns_double_colon_doctype) {
const char *text = "<!DOCTYPE foo:a:doc [ <!ENTITY bar 'baz' ]>\n"
"<foo:a:doc>&bar;</foo:a:doc>";
expect_failure(text, XML_ERROR_SYNTAX,
"Double colon in document name not faulted");
}
END_TEST
START_TEST(test_ns_separator_in_uri) {
struct test_case {
enum XML_Status expectedStatus;
const char *doc;
XML_Char namesep;
};
struct test_case cases[] = {
{XML_STATUS_OK, "<doc xmlns='one_two' />", XCS('\n')},
{XML_STATUS_ERROR, "<doc xmlns='one&#x0A;two' />", XCS('\n')},
{XML_STATUS_OK, "<doc xmlns='one:two' />", XCS(':')},
};
size_t i = 0;
size_t failCount = 0;
for (; i < sizeof(cases) / sizeof(cases[0]); i++) {
set_subtest("%s", cases[i].doc);
XML_Parser parser = XML_ParserCreateNS(NULL, cases[i].namesep);
XML_SetElementHandler(parser, dummy_start_element, dummy_end_element);
if (_XML_Parse_SINGLE_BYTES(parser, cases[i].doc, (int)strlen(cases[i].doc),
/*isFinal*/ XML_TRUE)
!= cases[i].expectedStatus) {
failCount++;
}
XML_ParserFree(parser);
}
if (failCount) {
fail("Namespace separator handling is broken");
}
}
END_TEST
void
make_namespace_test_case(Suite *s) {
TCase *tc_namespace = tcase_create("XML namespaces");
suite_add_tcase(s, tc_namespace);
tcase_add_checked_fixture(tc_namespace, namespace_setup, namespace_teardown);
tcase_add_test(tc_namespace, test_return_ns_triplet);
tcase_add_test(tc_namespace, test_ns_parser_reset);
tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
tcase_add_test__ifdef_xml_dtd(tc_namespace,
test_default_ns_from_ext_subset_and_ext_ge);
tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
tcase_add_test(tc_namespace, test_ns_unbound_prefix);
tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
tcase_add_test(tc_namespace, test_ns_duplicate_hashes);
tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
tcase_add_test(tc_namespace, test_ns_long_element);
tcase_add_test(tc_namespace, test_ns_mixed_prefix_atts);
tcase_add_test(tc_namespace, test_ns_extend_uri_buffer);
tcase_add_test(tc_namespace, test_ns_reserved_attributes);
tcase_add_test(tc_namespace, test_ns_reserved_attributes_2);
tcase_add_test(tc_namespace, test_ns_extremely_long_prefix);
tcase_add_test(tc_namespace, test_ns_unknown_encoding_success);
tcase_add_test(tc_namespace, test_ns_double_colon);
tcase_add_test(tc_namespace, test_ns_double_colon_element);
tcase_add_test(tc_namespace, test_ns_bad_attr_leafname);
tcase_add_test(tc_namespace, test_ns_bad_element_leafname);
tcase_add_test(tc_namespace, test_ns_utf16_leafname);
tcase_add_test(tc_namespace, test_ns_utf16_element_leafname);
tcase_add_test__if_xml_ge(tc_namespace, test_ns_utf16_doctype);
tcase_add_test(tc_namespace, test_ns_invalid_doctype);
tcase_add_test(tc_namespace, test_ns_double_colon_doctype);
tcase_add_test(tc_namespace, test_ns_separator_in_uri);
}

View File

@ -0,0 +1,56 @@
/* Tests in the "namespace" test case for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.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.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_NS_TESTS_H
# define XML_NS_TESTS_H
extern void make_namespace_test_case(Suite *s);
#endif /* XML_NS_TESTS_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "ns_tests.c"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
/* Tests in the "namespace allocation" test case for the Expat test suite
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2020 Tim Gates <tim.gates@iress.com>
Copyright (c) 2021 Donghee Na <donghee.na@python.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.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XML_NSALLOC_TESTS_H
# define XML_NSALLOC_TESTS_H
extern void make_nsalloc_test_case(Suite *s);
#endif /* XML_NSALLOC_TESTS_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "nsalloc_tests.c"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
/* C++ compilation harness for the test suite.
This is used to ensure the Expat headers can be included from C++
and have everything work as expected.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2005 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2017-2023 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.
*/
#include "runtests.c"

View File

@ -7,7 +7,8 @@
|_| XML parser
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
@ -30,6 +31,10 @@
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if defined(NDEBUG)
# undef NDEBUG /* because test suite relies on assert(...) at the moment */
#endif
#include "expat_config.h"
#include <assert.h>
@ -56,7 +61,7 @@
static XML_Char *
xmlstrdup(const XML_Char *s) {
size_t byte_count = (xcstrlen(s) + 1) * sizeof(XML_Char);
XML_Char *dup = malloc(byte_count);
XML_Char *const dup = (XML_Char *)malloc(byte_count);
assert(dup != NULL);
memcpy(dup, s, byte_count);
@ -79,13 +84,13 @@ StructData_AddItem(StructData *storage, const XML_Char *s, int data0, int data1,
assert(storage != NULL);
assert(s != NULL);
if (storage->count == storage->max_count) {
StructDataEntry *new;
StructDataEntry *new_entries;
storage->max_count += STRUCT_EXTENSION_COUNT;
new = realloc(storage->entries,
storage->max_count * sizeof(StructDataEntry));
assert(new != NULL);
storage->entries = new;
new_entries = (StructDataEntry *)realloc(
storage->entries, storage->max_count * sizeof(StructDataEntry));
assert(new_entries != NULL);
storage->entries = new_entries;
}
entry = &storage->entries[storage->count];
@ -103,17 +108,17 @@ void
StructData_CheckItems(StructData *storage, const StructDataEntry *expected,
int count) {
char buffer[1024];
int i;
assert(storage != NULL);
assert(expected != NULL);
if (count != storage->count) {
sprintf(buffer, "wrong number of entries: got %d, expected %d",
storage->count, count);
snprintf(buffer, sizeof(buffer),
"wrong number of entries: got %d, expected %d", storage->count,
count);
StructData_Dispose(storage);
fail(buffer);
} else {
for (i = 0; i < count; i++) {
for (int i = 0; i < count; i++) {
const StructDataEntry *got = &storage->entries[i];
const StructDataEntry *want = &expected[i];
@ -126,11 +131,11 @@ StructData_CheckItems(StructData *storage, const StructDataEntry *expected,
} else {
if (got->data0 != want->data0 || got->data1 != want->data1
|| got->data2 != want->data2) {
sprintf(buffer,
"struct '%" XML_FMT_STR
"' expected (%d,%d,%d), got (%d,%d,%d)",
got->str, want->data0, want->data1, want->data2, got->data0,
got->data1, got->data2);
snprintf(buffer, sizeof(buffer),
"struct '%" XML_FMT_STR
"' expected (%d,%d,%d), got (%d,%d,%d)",
got->str, want->data0, want->data1, want->data2, got->data0,
got->data1, got->data2);
StructData_Dispose(storage);
fail(buffer);
}

View File

@ -0,0 +1,32 @@
/* C++ compilation harness for the test suite.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2023 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.
*/
#include "structdata.c"

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kvm_file2.c,v 1.57 2022/02/22 17:35:01 deraadt Exp $ */
/* $OpenBSD: kvm_file2.c,v 1.58 2024/02/11 21:29:12 bluhm Exp $ */
/*
* Copyright (c) 2009 Todd C. Miller <millert@openbsd.org>
@ -103,7 +103,6 @@
#ifdef INET6
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#endif
#include <fcntl.h>

View File

@ -468,12 +468,8 @@ typedef uLong FAR uLongf;
#endif
#ifndef Z_HAVE_UNISTD_H
# ifdef __WATCOMC__
# define Z_HAVE_UNISTD_H
# endif
#endif
#ifndef Z_HAVE_UNISTD_H
# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
# if defined(__WATCOMC__) || defined(__GO32__) || \
(defined(_LARGEFILE64_SOURCE) && !defined(_WIN32))
# define Z_HAVE_UNISTD_H
# endif
#endif

View File

@ -1,6 +1,15 @@
# $OpenBSD: Makefile,v 1.4 2019/06/29 00:35:06 bluhm Exp $
# $OpenBSD: Makefile,v 1.5 2024/02/11 01:01:32 bluhm Exp $
SRCS= runtests.c
SRCS+= acc_tests.c alloc_tests.c
SRCS+= basic_tests.c
SRCS+= chardata.c common.c
SRCS+= dummy.c
SRCS+= handlers.c
SRCS+= memcheck.c minicheck.c misc_tests.c
SRCS+= ns_tests.c nsalloc_tests.c
SRCS+= structdata.c
SRCS= runtests.c chardata.c memcheck.c minicheck.c structdata.c
# _INTERNAL_trim_to_complete_utf8_characters is not exported in dynamic library
LDFLAGS= -static

View File

@ -1,6 +1,15 @@
# $OpenBSD: Makefile,v 1.4 2019/06/29 00:35:06 bluhm Exp $
# $OpenBSD: Makefile,v 1.5 2024/02/11 01:01:32 bluhm Exp $
SRCS= runtestspp.cpp
SRCS+= acc_tests.c alloc_tests.c
SRCS+= basic_tests.c
SRCS+= chardata.c common.c
SRCS+= dummy.c
SRCS+= handlers.c
SRCS+= memcheck.c minicheck.c misc_tests.c
SRCS+= ns_tests.c nsalloc_tests.c
SRCS+= structdata.c
SRCS= runtestspp.cpp chardata.c memcheck.c minicheck.c structdata.c
# _INTERNAL_trim_to_complete_utf8_characters is not exported in dynamic library
LDFLAGS= -static

View File

@ -1,4 +1,4 @@
/* $OpenBSD: engine.c,v 1.87 2024/02/03 18:30:17 florian Exp $ */
/* $OpenBSD: engine.c,v 1.88 2024/02/11 21:29:12 bluhm Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@ -60,7 +60,6 @@
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/nd6.h>
#include <netinet/icmp6.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: frontend.c,v 1.65 2023/12/14 09:58:59 claudio Exp $ */
/* $OpenBSD: frontend.c,v 1.66 2024/02/11 21:29:12 bluhm Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@ -37,7 +37,6 @@
#include <netinet6/nd6.h>
#include <netinet6/in6_var.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet/icmp6.h>
#include <errno.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sysctl.c,v 1.259 2023/05/17 22:12:51 kettenis Exp $ */
/* $OpenBSD: sysctl.c,v 1.260 2024/02/11 21:29:12 bluhm Exp $ */
/* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */
/*
@ -75,7 +75,6 @@
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/ip6_divert.h>
#include <netmpls/mpls.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: rkpinctrl.c,v 1.14 2023/09/22 01:10:44 jsg Exp $ */
/* $OpenBSD: rkpinctrl.c,v 1.15 2024/02/11 16:01:09 kettenis Exp $ */
/*
* Copyright (c) 2017, 2018 Mark Kettenis <kettenis@openbsd.org>
*
@ -260,12 +260,13 @@ rk3288_pinctrl(uint32_t phandle, void *cookie)
bank = pins[i];
idx = pins[i + 1];
mux = pins[i + 2];
if (bank > 8 || idx >= 32 || mux > 7)
continue;
pull = rk3288_pull(bank, idx, pins[i + 3]);
strength = rk3288_strength(bank, idx, pins[i + 3]);
if (bank > 8 || idx > 32 || mux > 7)
continue;
/* Bank 0 lives in the PMU. */
if (bank < 1) {
rm = sc->sc_pmu;
@ -401,12 +402,13 @@ rk3308_pinctrl(uint32_t phandle, void *cookie)
bank = pins[i];
idx = pins[i + 1];
mux = pins[i + 2];
if (bank > 4 || idx >= 32 || mux > 7)
continue;
pull = rk3308_pull(bank, idx, pins[i + 3]);
strength = rk3308_strength(bank, idx, pins[i + 3]);
if (bank > 4 || idx > 32 || mux > 7)
continue;
base = RK3308_GRF_GPIO0A_IOMUX;
s = splhigh();
@ -546,12 +548,13 @@ rk3328_pinctrl(uint32_t phandle, void *cookie)
bank = pins[i];
idx = pins[i + 1];
mux = pins[i + 2];
if (bank > 3 || idx >= 32 || mux > 3)
continue;
pull = rk3328_pull(bank, idx, pins[i + 3]);
strength = rk3328_strength(bank, idx, pins[i + 3]);
if (bank > 3 || idx > 32 || mux > 3)
continue;
base = RK3328_GRF_GPIO0A_IOMUX;
s = splhigh();
@ -738,12 +741,13 @@ rk3399_pinctrl(uint32_t phandle, void *cookie)
bank = pins[i];
idx = pins[i + 1];
mux = pins[i + 2];
if (bank > 4 || idx >= 32 || mux > 3)
continue;
pull = rk3399_pull(bank, idx, pins[i + 3]);
strength = rk3399_strength(bank, idx, pins[i + 3]);
if (bank > 5 || idx > 32 || mux > 3)
continue;
/* Bank 0 and 1 live in the PMU. */
if (bank < 2) {
rm = sc->sc_pmu;
@ -986,13 +990,14 @@ rk3568_pinctrl(uint32_t phandle, void *cookie)
bank = pins[i];
idx = pins[i + 1];
mux = pins[i + 2];
if (bank > 5 || idx >= 32 || mux > 7)
continue;
pull = rk3568_pull(bank, idx, pins[i + 3]);
strength = rk3568_strength(bank, idx, pins[i + 3]);
schmitt = rk3568_schmitt(bank, idx, pins[i + 3]);
if (bank > 5 || idx > 32 || mux > 7)
continue;
/* Bank 0 lives in the PMU. */
if (bank < 1) {
rm = sc->sc_pmu;
@ -1170,13 +1175,14 @@ rk3588_pinctrl(uint32_t phandle, void *cookie)
bank = pins[i];
idx = pins[i + 1];
mux = pins[i + 2];
if (bank > 5 || idx >= 32 || mux > 15)
continue;
pull = rk3588_pull(bank, idx, pins[i + 3]);
strength = rk3588_strength(bank, idx, pins[i + 3]);
schmitt = rk3588_schmitt(bank, idx, pins[i + 3]);
if (bank > 5 || idx > 32 || mux > 15)
continue;
if (bank == 0 && idx < 12) {
/* PMU1 */
iomux_base = RK3588_PMU1_IOC;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: if_bge.c,v 1.402 2023/11/10 15:51:20 bluhm Exp $ */
/* $OpenBSD: if_bge.c,v 1.403 2024/02/11 06:40:46 jmc Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@ -2099,7 +2099,7 @@ bge_blockinit(struct bge_softc *sc)
* The BD ring replenish thresholds control how often the
* hardware fetches new BD's from the producer rings in host
* memory. Setting the value too low on a busy system can
* starve the hardware and recue the throughput.
* starve the hardware and reduce the throughput.
*
* Set the BD ring replenish thresholds. The recommended
* values are 1/8th the number of descriptors allocated to

View File

@ -1,4 +1,4 @@
/* $OpenBSD: uipc_socket.c,v 1.317 2024/02/05 20:21:38 mvs Exp $ */
/* $OpenBSD: uipc_socket.c,v 1.319 2024/02/11 21:36:49 mvs Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@ -150,6 +150,18 @@ soalloc(const struct domain *dp, int wait)
TAILQ_INIT(&so->so_q0);
TAILQ_INIT(&so->so_q);
switch (dp->dom_family) {
case AF_INET:
case AF_INET6:
switch (dp->dom_protosw->pr_type) {
case SOCK_DGRAM:
case SOCK_RAW:
so->so_rcv.sb_flags |= SB_MTXLOCK;
break;
}
break;
}
return (so);
}
@ -825,7 +837,7 @@ restart:
sounlock_shared(so);
return (error);
}
pru_lock(so);
sb_mtx_lock(&so->so_rcv);
m = so->so_rcv.sb_mb;
#ifdef SOCKET_SPLICE
@ -888,8 +900,8 @@ restart:
}
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 1");
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1");
sb_mtx_unlock(&so->so_rcv);
sbunlock(so, &so->so_rcv);
pru_unlock(so);
error = sbwait(so, &so->so_rcv);
if (error) {
sounlock_shared(so);
@ -961,13 +973,13 @@ dontblock:
sbsync(&so->so_rcv, nextrecord);
if (controlp) {
if (pr->pr_domain->dom_externalize) {
pru_unlock(so);
sb_mtx_unlock(&so->so_rcv);
sounlock_shared(so);
error =
(*pr->pr_domain->dom_externalize)
(cm, controllen, flags);
solock_shared(so);
pru_lock(so);
sb_mtx_lock(&so->so_rcv);
}
*controlp = cm;
} else {
@ -1041,11 +1053,11 @@ dontblock:
SBLASTRECORDCHK(&so->so_rcv, "soreceive uiomove");
SBLASTMBUFCHK(&so->so_rcv, "soreceive uiomove");
resid = uio->uio_resid;
pru_unlock(so);
sb_mtx_unlock(&so->so_rcv);
sounlock_shared(so);
uio_error = uiomove(mtod(m, caddr_t) + moff, len, uio);
solock_shared(so);
pru_lock(so);
sb_mtx_lock(&so->so_rcv);
if (uio_error)
uio->uio_resid = resid - len;
} else
@ -1127,14 +1139,14 @@ dontblock:
break;
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2");
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");
pru_unlock(so);
sb_mtx_unlock(&so->so_rcv);
error = sbwait(so, &so->so_rcv);
if (error) {
sbunlock(so, &so->so_rcv);
sounlock_shared(so);
return (0);
}
pru_lock(so);
sb_mtx_lock(&so->so_rcv);
if ((m = so->so_rcv.sb_mb) != NULL)
nextrecord = m->m_nextpkt;
}
@ -1167,8 +1179,8 @@ dontblock:
if (orig_resid == uio->uio_resid && orig_resid &&
(flags & MSG_EOR) == 0 &&
(so->so_rcv.sb_state & SS_CANTRCVMORE) == 0) {
sb_mtx_unlock(&so->so_rcv);
sbunlock(so, &so->so_rcv);
pru_unlock(so);
goto restart;
}
@ -1178,8 +1190,8 @@ dontblock:
if (flagsp)
*flagsp |= flags;
release:
sb_mtx_unlock(&so->so_rcv);
sbunlock(so, &so->so_rcv);
pru_unlock(so);
sounlock_shared(so);
return (error);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: uipc_socket2.c,v 1.142 2024/02/05 20:21:38 mvs Exp $ */
/* $OpenBSD: uipc_socket2.c,v 1.143 2024/02/11 18:14:26 mvs Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/*
@ -504,6 +504,16 @@ sosleep_nsec(struct socket *so, void *ident, int prio, const char *wmesg,
return ret;
}
void
sbmtxassertlocked(struct socket *so, struct sockbuf *sb)
{
if (sb->sb_flags & SB_MTXLOCK) {
if (splassert_ctl > 0 && mtx_owned(&sb->sb_mtx) == 0)
splassert_fail(0, RW_WRITE, __func__);
} else
soassertlocked(so);
}
/*
* Wait for data to arrive at/drain from a socket buffer.
*/
@ -925,7 +935,7 @@ sbappendaddr(struct socket *so, struct sockbuf *sb, const struct sockaddr *asa,
struct mbuf *m, *n, *nlast;
int space = asa->sa_len;
soassertlocked(so);
sbmtxassertlocked(so, sb);
if (m0 && (m0->m_flags & M_PKTHDR) == 0)
panic("sbappendaddr");

View File

@ -472,12 +472,8 @@ typedef uLong FAR uLongf;
#endif
#ifndef Z_HAVE_UNISTD_H
# ifdef __WATCOMC__
# define Z_HAVE_UNISTD_H
# endif
#endif
#ifndef Z_HAVE_UNISTD_H
# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
# if defined(__WATCOMC__) || defined(__GO32__) || \
(defined(_LARGEFILE64_SOURCE) && !defined(_WIN32))
# define Z_HAVE_UNISTD_H
# endif
#endif

View File

@ -1,4 +1,4 @@
/* $OpenBSD: in_pcb.c,v 1.291 2024/02/09 14:02:11 bluhm Exp $ */
/* $OpenBSD: in_pcb.c,v 1.292 2024/02/11 01:27:45 bluhm Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@ -90,6 +90,7 @@
#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet6/ip6_var.h>
#include <netinet/in_pcb.h>
#ifdef IPSEC
#include <netinet/ip_esp.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: in_pcb.h,v 1.150 2024/01/31 12:27:57 bluhm Exp $ */
/* $OpenBSD: in_pcb.h,v 1.151 2024/02/11 01:27:45 bluhm Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
@ -69,7 +69,6 @@
#include <sys/rwlock.h>
#include <sys/refcnt.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet/icmp6.h>
#include <netinet/ip_ipsp.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip_divert.c,v 1.93 2024/02/03 22:50:09 mvs Exp $ */
/* $OpenBSD: ip_divert.c,v 1.94 2024/02/11 18:14:26 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@ -241,14 +241,14 @@ divert_packet(struct mbuf *m, int dir, u_int16_t divert_port)
in_proto_cksum_out(m, NULL);
}
mtx_enter(&inp->inp_mtx);
so = inp->inp_socket;
mtx_enter(&so->so_rcv.sb_mtx);
if (sbappendaddr(so, &so->so_rcv, sintosa(&sin), m, NULL) == 0) {
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
divstat_inc(divs_fullsock);
goto bad;
}
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
sorwakeup(so);
in_pcbunref(inp);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip_ipip.c,v 1.100 2023/11/28 13:23:20 bluhm Exp $ */
/* $OpenBSD: ip_ipip.c,v 1.101 2024/02/11 01:27:45 bluhm Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@ -60,6 +60,7 @@
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet6/ip6_var.h>
#include <netinet/ip_ecn.h>
#include <netinet/ip_ipip.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip_mroute.c,v 1.140 2023/12/06 09:27:17 bluhm Exp $ */
/* $OpenBSD: ip_mroute.c,v 1.141 2024/02/11 18:14:26 mvs Exp $ */
/* $NetBSD: ip_mroute.c,v 1.85 2004/04/26 01:31:57 matt Exp $ */
/*
@ -1051,12 +1051,11 @@ int
socket_send(struct socket *so, struct mbuf *mm, struct sockaddr_in *src)
{
if (so != NULL) {
struct inpcb *inp = sotoinpcb(so);
int ret;
mtx_enter(&inp->inp_mtx);
mtx_enter(&so->so_rcv.sb_mtx);
ret = sbappendaddr(so, &so->so_rcv, sintosa(src), mm, NULL);
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
if (ret != 0) {
sorwakeup(so);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ipsec_output.c,v 1.97 2022/01/02 22:36:04 jsg Exp $ */
/* $OpenBSD: ipsec_output.c,v 1.98 2024/02/11 01:27:45 bluhm Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
@ -36,6 +36,7 @@
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet6/ip6_var.h>
#if NPF > 0
#include <net/pfvar.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: raw_ip.c,v 1.155 2024/02/03 22:50:09 mvs Exp $ */
/* $OpenBSD: raw_ip.c,v 1.156 2024/02/11 18:14:26 mvs Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
@ -220,24 +220,24 @@ rip_input(struct mbuf **mp, int *offp, int proto, int af)
else
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n != NULL) {
struct socket *so = inp->inp_socket;
int ret;
if (inp->inp_flags & INP_CONTROLOPTS ||
inp->inp_socket->so_options & SO_TIMESTAMP)
so->so_options & SO_TIMESTAMP)
ip_savecontrol(inp, &opts, ip, n);
mtx_enter(&inp->inp_mtx);
ret = sbappendaddr(inp->inp_socket,
&inp->inp_socket->so_rcv,
mtx_enter(&so->so_rcv.sb_mtx);
ret = sbappendaddr(so, &so->so_rcv,
sintosa(&ripsrc), n, opts);
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
if (ret == 0) {
/* should notify about lost packet */
m_freem(n);
m_freem(opts);
} else
sorwakeup(inp->inp_socket);
sorwakeup(so);
}
in_pcbunref(inp);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_input.c,v 1.399 2024/01/27 21:13:46 bluhm Exp $ */
/* $OpenBSD: tcp_input.c,v 1.400 2024/02/11 01:27:45 bluhm Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@ -88,6 +88,7 @@
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet6/ip6_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_output.c,v 1.141 2023/11/26 22:08:10 bluhm Exp $ */
/* $OpenBSD: tcp_output.c,v 1.142 2024/02/11 01:27:45 bluhm Exp $ */
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
/*
@ -90,6 +90,7 @@
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet6/ip6_var.h>
#include <netinet/tcp.h>
#define TCPOUTFLAGS
#include <netinet/tcp_fsm.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_subr.c,v 1.197 2024/01/28 20:34:25 bluhm Exp $ */
/* $OpenBSD: tcp_subr.c,v 1.198 2024/02/11 01:27:45 bluhm Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
@ -85,6 +85,7 @@
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet6/ip6_var.h>
#include <netinet/ip_icmp.h>
#include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tcp_usrreq.c,v 1.229 2024/01/19 02:24:07 bluhm Exp $ */
/* $OpenBSD: tcp_usrreq.c,v 1.230 2024/02/11 01:27:45 bluhm Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@ -90,6 +90,7 @@
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet6/ip6_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: udp_usrreq.c,v 1.317 2024/02/03 22:50:09 mvs Exp $ */
/* $OpenBSD: udp_usrreq.c,v 1.318 2024/02/11 18:14:26 mvs Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@ -697,15 +697,15 @@ udp_sbappend(struct inpcb *inp, struct mbuf *m, struct ip *ip,
#endif
m_adj(m, hlen);
mtx_enter(&inp->inp_mtx);
mtx_enter(&so->so_rcv.sb_mtx);
if (sbappendaddr(so, &so->so_rcv, srcaddr, m, opts) == 0) {
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
udpstat_inc(udps_fullsock);
m_freem(m);
m_freem(opts);
return;
}
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
sorwakeup(so);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: in6_pcb.c,v 1.136 2024/02/09 14:02:12 bluhm Exp $ */
/* $OpenBSD: in6_pcb.c,v 1.137 2024/02/11 01:27:45 bluhm Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -116,6 +116,7 @@
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet6/ip6_var.h>
#include <netinet/in_pcb.h>
#include <netinet6/in6_var.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip6_divert.c,v 1.92 2024/02/03 22:50:09 mvs Exp $ */
/* $OpenBSD: ip6_divert.c,v 1.94 2024/02/11 18:14:27 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@ -35,6 +35,7 @@
#include <netinet/in_pcb.h>
#include <netinet/ip_divert.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/in6_var.h>
#include <netinet6/ip6_divert.h>
#include <netinet/tcp.h>
@ -248,14 +249,14 @@ divert6_packet(struct mbuf *m, int dir, u_int16_t divert_port)
in6_proto_cksum_out(m, NULL);
}
mtx_enter(&inp->inp_mtx);
so = inp->inp_socket;
mtx_enter(&so->so_rcv.sb_mtx);
if (sbappendaddr(so, &so->so_rcv, sin6tosa(&sin6), m, NULL) == 0) {
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
div6stat_inc(div6s_fullsock);
goto bad;
}
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
sorwakeup(so);
in_pcbunref(inp);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip6_mroute.c,v 1.139 2024/02/03 22:50:09 mvs Exp $ */
/* $OpenBSD: ip6_mroute.c,v 1.140 2024/02/11 18:14:27 mvs Exp $ */
/* $NetBSD: ip6_mroute.c,v 1.59 2003/12/10 09:28:38 itojun Exp $ */
/* $KAME: ip6_mroute.c,v 1.45 2001/03/25 08:38:51 itojun Exp $ */
@ -856,17 +856,16 @@ int
socket6_send(struct socket *so, struct mbuf *mm, struct sockaddr_in6 *src)
{
if (so != NULL) {
struct inpcb *inp = sotoinpcb(so);
int ret;
mtx_enter(&inp->inp_mtx);
mtx_enter(&so->so_rcv.sb_mtx);
ret = sbappendaddr(so, &so->so_rcv, sin6tosa(src), mm, NULL);
if (ret != 0)
sorwakeup(so);
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
if (ret != 0)
if (ret != 0) {
sorwakeup(so);
return 0;
}
}
m_freem(mm);
return -1;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: raw_ip6.c,v 1.180 2024/02/03 22:50:09 mvs Exp $ */
/* $OpenBSD: raw_ip6.c,v 1.181 2024/02/11 18:14:27 mvs Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
@ -263,6 +263,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
else
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n != NULL) {
struct socket *so = inp->inp_socket;
int ret;
if (inp->inp_flags & IN6P_CONTROLOPTS)
@ -270,11 +271,10 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
/* strip intermediate headers */
m_adj(n, *offp);
mtx_enter(&inp->inp_mtx);
ret = sbappendaddr(inp->inp_socket,
&inp->inp_socket->so_rcv,
mtx_enter(&so->so_rcv.sb_mtx);
ret = sbappendaddr(so, &so->so_rcv,
sin6tosa(&rip6src), n, opts);
mtx_leave(&inp->inp_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
if (ret == 0) {
/* should notify about lost packet */
@ -282,7 +282,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
m_freem(opts);
rip6stat_inc(rip6s_fullsock);
} else
sorwakeup(inp->inp_socket);
sorwakeup(so);
}
in_pcbunref(inp);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: socketvar.h,v 1.122 2024/02/03 22:50:09 mvs Exp $ */
/* $OpenBSD: socketvar.h,v 1.123 2024/02/11 18:14:27 mvs Exp $ */
/* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */
/*-
@ -134,6 +134,7 @@ struct socket {
#define SB_ASYNC 0x10 /* ASYNC I/O, need signals */
#define SB_SPLICE 0x20 /* buffer is splice source or drain */
#define SB_NOINTR 0x40 /* operations not interruptible */
#define SB_MTXLOCK 0x80 /* use sb_mtx for sockbuf protection */
void (*so_upcall)(struct socket *so, caddr_t arg, int waitf);
caddr_t so_upcallarg; /* Arg for above */
@ -197,6 +198,22 @@ sorele(struct socket *so)
#define isspliced(so) ((so)->so_sp && (so)->so_sp->ssp_socket)
#define issplicedback(so) ((so)->so_sp && (so)->so_sp->ssp_soback)
static inline void
sb_mtx_lock(struct sockbuf *sb)
{
if (sb->sb_flags & SB_MTXLOCK)
mtx_enter(&sb->sb_mtx);
}
static inline void
sb_mtx_unlock(struct sockbuf *sb)
{
if (sb->sb_flags & SB_MTXLOCK)
mtx_leave(&sb->sb_mtx);
}
void sbmtxassertlocked(struct socket *so, struct sockbuf *);
/*
* Do we need to notify the other side when I/O is possible?
*/

View File

@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
# $OpenBSD: PkgConfig.pm,v 1.11 2023/09/22 07:29:14 espie Exp $
# $OpenBSD: PkgConfig.pm,v 1.12 2024/02/11 03:57:10 gkoehler Exp $
#
# Copyright (c) 2006 Marc Espie <espie@openbsd.org>
#
@ -86,6 +86,9 @@ sub parse_value($self, $name, $value)
sub add_property($self, $name, $value)
{
if ($name eq "CFlags") {
$name = "Cflags";
}
if (defined $self->{properties}{$name}) {
die "Duplicate property $name";
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: frontend.c,v 1.43 2023/12/14 11:09:34 claudio Exp $ */
/* $OpenBSD: frontend.c,v 1.44 2024/02/11 21:29:12 bluhm Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@ -66,7 +66,6 @@
#include <netinet6/nd6.h>
#include <netinet6/in6_var.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet/icmp6.h>
#include <ctype.h>

View File

@ -1,4 +1,4 @@
/* $OpenBSD: makemap.c,v 1.75 2021/06/14 17:58:15 eric Exp $ */
/* $OpenBSD: makemap.c,v 1.76 2024/02/11 09:24:26 op Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@ -37,9 +37,8 @@
static void usage(void);
static int parse_map(DB *, int *, char *);
static int parse_entry(DB *, int *, char *, size_t, size_t);
static int parse_mapentry(DB *, int *, char *, size_t, size_t);
static int parse_setentry(DB *, int *, char *, size_t, size_t);
static int add_mapentry(DB *, int *, char *, char *, size_t);
static int add_setentry(DB *, int *, char *, size_t);
static int make_plain(DBT *, char *);
static int make_aliases(DBT *, char *);
static char *conf_aliases(char *);
@ -247,9 +246,10 @@ static int
parse_map(DB *db, int *dbputs, char *filename)
{
FILE *fp;
char *line;
size_t len;
char *key, *val, *line = NULL;
size_t linesize = 0;
size_t lineno = 0;
int malformed, table_type, r;
if (strcmp(filename, "-") == 0)
fp = fdopen(0, "r");
@ -269,55 +269,46 @@ parse_map(DB *db, int *dbputs, char *filename)
return 0;
}
while ((line = fparseln(fp, &len, &lineno,
NULL, FPARSELN_UNESCCOMM)) != NULL) {
if (!parse_entry(db, dbputs, line, len, lineno)) {
table_type = (type == T_SET) ? T_LIST : T_HASH;
while (parse_table_line(fp, &line, &linesize, &table_type,
&key, &val, &malformed) != -1) {
lineno++;
if (malformed) {
warnx("%s:%zd: invalid entry", source, lineno);
free(line);
fclose(fp);
return 0;
}
if (key == NULL)
continue;
switch (type) {
case T_PLAIN:
case T_ALIASES:
r = add_mapentry(db, dbputs, key, val, lineno);
break;
case T_SET:
r = add_setentry(db, dbputs, key, lineno);
break;
}
if (!r) {
free(line);
fclose(fp);
return 0;
}
free(line);
}
free(line);
fclose(fp);
return 1;
}
static int
parse_entry(DB *db, int *dbputs, char *line, size_t len, size_t lineno)
{
switch (type) {
case T_PLAIN:
case T_ALIASES:
return parse_mapentry(db, dbputs, line, len, lineno);
case T_SET:
return parse_setentry(db, dbputs, line, len, lineno);
}
return 0;
}
static int
parse_mapentry(DB *db, int *dbputs, char *line, size_t len, size_t lineno)
add_mapentry(DB *db, int *dbputs, char *keyp, char *valp, size_t lineno)
{
DBT key;
DBT val;
char *keyp;
char *valp;
keyp = line;
while (isspace((unsigned char)*keyp))
keyp++;
if (*keyp == '\0')
return 1;
valp = keyp;
strsep(&valp, " \t:");
if (valp == NULL || valp == keyp)
goto bad;
while (*valp == ':' || isspace((unsigned char)*valp))
valp++;
if (*valp == '\0')
goto bad;
/* Check for dups. */
key.data = keyp;
@ -355,17 +346,10 @@ bad:
}
static int
parse_setentry(DB *db, int *dbputs, char *line, size_t len, size_t lineno)
add_setentry(DB *db, int *dbputs, char *keyp, size_t lineno)
{
DBT key;
DBT val;
char *keyp;
keyp = line;
while (isspace((unsigned char)*keyp))
keyp++;
if (*keyp == '\0')
return 1;
val.data = "<set>";
val.size = strlen(val.data) + 1;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: smtpd.h,v 1.681 2024/02/02 22:02:12 gilles Exp $ */
/* $OpenBSD: smtpd.h,v 1.682 2024/02/11 09:24:26 op Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@ -1741,6 +1741,9 @@ void log_trace0(const char *, ...)
__attribute__((format (printf, 1, 2)));
#define log_trace(m, ...) do { if (tracing & (m)) log_trace0(__VA_ARGS__); } while (0)
int parse_table_line(FILE *, char **, size_t *, int *,
char **, char **, int *);
/* waitq.c */
int waitq_wait(void *, void (*)(void *, void *, void *), void *);
void waitq_run(void *, void *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: table_static.c,v 1.33 2021/06/14 17:58:16 eric Exp $ */
/* $OpenBSD: table_static.c,v 1.34 2024/02/11 09:24:26 op Exp $ */
/*
* Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
@ -111,80 +111,28 @@ static int
table_static_priv_load(struct table_static_priv *priv, const char *path)
{
FILE *fp;
char *buf = NULL, *p;
char *line = NULL;
int lineno = 0;
size_t sz = 0;
ssize_t flen;
size_t linesize = 0;
char *keyp;
char *valp;
int ret = 0;
int malformed, ret = 0;
if ((fp = fopen(path, "r")) == NULL) {
log_warn("%s: fopen", path);
return 0;
}
while ((flen = getline(&buf, &sz, fp)) != -1) {
while (parse_table_line(fp, &line, &linesize, &priv->type,
&keyp, &valp, &malformed) != -1) {
lineno++;
if (buf[flen - 1] == '\n')
buf[--flen] = '\0';
keyp = buf;
while (isspace((unsigned char)*keyp)) {
++keyp;
--flen;
}
if (*keyp == '\0')
continue;
while (isspace((unsigned char)keyp[flen - 1]))
keyp[--flen] = '\0';
if (*keyp == '#') {
if (priv->type == T_NONE) {
keyp++;
while (isspace((unsigned char)*keyp))
++keyp;
if (!strcmp(keyp, "@list"))
priv->type = T_LIST;
}
continue;
}
if (priv->type == T_NONE) {
for (p = keyp; *p; p++) {
if (*p == ' ' || *p == '\t' || *p == ':') {
priv->type = T_HASH;
break;
}
}
if (priv->type == T_NONE)
priv->type = T_LIST;
}
if (priv->type == T_LIST) {
table_static_priv_add(priv, keyp, NULL);
continue;
}
/* T_HASH */
valp = keyp;
strsep(&valp, " \t:");
if (valp) {
while (*valp) {
if (!isspace((unsigned char)*valp) &&
!(*valp == ':' &&
isspace((unsigned char)*(valp + 1))))
break;
++valp;
}
if (*valp == '\0')
valp = NULL;
}
if (valp == NULL) {
log_warnx("%s: invalid map entry line %d",
if (malformed) {
log_warnx("%s:%d invalid map entry",
path, lineno);
goto end;
}
if (keyp == NULL)
continue;
table_static_priv_add(priv, keyp, valp);
}
@ -199,7 +147,7 @@ table_static_priv_load(struct table_static_priv *priv, const char *path)
ret = 1;
end:
free(buf);
free(line);
fclose(fp);
return ret;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: util.c,v 1.155 2024/01/03 08:11:15 op Exp $ */
/* $OpenBSD: util.c,v 1.156 2024/02/11 09:24:26 op Exp $ */
/*
* Copyright (c) 2000,2001 Markus Friedl. All rights reserved.
@ -850,3 +850,75 @@ log_trace_verbose(int v)
/* Set debug logging in log.c */
log_setverbose(v & TRACE_DEBUG ? 2 : foreground_log);
}
int
parse_table_line(FILE *fp, char **line, size_t *linesize,
int *type, char **key, char **val, int *malformed)
{
char *keyp, *valp, *p;
ssize_t linelen;
*key = NULL;
*val = NULL;
*malformed = 0;
if ((linelen = getline(line, linesize, fp)) == -1)
return (-1);
keyp = *line;
while (isspace((unsigned char)*keyp)) {
++keyp;
--linelen;
}
if (*keyp == '\0')
return 0;
while (linelen > 0 && isspace((unsigned char)keyp[linelen - 1]))
keyp[--linelen] = '\0';
if (*keyp == '#') {
if (*type == T_NONE) {
keyp++;
while (isspace((unsigned char)*keyp))
++keyp;
if (!strcmp(keyp, "@list"))
*type = T_LIST;
}
return 0;
}
if (*type == T_NONE) {
for (p = keyp; *p; p++) {
if (*p == ' ' || *p == '\t' || *p == ':') {
*type = T_HASH;
break;
}
}
if (*type == T_NONE)
*type = T_LIST;
}
if (*type == T_LIST) {
*key = keyp;
return (0);
}
/* T_HASH */
valp = keyp;
strsep(&valp, " \t:");
if (valp) {
while (*valp) {
if (!isspace((unsigned char)*valp) &&
!(*valp == ':' &&
isspace((unsigned char)*(valp + 1))))
break;
++valp;
}
if (*valp == '\0')
valp = NULL;
}
if (valp == NULL)
*malformed = 1;
*key = keyp;
*val = valp;
return (0);
}