Merge pull request #674 from RMJ10/test_refactor_2

Refactor coverage and conformance tests
This commit is contained in:
Sebastian Pipping 2023-09-02 18:33:53 +02:00 committed by GitHub
commit 014a303dc1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 14092 additions and 12456 deletions

View file

@ -594,9 +594,18 @@ if(EXPAT_BUILD_TESTS)
enable_testing()
set(test_SRCS
tests/acc_tests.c
tests/alloc_tests.c
tests/basic_tests.c
tests/chardata.c
tests/common.c
tests/dummy.c
tests/handlers.c
tests/memcheck.c
tests/minicheck.c
tests/misc_tests.c
tests/ns_tests.c
tests/nsalloc_tests.c
tests/structdata.c
${_EXPAT_C_SOURCES}
)

View file

@ -43,7 +43,16 @@ TESTS = runtests runtestspp
LOG_DRIVER = $(srcdir)/../test-driver-wrapper.sh
libruntests_a_SOURCES = \
acc_tests.c \
alloc_tests.c \
basic_tests.c \
chardata.c \
common.c \
dummy.c \
handlers.c \
misc_tests.c \
ns_tests.c \
nsalloc_tests.c \
structdata.c \
memcheck.c \
minicheck.c
@ -61,7 +70,16 @@ runtests_LDFLAGS = @AM_LDFLAGS@ @LIBM@
runtestspp_LDFLAGS = @AM_LDFLAGS@ @LIBM@
EXTRA_DIST = \
acc_tests.h \
alloc_tests.h \
basic_tests.h \
chardata.h \
common.h \
dummy.h \
handlers.h \
misc_tests.h \
ns_tests.h \
nsalloc_tests.h \
structdata.h \
minicheck.h \
memcheck.h \

416
expat/tests/acc_tests.c Normal file
View file

