/* Tests in the "namespace allocation" test case for the Expat test suite __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| | __// \| |_) | (_| | |_ \___/_/\_\ .__/ \__,_|\__| |_| XML parser Copyright (c) 2001-2006 Fred L. Drake, Jr. Copyright (c) 2003 Greg Stein Copyright (c) 2005-2007 Steven Solie Copyright (c) 2005-2012 Karl Waclawek Copyright (c) 2016-2023 Sebastian Pipping Copyright (c) 2017-2022 Rhodri James Copyright (c) 2017 Joe Orton Copyright (c) 2017 José Gutiérrez de la Concha Copyright (c) 2018 Marco Maggi Copyright (c) 2019 David Loffredo Copyright (c) 2020 Tim Gates Copyright (c) 2021 Donghee Na 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 #include #include "expat.h" #include "common.h" #include "minicheck.h" #include "dummy.h" #include "handlers.h" #include "nsalloc_tests.h" static void nsalloc_setup(void) { XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free}; XML_Char ns_sep[2] = {' ', '\0'}; /* Ensure the parser creation will go through */ g_allocation_count = ALLOC_ALWAYS_SUCCEED; g_reallocation_count = REALLOC_ALWAYS_SUCCEED; g_parser = XML_ParserCreate_MM(NULL, &memsuite, ns_sep); if (g_parser == NULL) fail("Parser not created"); } static void nsalloc_teardown(void) { basic_teardown(); } /* Test the effects of allocation failure in simple namespace parsing. * Based on test_ns_default_with_empty_uri() */ START_TEST(test_nsalloc_xmlns) { const char *text = "\n" " \n" ""; unsigned int i; const unsigned int max_alloc_count = 30; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; /* Exercise more code paths with a default handler */ XML_SetDefaultHandler(g_parser, dummy_default_handler); if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* Resetting the parser is insufficient, because some memory * allocations are cached within the parser. Instead we use * the teardown and setup routines to ensure that we have the * right sort of parser back in our hands. */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at maximum allocation count"); } END_TEST /* Test XML_ParseBuffer interface with namespace and a dicky allocator */ START_TEST(test_nsalloc_parse_buffer) { const char *text = "Hello"; void *buffer; /* Try a parse before the start of the world */ /* (Exercises new code path) */ if (XML_ParseBuffer(g_parser, 0, XML_FALSE) != XML_STATUS_ERROR) fail("Pre-init XML_ParseBuffer not faulted"); if (XML_GetErrorCode(g_parser) != XML_ERROR_NO_BUFFER) fail("Pre-init XML_ParseBuffer faulted for wrong reason"); buffer = XML_GetBuffer(g_parser, 1 /* any small number greater than 0 */); if (buffer == NULL) fail("Could not acquire parse buffer"); g_allocation_count = 0; if (XML_ParseBuffer(g_parser, 0, XML_FALSE) != XML_STATUS_ERROR) fail("Pre-init XML_ParseBuffer not faulted"); if (XML_GetErrorCode(g_parser) != XML_ERROR_NO_MEMORY) fail("Pre-init XML_ParseBuffer faulted for wrong reason"); /* Now with actual memory allocation */ g_allocation_count = ALLOC_ALWAYS_SUCCEED; if (XML_ParseBuffer(g_parser, 0, XML_FALSE) != XML_STATUS_OK) xml_failure(g_parser); /* Check that resuming an unsuspended parser is faulted */ if (XML_ResumeParser(g_parser) != XML_STATUS_ERROR) fail("Resuming unsuspended parser not faulted"); if (XML_GetErrorCode(g_parser) != XML_ERROR_NOT_SUSPENDED) xml_failure(g_parser); /* Get the parser into suspended state */ XML_SetCharacterDataHandler(g_parser, clearing_aborting_character_handler); g_resumable = XML_TRUE; buffer = XML_GetBuffer(g_parser, (int)strlen(text)); if (buffer == NULL) fail("Could not acquire parse buffer"); assert(buffer != NULL); memcpy(buffer, text, strlen(text)); if (XML_ParseBuffer(g_parser, (int)strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED) xml_failure(g_parser); if (XML_GetErrorCode(g_parser) != XML_ERROR_NONE) xml_failure(g_parser); if (XML_ParseBuffer(g_parser, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) fail("Suspended XML_ParseBuffer not faulted"); if (XML_GetErrorCode(g_parser) != XML_ERROR_SUSPENDED) xml_failure(g_parser); if (XML_GetBuffer(g_parser, (int)strlen(text)) != NULL) fail("Suspended XML_GetBuffer not faulted"); /* Get it going again and complete the world */ XML_SetCharacterDataHandler(g_parser, NULL); if (XML_ResumeParser(g_parser) != XML_STATUS_OK) xml_failure(g_parser); if (XML_ParseBuffer(g_parser, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) fail("Post-finishing XML_ParseBuffer not faulted"); if (XML_GetErrorCode(g_parser) != XML_ERROR_FINISHED) xml_failure(g_parser); if (XML_GetBuffer(g_parser, (int)strlen(text)) != NULL) fail("Post-finishing XML_GetBuffer not faulted"); } END_TEST /* Check handling of long prefix names (pool growth) */ START_TEST(test_nsalloc_long_prefix) { const char *text = "<" /* 64 characters per line */ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" ":foo xmlns:" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "='http://example.org/'>" ""; int i; const int max_alloc_count = 40; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at max allocation count"); } END_TEST /* Check handling of long uri names (pool growth) */ START_TEST(test_nsalloc_long_uri) { const char *text = "" ""; int i; const int max_alloc_count = 40; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at max allocation count"); } END_TEST /* Test handling of long attribute names with prefixes */ START_TEST(test_nsalloc_long_attr) { const char *text = "" ""; int i; const int max_alloc_count = 40; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at max allocation count"); } END_TEST /* Test handling of an attribute name with a long namespace prefix */ START_TEST(test_nsalloc_long_attr_prefix) { const char *text = "" ""; const XML_Char *elemstr[] = { /* clang-format off */ XCS("http://example.org/ e foo"), XCS("http://example.org/ a ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ") /* clang-format on */ }; int i; const int max_alloc_count = 40; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; 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) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at max allocation count"); } END_TEST /* Test attribute handling in the face of a dodgy reallocator */ START_TEST(test_nsalloc_realloc_attributes) { const char *text = "" ""; int i; const int max_realloc_count = 10; for (i = 0; i < max_realloc_count; i++) { g_reallocation_count = i; if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing reallocations"); else if (i == max_realloc_count) fail("Parsing failed at max reallocation count"); } END_TEST /* Test long element names with namespaces under a failing allocator */ START_TEST(test_nsalloc_long_element) { const char *text = "" ""; const XML_Char *elemstr[] = {XCS("http://example.org/") XCS(" thisisalongenoughelementnametotriggerareallocation foo"), XCS("http://example.org/ a bar")}; int i; const int max_alloc_count = 30; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; 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) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing reallocations"); else if (i == max_alloc_count) fail("Parsing failed at max reallocation count"); } END_TEST /* Test the effects of reallocation failure when reassigning a * binding. * * XML_ParserReset does not free the BINDING structures used by a * parser, but instead adds them to an internal free list to be reused * as necessary. Likewise the URI buffers allocated for the binding * aren't freed, but kept attached to their existing binding. If the * new binding has a longer URI, it will need reallocation. This test * provokes that reallocation, and tests the control path if it fails. */ START_TEST(test_nsalloc_realloc_binding_uri) { const char *first = "\n" " \n" ""; const char *second = "\n" " \n" ""; unsigned i; const unsigned max_realloc_count = 10; /* First, do a full parse that will leave bindings around */ if (_XML_Parse_SINGLE_BYTES(g_parser, first, (int)strlen(first), XML_TRUE) == XML_STATUS_ERROR) xml_failure(g_parser); /* Now repeat with a longer URI and a duff reallocator */ for (i = 0; i < max_realloc_count; i++) { XML_ParserReset(g_parser, NULL); g_reallocation_count = i; if (_XML_Parse_SINGLE_BYTES(g_parser, second, (int)strlen(second), XML_TRUE) != XML_STATUS_ERROR) break; } if (i == 0) fail("Parsing worked despite failing reallocation"); else if (i == max_realloc_count) fail("Parsing failed at max reallocation count"); } END_TEST /* Check handling of long prefix names (pool growth) */ START_TEST(test_nsalloc_realloc_long_prefix) { const char *text = "<" /* 64 characters per line */ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" ":foo xmlns:" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "='http://example.org/'>" ""; int i; const int max_realloc_count = 12; for (i = 0; i < max_realloc_count; i++) { g_reallocation_count = i; if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing reallocations"); else if (i == max_realloc_count) fail("Parsing failed even at max reallocation count"); } END_TEST /* Check handling of even long prefix names (different code path) */ START_TEST(test_nsalloc_realloc_longer_prefix) { const char *text = "<" /* 64 characters per line */ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "Q:foo xmlns:" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "Q='http://example.org/'>" ""; int i; const int max_realloc_count = 12; for (i = 0; i < max_realloc_count; i++) { g_reallocation_count = i; if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing reallocations"); else if (i == max_realloc_count) fail("Parsing failed even at max reallocation count"); } END_TEST START_TEST(test_nsalloc_long_namespace) { const char *text1 = "<" /* 64 characters per line */ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" ":e xmlns:" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "='http://example.org/'>\n"; const char *text2 = "<" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" ":f " "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" ":attr='foo'/>\n" ""; int i; const int max_alloc_count = 40; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; if (_XML_Parse_SINGLE_BYTES(g_parser, text1, (int)strlen(text1), XML_FALSE) != XML_STATUS_ERROR && _XML_Parse_SINGLE_BYTES(g_parser, text2, (int)strlen(text2), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at max allocation count"); } END_TEST /* Using a slightly shorter namespace name provokes allocations in * slightly different places in the code. */ START_TEST(test_nsalloc_less_long_namespace) { const char *text = "<" /* 64 characters per line */ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678" ":e xmlns:" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678" "='http://example.org/'>\n" "<" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678" ":f " "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678" ":att='foo'/>\n" ""; int i; const int max_alloc_count = 40; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at max allocation count"); } END_TEST START_TEST(test_nsalloc_long_context) { const char *text = "\n" " \n" "]>\n" "\n" "&en;" ""; ExtOption options[] = { {XCS("foo"), ""}, {XCS("bar"), ""}, {NULL, NULL}}; int i; const int max_alloc_count = 70; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; XML_SetUserData(g_parser, options); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner); if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at max allocation count"); } END_TEST /* This function is void; it will throw a fail() on error, so if it * returns normally it must have succeeded. */ static void context_realloc_test(const char *text) { ExtOption options[] = { {XCS("foo"), ""}, {XCS("bar"), ""}, {NULL, NULL}}; int i; const int max_realloc_count = 6; for (i = 0; i < max_realloc_count; i++) { g_reallocation_count = i; XML_SetUserData(g_parser, options); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner); if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing reallocations"); else if (i == max_realloc_count) fail("Parsing failed even at max reallocation count"); } START_TEST(test_nsalloc_realloc_long_context) { const char *text = "\n" "]>\n" "\n" "&en;" ""; context_realloc_test(text); } END_TEST START_TEST(test_nsalloc_realloc_long_context_2) { const char *text = "\n" "]>\n" "\n" "&en;" ""; context_realloc_test(text); } END_TEST START_TEST(test_nsalloc_realloc_long_context_3) { const char *text = "\n" "]>\n" "\n" "&en;" ""; context_realloc_test(text); } END_TEST START_TEST(test_nsalloc_realloc_long_context_4) { const char *text = "\n" "]>\n" "\n" "&en;" ""; context_realloc_test(text); } END_TEST START_TEST(test_nsalloc_realloc_long_context_5) { const char *text = "\n" "]>\n" "\n" "&en;" ""; context_realloc_test(text); } END_TEST START_TEST(test_nsalloc_realloc_long_context_6) { const char *text = "\n" "]>\n" "\n" "&en;" ""; context_realloc_test(text); } END_TEST START_TEST(test_nsalloc_realloc_long_context_7) { const char *text = "\n" "]>\n" "\n" "&en;" ""; context_realloc_test(text); } END_TEST START_TEST(test_nsalloc_realloc_long_ge_name) { const char *text = "\n" "]>\n" "\n" "&" /* 64 characters per line */ "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" ";" ""; ExtOption options[] = { {XCS("foo"), ""}, {XCS("bar"), ""}, {NULL, NULL}}; int i; const int max_realloc_count = 10; for (i = 0; i < max_realloc_count; i++) { g_reallocation_count = i; XML_SetUserData(g_parser, options); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner); if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing reallocations"); else if (i == max_realloc_count) fail("Parsing failed even at max reallocation count"); } END_TEST /* Test that when a namespace is passed through the context mechanism * to an external entity parser, the parsers handle reallocation * failures correctly. The prefix is exactly the right length to * provoke particular uncommon code paths. */ START_TEST(test_nsalloc_realloc_long_context_in_dtd) { const char *text1 = "\n" "]>\n" "<" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" ":doc xmlns:" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP" "='foo/Second'>&First;"; const char *text2 = ""; ExtOption options[] = {{XCS("foo/First"), "Hello world"}, {NULL, NULL}}; int i; const int max_realloc_count = 20; for (i = 0; i < max_realloc_count; i++) { g_reallocation_count = i; XML_SetUserData(g_parser, options); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner); if (_XML_Parse_SINGLE_BYTES(g_parser, text1, (int)strlen(text1), XML_FALSE) != XML_STATUS_ERROR && _XML_Parse_SINGLE_BYTES(g_parser, text2, (int)strlen(text2), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing reallocations"); else if (i == max_realloc_count) fail("Parsing failed even at max reallocation count"); } END_TEST START_TEST(test_nsalloc_long_default_in_ext) { const char *text = "\n" " \n" "]>\n" "&x;"; ExtOption options[] = {{XCS("foo"), ""}, {NULL, NULL}}; int i; const int max_alloc_count = 50; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; XML_SetUserData(g_parser, options); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner); if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at max allocation count"); } END_TEST START_TEST(test_nsalloc_long_systemid_in_ext) { const char *text = "\n" "]>\n" "&en;"; ExtOption options[] = { {XCS("foo"), ""}, {/* clang-format off */ XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/") XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"), /* clang-format on */ ""}, {NULL, NULL}}; int i; const int max_alloc_count = 55; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; XML_SetUserData(g_parser, options); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner); if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Parsing worked despite failing allocations"); else if (i == max_alloc_count) fail("Parsing failed even at max allocation count"); } END_TEST /* Test the effects of allocation failure on parsing an element in a * namespace. Based on test_nsalloc_long_context. */ START_TEST(test_nsalloc_prefixed_element) { const char *text = "\n" " \n" "]>\n" "\n" "&en;" ""; ExtOption options[] = { {XCS("foo"), ""}, {XCS("bar"), ""}, {NULL, NULL}}; int i; const int max_alloc_count = 70; for (i = 0; i < max_alloc_count; i++) { g_allocation_count = i; XML_SetUserData(g_parser, options); XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS); XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner); if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR) break; /* See comment in test_nsalloc_xmlns() */ nsalloc_teardown(); nsalloc_setup(); } if (i == 0) fail("Success despite failing allocator"); else if (i == max_alloc_count) fail("Failed even at full allocation count"); } END_TEST void make_nsalloc_test_case(Suite *s) { TCase *tc_nsalloc = tcase_create("namespace allocation tests"); suite_add_tcase(s, tc_nsalloc); tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown); tcase_add_test(tc_nsalloc, test_nsalloc_xmlns); tcase_add_test(tc_nsalloc, test_nsalloc_parse_buffer); tcase_add_test(tc_nsalloc, test_nsalloc_long_prefix); tcase_add_test(tc_nsalloc, test_nsalloc_long_uri); tcase_add_test(tc_nsalloc, test_nsalloc_long_attr); tcase_add_test(tc_nsalloc, test_nsalloc_long_attr_prefix); tcase_add_test(tc_nsalloc, test_nsalloc_realloc_attributes); tcase_add_test(tc_nsalloc, test_nsalloc_long_element); tcase_add_test(tc_nsalloc, test_nsalloc_realloc_binding_uri); tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_prefix); tcase_add_test(tc_nsalloc, test_nsalloc_realloc_longer_prefix); tcase_add_test(tc_nsalloc, test_nsalloc_long_namespace); tcase_add_test(tc_nsalloc, test_nsalloc_less_long_namespace); tcase_add_test(tc_nsalloc, test_nsalloc_long_context); tcase_add_test__if_xml_ge(tc_nsalloc, test_nsalloc_realloc_long_context); tcase_add_test__if_xml_ge(tc_nsalloc, test_nsalloc_realloc_long_context_2); tcase_add_test__if_xml_ge(tc_nsalloc, test_nsalloc_realloc_long_context_3); tcase_add_test__if_xml_ge(tc_nsalloc, test_nsalloc_realloc_long_context_4); tcase_add_test__if_xml_ge(tc_nsalloc, test_nsalloc_realloc_long_context_5); tcase_add_test__if_xml_ge(tc_nsalloc, test_nsalloc_realloc_long_context_6); tcase_add_test__if_xml_ge(tc_nsalloc, test_nsalloc_realloc_long_context_7); tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_ge_name); tcase_add_test__if_xml_ge(tc_nsalloc, test_nsalloc_realloc_long_context_in_dtd); tcase_add_test__if_xml_ge(tc_nsalloc, test_nsalloc_long_default_in_ext); tcase_add_test(tc_nsalloc, test_nsalloc_long_systemid_in_ext); tcase_add_test(tc_nsalloc, test_nsalloc_prefixed_element); }