#undef MAX_ALLOC_COUNT
END_TEST
+typedef struct ExtOption {
+ const char *system_id;
+ const char *parse_text;
+} ExtOption;
+
+static int XMLCALL
+external_entity_optioner(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *UNUSED_P(base),
+ const XML_Char *systemId,
+ const XML_Char *UNUSED_P(publicId))
+{
+ ExtOption *options = (ExtOption *)XML_GetUserData(parser);
+ XML_Parser ext_parser;
+
+ while (options->parse_text != NULL) {
+ if (!strcmp(systemId, options->system_id)) {
+ ext_parser =
+ XML_ExternalEntityParserCreate(parser, context, NULL);
+ if (ext_parser == NULL)
+ return XML_STATUS_ERROR;
+ if (_XML_Parse_SINGLE_BYTES(ext_parser, options->parse_text,
+ strlen(options->parse_text),
+ XML_TRUE) == XML_STATUS_ERROR)
+ return XML_STATUS_ERROR;
+ XML_ParserFree(ext_parser);
+ return XML_STATUS_OK;
+ }
+ options++;
+ }
+ fail("No suitable option found");
+ return XML_STATUS_ERROR;
+}
+
+START_TEST(test_nsalloc_realloc_long_context)
+{
+ const char *text =
+ "<!DOCTYPE doc SYSTEM 'foo' [\n"
+ " <!ENTITY en SYSTEM 'bar'>\n"
+ "]>\n"
+ "<doc xmlns='http://example.org/"
+ /* 64 characters per line */
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
+ "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKL"
+ "'>\n"
+ "&en;"
+ "</doc>";
+ ExtOption options[] = {
+ { "foo", "<!ELEMENT e EMPTY>"},
+ { "bar", "<e/>" },
+ { NULL, NULL }
+ };
+ int i;
+#define MAX_REALLOC_COUNT 5
+
+ for (i = 0; i < MAX_REALLOC_COUNT; i++) {
+ reallocation_count = i;
+ XML_SetUserData(parser, options);
+ XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
+ XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
+ if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
+ XML_TRUE) != XML_STATUS_ERROR)
+ break;
+ XML_ParserReset(parser, NULL);
+ }
+ if (i == 0)
+ fail("Parsing worked despite failing reallocations");
+ else if (i == MAX_REALLOC_COUNT)
+ fail("Parsing failed even at max reallocation count");
+}
+#undef MAX_REALLOC_COUNT
+END_TEST
+
static Suite *
make_suite(void)
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_realloc_long_context);
return s;
}