@ -0,0 +1,416 @@
/* 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 Dong-hee 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 <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 defined(XML_DTD)
START_TEST(test_accounting_precision) {
const XML_Bool filled_later = XML_TRUE; /* value is arbitrary */
struct AccountingTestCase cases[] = {
{"<e/>", NULL, NULL, 0, 0},
{"<e></e>", NULL, NULL, 0, 0},
/* Attributes */
{"<e k1=\"v2\" k2=\"v2\"/>", NULL, NULL, 0, filled_later},
{"<e k1=\"v2\" k2=\"v2\"></e>", NULL, NULL, 0, 0},
{"<p:e xmlns:p=\"https://domain.invalid/\" />", NULL, NULL, 0,
filled_later},
{"<e k=\"&amp;&apos;&gt;&lt;&quot;\" />", NULL, NULL,
sizeof(XML_Char) * 5 /* number of predefined entities */, filled_later},
{"<e1 xmlns='https://example.org/'>\n"
" <e2 xmlns=''/>\n"
"</e1>",
NULL, NULL, 0, filled_later},
/* Text */
{"<e>text</e>", NULL, NULL, 0, filled_later},
{"<e1><e2>text1<e3/>text2</e2></e1>", NULL, NULL, 0, filled_later},
{"<e>&amp;&apos;&gt;&lt;&quot;</e>", NULL, NULL,
sizeof(XML_Char) * 5 /* number of predefined entities */, filled_later},
{"<e>&#65;&#41;</e>", NULL, NULL, 0, filled_later},
/* Prolog */
{"<?xml version=\"1.0\"?><root/>", NULL, NULL, 0, filled_later},
/* Whitespace */
{" <e1> <e2> </e2> </e1> ", NULL, NULL, 0, filled_later},
{"<e1 ><e2 /></e1 >", NULL, NULL, 0, filled_later},
{"<e1><e2 k = \"v\"/><e3 k = 'v'/></e1>", NULL, NULL, 0, filled_later},
/* Comments */
{"<!-- Comment --><e><!-- Comment --></e>", NULL, NULL, 0, filled_later},
/* Processing instructions */
{"<?xml-stylesheet type=\"text/xsl\" href=\"https://domain.invalid/\" media=\"all\"?><e/>",
NULL, NULL, 0, filled_later},
{"<?pi0?><?pi1 ?><?pi2 ?><!DOCTYPE r SYSTEM 'first.ent'><r/>",
"<?pi3?><!ENTITY % e1 SYSTEM 'second.ent'><?pi4?>%e1;<?pi5?>", "<?pi6?>",
0, filled_later},
/* CDATA */
{"<e><![CDATA[one two three]]></e>", NULL, NULL, 0, filled_later},
/* 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"),
filled_later},
/* 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")),
filled_later},
/* General entities */
{"<!DOCTYPE root [\n"
"<!ENTITY nine \"123456789\">\n"
"]>\n"
"<root>&nine;</root>",
NULL, NULL, sizeof(XML_Char) * strlen("123456789"), filled_later},
{"<!DOCTYPE root [\n"
"<!ENTITY nine \"123456789\">\n"
"]>\n"
"<root k1=\"&nine;\"/>",
NULL, NULL, sizeof(XML_Char) * strlen("123456789"), filled_later},
{"<!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")),
filled_later},
{"<!DOCTYPE r [\n"
" <!ENTITY five SYSTEM 'first.ent'>\n"
"]>\n"
"<r>&five;</r>",
"12345", NULL, 0, filled_later},
/* Parameter entities */
{"<!DOCTYPE r [\n"
"<!ENTITY % comment \"<!---->\">\n"
"%comment;\n"
"]>\n"
"<r/>",
NULL, NULL, sizeof(XML_Char) * strlen("<!---->"), filled_later},
{"<!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")),
filled_later},
{"<!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-->")),
filled_later},
{"<!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]]]]")),
filled_later},
{"<!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("<!---->")),
filled_later},
{"<!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-->"),
filled_later},
{
"<!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,
filled_later,
},
{
"<!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,
filled_later,
},
{"<!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'>"), filled_later},
{"<!DOCTYPE r [\n"
" <!ENTITY five SYSTEM 'first.ent'>\n"
"]>\n"
"<r>&five;</r>",
"\xEF\xBB\xBF" /* UTF-8 BOM */, NULL, 0, filled_later},
};
const size_t countCases = sizeof(cases) / sizeof(cases[0]);
size_t u = 0;
for (; u < countCases; u++) {
size_t v = 0;
for (; v < 2; v++) {
const XML_Bool singleBytesWanted = (v == 0) ? XML_FALSE : XML_TRUE;
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]);
cases[u].singleBytesWanted = singleBytesWanted;
}
const XmlParseFunction xmlParseFunction
= singleBytesWanted ? _XML_Parse_SINGLE_BYTES : XML_Parse;
enum XML_Status status
= xmlParseFunction(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("") ", %s: Expected " EXPAT_FMT_ULL(
"") " count direct bytes, got " EXPAT_FMT_ULL("") " instead.\n",
u + 1, countCases, singleBytesWanted ? "single bytes" : "chunks",
expectedCountBytesDirect, actualCountBytesDirect);
fail("Count of direct bytes is off");
}
if (actualCountBytesIndirect != expectedCountBytesIndirect) {
fprintf(
stderr,
"Document " EXPAT_FMT_SIZE_T("") " of " EXPAT_FMT_SIZE_T("") ", %s: Expected " EXPAT_FMT_ULL(
"") " count indirect bytes, got " EXPAT_FMT_ULL("") " instead.\n",
u + 1, countCases, singleBytesWanted ? "single bytes" : "chunks",
expectedCountBytesIndirect, actualCountBytesIndirect);
fail("Count of indirect bytes is off");
}
}
}
}
END_TEST
static float
portableNAN(void) {
return strtof("nan", NULL);
}
static float
portableINFINITY(void) {
return strtof("infinity", NULL);
}
START_TEST(test_billion_laughs_attack_protection_api) {
XML_Parser parserWithoutParent = XML_ParserCreate(NULL);
XML_Parser parserWithParent
= XML_ExternalEntityParserCreate(parserWithoutParent, NULL, 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, portableNAN())
== 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, portableINFINITY())
== 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++) {
const char *const printable = unsignedCharToPrintable(uc);
if (printable == NULL)
fail("unsignedCharToPrintable returned NULL");
if (strlen(printable) < (size_t)1)
fail("unsignedCharToPrintable returned empty string");
}
// Two concrete samples
if (strcmp(unsignedCharToPrintable('A'), "A") != 0)
fail("unsignedCharToPrintable result mistaken");
if (strcmp(unsignedCharToPrintable('\\'), "\\\\") != 0)
fail("unsignedCharToPrintable result mistaken");
}
END_TEST
#endif // defined(XML_DTD)
void
make_accounting_test_case(Suite *s) {
#if defined(XML_DTD)
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 /* defined(XML_DTD) */
}

56
expat/tests/acc_tests.h Normal file
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 Dong-hee 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

2126
expat/tests/alloc_tests.c Normal file

File diff suppressed because it is too large Load diff

56
expat/tests/alloc_tests.h Normal file
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 Dong-hee 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

5149
expat/tests/basic_tests.c Normal file

File diff suppressed because it is too large Load diff

56
expat/tests/basic_tests.h Normal file
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 Dong-hee 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

310
expat/tests/common.c Normal file
View file

