}
END_TEST
+/* Same test for external entity parsers */
+static int XMLCALL
+external_entity_reallocator(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *UNUSED_P(base),
+ const XML_Char *UNUSED_P(systemId),
+ const XML_Char *UNUSED_P(publicId))
+{
+ const char *text = get_buffer_test_text;
+ XML_Parser ext_parser;
+ void *buffer;
+ enum XML_Status status;
+
+ ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
+ if (ext_parser == NULL)
+ fail("Could not create external entity parser");
+
+ reallocation_count = (intptr_t)XML_GetUserData(parser);
+ buffer = XML_GetBuffer(ext_parser, 1536);
+ if (buffer == NULL)
+ fail("Buffer allocation failed");
+ memcpy(buffer, text, strlen(text));
+ status = XML_ParseBuffer(ext_parser, strlen(text), XML_FALSE);
+ reallocation_count = -1;
+ XML_ParserFree(ext_parser);
+ return (status == XML_STATUS_OK) ? 1 : 0;
+}
+
+START_TEST(test_alloc_ext_entity_realloc_buffer)
+{
+ const char *text =
+ "<!DOCTYPE doc [\n"
+ " <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
+ "]>\n"
+ "<doc>&en;</doc>";
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ XML_SetExternalEntityRefHandler(parser,
+ external_entity_reallocator);
+ XML_SetUserData(parser, (void *)(intptr_t)i);
+ if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
+ XML_TRUE) == XML_STATUS_OK)
+ break;
+ XML_ParserReset(parser, NULL);
+ }
+ if (i == 0)
+ fail("Succeeded with no reallocations");
+ if (i == 10)
+ fail("Failed with 10 reallocations");
+}
+END_TEST
+
+/* Test elements with many attributes are handled correctly */
+START_TEST(test_alloc_realloc_many_attributes)
+{
+ const char *text =
+ "<!DOCTYPE doc [\n"
+ "<!ATTLIST doc za CDATA 'default'>\n"
+ "<!ATTLIST doc zb CDATA 'def2'>\n"
+ "<!ATTLIST doc zc CDATA 'def3'>\n"
+ "]>\n"
+ "<doc a='1'"
+ " b='2'"
+ " c='3'"
+ " d='4'"
+ " e='5'"
+ " f='6'"
+ " g='7'"
+ " h='8'"
+ " i='9'"
+ " j='10'"
+ " k='11'"
+ " l='12'"
+ " m='13'"
+ " n='14'"
+ " p='15'>"
+ "</doc>";
+ int i;
+#define MAX_REALLOC_COUNT 10
+
+ for (i = 0; i < MAX_REALLOC_COUNT; i++) {
+ reallocation_count = i;
+ if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
+ XML_TRUE) != XML_STATUS_ERROR)
+ break;
+ XML_ParserReset(parser, NULL);
+ }
+ if (i == 0)
+ fail("Parse succeeded despite no reallocations");
+ if (i == MAX_REALLOC_COUNT)
+ fail("Parse failed at max reallocations");
+#undef MAX_REALLOC_COUNT
+}
+END_TEST
+
+
static void
nsalloc_setup(void)
{
tcase_add_test(tc_alloc, test_alloc_explicit_encoding);
tcase_add_test(tc_alloc, test_alloc_set_base);
tcase_add_test(tc_alloc, test_alloc_realloc_buffer);
+ tcase_add_test(tc_alloc, test_alloc_ext_entity_realloc_buffer);
+ tcase_add_test(tc_alloc, test_alloc_realloc_many_attributes);
suite_add_tcase(s, tc_nsalloc);
tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown);