diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-11-12 20:33:39 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-11-12 20:33:39 +0000 |
commit | a6c6dbe4d7e62c2bdd1308242aec0d9e11cee5b8 (patch) | |
tree | 9f39d4764a6663bad4d4ac03cad6f7b58ee5b795 /lib/libexpat | |
parent | f170683aac7637bf94515fbaae2d48f3e9086811 (diff) |
Update libexpat to version 2.6.4.
Relevant for OpenBSD are security fix #915, other changes #905 #902
#904 #317 #918 #914. Major library bump is necessary as new error
constant has been added to a public header file. CVE-2024-50602
OK matthieu@ tb@ deraadt@
Diffstat (limited to 'lib/libexpat')
-rw-r--r-- | lib/libexpat/Changes | 31 | ||||
-rw-r--r-- | lib/libexpat/README.md | 47 | ||||
-rw-r--r-- | lib/libexpat/doc/reference.html | 2 | ||||
-rw-r--r-- | lib/libexpat/examples/element_declarations.c | 9 | ||||
-rw-r--r-- | lib/libexpat/lib/expat.h | 6 | ||||
-rw-r--r-- | lib/libexpat/lib/xmlparse.c | 18 | ||||
-rw-r--r-- | lib/libexpat/shlib_version | 4 | ||||
-rw-r--r-- | lib/libexpat/tests/basic_tests.c | 17 | ||||
-rw-r--r-- | lib/libexpat/tests/common.c | 33 | ||||
-rw-r--r-- | lib/libexpat/tests/common.h | 11 | ||||
-rw-r--r-- | lib/libexpat/tests/handlers.c | 42 | ||||
-rw-r--r-- | lib/libexpat/tests/handlers.h | 17 | ||||
-rw-r--r-- | lib/libexpat/tests/misc_tests.c | 39 |
13 files changed, 195 insertions, 81 deletions
diff --git a/lib/libexpat/Changes b/lib/libexpat/Changes index c1d22efa5a3..aa19f70ae21 100644 --- a/lib/libexpat/Changes +++ b/lib/libexpat/Changes @@ -30,6 +30,37 @@ !! THANK YOU! Sebastian Pipping -- Berlin, 2024-03-09 !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +Release 2.6.4 Wed November 6 2024 + Security fixes: + #915 CVE-2024-50602 -- Fix crash within function XML_ResumeParser + from a NULL pointer dereference by disallowing function + XML_StopParser to (stop or) suspend an unstarted parser. + A new error code XML_ERROR_NOT_STARTED was introduced to + properly communicate this situation. // CWE-476 CWE-754 + + Other changes: + #903 CMake: Add alias target "expat::expat" + #905 docs: Document use via CMake >=3.18 with FetchContent + and SOURCE_SUBDIR and its consequences + #902 tests: Reduce use of global parser instance + #904 tests: Resolve duplicate handler + #317 #918 tests: Improve tests on doctype closing (ex CVE-2019-15903) + #914 Fix signedness of format strings + #919 #920 Version info bumped from 10:3:9 (libexpat*.so.1.9.3) + to 11:0:10 (libexpat*.so.1.10.0); see https://verbump.de/ + for what these numbers do + + Infrastructure: + #907 CI: Upgrade Clang from 18 to 19 + #913 CI: Drop macos-12 and add macos-15 + #910 CI: Adapt to breaking changes in GitHub Actions + #898 Add missing entries to .gitignore + + Special thanks to: + Hanno Böck + José Eduardo Gutiérrez Conejo + José Ricardo Cardona Quesada + Release 2.6.3 Wed September 4 2024 Security fixes: #887 #890 CVE-2024-45490 -- Calling function XML_ParseBuffer with diff --git a/lib/libexpat/README.md b/lib/libexpat/README.md index 180a68e4abb..23d26dad2b9 100644 --- a/lib/libexpat/README.md +++ b/lib/libexpat/README.md @@ -11,7 +11,7 @@ > at the top of the `Changes` file. -# Expat, Release 2.6.3 +# Expat, Release 2.6.4 This is Expat, a C99 library for parsing [XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by @@ -43,9 +43,9 @@ This license is the same as the MIT/X Consortium license. ## Using libexpat in your CMake-Based Project -There are two ways of using libexpat with CMake: +There are three documented ways of using libexpat with CMake: -### a) Module Mode +### a) `find_package` with Module Mode This approach leverages CMake's own [module `FindEXPAT`](https://cmake.org/cmake/help/latest/module/FindEXPAT.html). @@ -70,7 +70,7 @@ target_include_directories(hello PRIVATE ${EXPAT_INCLUDE_DIRS}) target_link_libraries(hello PUBLIC ${EXPAT_LIBRARIES}) ``` -### b) Config Mode +### b) `find_package` with Config Mode This approach requires files from… @@ -98,6 +98,45 @@ add_executable(hello target_link_libraries(hello PUBLIC expat::expat) ``` +### c) The `FetchContent` module + +This approach — as demonstrated below — requires CMake >=3.18 for both the +[`FetchContent` module](https://cmake.org/cmake/help/latest/module/FetchContent.html) +and its support for the `SOURCE_SUBDIR` option to be available. + +Please note that: +- Use of the `FetchContent` module with *non-release* SHA1s or `master` + of libexpat is neither advised nor considered officially supported. +- Pinning to a specific commit is great for robust CI. +- Pinning to a specific commit needs updating every time there is a new + release of libexpat — either manually or through automation —, + to not miss out on libexpat security updates. + +For an example that pulls in libexpat via Git: + +```cmake +cmake_minimum_required(VERSION 3.18) + +include(FetchContent) + +project(hello VERSION 1.0.0) + +FetchContent_Declare( + expat + GIT_REPOSITORY https://github.com/libexpat/libexpat/ + GIT_TAG 000000000_GIT_COMMIT_SHA1_HERE_000000000 # i.e. Git tag R_0_Y_Z + SOURCE_SUBDIR expat/ +) + +FetchContent_MakeAvailable(expat) + +add_executable(hello + hello.c +) + +target_link_libraries(hello PUBLIC expat) +``` + ## Building from a Git Clone diff --git a/lib/libexpat/doc/reference.html b/lib/libexpat/doc/reference.html index 4cfb2ce9384..c2ae9bb7143 100644 --- a/lib/libexpat/doc/reference.html +++ b/lib/libexpat/doc/reference.html @@ -52,7 +52,7 @@ <div> <h1> The Expat XML Parser - <small>Release 2.6.3</small> + <small>Release 2.6.4</small> </h1> </div> <div class="content"> diff --git a/lib/libexpat/examples/element_declarations.c b/lib/libexpat/examples/element_declarations.c index 7ce8544f6f0..d644b2ffa5e 100644 --- a/lib/libexpat/examples/element_declarations.c +++ b/lib/libexpat/examples/element_declarations.c @@ -15,6 +15,7 @@ Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2019 Zhongyuan Zhou <zhouzhongyuan@huawei.com> + Copyright (c) 2024 Hanno Böck <hanno@gentoo.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -127,15 +128,15 @@ dumpContentModelElement(const XML_Content *model, unsigned level, } // Node - printf("[%u] type=%s(%d), quant=%s(%d)", (unsigned)(model - root), - contentTypeName(model->type), model->type, - contentQuantName(model->quant), model->quant); + printf("[%u] type=%s(%u), quant=%s(%u)", (unsigned)(model - root), + contentTypeName(model->type), (unsigned int)model->type, + contentQuantName(model->quant), (unsigned int)model->quant); if (model->name) { printf(", name=\"%" XML_FMT_STR "\"", model->name); } else { printf(", name=NULL"); } - printf(", numchildren=%d", model->numchildren); + printf(", numchildren=%u", model->numchildren); printf("\n"); } diff --git a/lib/libexpat/lib/expat.h b/lib/libexpat/lib/expat.h index d0d6015a662..523b37d8d57 100644 --- a/lib/libexpat/lib/expat.h +++ b/lib/libexpat/lib/expat.h @@ -130,7 +130,9 @@ enum XML_Error { /* Added in 2.3.0. */ XML_ERROR_NO_BUFFER, /* Added in 2.4.0. */ - XML_ERROR_AMPLIFICATION_LIMIT_BREACH + XML_ERROR_AMPLIFICATION_LIMIT_BREACH, + /* Added in 2.6.4. */ + XML_ERROR_NOT_STARTED, }; enum XML_Content_Type { @@ -1066,7 +1068,7 @@ XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled); */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 6 -#define XML_MICRO_VERSION 3 +#define XML_MICRO_VERSION 4 #ifdef __cplusplus } diff --git a/lib/libexpat/lib/xmlparse.c b/lib/libexpat/lib/xmlparse.c index d9285b213b3..a4e091e7c33 100644 --- a/lib/libexpat/lib/xmlparse.c +++ b/lib/libexpat/lib/xmlparse.c @@ -1,4 +1,4 @@ -/* ba4cdf9bdb534f355a9def4c9e25d20ee8e72f95b0a4d930be52e563f5080196 (2.6.3+) +/* c5625880f4bf417c1463deee4eb92d86ff413f802048621c57e25fe483eb59e4 (2.6.4+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -40,6 +40,7 @@ Copyright (c) 2023 Owain Davies <owaind@bath.edu> Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com> Copyright (c) 2024 Berkay Eren Ürün <berkay.ueruen@siemens.com> + Copyright (c) 2024 Hanno Böck <hanno@gentoo.org> Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -2234,6 +2235,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { if (parser == NULL) return XML_STATUS_ERROR; switch (parser->m_parsingStatus.parsing) { + case XML_INITIALIZED: + parser->m_errorCode = XML_ERROR_NOT_STARTED; + return XML_STATUS_ERROR; case XML_SUSPENDED: if (resumable) { parser->m_errorCode = XML_ERROR_SUSPENDED; @@ -2244,7 +2248,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { case XML_FINISHED: parser->m_errorCode = XML_ERROR_FINISHED; return XML_STATUS_ERROR; - default: + case XML_PARSING: if (resumable) { #ifdef XML_DTD if (parser->m_isParamEntity) { @@ -2255,6 +2259,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { parser->m_parsingStatus.parsing = XML_SUSPENDED; } else parser->m_parsingStatus.parsing = XML_FINISHED; + break; + default: + assert(0); } return XML_STATUS_OK; } @@ -2519,6 +2526,9 @@ XML_ErrorString(enum XML_Error code) { case XML_ERROR_AMPLIFICATION_LIMIT_BREACH: return XML_L( "limit on input amplification factor (from DTD and entities) breached"); + /* Added in 2.6.4. */ + case XML_ERROR_NOT_STARTED: + return XML_L("parser not started"); } return NULL; } @@ -7856,7 +7866,7 @@ accountingReportDiff(XML_Parser rootParser, assert(! rootParser->m_parentParser); fprintf(stderr, - " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"", + " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%u, xmlparse.c:%d) %*s\"", bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP", levelsAwayFromRootParser, source_line, 10, ""); @@ -7969,7 +7979,7 @@ entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity, fprintf( stderr, - "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d (xmlparse.c:%d)\n", + "expat: Entities(%p): Count %9u, depth %2u/%2u %*s%s%s; %s length %d (xmlparse.c:%d)\n", (void *)rootParser, rootParser->m_entity_stats.countEverOpened, rootParser->m_entity_stats.currentDepth, rootParser->m_entity_stats.maximumDepthSeen, diff --git a/lib/libexpat/shlib_version b/lib/libexpat/shlib_version index 7cc7abc9d73..77913220429 100644 --- a/lib/libexpat/shlib_version +++ b/lib/libexpat/shlib_version @@ -1,2 +1,2 @@ -major=14 -minor=1 +major=15 +minor=0 diff --git a/lib/libexpat/tests/basic_tests.c b/lib/libexpat/tests/basic_tests.c index 5dba5ed594f..cb124a24ecd 100644 --- a/lib/libexpat/tests/basic_tests.c +++ b/lib/libexpat/tests/basic_tests.c @@ -2357,11 +2357,20 @@ START_TEST(test_attributes) { info[0].attributes = doc_info; info[1].attributes = tag_info; - XML_SetStartElementHandler(g_parser, counting_start_element_handler); - XML_SetUserData(g_parser, info); - if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) + XML_Parser parser = XML_ParserCreate(NULL); + assert_true(parser != NULL); + ParserAndElementInfo parserAndElementInfos = { + parser, + info, + }; + + XML_SetStartElementHandler(parser, counting_start_element_handler); + XML_SetUserData(parser, &parserAndElementInfos); + if (_XML_Parse_SINGLE_BYTES(parser, text, (int)strlen(text), XML_TRUE) == XML_STATUS_ERROR) - xml_failure(g_parser); + xml_failure(parser); + + XML_ParserFree(parser); } END_TEST diff --git a/lib/libexpat/tests/common.c b/lib/libexpat/tests/common.c index 26d0c5473a6..3aea8d74d1e 100644 --- a/lib/libexpat/tests/common.c +++ b/lib/libexpat/tests/common.c @@ -10,7 +10,7 @@ Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2017 Joe Orton <jorton@redhat.com> Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> @@ -51,6 +51,7 @@ #include "chardata.h" #include "minicheck.h" #include "common.h" +#include "handlers.h" /* Common test data */ @@ -221,30 +222,6 @@ _expect_failure(const char *text, enum XML_Error 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) { @@ -273,12 +250,6 @@ _run_attribute_check(const char *text, const XML_Char *expected, 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) { diff --git a/lib/libexpat/tests/common.h b/lib/libexpat/tests/common.h index 52f00cc0eeb..bc4c7da6807 100644 --- a/lib/libexpat/tests/common.h +++ b/lib/libexpat/tests/common.h @@ -10,7 +10,7 @@ Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net> Copyright (c) 2005-2007 Steven Solie <steven@solie.ca> Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net> - Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> Copyright (c) 2017 Joe Orton <jorton@redhat.com> Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com> @@ -111,12 +111,6 @@ extern void _expect_failure(const char *text, enum XML_Error errorCode, /* 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); @@ -135,9 +129,6 @@ typedef struct ExtTest { 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); diff --git a/lib/libexpat/tests/handlers.c b/lib/libexpat/tests/handlers.c index 449ada70f9a..0211985fe95 100644 --- a/lib/libexpat/tests/handlers.c +++ b/lib/libexpat/tests/handlers.c @@ -103,7 +103,9 @@ end_element_event_handler2(void *userData, const XML_Char *name) { void XMLCALL counting_start_element_handler(void *userData, const XML_Char *name, const XML_Char **atts) { - ElementInfo *info = (ElementInfo *)userData; + ParserAndElementInfo *const parserAndElementInfos + = (ParserAndElementInfo *)userData; + ElementInfo *info = parserAndElementInfos->info; AttrInfo *attr; int count, id, i; @@ -120,12 +122,12 @@ counting_start_element_handler(void *userData, const XML_Char *name, * is possibly a little unexpected, but it is what the * documentation in expat.h tells us to expect. */ - count = XML_GetSpecifiedAttributeCount(g_parser); + count = XML_GetSpecifiedAttributeCount(parserAndElementInfos->parser); if (info->attr_count * 2 != count) { fail("Not got expected attribute count"); return; } - id = XML_GetIdAttributeIndex(g_parser); + id = XML_GetIdAttributeIndex(parserAndElementInfos->parser); if (id == -1 && info->id_name != NULL) { fail("ID not present"); return; @@ -1881,12 +1883,6 @@ accumulate_entity_decl(void *userData, const XML_Char *entityName, } void XMLCALL -accumulate_char_data(void *userData, const XML_Char *s, int len) { - CharData *const storage = (CharData *)userData; - CharData_AppendXMLChars(storage, s, len); -} - -void XMLCALL accumulate_start_element(void *userData, const XML_Char *name, const XML_Char **atts) { CharData *const storage = (CharData *)userData; @@ -1911,6 +1907,34 @@ accumulate_start_element(void *userData, const XML_Char *name, } void XMLCALL +accumulate_characters(void *userData, const XML_Char *s, int len) { + CharData *const storage = (CharData *)userData; + CharData_AppendXMLChars(storage, s, len); +} + +void XMLCALL +accumulate_attribute(void *userData, const XML_Char *name, + const XML_Char **atts) { + CharData *const 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 XMLCALL +ext_accumulate_characters(void *userData, const XML_Char *s, int len) { + ExtTest *const test_data = (ExtTest *)userData; + accumulate_characters(test_data->storage, s, len); +} + +void XMLCALL checking_default_handler(void *userData, const XML_Char *s, int len) { DefaultCheck *data = (DefaultCheck *)userData; int i; diff --git a/lib/libexpat/tests/handlers.h b/lib/libexpat/tests/handlers.h index e1f0995f79e..8850bb948da 100644 --- a/lib/libexpat/tests/handlers.h +++ b/lib/libexpat/tests/handlers.h @@ -92,6 +92,11 @@ typedef struct elementInfo { AttrInfo *attributes; } ElementInfo; +typedef struct StructParserAndElementInfo { + XML_Parser parser; + ElementInfo *info; +} ParserAndElementInfo; + extern void XMLCALL counting_start_element_handler(void *userData, const XML_Char *name, const XML_Char **atts); @@ -564,13 +569,19 @@ extern void XMLCALL accumulate_entity_decl( const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); -extern void XMLCALL accumulate_char_data(void *userData, const XML_Char *s, - int len); - extern void XMLCALL accumulate_start_element(void *userData, const XML_Char *name, const XML_Char **atts); +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 XMLCALL ext_accumulate_characters(void *userData, const XML_Char *s, + int len); + typedef struct default_check { const XML_Char *expected; const int expectedLen; diff --git a/lib/libexpat/tests/misc_tests.c b/lib/libexpat/tests/misc_tests.c index 2ee9320b139..9afe0922d6b 100644 --- a/lib/libexpat/tests/misc_tests.c +++ b/lib/libexpat/tests/misc_tests.c @@ -208,7 +208,7 @@ START_TEST(test_misc_version) { if (! versions_equal(&read_version, &parsed_version)) fail("Version mismatch"); - if (xcstrcmp(version_text, XCS("expat_2.6.3"))) /* needs bump on releases */ + if (xcstrcmp(version_text, XCS("expat_2.6.4"))) /* needs bump on releases */ fail("XML_*_VERSION in expat.h out of sync?\n"); } END_TEST @@ -332,14 +332,15 @@ START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) { "<!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 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;"; + "%e;/>"; const char *const inputIssue317 = "<!DOCTYPE doc [\n" "<!ENTITY % foo ']>\n" "<doc>Hell<oc (#PCDATA)*>'>\n" @@ -447,7 +448,7 @@ START_TEST(test_misc_general_entities_support) { XML_SetExternalEntityRefHandler(parser, external_entity_failer__if_not_xml_ge); XML_SetEntityDeclHandler(parser, accumulate_entity_decl); - XML_SetCharacterDataHandler(parser, accumulate_char_data); + XML_SetCharacterDataHandler(parser, accumulate_characters); if (_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), XML_TRUE) != XML_STATUS_OK) { @@ -496,6 +497,28 @@ START_TEST(test_misc_char_handler_stop_without_leak) { } END_TEST +START_TEST(test_misc_resumeparser_not_crashing) { + XML_Parser parser = XML_ParserCreate(NULL); + XML_GetBuffer(parser, 1); + XML_StopParser(parser, /*resumable=*/XML_TRUE); + XML_ResumeParser(parser); // could crash here, previously + XML_ParserFree(parser); +} +END_TEST + +START_TEST(test_misc_stopparser_rejects_unstarted_parser) { + const XML_Bool cases[] = {XML_TRUE, XML_FALSE}; + for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { + const XML_Bool resumable = cases[i]; + XML_Parser parser = XML_ParserCreate(NULL); + assert_true(XML_GetErrorCode(parser) == XML_ERROR_NONE); + assert_true(XML_StopParser(parser, resumable) == XML_STATUS_ERROR); + assert_true(XML_GetErrorCode(parser) == XML_ERROR_NOT_STARTED); + XML_ParserFree(parser); + } +} +END_TEST + void make_miscellaneous_test_case(Suite *s) { TCase *tc_misc = tcase_create("miscellaneous tests"); @@ -520,4 +543,6 @@ make_miscellaneous_test_case(Suite *s) { test_misc_create_external_entity_parser_with_null_context); tcase_add_test(tc_misc, test_misc_general_entities_support); tcase_add_test(tc_misc, test_misc_char_handler_stop_without_leak); + tcase_add_test(tc_misc, test_misc_resumeparser_not_crashing); + tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser); } |