@ -0,0 +1,310 @@
/* 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-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 Dong-hee 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 <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;
/* 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
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_unless(0, file, line, buffer);
}
enum XML_Status
_XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len,
int isFinal) {
enum XML_Status res = XML_STATUS_ERROR;
int offset = 0;
if (len == 0) {
return XML_Parse(parser, s, len, isFinal);
}
for (; offset < len; offset++) {
const int innerIsFinal = (offset == len - 1) && isFinal;
const char c = s[offset]; /* to help out-of-bounds detection */
res = XML_Parse(parser, &c, sizeof(char), innerIsFinal);
if (res != XML_STATUS_OK) {
return res;
}
}
return res;
}
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_unless() macro, but let's us report
the right filename and line number. */
_fail_unless(0, 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);
}

158
expat/tests/common.h Normal file
View file

@ -0,0 +1,158 @@
/* 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-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 Dong-hee 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_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 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 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

261
expat/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 Dong-hee 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
expat/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 Dong-hee 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

1862
expat/tests/handlers.c Normal file

File diff suppressed because it is too large Load diff

565
expat/tests/handlers.h Normal file
View file

@ -0,0 +1,565 @@
/* 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-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 Dong-hee 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_HANDLERS_H
# define XML_HANDLERS_H
# include "expat.h"
/* Variable holding the expected handler userData */
extern 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_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);
enum ee_parse_flags { EE_PARSE_NONE = 0x00, EE_PARSE_FULL_BUFFER = 0x01 };
typedef struct ExtTest2 {
const char *parse_text;
int parse_len;
const XML_Char *encoding;
CharData *storage;
enum ee_parse_flags flags;
} 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);
# if defined(XML_DTD)
typedef enum XML_Status (*XmlParseFunction)(XML_Parser, const char *, int, int);
struct AccountingTestCase {
const char *primaryText;
const char *firstExternalText; /* often NULL */
const char *secondExternalText; /* often NULL */
const unsigned long long expectedCountBytesIndirectExtra;
XML_Bool singleBytesWanted;
};
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);
# endif /* defined(XML_DTD) */
/* 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 invocation by single characters */
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);
/* 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);
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

@ -41,30 +41,33 @@
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 \
} \
}
# define START_TEST(testname) \
static void testname(void) { \
_check_set_test_info(__func__, __FILE__, __LINE__); \
{
# define END_TEST \
} \
}
#define fail(msg) _fail_unless(0, __FILE__, __LINE__, msg)
# define fail(msg) _fail_unless(0, __FILE__, __LINE__, msg)
typedef void (*tcase_setup_function)(void);
typedef void (*tcase_teardown_function)(void);
@ -115,6 +118,8 @@ void srunner_run_all(SRunner *runner, int verbosity);
int srunner_ntests_failed(SRunner *runner);
void srunner_free(SRunner *runner);
#endif /* XML_MINICHECK_H */
#ifdef __cplusplus
}
#endif

410
expat/tests/misc_tests.c Normal file
View file

@ -0,0 +1,410 @@
/* 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 Dong-hee 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.
*/
#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
/* Test that XML_ErrorString rejects out-of-range codes */
START_TEST(test_misc_error_string) {
if (XML_ErrorString((enum XML_Error) - 1) != NULL)
fail("Negative error code not rejected");
if (XML_ErrorString((enum XML_Error)100) != NULL)
fail("Large error code not rejected");
}
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.5.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(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(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++) {
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(parser, input, (int)strlen(input), 0);
if (parseResult != XML_STATUS_ERROR) {
parseResult = XML_Parse(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(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
fail("Call to parse was expected to fail");
if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
fail("Call to parse was expected to fail from a closing tag mismatch");
XML_ParserReset(parser, NULL);
if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
fail("Call to parse was expected to fail");
if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
fail("Call to parse was expected to fail from a closing tag mismatch");
XML_ParserFree(parser);
#endif
}
END_TEST
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);
}

56
expat/tests/misc_tests.h Normal file
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 Dong-hee 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

750
expat/tests/ns_tests.c Normal file
View file

@ -0,0 +1,750 @@
/* 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 Dong-hee 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 <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);
if (! g_triplet_start_flag)
fail("triplet_start_checker not invoked");
/* 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_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 re-use 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++) {
XML_Parser parser = XML_ParserCreateNS(NULL, cases[i].namesep);
XML_SetElementHandler(parser, dummy_start_element, dummy_end_element);
if (XML_Parse(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(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);
}

56
expat/tests/ns_tests.h Normal file
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 Dong-hee 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

1536
expat/tests/nsalloc_tests.c Normal file

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 Dong-hee 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

File diff suppressed because it is too large Load diff