Home | History | Annotate | Download | only in tests
      1 /* Run the Expat test suite
      2                             __  __            _
      3                          ___\ \/ /_ __   __ _| |_
      4                         / _ \\  /| '_ \ / _` | __|
      5                        |  __//  \| |_) | (_| | |_
      6                         \___/_/\_\ .__/ \__,_|\__|
      7                                  |_| XML parser
      8 
      9    Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
     10    Copyright (c) 2000-2017 Expat development team
     11    Licensed under the MIT license:
     12 
     13    Permission is  hereby granted,  free of charge,  to any  person obtaining
     14    a  copy  of  this  software   and  associated  documentation  files  (the
     15    "Software"),  to  deal in  the  Software  without restriction,  including
     16    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
     17    distribute, sublicense, and/or sell copies of the Software, and to permit
     18    persons  to whom  the Software  is  furnished to  do so,  subject to  the
     19    following conditions:
     20 
     21    The above copyright  notice and this permission notice  shall be included
     22    in all copies or substantial portions of the Software.
     23 
     24    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
     25    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
     26    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
     27    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
     28    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
     29    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     30    USE OR OTHER DEALINGS IN THE SOFTWARE.
     31 */
     32 
     33 #if defined(NDEBUG)
     34 # undef NDEBUG  /* because test suite relies on assert(...) at the moment */
     35 #endif
     36 
     37 #ifdef HAVE_EXPAT_CONFIG_H
     38 # include <expat_config.h>
     39 #endif
     40 
     41 #include <assert.h>
     42 #include <stdlib.h>
     43 #include <stdio.h>
     44 #include <string.h>
     45 #include <stdint.h>
     46 #include <stddef.h>  /* ptrdiff_t */
     47 #include <ctype.h>
     48 #include <limits.h>
     49 
     50 #if ! defined(__cplusplus)
     51 # if defined(_MSC_VER) && (_MSC_VER <= 1700)
     52    /* for vs2012/11.0/1700 and earlier Visual Studio compilers */
     53 #  define bool   int
     54 #  define false  0
     55 #  define true   1
     56 # else
     57 #  include <stdbool.h>
     58 # endif
     59 #endif
     60 
     61 
     62 #include "expat.h"
     63 #include "chardata.h"
     64 #include "structdata.h"
     65 #include "internal.h"  /* for UNUSED_P only */
     66 #include "minicheck.h"
     67 #include "memcheck.h"
     68 #include "siphash.h"
     69 #include "ascii.h" /* for ASCII_xxx */
     70 
     71 #ifdef XML_LARGE_SIZE
     72 # define XML_FMT_INT_MOD "ll"
     73 #else
     74 # define XML_FMT_INT_MOD "l"
     75 #endif
     76 
     77 #ifdef XML_UNICODE_WCHAR_T
     78 # define XML_FMT_CHAR "lc"
     79 # define XML_FMT_STR "ls"
     80 # include <wchar.h>
     81 # define xcstrlen(s) wcslen(s)
     82 # define xcstrcmp(s, t) wcscmp((s), (t))
     83 # define xcstrncmp(s, t, n) wcsncmp((s), (t), (n))
     84 # define XCS(s) _XCS(s)
     85 # define _XCS(s) L ## s
     86 #else
     87 # ifdef XML_UNICODE
     88 #  error "No support for UTF-16 character without wchar_t in tests"
     89 # else
     90 #  define XML_FMT_CHAR "c"
     91 #  define XML_FMT_STR "s"
     92 #  define xcstrlen(s) strlen(s)
     93 #  define xcstrcmp(s, t) strcmp((s), (t))
     94 #  define xcstrncmp(s, t, n) strncmp((s), (t), (n))
     95 #  define XCS(s) s
     96 # endif /* XML_UNICODE */
     97 #endif /* XML_UNICODE_WCHAR_T */
     98 
     99 
    100 static XML_Parser parser = NULL;
    101 
    102 
    103 static void
    104 basic_setup(void)
    105 {
    106     parser = XML_ParserCreate(NULL);
    107     if (parser == NULL)
    108         fail("Parser not created.");
    109 }
    110 
    111 static void
    112 basic_teardown(void)
    113 {
    114     if (parser != NULL) {
    115         XML_ParserFree(parser);
    116         parser = NULL;
    117     }
    118 }
    119 
    120 /* Generate a failure using the parser state to create an error message;
    121    this should be used when the parser reports an error we weren't
    122    expecting.
    123 */
    124 static void
    125 _xml_failure(XML_Parser parser, const char *file, int line)
    126 {
    127     char buffer[1024];
    128     enum XML_Error err = XML_GetErrorCode(parser);
    129     sprintf(buffer,
    130             "    %d: %" XML_FMT_STR " (line %"
    131                 XML_FMT_INT_MOD "u, offset %"
    132                 XML_FMT_INT_MOD "u)\n    reported from %s, line %d\n",
    133             err,
    134             XML_ErrorString(err),
    135             XML_GetCurrentLineNumber(parser),
    136             XML_GetCurrentColumnNumber(parser),
    137             file, line);
    138     _fail_unless(0, file, line, buffer);
    139 }
    140 
    141 static enum XML_Status
    142 _XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len, int isFinal)
    143 {
    144     enum XML_Status res = XML_STATUS_ERROR;
    145     int offset = 0;
    146 
    147     if (len == 0) {
    148         return XML_Parse(parser, s, len, isFinal);
    149     }
    150 
    151     for (; offset < len; offset++) {
    152         const int innerIsFinal = (offset == len - 1) && isFinal;
    153         const char c = s[offset]; /* to help out-of-bounds detection */
    154         res = XML_Parse(parser, &c, sizeof(char), innerIsFinal);
    155         if (res != XML_STATUS_OK) {
    156             return res;
    157         }
    158     }
    159     return res;
    160 }
    161 
    162 #define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
    163 
    164 static void
    165 _expect_failure(const char *text, enum XML_Error errorCode, const char *errorMessage,
    166                 const char *file, int lineno)
    167 {
    168     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK)
    169         /* Hackish use of _fail_unless() macro, but let's us report
    170            the right filename and line number. */
    171         _fail_unless(0, file, lineno, errorMessage);
    172     if (XML_GetErrorCode(parser) != errorCode)
    173         _xml_failure(parser, file, lineno);
    174 }
    175 
    176 #define expect_failure(text, errorCode, errorMessage) \
    177         _expect_failure((text), (errorCode), (errorMessage), \
    178                         __FILE__, __LINE__)
    179 
    180 /* Dummy handlers for when we need to set a handler to tickle a bug,
    181    but it doesn't need to do anything.
    182 */
    183 static unsigned long dummy_handler_flags = 0;
    184 
    185 #define DUMMY_START_DOCTYPE_HANDLER_FLAG        (1UL << 0)
    186 #define DUMMY_END_DOCTYPE_HANDLER_FLAG          (1UL << 1)
    187 #define DUMMY_ENTITY_DECL_HANDLER_FLAG          (1UL << 2)
    188 #define DUMMY_NOTATION_DECL_HANDLER_FLAG        (1UL << 3)
    189 #define DUMMY_ELEMENT_DECL_HANDLER_FLAG         (1UL << 4)
    190 #define DUMMY_ATTLIST_DECL_HANDLER_FLAG         (1UL << 5)
    191 #define DUMMY_COMMENT_HANDLER_FLAG              (1UL << 6)
    192 #define DUMMY_PI_HANDLER_FLAG                   (1UL << 7)
    193 #define DUMMY_START_ELEMENT_HANDLER_FLAG        (1UL << 8)
    194 #define DUMMY_START_CDATA_HANDLER_FLAG          (1UL << 9)
    195 #define DUMMY_END_CDATA_HANDLER_FLAG            (1UL << 10)
    196 #define DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG (1UL << 11)
    197 #define DUMMY_START_NS_DECL_HANDLER_FLAG        (1UL << 12)
    198 #define DUMMY_END_NS_DECL_HANDLER_FLAG          (1UL << 13)
    199 #define DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG   (1UL << 14)
    200 #define DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG     (1UL << 15)
    201 #define DUMMY_SKIP_HANDLER_FLAG                 (1UL << 16)
    202 #define DUMMY_DEFAULT_HANDLER_FLAG              (1UL << 17)
    203 
    204 
    205 static void XMLCALL
    206 dummy_xdecl_handler(void *UNUSED_P(userData),
    207                     const XML_Char *UNUSED_P(version),
    208                     const XML_Char *UNUSED_P(encoding),
    209                     int UNUSED_P(standalone))
    210 {}
    211 
    212 static void XMLCALL
    213 dummy_start_doctype_handler(void           *UNUSED_P(userData),
    214                             const XML_Char *UNUSED_P(doctypeName),
    215                             const XML_Char *UNUSED_P(sysid),
    216                             const XML_Char *UNUSED_P(pubid),
    217                             int            UNUSED_P(has_internal_subset))
    218 {
    219     dummy_handler_flags |= DUMMY_START_DOCTYPE_HANDLER_FLAG;
    220 }
    221 
    222 static void XMLCALL
    223 dummy_end_doctype_handler(void *UNUSED_P(userData))
    224 {
    225     dummy_handler_flags |= DUMMY_END_DOCTYPE_HANDLER_FLAG;
    226 }
    227 
    228 static void XMLCALL
    229 dummy_entity_decl_handler(void           *UNUSED_P(userData),
    230                           const XML_Char *UNUSED_P(entityName),
    231                           int            UNUSED_P(is_parameter_entity),
    232                           const XML_Char *UNUSED_P(value),
    233                           int            UNUSED_P(value_length),
    234                           const XML_Char *UNUSED_P(base),
    235                           const XML_Char *UNUSED_P(systemId),
    236                           const XML_Char *UNUSED_P(publicId),
    237                           const XML_Char *UNUSED_P(notationName))
    238 {
    239     dummy_handler_flags |= DUMMY_ENTITY_DECL_HANDLER_FLAG;
    240 }
    241 
    242 static void XMLCALL
    243 dummy_notation_decl_handler(void *UNUSED_P(userData),
    244                             const XML_Char *UNUSED_P(notationName),
    245                             const XML_Char *UNUSED_P(base),
    246                             const XML_Char *UNUSED_P(systemId),
    247                             const XML_Char *UNUSED_P(publicId))
    248 {
    249     dummy_handler_flags |= DUMMY_NOTATION_DECL_HANDLER_FLAG;
    250 }
    251 
    252 static void XMLCALL
    253 dummy_element_decl_handler(void *UNUSED_P(userData),
    254                            const XML_Char *UNUSED_P(name),
    255                            XML_Content *model)
    256 {
    257     /* The content model must be freed by the handler.  Unfortunately
    258      * we cannot pass the parser as the userData because this is used
    259      * with other handlers that require other userData.
    260      */
    261     XML_FreeContentModel(parser, model);
    262     dummy_handler_flags |= DUMMY_ELEMENT_DECL_HANDLER_FLAG;
    263 }
    264 
    265 static void XMLCALL
    266 dummy_attlist_decl_handler(void           *UNUSED_P(userData),
    267                            const XML_Char *UNUSED_P(elname),
    268                            const XML_Char *UNUSED_P(attname),
    269                            const XML_Char *UNUSED_P(att_type),
    270                            const XML_Char *UNUSED_P(dflt),
    271                            int            UNUSED_P(isrequired))
    272 {
    273     dummy_handler_flags |= DUMMY_ATTLIST_DECL_HANDLER_FLAG;
    274 }
    275 
    276 static void XMLCALL
    277 dummy_comment_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(data))
    278 {
    279     dummy_handler_flags |= DUMMY_COMMENT_HANDLER_FLAG;
    280 }
    281 
    282 static void XMLCALL
    283 dummy_pi_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(target), const XML_Char *UNUSED_P(data))
    284 {
    285     dummy_handler_flags |= DUMMY_PI_HANDLER_FLAG;
    286 }
    287 
    288 static void XMLCALL
    289 dummy_start_element(void *UNUSED_P(userData),
    290                     const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
    291 {
    292     dummy_handler_flags |= DUMMY_START_ELEMENT_HANDLER_FLAG;
    293 }
    294 
    295 static void XMLCALL
    296 dummy_end_element(void *UNUSED_P(userData), const XML_Char *UNUSED_P(name))
    297 {}
    298 
    299 static void XMLCALL
    300 dummy_start_cdata_handler(void *UNUSED_P(userData))
    301 {
    302     dummy_handler_flags |= DUMMY_START_CDATA_HANDLER_FLAG;
    303 }
    304 
    305 static void XMLCALL
    306 dummy_end_cdata_handler(void *UNUSED_P(userData))
    307 {
    308     dummy_handler_flags |= DUMMY_END_CDATA_HANDLER_FLAG;
    309 }
    310 
    311 static void XMLCALL
    312 dummy_cdata_handler(void *UNUSED_P(userData),
    313                     const XML_Char *UNUSED_P(s),
    314                     int UNUSED_P(len))
    315 {}
    316 
    317 static void XMLCALL
    318 dummy_start_namespace_decl_handler(void *UNUSED_P(userData),
    319                                    const XML_Char *UNUSED_P(prefix),
    320                                    const XML_Char *UNUSED_P(uri))
    321 {
    322     dummy_handler_flags |= DUMMY_START_NS_DECL_HANDLER_FLAG;
    323 }
    324 
    325 static void XMLCALL
    326 dummy_end_namespace_decl_handler(void *UNUSED_P(userData),
    327                                  const XML_Char *UNUSED_P(prefix))
    328 {
    329     dummy_handler_flags |= DUMMY_END_NS_DECL_HANDLER_FLAG;
    330 }
    331 
    332 /* This handler is obsolete, but while the code exists we should
    333  * ensure that dealing with the handler is covered by tests.
    334  */
    335 static void XMLCALL
    336 dummy_unparsed_entity_decl_handler(void *UNUSED_P(userData),
    337                                    const XML_Char *UNUSED_P(entityName),
    338                                    const XML_Char *UNUSED_P(base),
    339                                    const XML_Char *UNUSED_P(systemId),
    340                                    const XML_Char *UNUSED_P(publicId),
    341                                    const XML_Char *UNUSED_P(notationName))
    342 {
    343     dummy_handler_flags |= DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG;
    344 }
    345 
    346 static void XMLCALL
    347 dummy_default_handler(void *UNUSED_P(userData),
    348                       const XML_Char *UNUSED_P(s),
    349                       int UNUSED_P(len))
    350 {}
    351 
    352 static void XMLCALL
    353 dummy_start_doctype_decl_handler(void *UNUSED_P(userData),
    354                                  const XML_Char *UNUSED_P(doctypeName),
    355                                  const XML_Char *UNUSED_P(sysid),
    356                                  const XML_Char *UNUSED_P(pubid),
    357                                  int UNUSED_P(has_internal_subset))
    358 {
    359     dummy_handler_flags |= DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG;
    360 }
    361 
    362 static void XMLCALL
    363 dummy_end_doctype_decl_handler(void *UNUSED_P(userData))
    364 {
    365     dummy_handler_flags |= DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG;
    366 }
    367 
    368 static void XMLCALL
    369 dummy_skip_handler(void *UNUSED_P(userData),
    370                    const XML_Char *UNUSED_P(entityName),
    371                    int UNUSED_P(is_parameter_entity))
    372 {
    373     dummy_handler_flags |= DUMMY_SKIP_HANDLER_FLAG;
    374 }
    375 
    376 /* Useful external entity handler */
    377 typedef struct ExtOption {
    378     const XML_Char *system_id;
    379     const char *parse_text;
    380 } ExtOption;
    381 
    382 static int XMLCALL
    383 external_entity_optioner(XML_Parser parser,
    384                          const XML_Char *context,
    385                          const XML_Char *UNUSED_P(base),
    386                          const XML_Char *systemId,
    387                          const XML_Char *UNUSED_P(publicId))
    388 {
    389     ExtOption *options = (ExtOption *)XML_GetUserData(parser);
    390     XML_Parser ext_parser;
    391 
    392     while (options->parse_text != NULL) {
    393         if (!xcstrcmp(systemId, options->system_id)) {
    394             enum XML_Status rc;
    395             ext_parser =
    396                 XML_ExternalEntityParserCreate(parser, context, NULL);
    397             if (ext_parser == NULL)
    398                 return XML_STATUS_ERROR;
    399             rc = _XML_Parse_SINGLE_BYTES(ext_parser, options->parse_text,
    400                                          strlen(options->parse_text),
    401                                          XML_TRUE);
    402             XML_ParserFree(ext_parser);
    403             return rc;
    404         }
    405         options++;
    406     }
    407     fail("No suitable option found");
    408     return XML_STATUS_ERROR;
    409 }
    410 
    411 /*
    412  * Parameter entity evaluation support.
    413  */
    414 #define ENTITY_MATCH_FAIL      (-1)
    415 #define ENTITY_MATCH_NOT_FOUND  (0)
    416 #define ENTITY_MATCH_SUCCESS    (1)
    417 static const XML_Char *entity_name_to_match = NULL;
    418 static const XML_Char *entity_value_to_match = NULL;
    419 static int entity_match_flag = ENTITY_MATCH_NOT_FOUND;
    420 
    421 static void XMLCALL
    422 param_entity_match_handler(void           *UNUSED_P(userData),
    423                            const XML_Char *entityName,
    424                            int            is_parameter_entity,
    425                            const XML_Char *value,
    426                            int            value_length,
    427                            const XML_Char *UNUSED_P(base),
    428                            const XML_Char *UNUSED_P(systemId),
    429                            const XML_Char *UNUSED_P(publicId),
    430                            const XML_Char *UNUSED_P(notationName))
    431 {
    432     if (!is_parameter_entity ||
    433         entity_name_to_match == NULL ||
    434         entity_value_to_match == NULL) {
    435         return;
    436     }
    437     if (!xcstrcmp(entityName, entity_name_to_match)) {
    438         /* The cast here is safe because we control the horizontal and
    439          * the vertical, and we therefore know our strings are never
    440          * going to overflow an int.
    441          */
    442         if (value_length != (int)xcstrlen(entity_value_to_match) ||
    443             xcstrncmp(value, entity_value_to_match, value_length)) {
    444             entity_match_flag = ENTITY_MATCH_FAIL;
    445         } else {
    446             entity_match_flag = ENTITY_MATCH_SUCCESS;
    447         }
    448     }
    449     /* Else leave the match flag alone */
    450 }
    451 
    452 /*
    453  * Character & encoding tests.
    454  */
    455 
    456 START_TEST(test_nul_byte)
    457 {
    458     char text[] = "<doc>\0</doc>";
    459 
    460     /* test that a NUL byte (in US-ASCII data) is an error */
    461     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK)
    462         fail("Parser did not report error on NUL-byte.");
    463     if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
    464         xml_failure(parser);
    465 }
    466 END_TEST
    467 
    468 
    469 START_TEST(test_u0000_char)
    470 {
    471     /* test that a NUL byte (in US-ASCII data) is an error */
    472     expect_failure("<doc>&#0;</doc>",
    473                    XML_ERROR_BAD_CHAR_REF,
    474                    "Parser did not report error on NUL-byte.");
    475 }
    476 END_TEST
    477 
    478 START_TEST(test_siphash_self)
    479 {
    480     if (! sip24_valid())
    481         fail("SipHash self-test failed");
    482 }
    483 END_TEST
    484 
    485 START_TEST(test_siphash_spec)
    486 {
    487     /* https://131002.net/siphash/siphash.pdf (page 19, "Test values") */
    488     const char message[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09"
    489             "\x0a\x0b\x0c\x0d\x0e";
    490     const size_t len = sizeof(message) - 1;
    491     const uint64_t expected = _SIP_ULL(0xa129ca61U, 0x49be45e5U);
    492     struct siphash state;
    493     struct sipkey key;
    494     (void)sip_tobin;
    495 
    496     sip_tokey(&key,
    497             "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09"
    498             "\x0a\x0b\x0c\x0d\x0e\x0f");
    499     sip24_init(&state, &key);
    500 
    501     /* Cover spread across calls */
    502     sip24_update(&state, message, 4);
    503     sip24_update(&state, message + 4, len - 4);
    504 
    505     /* Cover null length */
    506     sip24_update(&state, message, 0);
    507 
    508     if (sip24_final(&state) != expected)
    509         fail("sip24_final failed spec test\n");
    510 
    511     /* Cover wrapper */
    512     if (siphash24(message, len, &key) != expected)
    513         fail("siphash24 failed spec test\n");
    514 }
    515 END_TEST
    516 
    517 START_TEST(test_bom_utf8)
    518 {
    519     /* This test is really just making sure we don't core on a UTF-8 BOM. */
    520     const char *text = "\357\273\277<e/>";
    521 
    522     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
    523         xml_failure(parser);
    524 }
    525 END_TEST
    526 
    527 START_TEST(test_bom_utf16_be)
    528 {
    529     char text[] = "\376\377\0<\0e\0/\0>";
    530 
    531     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
    532         xml_failure(parser);
    533 }
    534 END_TEST
    535 
    536 START_TEST(test_bom_utf16_le)
    537 {
    538     char text[] = "\377\376<\0e\0/\0>\0";
    539 
    540     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
    541         xml_failure(parser);
    542 }
    543 END_TEST
    544 
    545 /* Parse whole buffer at once to exercise a different code path */
    546 START_TEST(test_nobom_utf16_le)
    547 {
    548     char text[] = " \0<\0e\0/\0>\0";
    549 
    550     if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
    551         xml_failure(parser);
    552 }
    553 END_TEST
    554 
    555 static void XMLCALL
    556 accumulate_characters(void *userData, const XML_Char *s, int len)
    557 {
    558     CharData_AppendXMLChars((CharData *)userData, s, len);
    559 }
    560 
    561 static void XMLCALL
    562 accumulate_attribute(void *userData, const XML_Char *UNUSED_P(name),
    563                      const XML_Char **atts)
    564 {
    565     CharData *storage = (CharData *)userData;
    566 
    567     /* Check there are attributes to deal with */
    568     if (atts == NULL)
    569         return;
    570 
    571     while (storage->count < 0 && atts[0] != NULL) {
    572         /* "accumulate" the value of the first attribute we see */
    573         CharData_AppendXMLChars(storage, atts[1], -1);
    574         atts += 2;
    575     }
    576 }
    577 
    578 
    579 static void
    580 _run_character_check(const char *text, const XML_Char *expected,
    581                      const char *file, int line)
    582 {
    583     CharData storage;
    584 
    585     CharData_Init(&storage);
    586     XML_SetUserData(parser, &storage);
    587     XML_SetCharacterDataHandler(parser, accumulate_characters);
    588     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
    589         _xml_failure(parser, file, line);
    590     CharData_CheckXMLChars(&storage, expected);
    591 }
    592 
    593 #define run_character_check(text, expected) \
    594         _run_character_check(text, expected, __FILE__, __LINE__)
    595 
    596 static void
    597 _run_attribute_check(const char *text, const XML_Char *expected,
    598                      const char *file, int line)
    599 {
    600     CharData storage;
    601 
    602     CharData_Init(&storage);
    603     XML_SetUserData(parser, &storage);
    604     XML_SetStartElementHandler(parser, accumulate_attribute);
    605     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
    606         _xml_failure(parser, file, line);
    607     CharData_CheckXMLChars(&storage, expected);
    608 }
    609 
    610 #define run_attribute_check(text, expected) \
    611         _run_attribute_check(text, expected, __FILE__, __LINE__)
    612 
    613 typedef struct ExtTest {
    614     const char *parse_text;
    615     const XML_Char *encoding;
    616     CharData *storage;
    617 } ExtTest;
    618 
    619 static void XMLCALL
    620 ext_accumulate_characters(void *userData, const XML_Char *s, int len)
    621 {
    622     ExtTest *test_data = (ExtTest *)userData;
    623     accumulate_characters(test_data->storage, s, len);
    624 }
    625 
    626 static void
    627 _run_ext_character_check(const char *text,
    628                          ExtTest *test_data,
    629                          const XML_Char *expected,
    630                          const char *file, int line)
    631 {
    632     CharData storage;
    633 
    634     CharData_Init(&storage);
    635     test_data->storage = &storage;
    636     XML_SetUserData(parser, test_data);
    637     XML_SetCharacterDataHandler(parser, ext_accumulate_characters);
    638     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
    639                                 XML_TRUE) == XML_STATUS_ERROR)
    640         _xml_failure(parser, file, line);
    641     CharData_CheckXMLChars(&storage, expected);
    642 }
    643 
    644 #define run_ext_character_check(text, test_data, expected)               \
    645     _run_ext_character_check(text, test_data, expected, __FILE__, __LINE__)
    646 
    647 /* Regression test for SF bug #491986. */
    648 START_TEST(test_danish_latin1)
    649 {
    650     const char *text =
    651         "<?xml version='1.0' encoding='iso-8859-1'?>\n"
    652         "<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>";
    653 #ifdef XML_UNICODE
    654     const XML_Char *expected =
    655         XCS("J\x00f8rgen \x00e6\x00f8\x00e5\x00c6\x00d8\x00c5");
    656 #else
    657     const XML_Char *expected =
    658         XCS("J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85");
    659 #endif
    660     run_character_check(text, expected);
    661 }
    662 END_TEST
    663 
    664 
    665 /* Regression test for SF bug #514281. */
    666 START_TEST(test_french_charref_hexidecimal)
    667 {
    668     const char *text =
    669         "<?xml version='1.0' encoding='iso-8859-1'?>\n"
    670         "<doc>&#xE9;&#xE8;&#xE0;&#xE7;&#xEA;&#xC8;</doc>";
    671 #ifdef XML_UNICODE
    672     const XML_Char *expected =
    673         XCS("\x00e9\x00e8\x00e0\x00e7\x00ea\x00c8");
    674 #else
    675     const XML_Char *expected =
    676         XCS("\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
    677 #endif
    678     run_character_check(text, expected);
    679 }
    680 END_TEST
    681 
    682 START_TEST(test_french_charref_decimal)
    683 {
    684     const char *text =
    685         "<?xml version='1.0' encoding='iso-8859-1'?>\n"
    686         "<doc>&#233;&#232;&#224;&#231;&#234;&#200;</doc>";
    687 #ifdef XML_UNICODE
    688     const XML_Char *expected =
    689         XCS("\x00e9\x00e8\x00e0\x00e7\x00ea\x00c8");
    690 #else
    691     const XML_Char *expected =
    692         XCS("\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
    693 #endif
    694     run_character_check(text, expected);
    695 }
    696 END_TEST
    697 
    698 START_TEST(test_french_latin1)
    699 {
    700     const char *text =
    701         "<?xml version='1.0' encoding='iso-8859-1'?>\n"
    702         "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>";
    703 #ifdef XML_UNICODE
    704     const XML_Char *expected =
    705         XCS("\x00e9\x00e8\x00e0\x00e7\x00ea\x00c8");
    706 #else
    707     const XML_Char *expected =
    708         XCS("\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
    709 #endif
    710     run_character_check(text, expected);
    711 }
    712 END_TEST
    713 
    714 START_TEST(test_french_utf8)
    715 {
    716     const char *text =
    717         "<?xml version='1.0' encoding='utf-8'?>\n"
    718         "<doc>\xC3\xA9</doc>";
    719 #ifdef XML_UNICODE
    720     const XML_Char *expected = XCS("\x00e9");
    721 #else
    722     const XML_Char *expected = XCS("\xC3\xA9");
    723 #endif
    724     run_character_check(text, expected);
    725 }
    726 END_TEST
    727 
    728 /* Regression test for SF bug #600479.
    729    XXX There should be a test that exercises all legal XML Unicode
    730    characters as PCDATA and attribute value content, and XML Name
    731    characters as part of element and attribute names.
    732 */
    733 START_TEST(test_utf8_false_rejection)
    734 {
    735     const char *text = "<doc>\xEF\xBA\xBF</doc>";
    736 #ifdef XML_UNICODE
    737     const XML_Char *expected = XCS("\xfebf");
    738 #else
    739     const XML_Char *expected = XCS("\xEF\xBA\xBF");
    740 #endif
    741     run_character_check(text, expected);
    742 }
    743 END_TEST
    744 
    745 /* Regression test for SF bug #477667.
    746    This test assures that any 8-bit character followed by a 7-bit
    747    character will not be mistakenly interpreted as a valid UTF-8
    748    sequence.
    749 */
    750 START_TEST(test_illegal_utf8)
    751 {
    752     char text[100];
    753     int i;
    754 
    755     for (i = 128; i <= 255; ++i) {
    756         sprintf(text, "<e>%ccd</e>", i);
    757         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) {
    758             sprintf(text,
    759                     "expected token error for '%c' (ordinal %d) in UTF-8 text",
    760                     i, i);
    761             fail(text);
    762         }
    763         else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
    764             xml_failure(parser);
    765         /* Reset the parser since we use the same parser repeatedly. */
    766         XML_ParserReset(parser, NULL);
    767     }
    768 }
    769 END_TEST
    770 
    771 
    772 /* Examples, not masks: */
    773 #define UTF8_LEAD_1  "\x7f"  /* 0b01111111 */
    774 #define UTF8_LEAD_2  "\xdf"  /* 0b11011111 */
    775 #define UTF8_LEAD_3  "\xef"  /* 0b11101111 */
    776 #define UTF8_LEAD_4  "\xf7"  /* 0b11110111 */
    777 #define UTF8_FOLLOW  "\xbf"  /* 0b10111111 */
    778 
    779 START_TEST(test_utf8_auto_align)
    780 {
    781     struct TestCase {
    782         ptrdiff_t expectedMovementInChars;
    783         const char * input;
    784     };
    785 
    786     struct TestCase cases[] = {
    787         {00, ""},
    788 
    789         {00, UTF8_LEAD_1},
    790 
    791         {-1, UTF8_LEAD_2},
    792         {00, UTF8_LEAD_2 UTF8_FOLLOW},
    793 
    794         {-1, UTF8_LEAD_3},
    795         {-2, UTF8_LEAD_3 UTF8_FOLLOW},
    796         {00, UTF8_LEAD_3 UTF8_FOLLOW UTF8_FOLLOW},
    797 
    798         {-1, UTF8_LEAD_4},
    799         {-2, UTF8_LEAD_4 UTF8_FOLLOW},
    800         {-3, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW},
    801         {00, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW UTF8_FOLLOW},
    802     };
    803 
    804     size_t i = 0;
    805     bool success = true;
    806     for (; i < sizeof(cases) / sizeof(*cases); i++) {
    807         const char * fromLim = cases[i].input + strlen(cases[i].input);
    808         const char * const fromLimInitially = fromLim;
    809         ptrdiff_t actualMovementInChars;
    810 
    811         _INTERNAL_trim_to_complete_utf8_characters(cases[i].input, &fromLim);
    812 
    813         actualMovementInChars = (fromLim - fromLimInitially);
    814         if (actualMovementInChars != cases[i].expectedMovementInChars) {
    815             size_t j = 0;
    816             success = false;
    817             printf("[-] UTF-8 case %2u: Expected movement by %2d chars"
    818                     ", actually moved by %2d chars: \"",
    819                     (unsigned)(i + 1),
    820                     (int)cases[i].expectedMovementInChars,
    821                     (int)actualMovementInChars);
    822             for (; j < strlen(cases[i].input); j++) {
    823                 printf("\\x%02x", (unsigned char)cases[i].input[j]);
    824             }
    825             printf("\"\n");
    826         }
    827     }
    828 
    829     if (! success) {
    830         fail("UTF-8 auto-alignment is not bullet-proof\n");
    831     }
    832 }
    833 END_TEST
    834 
    835 START_TEST(test_utf16)
    836 {
    837     /* <?xml version="1.0" encoding="UTF-16"?>
    838      *  <doc a='123'>some {A} text</doc>
    839      *
    840      * where {A} is U+FF21, FULLWIDTH LATIN CAPITAL LETTER A
    841      */
    842     char text[] =
    843         "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o"
    844         "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o"
    845         "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066"
    846         "\000'\000?\000>\000\n"
    847         "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'\000>"
    848         "\000s\000o\000m\000e\000 \xff\x21\000 \000t\000e\000x\000t\000"
    849         "<\000/\000d\000o\000c\000>";
    850 #ifdef XML_UNICODE
    851     const XML_Char *expected = XCS("some \xff21 text");
    852 #else
    853     const XML_Char *expected = XCS("some \357\274\241 text");
    854 #endif
    855     CharData storage;
    856 
    857     CharData_Init(&storage);
    858     XML_SetUserData(parser, &storage);
    859     XML_SetCharacterDataHandler(parser, accumulate_characters);
    860     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
    861         xml_failure(parser);
    862     CharData_CheckXMLChars(&storage, expected);
    863 }
    864 END_TEST
    865 
    866 START_TEST(test_utf16_le_epilog_newline)
    867 {
    868     unsigned int first_chunk_bytes = 17;
    869     char text[] =
    870         "\xFF\xFE"                      /* BOM */
    871         "<\000e\000/\000>\000"          /* document element */
    872         "\r\000\n\000\r\000\n\000";     /* epilog */
    873 
    874     if (first_chunk_bytes >= sizeof(text) - 1)
    875         fail("bad value of first_chunk_bytes");
    876     if (  _XML_Parse_SINGLE_BYTES(parser, text, first_chunk_bytes, XML_FALSE)
    877           == XML_STATUS_ERROR)
    878         xml_failure(parser);
    879     else {
    880         enum XML_Status rc;
    881         rc = _XML_Parse_SINGLE_BYTES(parser, text + first_chunk_bytes,
    882                        sizeof(text) - first_chunk_bytes - 1, XML_TRUE);
    883         if (rc == XML_STATUS_ERROR)
    884             xml_failure(parser);
    885     }
    886 }
    887 END_TEST
    888 
    889 /* Test that an outright lie in the encoding is faulted */
    890 START_TEST(test_not_utf16)
    891 {
    892     const char *text =
    893         "<?xml version='1.0' encoding='utf-16'?>"
    894         "<doc>Hi</doc>";
    895 
    896     /* Use a handler to provoke the appropriate code paths */
    897     XML_SetXmlDeclHandler(parser, dummy_xdecl_handler);
    898     expect_failure(text,
    899                    XML_ERROR_INCORRECT_ENCODING,
    900                    "UTF-16 declared in UTF-8 not faulted");
    901 }
    902 END_TEST
    903 
    904 /* Test that an unknown encoding is rejected */
    905 START_TEST(test_bad_encoding)
    906 {
    907     const char *text = "<doc>Hi</doc>";
    908 
    909     if (!XML_SetEncoding(parser, XCS("unknown-encoding")))
    910         fail("XML_SetEncoding failed");
    911     expect_failure(text,
    912                    XML_ERROR_UNKNOWN_ENCODING,
    913                    "Unknown encoding not faulted");
    914 }
    915 END_TEST
    916 
    917 /* Regression test for SF bug #481609, #774028. */
    918 START_TEST(test_latin1_umlauts)
    919 {
    920     const char *text =
    921         "<?xml version='1.0' encoding='iso-8859-1'?>\n"
    922         "<e a='\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; >'\n"
    923         "  >\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; ></e>";
    924 #ifdef XML_UNICODE
    925     /* Expected results in UTF-16 */
    926     const XML_Char *expected =
    927         XCS("\x00e4 \x00f6 \x00fc ")
    928         XCS("\x00e4 \x00f6 \x00fc ")
    929         XCS("\x00e4 \x00f6 \x00fc >");
    930 #else
    931     /* Expected results in UTF-8 */
    932     const XML_Char *expected =
    933         XCS("\xC3\xA4 \xC3\xB6 \xC3\xBC ")
    934         XCS("\xC3\xA4 \xC3\xB6 \xC3\xBC ")
    935         XCS("\xC3\xA4 \xC3\xB6 \xC3\xBC >");
    936 #endif
    937 
    938     run_character_check(text, expected);
    939     XML_ParserReset(parser, NULL);
    940     run_attribute_check(text, expected);
    941     /* Repeat with a default handler */
    942     XML_ParserReset(parser, NULL);
    943     XML_SetDefaultHandler(parser, dummy_default_handler);
    944     run_character_check(text, expected);
    945     XML_ParserReset(parser, NULL);
    946     XML_SetDefaultHandler(parser, dummy_default_handler);
    947     run_attribute_check(text, expected);
    948 }
    949 END_TEST
    950 
    951 /* Test that an element name with a 4-byte UTF-8 character is rejected */
    952 START_TEST(test_long_utf8_character)
    953 {
    954     const char *text =
    955         "<?xml version='1.0' encoding='utf-8'?>\n"
    956         /* 0xf0 0x90 0x80 0x80 = U+10000, the first Linear B character */
    957         "<do\xf0\x90\x80\x80/>";
    958     expect_failure(text,
    959                    XML_ERROR_INVALID_TOKEN,
    960                    "4-byte UTF-8 character in element name not faulted");
    961 }
    962 END_TEST
    963 
    964 /* Test that a long latin-1 attribute (too long to convert in one go)
    965  * is correctly converted
    966  */
    967 START_TEST(test_long_latin1_attribute)
    968 {
    969     const char *text =
    970         "<?xml version='1.0' encoding='iso-8859-1'?>\n"
    971         "<doc att='"
    972         /* 64 characters per line */
    973         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    974         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    975         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    976         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    977         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    978         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    979         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    980         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    981         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    982         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    983         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    984         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    985         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    986         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    987         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    988         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
    989         /* Last character splits across a buffer boundary */
    990         "\xe4'>\n</doc>";
    991 #ifdef XML_UNICODE
    992     const XML_Char *expected =
    993         /* 64 characters per line */
    994         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
    995         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
    996         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
    997         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
    998         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
    999         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1000         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1001         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1002         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1003         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1004         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1005         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1006         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1007         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1008         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1009         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO")
   1010         XCS("\x00e4");
   1011 #else
   1012     const XML_Char *expected =
   1013         /* 64 characters per line */
   1014         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1015         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1016         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1017         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1018         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1019         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1020         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1021         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1022         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1023         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1024         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1025         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1026         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1027         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1028         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1029         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO")
   1030         XCS("\xc3\xa4");
   1031 #endif
   1032 
   1033     run_attribute_check(text, expected);
   1034 }
   1035 END_TEST
   1036 
   1037 
   1038 /* Test that a long ASCII attribute (too long to convert in one go)
   1039  * is correctly converted
   1040  */
   1041 START_TEST(test_long_ascii_attribute)
   1042 {
   1043     const char *text =
   1044         "<?xml version='1.0' encoding='us-ascii'?>\n"
   1045         "<doc att='"
   1046         /* 64 characters per line */
   1047         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1048         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1049         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1050         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1051         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1052         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1053         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1054         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1055         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1056         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1057         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1058         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1059         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1060         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1061         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1062         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   1063         "01234'>\n</doc>";
   1064     const XML_Char *expected =
   1065         /* 64 characters per line */
   1066         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1067         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1068         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1069         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1070         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1071         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1072         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1073         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1074         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1075         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1076         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1077         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1078         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1079         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1080         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1081         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   1082         XCS("01234");
   1083 
   1084     run_attribute_check(text, expected);
   1085 }
   1086 END_TEST
   1087 
   1088 /* Regression test #1 for SF bug #653180. */
   1089 START_TEST(test_line_number_after_parse)
   1090 {
   1091     const char *text =
   1092         "<tag>\n"
   1093         "\n"
   1094         "\n</tag>";
   1095     XML_Size lineno;
   1096 
   1097     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
   1098         xml_failure(parser);
   1099     lineno = XML_GetCurrentLineNumber(parser);
   1100     if (lineno != 4) {
   1101         char buffer[100];
   1102         sprintf(buffer,
   1103             "expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno);
   1104         fail(buffer);
   1105     }
   1106 }
   1107 END_TEST
   1108 
   1109 /* Regression test #2 for SF bug #653180. */
   1110 START_TEST(test_column_number_after_parse)
   1111 {
   1112     const char *text = "<tag></tag>";
   1113     XML_Size colno;
   1114 
   1115     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
   1116         xml_failure(parser);
   1117     colno = XML_GetCurrentColumnNumber(parser);
   1118     if (colno != 11) {
   1119         char buffer[100];
   1120         sprintf(buffer,
   1121             "expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno);
   1122         fail(buffer);
   1123     }
   1124 }
   1125 END_TEST
   1126 
   1127 #define STRUCT_START_TAG 0
   1128 #define STRUCT_END_TAG 1
   1129 static void XMLCALL
   1130 start_element_event_handler2(void *userData, const XML_Char *name,
   1131 			     const XML_Char **UNUSED_P(attr))
   1132 {
   1133     StructData *storage = (StructData *) userData;
   1134     StructData_AddItem(storage, name,
   1135                        XML_GetCurrentColumnNumber(parser),
   1136                        XML_GetCurrentLineNumber(parser),
   1137                        STRUCT_START_TAG);
   1138 }
   1139 
   1140 static void XMLCALL
   1141 end_element_event_handler2(void *userData, const XML_Char *name)
   1142 {
   1143     StructData *storage = (StructData *) userData;
   1144     StructData_AddItem(storage, name,
   1145                        XML_GetCurrentColumnNumber(parser),
   1146                        XML_GetCurrentLineNumber(parser),
   1147                        STRUCT_END_TAG);
   1148 }
   1149 
   1150 /* Regression test #3 for SF bug #653180. */
   1151 START_TEST(test_line_and_column_numbers_inside_handlers)
   1152 {
   1153     const char *text =
   1154         "<a>\n"        /* Unix end-of-line */
   1155         "  <b>\r\n"    /* Windows end-of-line */
   1156         "    <c/>\r"   /* Mac OS end-of-line */
   1157         "  </b>\n"
   1158         "  <d>\n"
   1159         "    <f/>\n"
   1160         "  </d>\n"
   1161         "</a>";
   1162     const StructDataEntry expected[] = {
   1163         { XCS("a"), 0, 1, STRUCT_START_TAG },
   1164         { XCS("b"), 2, 2, STRUCT_START_TAG },
   1165         { XCS("c"), 4, 3, STRUCT_START_TAG },
   1166         { XCS("c"), 8, 3, STRUCT_END_TAG },
   1167         { XCS("b"), 2, 4, STRUCT_END_TAG },
   1168         { XCS("d"), 2, 5, STRUCT_START_TAG },
   1169         { XCS("f"), 4, 6, STRUCT_START_TAG },
   1170         { XCS("f"), 8, 6, STRUCT_END_TAG },
   1171         { XCS("d"), 2, 7, STRUCT_END_TAG },
   1172         { XCS("a"), 0, 8, STRUCT_END_TAG }
   1173     };
   1174     const int expected_count = sizeof(expected) / sizeof(StructDataEntry);
   1175     StructData storage;
   1176 
   1177     StructData_Init(&storage);
   1178     XML_SetUserData(parser, &storage);
   1179     XML_SetStartElementHandler(parser, start_element_event_handler2);
   1180     XML_SetEndElementHandler(parser, end_element_event_handler2);
   1181     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   1182         xml_failure(parser);
   1183 
   1184     StructData_CheckItems(&storage, expected, expected_count);
   1185     StructData_Dispose(&storage);
   1186 }
   1187 END_TEST
   1188 
   1189 /* Regression test #4 for SF bug #653180. */
   1190 START_TEST(test_line_number_after_error)
   1191 {
   1192     const char *text =
   1193         "<a>\n"
   1194         "  <b>\n"
   1195         "  </a>";  /* missing </b> */
   1196     XML_Size lineno;
   1197     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
   1198         fail("Expected a parse error");
   1199 
   1200     lineno = XML_GetCurrentLineNumber(parser);
   1201     if (lineno != 3) {
   1202         char buffer[100];
   1203         sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno);
   1204         fail(buffer);
   1205     }
   1206 }
   1207 END_TEST
   1208 
   1209 /* Regression test #5 for SF bug #653180. */
   1210 START_TEST(test_column_number_after_error)
   1211 {
   1212     const char *text =
   1213         "<a>\n"
   1214         "  <b>\n"
   1215         "  </a>";  /* missing </b> */
   1216     XML_Size colno;
   1217     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
   1218         fail("Expected a parse error");
   1219 
   1220     colno = XML_GetCurrentColumnNumber(parser);
   1221     if (colno != 4) {
   1222         char buffer[100];
   1223         sprintf(buffer,
   1224             "expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno);
   1225         fail(buffer);
   1226     }
   1227 }
   1228 END_TEST
   1229 
   1230 /* Regression test for SF bug #478332. */
   1231 START_TEST(test_really_long_lines)
   1232 {
   1233     /* This parses an input line longer than INIT_DATA_BUF_SIZE
   1234        characters long (defined to be 1024 in xmlparse.c).  We take a
   1235        really cheesy approach to building the input buffer, because
   1236        this avoids writing bugs in buffer-filling code.
   1237     */
   1238     const char *text =
   1239         "<e>"
   1240         /* 64 chars */
   1241         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1242         /* until we have at least 1024 characters on the line: */
   1243         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1244         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1245         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1246         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1247         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1248         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1249         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1250         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1251         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1252         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1253         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1254         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1255         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1256         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1257         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1258         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1259         "</e>";
   1260     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   1261         xml_failure(parser);
   1262 }
   1263 END_TEST
   1264 
   1265 /* Test cdata processing across a buffer boundary */
   1266 START_TEST(test_really_long_encoded_lines)
   1267 {
   1268     /* As above, except that we want to provoke an output buffer
   1269      * overflow with a non-trivial encoding.  For this we need to pass
   1270      * the whole cdata in one go, not byte-by-byte.
   1271      */
   1272     void *buffer;
   1273     const char *text =
   1274         "<?xml version='1.0' encoding='iso-8859-1'?>"
   1275         "<e>"
   1276         /* 64 chars */
   1277         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1278         /* until we have at least 1024 characters on the line: */
   1279         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1280         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1281         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1282         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1283         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1284         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1285         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1286         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1287         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1288         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1289         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1290         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1291         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1292         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1293         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1294         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
   1295         "</e>";
   1296     int parse_len = strlen(text);
   1297 
   1298     /* Need a cdata handler to provoke the code path we want to test */
   1299     XML_SetCharacterDataHandler(parser, dummy_cdata_handler);
   1300     buffer = XML_GetBuffer(parser, parse_len);
   1301     if (buffer == NULL)
   1302         fail("Could not allocate parse buffer");
   1303     memcpy(buffer, text, parse_len);
   1304     if (XML_ParseBuffer(parser, parse_len, XML_TRUE) == XML_STATUS_ERROR)
   1305         xml_failure(parser);
   1306 }
   1307 END_TEST
   1308 
   1309 
   1310 /*
   1311  * Element event tests.
   1312  */
   1313 
   1314 static void XMLCALL
   1315 start_element_event_handler(void *userData,
   1316                             const XML_Char *name,
   1317                             const XML_Char **UNUSED_P(atts))
   1318 {
   1319     CharData_AppendXMLChars((CharData *)userData, name, -1);
   1320 }
   1321 
   1322 static void XMLCALL
   1323 end_element_event_handler(void *userData, const XML_Char *name)
   1324 {
   1325     CharData *storage = (CharData *) userData;
   1326     CharData_AppendXMLChars(storage, XCS("/"), 1);
   1327     CharData_AppendXMLChars(storage, name, -1);
   1328 }
   1329 
   1330 START_TEST(test_end_element_events)
   1331 {
   1332     const char *text = "<a><b><c/></b><d><f/></d></a>";
   1333     const XML_Char *expected = XCS("/c/b/f/d/a");
   1334     CharData storage;
   1335 
   1336     CharData_Init(&storage);
   1337     XML_SetUserData(parser, &storage);
   1338     XML_SetEndElementHandler(parser, end_element_event_handler);
   1339     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   1340         xml_failure(parser);
   1341     CharData_CheckXMLChars(&storage, expected);
   1342 }
   1343 END_TEST
   1344 
   1345 
   1346 /*
   1347  * Attribute tests.
   1348  */
   1349 
   1350 /* Helpers used by the following test; this checks any "attr" and "refs"
   1351    attributes to make sure whitespace has been normalized.
   1352 
   1353    Return true if whitespace has been normalized in a string, using
   1354    the rules for attribute value normalization.  The 'is_cdata' flag
   1355    is needed since CDATA attributes don't need to have multiple
   1356    whitespace characters collapsed to a single space, while other
   1357    attribute data types do.  (Section 3.3.3 of the recommendation.)
   1358 */
   1359 static int
   1360 is_whitespace_normalized(const XML_Char *s, int is_cdata)
   1361 {
   1362     int blanks = 0;
   1363     int at_start = 1;
   1364     while (*s) {
   1365         if (*s == XCS(' '))
   1366             ++blanks;
   1367         else if (*s == XCS('\t') || *s == XCS('\n') || *s == XCS('\r'))
   1368             return 0;
   1369         else {
   1370             if (at_start) {
   1371                 at_start = 0;
   1372                 if (blanks && !is_cdata)
   1373                     /* illegal leading blanks */
   1374                     return 0;
   1375             }
   1376             else if (blanks > 1 && !is_cdata)
   1377                 return 0;
   1378             blanks = 0;
   1379         }
   1380         ++s;
   1381     }
   1382     if (blanks && !is_cdata)
   1383         return 0;
   1384     return 1;
   1385 }
   1386 
   1387 /* Check the attribute whitespace checker: */
   1388 static void
   1389 testhelper_is_whitespace_normalized(void)
   1390 {
   1391     assert(is_whitespace_normalized(XCS("abc"), 0));
   1392     assert(is_whitespace_normalized(XCS("abc"), 1));
   1393     assert(is_whitespace_normalized(XCS("abc def ghi"), 0));
   1394     assert(is_whitespace_normalized(XCS("abc def ghi"), 1));
   1395     assert(!is_whitespace_normalized(XCS(" abc def ghi"), 0));
   1396     assert(is_whitespace_normalized(XCS(" abc def ghi"), 1));
   1397     assert(!is_whitespace_normalized(XCS("abc  def ghi"), 0));
   1398     assert(is_whitespace_normalized(XCS("abc  def ghi"), 1));
   1399     assert(!is_whitespace_normalized(XCS("abc def ghi "), 0));
   1400     assert(is_whitespace_normalized(XCS("abc def ghi "), 1));
   1401     assert(!is_whitespace_normalized(XCS(" "), 0));
   1402     assert(is_whitespace_normalized(XCS(" "), 1));
   1403     assert(!is_whitespace_normalized(XCS("\t"), 0));
   1404     assert(!is_whitespace_normalized(XCS("\t"), 1));
   1405     assert(!is_whitespace_normalized(XCS("\n"), 0));
   1406     assert(!is_whitespace_normalized(XCS("\n"), 1));
   1407     assert(!is_whitespace_normalized(XCS("\r"), 0));
   1408     assert(!is_whitespace_normalized(XCS("\r"), 1));
   1409     assert(!is_whitespace_normalized(XCS("abc\t def"), 1));
   1410 }
   1411 
   1412 static void XMLCALL
   1413 check_attr_contains_normalized_whitespace(void *UNUSED_P(userData),
   1414                                           const XML_Char *UNUSED_P(name),
   1415                                           const XML_Char **atts)
   1416 {
   1417     int i;
   1418     for (i = 0; atts[i] != NULL; i += 2) {
   1419         const XML_Char *attrname = atts[i];
   1420         const XML_Char *value = atts[i + 1];
   1421         if (xcstrcmp(XCS("attr"), attrname) == 0
   1422             || xcstrcmp(XCS("ents"), attrname) == 0
   1423             || xcstrcmp(XCS("refs"), attrname) == 0) {
   1424             if (!is_whitespace_normalized(value, 0)) {
   1425                 char buffer[256];
   1426                 sprintf(buffer, "attribute value not normalized: %"
   1427                         XML_FMT_STR "='%" XML_FMT_STR "'",
   1428                         attrname, value);
   1429                 fail(buffer);
   1430             }
   1431         }
   1432     }
   1433 }
   1434 
   1435 START_TEST(test_attr_whitespace_normalization)
   1436 {
   1437     const char *text =
   1438         "<!DOCTYPE doc [\n"
   1439         "  <!ATTLIST doc\n"
   1440         "            attr NMTOKENS #REQUIRED\n"
   1441         "            ents ENTITIES #REQUIRED\n"
   1442         "            refs IDREFS   #REQUIRED>\n"
   1443         "]>\n"
   1444         "<doc attr='    a  b c\t\td\te\t' refs=' id-1   \t  id-2\t\t'  \n"
   1445         "     ents=' ent-1   \t\r\n"
   1446         "            ent-2  ' >\n"
   1447         "  <e id='id-1'/>\n"
   1448         "  <e id='id-2'/>\n"
   1449         "</doc>";
   1450 
   1451     XML_SetStartElementHandler(parser,
   1452                                check_attr_contains_normalized_whitespace);
   1453     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   1454         xml_failure(parser);
   1455 }
   1456 END_TEST
   1457 
   1458 
   1459 /*
   1460  * XML declaration tests.
   1461  */
   1462 
   1463 START_TEST(test_xmldecl_misplaced)
   1464 {
   1465     expect_failure("\n"
   1466                    "<?xml version='1.0'?>\n"
   1467                    "<a/>",
   1468                    XML_ERROR_MISPLACED_XML_PI,
   1469                    "failed to report misplaced XML declaration");
   1470 }
   1471 END_TEST
   1472 
   1473 START_TEST(test_xmldecl_invalid)
   1474 {
   1475     expect_failure("<?xml version='1.0' \xc3\xa7?>\n<doc/>",
   1476                    XML_ERROR_XML_DECL,
   1477                    "Failed to report invalid XML declaration");
   1478 }
   1479 END_TEST
   1480 
   1481 START_TEST(test_xmldecl_missing_attr)
   1482 {
   1483     expect_failure("<?xml ='1.0'?>\n<doc/>\n",
   1484                    XML_ERROR_XML_DECL,
   1485                    "Failed to report missing XML declaration attribute");
   1486 }
   1487 END_TEST
   1488 
   1489 START_TEST(test_xmldecl_missing_value)
   1490 {
   1491     expect_failure("<?xml version='1.0' encoding='us-ascii' standalone?>\n"
   1492                    "<doc/>",
   1493                    XML_ERROR_XML_DECL,
   1494                    "Failed to report missing attribute value");
   1495 }
   1496 END_TEST
   1497 
   1498 /* Regression test for SF bug #584832. */
   1499 static int XMLCALL
   1500 UnknownEncodingHandler(void *UNUSED_P(data),const XML_Char *encoding,XML_Encoding *info)
   1501 {
   1502     if (xcstrcmp(encoding, XCS("unsupported-encoding")) == 0) {
   1503         int i;
   1504         for (i = 0; i < 256; ++i)
   1505             info->map[i] = i;
   1506         info->data = NULL;
   1507         info->convert = NULL;
   1508         info->release = NULL;
   1509         return XML_STATUS_OK;
   1510     }
   1511     return XML_STATUS_ERROR;
   1512 }
   1513 
   1514 START_TEST(test_unknown_encoding_internal_entity)
   1515 {
   1516     const char *text =
   1517         "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
   1518         "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
   1519         "<test a='&foo;'/>";
   1520 
   1521     XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL);
   1522     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   1523         xml_failure(parser);
   1524 }
   1525 END_TEST
   1526 
   1527 /* Test unrecognised encoding handler */
   1528 static void dummy_release(void *UNUSED_P(data))
   1529 {
   1530 }
   1531 
   1532 static int XMLCALL
   1533 UnrecognisedEncodingHandler(void *UNUSED_P(data),
   1534                             const XML_Char *UNUSED_P(encoding),
   1535                             XML_Encoding *info)
   1536 {
   1537     info->data = NULL;
   1538     info->convert = NULL;
   1539     info->release = dummy_release;
   1540     return XML_STATUS_ERROR;
   1541 }
   1542 
   1543 START_TEST(test_unrecognised_encoding_internal_entity)
   1544 {
   1545     const char *text =
   1546         "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
   1547         "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
   1548         "<test a='&foo;'/>";
   1549 
   1550     XML_SetUnknownEncodingHandler(parser,
   1551                                   UnrecognisedEncodingHandler,
   1552                                   NULL);
   1553     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
   1554         fail("Unrecognised encoding not rejected");
   1555 }
   1556 END_TEST
   1557 
   1558 /* Regression test for SF bug #620106. */
   1559 static int XMLCALL
   1560 external_entity_loader(XML_Parser parser,
   1561                        const XML_Char *context,
   1562                        const XML_Char *UNUSED_P(base),
   1563                        const XML_Char *UNUSED_P(systemId),
   1564                        const XML_Char *UNUSED_P(publicId))
   1565 {
   1566     ExtTest *test_data = (ExtTest *)XML_GetUserData(parser);
   1567     XML_Parser extparser;
   1568 
   1569     extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1570     if (extparser == NULL)
   1571         fail("Could not create external entity parser.");
   1572     if (test_data->encoding != NULL) {
   1573         if (!XML_SetEncoding(extparser, test_data->encoding))
   1574             fail("XML_SetEncoding() ignored for external entity");
   1575     }
   1576     if ( _XML_Parse_SINGLE_BYTES(extparser,
   1577                                  test_data->parse_text,
   1578                                  strlen(test_data->parse_text),
   1579                                  XML_TRUE)
   1580           == XML_STATUS_ERROR) {
   1581         xml_failure(extparser);
   1582         return XML_STATUS_ERROR;
   1583     }
   1584     XML_ParserFree(extparser);
   1585     return XML_STATUS_OK;
   1586 }
   1587 
   1588 START_TEST(test_ext_entity_set_encoding)
   1589 {
   1590     const char *text =
   1591         "<!DOCTYPE doc [\n"
   1592         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   1593         "]>\n"
   1594         "<doc>&en;</doc>";
   1595     ExtTest test_data = {
   1596         /* This text says it's an unsupported encoding, but it's really
   1597            UTF-8, which we tell Expat using XML_SetEncoding().
   1598         */
   1599         "<?xml encoding='iso-8859-3'?>\xC3\xA9",
   1600         XCS("utf-8"),
   1601         NULL
   1602     };
   1603 #ifdef XML_UNICODE
   1604     const XML_Char *expected = XCS("\x00e9");
   1605 #else
   1606     const XML_Char *expected = XCS("\xc3\xa9");
   1607 #endif
   1608 
   1609     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   1610     run_ext_character_check(text, &test_data, expected);
   1611 }
   1612 END_TEST
   1613 
   1614 /* Test external entities with no handler */
   1615 START_TEST(test_ext_entity_no_handler)
   1616 {
   1617     const char *text =
   1618         "<!DOCTYPE doc [\n"
   1619         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   1620         "]>\n"
   1621         "<doc>&en;</doc>";
   1622 
   1623     XML_SetDefaultHandler(parser, dummy_default_handler);
   1624     run_character_check(text, XCS(""));
   1625 }
   1626 END_TEST
   1627 
   1628 /* Test UTF-8 BOM is accepted */
   1629 START_TEST(test_ext_entity_set_bom)
   1630 {
   1631     const char *text =
   1632         "<!DOCTYPE doc [\n"
   1633         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   1634         "]>\n"
   1635         "<doc>&en;</doc>";
   1636     ExtTest test_data = {
   1637         "\xEF\xBB\xBF" /* BOM */
   1638         "<?xml encoding='iso-8859-3'?>"
   1639         "\xC3\xA9",
   1640         XCS("utf-8"),
   1641         NULL
   1642     };
   1643 #ifdef XML_UNICODE
   1644     const XML_Char *expected = XCS("\x00e9");
   1645 #else
   1646     const XML_Char *expected = XCS("\xc3\xa9");
   1647 #endif
   1648 
   1649     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   1650     run_ext_character_check(text, &test_data, expected);
   1651 }
   1652 END_TEST
   1653 
   1654 
   1655 /* Test that bad encodings are faulted */
   1656 typedef struct ext_faults
   1657 {
   1658     const char *parse_text;
   1659     const char *fail_text;
   1660     const XML_Char *encoding;
   1661     enum XML_Error error;
   1662 } ExtFaults;
   1663 
   1664 static int XMLCALL
   1665 external_entity_faulter(XML_Parser parser,
   1666                         const XML_Char *context,
   1667                         const XML_Char *UNUSED_P(base),
   1668                         const XML_Char *UNUSED_P(systemId),
   1669                         const XML_Char *UNUSED_P(publicId))
   1670 {
   1671     XML_Parser ext_parser;
   1672     ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser);
   1673 
   1674     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1675     if (ext_parser == NULL)
   1676         fail("Could not create external entity parser");
   1677     if (fault->encoding != NULL) {
   1678         if (!XML_SetEncoding(ext_parser, fault->encoding))
   1679             fail("XML_SetEncoding failed");
   1680     }
   1681     if (_XML_Parse_SINGLE_BYTES(ext_parser,
   1682                                 fault->parse_text,
   1683                                 strlen(fault->parse_text),
   1684                                 XML_TRUE) != XML_STATUS_ERROR)
   1685         fail(fault->fail_text);
   1686     if (XML_GetErrorCode(ext_parser) != fault->error)
   1687         xml_failure(ext_parser);
   1688 
   1689     XML_ParserFree(ext_parser);
   1690     return XML_STATUS_ERROR;
   1691 }
   1692 
   1693 START_TEST(test_ext_entity_bad_encoding)
   1694 {
   1695     const char *text =
   1696         "<!DOCTYPE doc [\n"
   1697         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   1698         "]>\n"
   1699         "<doc>&en;</doc>";
   1700     ExtFaults fault = {
   1701         "<?xml encoding='iso-8859-3'?>u",
   1702         "Unsupported encoding not faulted",
   1703         XCS("unknown"),
   1704         XML_ERROR_UNKNOWN_ENCODING
   1705     };
   1706 
   1707     XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
   1708     XML_SetUserData(parser, &fault);
   1709     expect_failure(text,
   1710                    XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   1711                    "Bad encoding should not have been accepted");
   1712 }
   1713 END_TEST
   1714 
   1715 /* Try handing an invalid encoding to an external entity parser */
   1716 START_TEST(test_ext_entity_bad_encoding_2)
   1717 {
   1718     const char *text =
   1719         "<?xml version='1.0' encoding='us-ascii'?>\n"
   1720         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   1721         "<doc>&entity;</doc>";
   1722     ExtFaults fault = {
   1723         "<!ELEMENT doc (#PCDATA)*>",
   1724         "Unknown encoding not faulted",
   1725         XCS("unknown-encoding"),
   1726         XML_ERROR_UNKNOWN_ENCODING
   1727     };
   1728 
   1729     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   1730     XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
   1731     XML_SetUserData(parser, &fault);
   1732     expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   1733                    "Bad encoding not faulted in external entity handler");
   1734 }
   1735 END_TEST
   1736 
   1737 /* Test that no error is reported for unknown entities if we don't
   1738    read an external subset.  This was fixed in Expat 1.95.5.
   1739 */
   1740 START_TEST(test_wfc_undeclared_entity_unread_external_subset) {
   1741     const char *text =
   1742         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   1743         "<doc>&entity;</doc>";
   1744 
   1745     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   1746         xml_failure(parser);
   1747 }
   1748 END_TEST
   1749 
   1750 /* Test that an error is reported for unknown entities if we don't
   1751    have an external subset.
   1752 */
   1753 START_TEST(test_wfc_undeclared_entity_no_external_subset) {
   1754     expect_failure("<doc>&entity;</doc>",
   1755                    XML_ERROR_UNDEFINED_ENTITY,
   1756                    "Parser did not report undefined entity w/out a DTD.");
   1757 }
   1758 END_TEST
   1759 
   1760 /* Test that an error is reported for unknown entities if we don't
   1761    read an external subset, but have been declared standalone.
   1762 */
   1763 START_TEST(test_wfc_undeclared_entity_standalone) {
   1764     const char *text =
   1765         "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
   1766         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   1767         "<doc>&entity;</doc>";
   1768 
   1769     expect_failure(text,
   1770                    XML_ERROR_UNDEFINED_ENTITY,
   1771                    "Parser did not report undefined entity (standalone).");
   1772 }
   1773 END_TEST
   1774 
   1775 /* Test that an error is reported for unknown entities if we have read
   1776    an external subset, and standalone is true.
   1777 */
   1778 START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) {
   1779     const char *text =
   1780         "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
   1781         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   1782         "<doc>&entity;</doc>";
   1783     ExtTest test_data = {
   1784         "<!ELEMENT doc (#PCDATA)*>",
   1785         NULL,
   1786         NULL
   1787     };
   1788 
   1789     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   1790     XML_SetUserData(parser, &test_data);
   1791     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   1792     expect_failure(text,
   1793                    XML_ERROR_UNDEFINED_ENTITY,
   1794                    "Parser did not report undefined entity (external DTD).");
   1795 }
   1796 END_TEST
   1797 
   1798 /* Test that external entity handling is not done if the parsing flag
   1799  * is set to UNLESS_STANDALONE
   1800  */
   1801 START_TEST(test_entity_with_external_subset_unless_standalone) {
   1802     const char *text =
   1803         "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
   1804         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   1805         "<doc>&entity;</doc>";
   1806     ExtTest test_data = { "<!ENTITY entity 'bar'>", NULL, NULL };
   1807 
   1808     XML_SetParamEntityParsing(parser,
   1809                               XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
   1810     XML_SetUserData(parser, &test_data);
   1811     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   1812     expect_failure(text,
   1813                    XML_ERROR_UNDEFINED_ENTITY,
   1814                    "Parser did not report undefined entity");
   1815 }
   1816 END_TEST
   1817 
   1818 /* Test that no error is reported for unknown entities if we have read
   1819    an external subset, and standalone is false.
   1820 */
   1821 START_TEST(test_wfc_undeclared_entity_with_external_subset) {
   1822     const char *text =
   1823         "<?xml version='1.0' encoding='us-ascii'?>\n"
   1824         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   1825         "<doc>&entity;</doc>";
   1826     ExtTest test_data = {
   1827         "<!ELEMENT doc (#PCDATA)*>",
   1828         NULL,
   1829         NULL
   1830     };
   1831 
   1832     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   1833     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   1834     run_ext_character_check(text, &test_data, XCS(""));
   1835 }
   1836 END_TEST
   1837 
   1838 /* Test that an error is reported if our NotStandalone handler fails */
   1839 static int XMLCALL
   1840 reject_not_standalone_handler(void *UNUSED_P(userData))
   1841 {
   1842     return XML_STATUS_ERROR;
   1843 }
   1844 
   1845 START_TEST(test_not_standalone_handler_reject)
   1846 {
   1847     const char *text =
   1848         "<?xml version='1.0' encoding='us-ascii'?>\n"
   1849         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   1850         "<doc>&entity;</doc>";
   1851     ExtTest test_data = {
   1852         "<!ELEMENT doc (#PCDATA)*>",
   1853         NULL,
   1854         NULL
   1855     };
   1856 
   1857     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   1858     XML_SetUserData(parser, &test_data);
   1859     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   1860     XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler);
   1861     expect_failure(text, XML_ERROR_NOT_STANDALONE,
   1862                    "NotStandalone handler failed to reject");
   1863 
   1864     /* Try again but without external entity handling */
   1865     XML_ParserReset(parser, NULL);
   1866     XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler);
   1867     expect_failure(text, XML_ERROR_NOT_STANDALONE,
   1868                    "NotStandalone handler failed to reject");
   1869 }
   1870 END_TEST
   1871 
   1872 /* Test that no error is reported if our NotStandalone handler succeeds */
   1873 static int XMLCALL
   1874 accept_not_standalone_handler(void *UNUSED_P(userData))
   1875 {
   1876     return XML_STATUS_OK;
   1877 }
   1878 
   1879 START_TEST(test_not_standalone_handler_accept)
   1880 {
   1881     const char *text =
   1882         "<?xml version='1.0' encoding='us-ascii'?>\n"
   1883         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   1884         "<doc>&entity;</doc>";
   1885     ExtTest test_data = {
   1886         "<!ELEMENT doc (#PCDATA)*>",
   1887         NULL,
   1888         NULL
   1889     };
   1890 
   1891     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   1892     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   1893     XML_SetNotStandaloneHandler(parser, accept_not_standalone_handler);
   1894     run_ext_character_check(text, &test_data, XCS(""));
   1895 
   1896     /* Repeat wtihout the external entity handler */
   1897     XML_ParserReset(parser, NULL);
   1898     XML_SetNotStandaloneHandler(parser, accept_not_standalone_handler);
   1899     run_character_check(text, XCS(""));
   1900 }
   1901 END_TEST
   1902 
   1903 START_TEST(test_wfc_no_recursive_entity_refs)
   1904 {
   1905     const char *text =
   1906         "<!DOCTYPE doc [\n"
   1907         "  <!ENTITY entity '&#38;entity;'>\n"
   1908         "]>\n"
   1909         "<doc>&entity;</doc>";
   1910 
   1911     expect_failure(text,
   1912                    XML_ERROR_RECURSIVE_ENTITY_REF,
   1913                    "Parser did not report recursive entity reference.");
   1914 }
   1915 END_TEST
   1916 
   1917 /* Test incomplete external entities are faulted */
   1918 START_TEST(test_ext_entity_invalid_parse)
   1919 {
   1920     const char *text =
   1921         "<!DOCTYPE doc [\n"
   1922         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   1923         "]>\n"
   1924         "<doc>&en;</doc>";
   1925     const ExtFaults faults[] = {
   1926         {
   1927             "<",
   1928             "Incomplete element declaration not faulted",
   1929             NULL,
   1930             XML_ERROR_UNCLOSED_TOKEN
   1931         },
   1932         {
   1933             "<\xe2\x82", /* First two bytes of a three-byte char */
   1934             "Incomplete character not faulted",
   1935             NULL,
   1936             XML_ERROR_PARTIAL_CHAR
   1937         },
   1938         {
   1939             "<tag>\xe2\x82",
   1940             "Incomplete character in CDATA not faulted",
   1941             NULL,
   1942             XML_ERROR_PARTIAL_CHAR
   1943         },
   1944         { NULL, NULL, NULL, XML_ERROR_NONE }
   1945     };
   1946     const ExtFaults *fault = faults;
   1947 
   1948     for (; fault->parse_text != NULL; fault++) {
   1949         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   1950         XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
   1951         XML_SetUserData(parser, (void *)fault);
   1952         expect_failure(text,
   1953                        XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   1954                        "Parser did not report external entity error");
   1955         XML_ParserReset(parser, NULL);
   1956     }
   1957 }
   1958 END_TEST
   1959 
   1960 
   1961 /* Regression test for SF bug #483514. */
   1962 START_TEST(test_dtd_default_handling)
   1963 {
   1964     const char *text =
   1965         "<!DOCTYPE doc [\n"
   1966         "<!ENTITY e SYSTEM 'http://example.org/e'>\n"
   1967         "<!NOTATION n SYSTEM 'http://example.org/n'>\n"
   1968         "<!ELEMENT doc EMPTY>\n"
   1969         "<!ATTLIST doc a CDATA #IMPLIED>\n"
   1970         "<?pi in dtd?>\n"
   1971         "<!--comment in dtd-->\n"
   1972         "]><doc/>";
   1973 
   1974     XML_SetDefaultHandler(parser, accumulate_characters);
   1975     XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler);
   1976     XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler);
   1977     XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
   1978     XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
   1979     XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   1980     XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
   1981     XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
   1982     XML_SetCommentHandler(parser, dummy_comment_handler);
   1983     XML_SetStartCdataSectionHandler(parser, dummy_start_cdata_handler);
   1984     XML_SetEndCdataSectionHandler(parser, dummy_end_cdata_handler);
   1985     run_character_check(text, XCS("\n\n\n\n\n\n\n<doc/>"));
   1986 }
   1987 END_TEST
   1988 
   1989 /* Test handling of attribute declarations */
   1990 typedef struct AttTest {
   1991     const char *definition;
   1992     const XML_Char *element_name;
   1993     const XML_Char *attr_name;
   1994     const XML_Char *attr_type;
   1995     const XML_Char *default_value;
   1996     int is_required;
   1997 } AttTest;
   1998 
   1999 static void XMLCALL
   2000 verify_attlist_decl_handler(void *userData,
   2001                             const XML_Char *element_name,
   2002                             const XML_Char *attr_name,
   2003                             const XML_Char *attr_type,
   2004                             const XML_Char *default_value,
   2005                             int is_required)
   2006 {
   2007     AttTest *at = (AttTest *)userData;
   2008 
   2009     if (xcstrcmp(element_name, at->element_name))
   2010         fail("Unexpected element name in attribute declaration");
   2011     if (xcstrcmp(attr_name, at->attr_name))
   2012         fail("Unexpected attribute name in attribute declaration");
   2013     if (xcstrcmp(attr_type, at->attr_type))
   2014         fail("Unexpected attribute type in attribute declaration");
   2015     if ((default_value == NULL && at->default_value != NULL) ||
   2016         (default_value != NULL && at->default_value == NULL) ||
   2017         (default_value != NULL && xcstrcmp(default_value, at->default_value)))
   2018         fail("Unexpected default value in attribute declaration");
   2019     if (is_required != at->is_required)
   2020         fail("Requirement mismatch in attribute declaration");
   2021 }
   2022 
   2023 START_TEST(test_dtd_attr_handling)
   2024 {
   2025     const char *prolog =
   2026         "<!DOCTYPE doc [\n"
   2027         "<!ELEMENT doc EMPTY>\n";
   2028     AttTest attr_data[] = {
   2029         {
   2030             "<!ATTLIST doc a ( one | two | three ) #REQUIRED>\n"
   2031             "]>"
   2032             "<doc a='two'/>",
   2033             XCS("doc"),
   2034             XCS("a"),
   2035             XCS("(one|two|three)"), /* Extraneous spaces will be removed */
   2036             NULL,
   2037             XML_TRUE
   2038         },
   2039         {
   2040             "<!NOTATION foo SYSTEM 'http://example.org/foo'>\n"
   2041             "<!ATTLIST doc a NOTATION (foo) #IMPLIED>\n"
   2042             "]>"
   2043             "<doc/>",
   2044             XCS("doc"),
   2045             XCS("a"),
   2046             XCS("NOTATION(foo)"),
   2047             NULL,
   2048             XML_FALSE
   2049         },
   2050         {
   2051             "<!ATTLIST doc a NOTATION (foo) 'bar'>\n"
   2052             "]>"
   2053             "<doc/>",
   2054             XCS("doc"),
   2055             XCS("a"),
   2056             XCS("NOTATION(foo)"),
   2057             XCS("bar"),
   2058             XML_FALSE
   2059         },
   2060         {
   2061             "<!ATTLIST doc a CDATA '\xdb\xb2'>\n"
   2062             "]>"
   2063             "<doc/>",
   2064             XCS("doc"),
   2065             XCS("a"),
   2066             XCS("CDATA"),
   2067 #ifdef XML_UNICODE
   2068             XCS("\x06f2"),
   2069 #else
   2070             XCS("\xdb\xb2"),
   2071 #endif
   2072             XML_FALSE
   2073         },
   2074         { NULL, NULL, NULL, NULL, NULL, XML_FALSE }
   2075     };
   2076     AttTest *test;
   2077 
   2078     for (test = attr_data; test->definition != NULL; test++) {
   2079         XML_SetAttlistDeclHandler(parser, verify_attlist_decl_handler);
   2080         XML_SetUserData(parser, test);
   2081         if (_XML_Parse_SINGLE_BYTES(parser, prolog, strlen(prolog),
   2082                                     XML_FALSE) == XML_STATUS_ERROR)
   2083             xml_failure(parser);
   2084         if (_XML_Parse_SINGLE_BYTES(parser,
   2085                                     test->definition,
   2086                                     strlen(test->definition),
   2087                                     XML_TRUE) == XML_STATUS_ERROR)
   2088             xml_failure(parser);
   2089         XML_ParserReset(parser, NULL);
   2090     }
   2091 }
   2092 END_TEST
   2093 
   2094 /* See related SF bug #673791.
   2095    When namespace processing is enabled, setting the namespace URI for
   2096    a prefix is not allowed; this test ensures that it *is* allowed
   2097    when namespace processing is not enabled.
   2098    (See Namespaces in XML, section 2.)
   2099 */
   2100 START_TEST(test_empty_ns_without_namespaces)
   2101 {
   2102     const char *text =
   2103         "<doc xmlns:prefix='http://example.org/'>\n"
   2104         "  <e xmlns:prefix=''/>\n"
   2105         "</doc>";
   2106 
   2107     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   2108         xml_failure(parser);
   2109 }
   2110 END_TEST
   2111 
   2112 /* Regression test for SF bug #824420.
   2113    Checks that an xmlns:prefix attribute set in an attribute's default
   2114    value isn't misinterpreted.
   2115 */
   2116 START_TEST(test_ns_in_attribute_default_without_namespaces)
   2117 {
   2118     const char *text =
   2119         "<!DOCTYPE e:element [\n"
   2120         "  <!ATTLIST e:element\n"
   2121         "    xmlns:e CDATA 'http://example.org/'>\n"
   2122         "      ]>\n"
   2123         "<e:element/>";
   2124 
   2125     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   2126         xml_failure(parser);
   2127 }
   2128 END_TEST
   2129 
   2130 static const char *long_character_data_text =
   2131     "<?xml version='1.0' encoding='iso-8859-1'?><s>"
   2132     "012345678901234567890123456789012345678901234567890123456789"
   2133     "012345678901234567890123456789012345678901234567890123456789"
   2134     "012345678901234567890123456789012345678901234567890123456789"
   2135     "012345678901234567890123456789012345678901234567890123456789"
   2136     "012345678901234567890123456789012345678901234567890123456789"
   2137     "012345678901234567890123456789012345678901234567890123456789"
   2138     "012345678901234567890123456789012345678901234567890123456789"
   2139     "012345678901234567890123456789012345678901234567890123456789"
   2140     "012345678901234567890123456789012345678901234567890123456789"
   2141     "012345678901234567890123456789012345678901234567890123456789"
   2142     "012345678901234567890123456789012345678901234567890123456789"
   2143     "012345678901234567890123456789012345678901234567890123456789"
   2144     "012345678901234567890123456789012345678901234567890123456789"
   2145     "012345678901234567890123456789012345678901234567890123456789"
   2146     "012345678901234567890123456789012345678901234567890123456789"
   2147     "012345678901234567890123456789012345678901234567890123456789"
   2148     "012345678901234567890123456789012345678901234567890123456789"
   2149     "012345678901234567890123456789012345678901234567890123456789"
   2150     "012345678901234567890123456789012345678901234567890123456789"
   2151     "012345678901234567890123456789012345678901234567890123456789"
   2152     "</s>";
   2153 
   2154 static XML_Bool resumable = XML_FALSE;
   2155 
   2156 static void
   2157 clearing_aborting_character_handler(void *UNUSED_P(userData),
   2158                                     const XML_Char *UNUSED_P(s), int UNUSED_P(len))
   2159 {
   2160     XML_StopParser(parser, resumable);
   2161     XML_SetCharacterDataHandler(parser, NULL);
   2162 }
   2163 
   2164 /* Regression test for SF bug #1515266: missing check of stopped
   2165    parser in doContext() 'for' loop. */
   2166 START_TEST(test_stop_parser_between_char_data_calls)
   2167 {
   2168     /* The sample data must be big enough that there are two calls to
   2169        the character data handler from within the inner "for" loop of
   2170        the XML_TOK_DATA_CHARS case in doContent(), and the character
   2171        handler must stop the parser and clear the character data
   2172        handler.
   2173     */
   2174     const char *text = long_character_data_text;
   2175 
   2176     XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
   2177     resumable = XML_FALSE;
   2178     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
   2179         xml_failure(parser);
   2180     if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED)
   2181         xml_failure(parser);
   2182 }
   2183 END_TEST
   2184 
   2185 /* Regression test for SF bug #1515266: missing check of stopped
   2186    parser in doContext() 'for' loop. */
   2187 START_TEST(test_suspend_parser_between_char_data_calls)
   2188 {
   2189     /* The sample data must be big enough that there are two calls to
   2190        the character data handler from within the inner "for" loop of
   2191        the XML_TOK_DATA_CHARS case in doContent(), and the character
   2192        handler must stop the parser and clear the character data
   2193        handler.
   2194     */
   2195     const char *text = long_character_data_text;
   2196 
   2197     XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
   2198     resumable = XML_TRUE;
   2199     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED)
   2200         xml_failure(parser);
   2201     if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
   2202         xml_failure(parser);
   2203     /* Try parsing directly */
   2204     if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
   2205         fail("Attempt to continue parse while suspended not faulted");
   2206     if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
   2207         fail("Suspended parse not faulted with correct error");
   2208 }
   2209 END_TEST
   2210 
   2211 
   2212 static XML_Bool abortable = XML_FALSE;
   2213 
   2214 static void
   2215 parser_stop_character_handler(void *UNUSED_P(userData),
   2216                               const XML_Char *UNUSED_P(s),
   2217                               int UNUSED_P(len))
   2218 {
   2219     XML_StopParser(parser, resumable);
   2220     XML_SetCharacterDataHandler(parser, NULL);
   2221     if (!resumable) {
   2222         /* Check that aborting an aborted parser is faulted */
   2223         if (XML_StopParser(parser, XML_FALSE) != XML_STATUS_ERROR)
   2224             fail("Aborting aborted parser not faulted");
   2225         if (XML_GetErrorCode(parser) != XML_ERROR_FINISHED)
   2226             xml_failure(parser);
   2227     } else if (abortable) {
   2228         /* Check that aborting a suspended parser works */
   2229         if (XML_StopParser(parser, XML_FALSE) == XML_STATUS_ERROR)
   2230             xml_failure(parser);
   2231     } else {
   2232         /* Check that suspending a suspended parser works */
   2233         if (XML_StopParser(parser, XML_TRUE) != XML_STATUS_ERROR)
   2234             fail("Suspending suspended parser not faulted");
   2235         if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
   2236             xml_failure(parser);
   2237     }
   2238 }
   2239 
   2240 /* Test repeated calls to XML_StopParser are handled correctly */
   2241 START_TEST(test_repeated_stop_parser_between_char_data_calls)
   2242 {
   2243     const char *text = long_character_data_text;
   2244 
   2245     XML_SetCharacterDataHandler(parser, parser_stop_character_handler);
   2246     resumable = XML_FALSE;
   2247     abortable = XML_FALSE;
   2248     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   2249                                 XML_TRUE) != XML_STATUS_ERROR)
   2250         fail("Failed to double-stop parser");
   2251 
   2252     XML_ParserReset(parser, NULL);
   2253     XML_SetCharacterDataHandler(parser, parser_stop_character_handler);
   2254     resumable = XML_TRUE;
   2255     abortable = XML_FALSE;
   2256     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   2257                                 XML_TRUE) != XML_STATUS_SUSPENDED)
   2258         fail("Failed to double-suspend parser");
   2259 
   2260     XML_ParserReset(parser, NULL);
   2261     XML_SetCharacterDataHandler(parser, parser_stop_character_handler);
   2262     resumable = XML_TRUE;
   2263     abortable = XML_TRUE;
   2264     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   2265                                 XML_TRUE) != XML_STATUS_ERROR)
   2266         fail("Failed to suspend-abort parser");
   2267 }
   2268 END_TEST
   2269 
   2270 
   2271 START_TEST(test_good_cdata_ascii)
   2272 {
   2273     const char *text = "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>";
   2274     const XML_Char *expected = XCS("<greeting>Hello, world!</greeting>");
   2275 
   2276     CharData storage;
   2277     CharData_Init(&storage);
   2278     XML_SetUserData(parser, &storage);
   2279     XML_SetCharacterDataHandler(parser, accumulate_characters);
   2280     /* Add start and end handlers for coverage */
   2281     XML_SetStartCdataSectionHandler(parser, dummy_start_cdata_handler);
   2282     XML_SetEndCdataSectionHandler(parser, dummy_end_cdata_handler);
   2283 
   2284     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   2285         xml_failure(parser);
   2286     CharData_CheckXMLChars(&storage, expected);
   2287 
   2288     /* Try again, this time with a default handler */
   2289     XML_ParserReset(parser, NULL);
   2290     CharData_Init(&storage);
   2291     XML_SetUserData(parser, &storage);
   2292     XML_SetCharacterDataHandler(parser, accumulate_characters);
   2293     XML_SetDefaultHandler(parser, dummy_default_handler);
   2294 
   2295     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   2296         xml_failure(parser);
   2297     CharData_CheckXMLChars(&storage, expected);
   2298 }
   2299 END_TEST
   2300 
   2301 START_TEST(test_good_cdata_utf16)
   2302 {
   2303     /* Test data is:
   2304      *   <?xml version='1.0' encoding='utf-16'?>
   2305      *   <a><![CDATA[hello]]></a>
   2306      */
   2307     const char text[] =
   2308             "\0<\0?\0x\0m\0l\0"
   2309                 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
   2310                 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
   2311                 "\0?\0>\0\n"
   2312             "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[\0h\0e\0l\0l\0o\0]\0]\0>\0<\0/\0a\0>";
   2313     const XML_Char *expected = XCS("hello");
   2314 
   2315     CharData storage;
   2316     CharData_Init(&storage);
   2317     XML_SetUserData(parser, &storage);
   2318     XML_SetCharacterDataHandler(parser, accumulate_characters);
   2319 
   2320     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR)
   2321         xml_failure(parser);
   2322     CharData_CheckXMLChars(&storage, expected);
   2323 }
   2324 END_TEST
   2325 
   2326 START_TEST(test_good_cdata_utf16_le)
   2327 {
   2328     /* Test data is:
   2329      *   <?xml version='1.0' encoding='utf-16'?>
   2330      *   <a><![CDATA[hello]]></a>
   2331      */
   2332     const char text[] =
   2333             "<\0?\0x\0m\0l\0"
   2334                 " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
   2335                 " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
   2336                 "\0?\0>\0\n"
   2337             "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[\0h\0e\0l\0l\0o\0]\0]\0>\0<\0/\0a\0>\0";
   2338     const XML_Char *expected = XCS("hello");
   2339 
   2340     CharData storage;
   2341     CharData_Init(&storage);
   2342     XML_SetUserData(parser, &storage);
   2343     XML_SetCharacterDataHandler(parser, accumulate_characters);
   2344 
   2345     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR)
   2346         xml_failure(parser);
   2347     CharData_CheckXMLChars(&storage, expected);
   2348 }
   2349 END_TEST
   2350 
   2351 /* Test UTF16 conversion of a long cdata string */
   2352 
   2353 /* 16 characters: handy macro to reduce visual clutter */
   2354 #define A_TO_P_IN_UTF16 "\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P"
   2355 
   2356 START_TEST(test_long_cdata_utf16)
   2357 {
   2358     /* Test data is:
   2359      * <?xlm version='1.0' encoding='utf-16'?>
   2360      * <a><![CDATA[
   2361      * ABCDEFGHIJKLMNOP
   2362      * ]]></a>
   2363      */
   2364     const char text[] =
   2365         "\0<\0?\0x\0m\0l\0 "
   2366         "\0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0 "
   2367         "\0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0\x31\0\x36\0'\0?\0>"
   2368         "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0["
   2369         /* 64 characters per line */
   2370         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2371         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2372         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2373         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2374         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2375         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2376         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2377         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2378         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2379         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2380         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2381         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2382         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2383         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2384         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2385         A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16  A_TO_P_IN_UTF16
   2386         A_TO_P_IN_UTF16
   2387         "\0]\0]\0>\0<\0/\0a\0>";
   2388     const XML_Char *expected =
   2389         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2390         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2391         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2392         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2393         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2394         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2395         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2396         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2397         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2398         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2399         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2400         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2401         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2402         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2403         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2404         XCS("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP")
   2405         XCS("ABCDEFGHIJKLMNOP";)
   2406     CharData storage;
   2407     void *buffer;
   2408 
   2409     CharData_Init(&storage);
   2410     XML_SetUserData(parser, &storage);
   2411     XML_SetCharacterDataHandler(parser, accumulate_characters);
   2412     buffer = XML_GetBuffer(parser, sizeof(text) - 1);
   2413     if (buffer == NULL)
   2414         fail("Could not allocate parse buffer");
   2415     memcpy(buffer, text, sizeof(text) - 1);
   2416     if (XML_ParseBuffer(parser,
   2417                         sizeof(text) - 1,
   2418                         XML_TRUE) == XML_STATUS_ERROR)
   2419         xml_failure(parser);
   2420     CharData_CheckXMLChars(&storage, expected);
   2421 }
   2422 END_TEST
   2423 
   2424 /* Test handling of multiple unit UTF-16 characters */
   2425 START_TEST(test_multichar_cdata_utf16)
   2426 {
   2427     /* Test data is:
   2428      *   <?xml version='1.0' encoding='utf-16'?>
   2429      *   <a><![CDATA[{MINIM}{CROTCHET}]]></a>
   2430      *
   2431      * where {MINIM} is U+1d15e (a minim or half-note)
   2432      *   UTF-16: 0xd834 0xdd5e
   2433      *   UTF-8:  0xf0 0x9d 0x85 0x9e
   2434      * and {CROTCHET} is U+1d15f (a crotchet or quarter-note)
   2435      *   UTF-16: 0xd834 0xdd5f
   2436      *   UTF-8:  0xf0 0x9d 0x85 0x9f
   2437      */
   2438     const char text[] =
   2439         "\0<\0?\0x\0m\0l\0"
   2440         " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
   2441         " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
   2442         "\0?\0>\0\n"
   2443         "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0["
   2444         "\xd8\x34\xdd\x5e\xd8\x34\xdd\x5f"
   2445         "\0]\0]\0>\0<\0/\0a\0>";
   2446 #ifdef XML_UNICODE
   2447     const XML_Char *expected = XCS("\xd834\xdd5e\xd834\xdd5f");
   2448 #else
   2449     const XML_Char *expected = XCS("\xf0\x9d\x85\x9e\xf0\x9d\x85\x9f");
   2450 #endif
   2451     CharData storage;
   2452 
   2453     CharData_Init(&storage);
   2454     XML_SetUserData(parser, &storage);
   2455     XML_SetCharacterDataHandler(parser, accumulate_characters);
   2456 
   2457     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR)
   2458         xml_failure(parser);
   2459     CharData_CheckXMLChars(&storage, expected);
   2460 }
   2461 END_TEST
   2462 
   2463 /* Test that an element name with a UTF-16 surrogate pair is rejected */
   2464 START_TEST(test_utf16_bad_surrogate_pair)
   2465 {
   2466     /* Test data is:
   2467      *   <?xml version='1.0' encoding='utf-16'?>
   2468      *   <a><![CDATA[{BADLINB}]]></a>
   2469      *
   2470      * where {BADLINB} is U+10000 (the first Linear B character)
   2471      * with the UTF-16 surrogate pair in the wrong order, i.e.
   2472      *   0xdc00 0xd800
   2473      */
   2474     const char text[] =
   2475         "\0<\0?\0x\0m\0l\0"
   2476         " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
   2477         " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
   2478         "\0?\0>\0\n"
   2479         "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0["
   2480         "\xdc\x00\xd8\x00"
   2481         "\0]\0]\0>\0<\0/\0a\0>";
   2482 
   2483     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1,
   2484                                 XML_TRUE) != XML_STATUS_ERROR)
   2485         fail("Reversed UTF-16 surrogate pair not faulted");
   2486     if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
   2487         xml_failure(parser);
   2488 }
   2489 END_TEST
   2490 
   2491 
   2492 START_TEST(test_bad_cdata)
   2493 {
   2494     struct CaseData {
   2495         const char *text;
   2496         enum XML_Error expectedError;
   2497     };
   2498 
   2499     struct CaseData cases[] = {
   2500         {"<a><", XML_ERROR_UNCLOSED_TOKEN},
   2501         {"<a><!", XML_ERROR_UNCLOSED_TOKEN},
   2502         {"<a><![", XML_ERROR_UNCLOSED_TOKEN},
   2503         {"<a><![C", XML_ERROR_UNCLOSED_TOKEN},
   2504         {"<a><![CD", XML_ERROR_UNCLOSED_TOKEN},
   2505         {"<a><![CDA", XML_ERROR_UNCLOSED_TOKEN},
   2506         {"<a><![CDAT", XML_ERROR_UNCLOSED_TOKEN},
   2507         {"<a><![CDATA", XML_ERROR_UNCLOSED_TOKEN},
   2508 
   2509         {"<a><![CDATA[", XML_ERROR_UNCLOSED_CDATA_SECTION},
   2510         {"<a><![CDATA[]", XML_ERROR_UNCLOSED_CDATA_SECTION},
   2511         {"<a><![CDATA[]]", XML_ERROR_UNCLOSED_CDATA_SECTION},
   2512 
   2513         {"<a><!<a/>", XML_ERROR_INVALID_TOKEN},
   2514         {"<a><![<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */
   2515         {"<a><![C<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */
   2516         {"<a><![CD<a/>", XML_ERROR_INVALID_TOKEN},
   2517         {"<a><![CDA<a/>", XML_ERROR_INVALID_TOKEN},
   2518         {"<a><![CDAT<a/>", XML_ERROR_INVALID_TOKEN},
   2519         {"<a><![CDATA<a/>", XML_ERROR_INVALID_TOKEN},
   2520 
   2521         {"<a><![CDATA[<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION},
   2522         {"<a><![CDATA[]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION},
   2523         {"<a><![CDATA[]]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION}
   2524     };
   2525 
   2526     size_t i = 0;
   2527     for (; i < sizeof(cases) / sizeof(struct CaseData); i++) {
   2528         const enum XML_Status actualStatus = _XML_Parse_SINGLE_BYTES(
   2529                 parser, cases[i].text, strlen(cases[i].text), XML_TRUE);
   2530         const enum XML_Error actualError = XML_GetErrorCode(parser);
   2531 
   2532         assert(actualStatus == XML_STATUS_ERROR);
   2533 
   2534         if (actualError != cases[i].expectedError) {
   2535             char message[100];
   2536             sprintf(message, "Expected error %d but got error %d for case %u: \"%s\"\n",
   2537                     cases[i].expectedError, actualError, (unsigned int)i + 1, cases[i].text);
   2538             fail(message);
   2539         }
   2540 
   2541         XML_ParserReset(parser, NULL);
   2542     }
   2543 }
   2544 END_TEST
   2545 
   2546 /* Test failures in UTF-16 CDATA */
   2547 START_TEST(test_bad_cdata_utf16)
   2548 {
   2549     struct CaseData {
   2550         size_t text_bytes;
   2551         const char *text;
   2552         enum XML_Error expected_error;
   2553     };
   2554 
   2555     const char prolog[] =
   2556         "\0<\0?\0x\0m\0l\0"
   2557         " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
   2558         " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
   2559         "\0?\0>\0\n"
   2560         "\0<\0a\0>";
   2561     struct CaseData cases[] = {
   2562         {1, "\0", XML_ERROR_UNCLOSED_TOKEN},
   2563         {2, "\0<", XML_ERROR_UNCLOSED_TOKEN},
   2564         {3, "\0<\0", XML_ERROR_UNCLOSED_TOKEN},
   2565         {4, "\0<\0!", XML_ERROR_UNCLOSED_TOKEN},
   2566         {5, "\0<\0!\0", XML_ERROR_UNCLOSED_TOKEN},
   2567         {6, "\0<\0!\0[", XML_ERROR_UNCLOSED_TOKEN},
   2568         {7, "\0<\0!\0[\0", XML_ERROR_UNCLOSED_TOKEN},
   2569         {8, "\0<\0!\0[\0C", XML_ERROR_UNCLOSED_TOKEN},
   2570         {9, "\0<\0!\0[\0C\0", XML_ERROR_UNCLOSED_TOKEN},
   2571         {10, "\0<\0!\0[\0C\0D", XML_ERROR_UNCLOSED_TOKEN},
   2572         {11, "\0<\0!\0[\0C\0D\0", XML_ERROR_UNCLOSED_TOKEN},
   2573         {12, "\0<\0!\0[\0C\0D\0A", XML_ERROR_UNCLOSED_TOKEN},
   2574         {13, "\0<\0!\0[\0C\0D\0A\0", XML_ERROR_UNCLOSED_TOKEN},
   2575         {14, "\0<\0!\0[\0C\0D\0A\0T", XML_ERROR_UNCLOSED_TOKEN},
   2576         {15, "\0<\0!\0[\0C\0D\0A\0T\0", XML_ERROR_UNCLOSED_TOKEN},
   2577         {16, "\0<\0!\0[\0C\0D\0A\0T\0A", XML_ERROR_UNCLOSED_TOKEN},
   2578         {17, "\0<\0!\0[\0C\0D\0A\0T\0A\0", XML_ERROR_UNCLOSED_TOKEN},
   2579         {18, "\0<\0!\0[\0C\0D\0A\0T\0A\0[",
   2580          XML_ERROR_UNCLOSED_CDATA_SECTION},
   2581         {19, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0",
   2582          XML_ERROR_UNCLOSED_CDATA_SECTION},
   2583         {20, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z",
   2584          XML_ERROR_UNCLOSED_CDATA_SECTION},
   2585         /* Now add a four-byte UTF-16 character */
   2586         {21, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8",
   2587          XML_ERROR_UNCLOSED_CDATA_SECTION},
   2588         {22, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8\x34",
   2589          XML_ERROR_PARTIAL_CHAR},
   2590         {23, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8\x34\xdd",
   2591          XML_ERROR_PARTIAL_CHAR},
   2592         {24, "\0<\0!\0[\0C\0D\0A\0T\0A\0[\0Z\xd8\x34\xdd\x5e",
   2593          XML_ERROR_UNCLOSED_CDATA_SECTION}
   2594     };
   2595     size_t i;
   2596 
   2597     for (i = 0; i < sizeof(cases)/sizeof(struct CaseData); i++) {
   2598         enum XML_Status actual_status;
   2599         enum XML_Error actual_error;
   2600 
   2601         if (_XML_Parse_SINGLE_BYTES(parser, prolog, sizeof(prolog)-1,
   2602                                     XML_FALSE) == XML_STATUS_ERROR)
   2603             xml_failure(parser);
   2604         actual_status = _XML_Parse_SINGLE_BYTES(parser,
   2605                                                 cases[i].text,
   2606                                                 cases[i].text_bytes,
   2607                                                 XML_TRUE);
   2608         assert(actual_status == XML_STATUS_ERROR);
   2609         actual_error = XML_GetErrorCode(parser);
   2610         if (actual_error != cases[i].expected_error) {
   2611             char message[1024];
   2612 
   2613             sprintf(message,
   2614                     "Expected error %d (%" XML_FMT_STR
   2615                     "), got %d (%" XML_FMT_STR ") for case %lu\n",
   2616                     cases[i].expected_error,
   2617                     XML_ErrorString(cases[i].expected_error),
   2618                     actual_error,
   2619                     XML_ErrorString(actual_error),
   2620                     (long unsigned)(i+1));
   2621             fail(message);
   2622         }
   2623         XML_ParserReset(parser, NULL);
   2624     }
   2625 }
   2626 END_TEST
   2627 
   2628 static const char *long_cdata_text =
   2629     "<s><![CDATA["
   2630     "012345678901234567890123456789012345678901234567890123456789"
   2631     "012345678901234567890123456789012345678901234567890123456789"
   2632     "012345678901234567890123456789012345678901234567890123456789"
   2633     "012345678901234567890123456789012345678901234567890123456789"
   2634     "012345678901234567890123456789012345678901234567890123456789"
   2635     "012345678901234567890123456789012345678901234567890123456789"
   2636     "012345678901234567890123456789012345678901234567890123456789"
   2637     "012345678901234567890123456789012345678901234567890123456789"
   2638     "012345678901234567890123456789012345678901234567890123456789"
   2639     "012345678901234567890123456789012345678901234567890123456789"
   2640     "012345678901234567890123456789012345678901234567890123456789"
   2641     "012345678901234567890123456789012345678901234567890123456789"
   2642     "012345678901234567890123456789012345678901234567890123456789"
   2643     "012345678901234567890123456789012345678901234567890123456789"
   2644     "012345678901234567890123456789012345678901234567890123456789"
   2645     "012345678901234567890123456789012345678901234567890123456789"
   2646     "012345678901234567890123456789012345678901234567890123456789"
   2647     "012345678901234567890123456789012345678901234567890123456789"
   2648     "012345678901234567890123456789012345678901234567890123456789"
   2649     "012345678901234567890123456789012345678901234567890123456789"
   2650     "]]></s>";
   2651 
   2652 /* Test stopping the parser in cdata handler */
   2653 START_TEST(test_stop_parser_between_cdata_calls)
   2654 {
   2655     const char *text = long_cdata_text;
   2656 
   2657     XML_SetCharacterDataHandler(parser,
   2658                                 clearing_aborting_character_handler);
   2659     resumable = XML_FALSE;
   2660     expect_failure(text, XML_ERROR_ABORTED,
   2661                    "Parse not aborted in CDATA handler");
   2662 }
   2663 END_TEST
   2664 
   2665 /* Test suspending the parser in cdata handler */
   2666 START_TEST(test_suspend_parser_between_cdata_calls)
   2667 {
   2668     const char *text = long_cdata_text;
   2669     enum XML_Status result;
   2670 
   2671     XML_SetCharacterDataHandler(parser,
   2672                                 clearing_aborting_character_handler);
   2673     resumable = XML_TRUE;
   2674     result = _XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE);
   2675     if (result != XML_STATUS_SUSPENDED) {
   2676         if (result == XML_STATUS_ERROR)
   2677             xml_failure(parser);
   2678         fail("Parse not suspended in CDATA handler");
   2679     }
   2680     if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
   2681         xml_failure(parser);
   2682 }
   2683 END_TEST
   2684 
   2685 /* Test memory allocation functions */
   2686 START_TEST(test_memory_allocation)
   2687 {
   2688     char *buffer = (char *)XML_MemMalloc(parser, 256);
   2689     char *p;
   2690 
   2691     if (buffer == NULL) {
   2692         fail("Allocation failed");
   2693     } else {
   2694         /* Try writing to memory; some OSes try to cheat! */
   2695         buffer[0] = 'T';
   2696         buffer[1] = 'E';
   2697         buffer[2] = 'S';
   2698         buffer[3] = 'T';
   2699         buffer[4] = '\0';
   2700         if (strcmp(buffer, "TEST") != 0) {
   2701             fail("Memory not writable");
   2702         } else {
   2703             p = (char *)XML_MemRealloc(parser, buffer, 512);
   2704             if (p == NULL) {
   2705                 fail("Reallocation failed");
   2706             } else {
   2707                 /* Write again, just to be sure */
   2708                 buffer = p;
   2709                 buffer[0] = 'V';
   2710                 if (strcmp(buffer, "VEST") != 0) {
   2711                     fail("Reallocated memory not writable");
   2712                 }
   2713             }
   2714         }
   2715         XML_MemFree(parser, buffer);
   2716     }
   2717 }
   2718 END_TEST
   2719 
   2720 static void XMLCALL
   2721 record_default_handler(void *userData,
   2722                        const XML_Char *UNUSED_P(s),
   2723                        int UNUSED_P(len))
   2724 {
   2725     CharData_AppendXMLChars((CharData *)userData, XCS("D"), 1);
   2726 }
   2727 
   2728 static void XMLCALL
   2729 record_cdata_handler(void *userData,
   2730                      const XML_Char *UNUSED_P(s),
   2731                      int UNUSED_P(len))
   2732 {
   2733     CharData_AppendXMLChars((CharData *)userData, XCS("C"), 1);
   2734     XML_DefaultCurrent(parser);
   2735 }
   2736 
   2737 static void XMLCALL
   2738 record_cdata_nodefault_handler(void *userData,
   2739                      const XML_Char *UNUSED_P(s),
   2740                      int UNUSED_P(len))
   2741 {
   2742     CharData_AppendXMLChars((CharData *)userData, XCS("c"), 1);
   2743 }
   2744 
   2745 static void XMLCALL
   2746 record_skip_handler(void *userData,
   2747                     const XML_Char *UNUSED_P(entityName),
   2748                     int is_parameter_entity)
   2749 {
   2750     CharData_AppendXMLChars((CharData *)userData,
   2751                             is_parameter_entity ? XCS("E") : XCS("e"), 1);
   2752 }
   2753 
   2754 /* Test XML_DefaultCurrent() passes handling on correctly */
   2755 START_TEST(test_default_current)
   2756 {
   2757     const char *text = "<doc>hell]</doc>";
   2758     const char *entity_text =
   2759         "<!DOCTYPE doc [\n"
   2760         "<!ENTITY entity '&#37;'>\n"
   2761         "]>\n"
   2762         "<doc>&entity;</doc>";
   2763     CharData storage;
   2764 
   2765     XML_SetDefaultHandler(parser, record_default_handler);
   2766     XML_SetCharacterDataHandler(parser, record_cdata_handler);
   2767     CharData_Init(&storage);
   2768     XML_SetUserData(parser, &storage);
   2769     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   2770                                 XML_TRUE) == XML_STATUS_ERROR)
   2771         xml_failure(parser);
   2772     CharData_CheckXMLChars(&storage, XCS("DCDCDCDCDCDD"));
   2773 
   2774     /* Again, without the defaulting */
   2775     XML_ParserReset(parser, NULL);
   2776     XML_SetDefaultHandler(parser, record_default_handler);
   2777     XML_SetCharacterDataHandler(parser, record_cdata_nodefault_handler);
   2778     CharData_Init(&storage);
   2779     XML_SetUserData(parser, &storage);
   2780     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   2781                                 XML_TRUE) == XML_STATUS_ERROR)
   2782         xml_failure(parser);
   2783     CharData_CheckXMLChars(&storage, XCS("DcccccD"));
   2784 
   2785     /* Now with an internal entity to complicate matters */
   2786     XML_ParserReset(parser, NULL);
   2787     XML_SetDefaultHandler(parser, record_default_handler);
   2788     XML_SetCharacterDataHandler(parser, record_cdata_handler);
   2789     CharData_Init(&storage);
   2790     XML_SetUserData(parser, &storage);
   2791     if (_XML_Parse_SINGLE_BYTES(parser, entity_text, strlen(entity_text),
   2792                                 XML_TRUE) == XML_STATUS_ERROR)
   2793         xml_failure(parser);
   2794     /* The default handler suppresses the entity */
   2795     CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDDD"));
   2796 
   2797     /* Again, with a skip handler */
   2798     XML_ParserReset(parser, NULL);
   2799     XML_SetDefaultHandler(parser, record_default_handler);
   2800     XML_SetCharacterDataHandler(parser, record_cdata_handler);
   2801     XML_SetSkippedEntityHandler(parser, record_skip_handler);
   2802     CharData_Init(&storage);
   2803     XML_SetUserData(parser, &storage);
   2804     if (_XML_Parse_SINGLE_BYTES(parser, entity_text, strlen(entity_text),
   2805                                 XML_TRUE) == XML_STATUS_ERROR)
   2806         xml_failure(parser);
   2807     /* The default handler suppresses the entity */
   2808     CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDeD"));
   2809 
   2810     /* This time, allow the entity through */
   2811     XML_ParserReset(parser, NULL);
   2812     XML_SetDefaultHandlerExpand(parser, record_default_handler);
   2813     XML_SetCharacterDataHandler(parser, record_cdata_handler);
   2814     CharData_Init(&storage);
   2815     XML_SetUserData(parser, &storage);
   2816     if (_XML_Parse_SINGLE_BYTES(parser, entity_text, strlen(entity_text),
   2817                                 XML_TRUE) == XML_STATUS_ERROR)
   2818         xml_failure(parser);
   2819     CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDCDD"));
   2820 
   2821     /* Finally, without passing the cdata to the default handler */
   2822     XML_ParserReset(parser, NULL);
   2823     XML_SetDefaultHandlerExpand(parser, record_default_handler);
   2824     XML_SetCharacterDataHandler(parser, record_cdata_nodefault_handler);
   2825     CharData_Init(&storage);
   2826     XML_SetUserData(parser, &storage);
   2827     if (_XML_Parse_SINGLE_BYTES(parser, entity_text, strlen(entity_text),
   2828                                 XML_TRUE) == XML_STATUS_ERROR)
   2829         xml_failure(parser);
   2830     CharData_CheckXMLChars(&storage, XCS("DDDDDDDDDDDDDDDDDcD"));
   2831 }
   2832 END_TEST
   2833 
   2834 /* Test DTD element parsing code paths */
   2835 START_TEST(test_dtd_elements)
   2836 {
   2837     const char *text =
   2838         "<!DOCTYPE doc [\n"
   2839         "<!ELEMENT doc (chapter)>\n"
   2840         "<!ELEMENT chapter (#PCDATA)>\n"
   2841         "]>\n"
   2842         "<doc><chapter>Wombats are go</chapter></doc>";
   2843 
   2844     XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   2845     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   2846                                 XML_TRUE) == XML_STATUS_ERROR)
   2847         xml_failure(parser);
   2848 }
   2849 END_TEST
   2850 
   2851 /* Test foreign DTD handling */
   2852 START_TEST(test_set_foreign_dtd)
   2853 {
   2854     const char *text1 =
   2855         "<?xml version='1.0' encoding='us-ascii'?>\n";
   2856     const char *text2 =
   2857         "<doc>&entity;</doc>";
   2858     ExtTest test_data = {
   2859         "<!ELEMENT doc (#PCDATA)*>",
   2860         NULL,
   2861         NULL
   2862     };
   2863 
   2864     /* Check hash salt is passed through too */
   2865     XML_SetHashSalt(parser, 0x12345678);
   2866     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   2867     XML_SetUserData(parser, &test_data);
   2868     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   2869     /* Add a default handler to exercise more code paths */
   2870     XML_SetDefaultHandler(parser, dummy_default_handler);
   2871     if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE)
   2872         fail("Could not set foreign DTD");
   2873     if (_XML_Parse_SINGLE_BYTES(parser, text1, strlen(text1),
   2874                                 XML_FALSE) == XML_STATUS_ERROR)
   2875         xml_failure(parser);
   2876 
   2877     /* Ensure that trying to set the DTD after parsing has started
   2878      * is faulted, even if it's the same setting.
   2879      */
   2880     if (XML_UseForeignDTD(parser, XML_TRUE) !=
   2881         XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING)
   2882         fail("Failed to reject late foreign DTD setting");
   2883     /* Ditto for the hash salt */
   2884     if (XML_SetHashSalt(parser, 0x23456789))
   2885         fail("Failed to reject late hash salt change");
   2886 
   2887     /* Now finish the parse */
   2888     if (_XML_Parse_SINGLE_BYTES(parser, text2, strlen(text2),
   2889                                 XML_TRUE) == XML_STATUS_ERROR)
   2890         xml_failure(parser);
   2891 }
   2892 END_TEST
   2893 
   2894 /* Test foreign DTD handling with a failing NotStandalone handler */
   2895 START_TEST(test_foreign_dtd_not_standalone)
   2896 {
   2897     const char *text =
   2898         "<?xml version='1.0' encoding='us-ascii'?>\n"
   2899         "<doc>&entity;</doc>";
   2900     ExtTest test_data = {
   2901         "<!ELEMENT doc (#PCDATA)*>",
   2902         NULL,
   2903         NULL
   2904     };
   2905 
   2906     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   2907     XML_SetUserData(parser, &test_data);
   2908     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   2909     XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler);
   2910     if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE)
   2911         fail("Could not set foreign DTD");
   2912     expect_failure(text, XML_ERROR_NOT_STANDALONE,
   2913                    "NotStandalonehandler failed to reject");
   2914 }
   2915 END_TEST
   2916 
   2917 /* Test invalid character in a foreign DTD is faulted */
   2918 START_TEST(test_invalid_foreign_dtd)
   2919 {
   2920     const char *text =
   2921         "<?xml version='1.0' encoding='us-ascii'?>\n"
   2922         "<doc>&entity;</doc>";
   2923     ExtFaults test_data = {
   2924         "$",
   2925         "Dollar not faulted",
   2926         NULL,
   2927         XML_ERROR_INVALID_TOKEN
   2928     };
   2929 
   2930     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   2931     XML_SetUserData(parser, &test_data);
   2932     XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
   2933     XML_UseForeignDTD(parser, XML_TRUE);
   2934     expect_failure(text,
   2935                    XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   2936                    "Bad DTD should not have been accepted");
   2937 }
   2938 END_TEST
   2939 
   2940 /* Test foreign DTD use with a doctype */
   2941 START_TEST(test_foreign_dtd_with_doctype)
   2942 {
   2943     const char *text1 =
   2944         "<?xml version='1.0' encoding='us-ascii'?>\n"
   2945         "<!DOCTYPE doc [<!ENTITY entity 'hello world'>]>\n";
   2946     const char *text2 =
   2947         "<doc>&entity;</doc>";
   2948     ExtTest test_data = {
   2949         "<!ELEMENT doc (#PCDATA)*>",
   2950         NULL,
   2951         NULL
   2952     };
   2953 
   2954     /* Check hash salt is passed through too */
   2955     XML_SetHashSalt(parser, 0x12345678);
   2956     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   2957     XML_SetUserData(parser, &test_data);
   2958     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   2959     /* Add a default handler to exercise more code paths */
   2960     XML_SetDefaultHandler(parser, dummy_default_handler);
   2961     if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE)
   2962         fail("Could not set foreign DTD");
   2963     if (_XML_Parse_SINGLE_BYTES(parser, text1, strlen(text1),
   2964                                 XML_FALSE) == XML_STATUS_ERROR)
   2965         xml_failure(parser);
   2966 
   2967     /* Ensure that trying to set the DTD after parsing has started
   2968      * is faulted, even if it's the same setting.
   2969      */
   2970     if (XML_UseForeignDTD(parser, XML_TRUE) !=
   2971         XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING)
   2972         fail("Failed to reject late foreign DTD setting");
   2973     /* Ditto for the hash salt */
   2974     if (XML_SetHashSalt(parser, 0x23456789))
   2975         fail("Failed to reject late hash salt change");
   2976 
   2977     /* Now finish the parse */
   2978     if (_XML_Parse_SINGLE_BYTES(parser, text2, strlen(text2),
   2979                                 XML_TRUE) == XML_STATUS_ERROR)
   2980         xml_failure(parser);
   2981 }
   2982 END_TEST
   2983 
   2984 /* Test XML_UseForeignDTD with no external subset present */
   2985 static int XMLCALL
   2986 external_entity_null_loader(XML_Parser UNUSED_P(parser),
   2987                             const XML_Char *UNUSED_P(context),
   2988                             const XML_Char *UNUSED_P(base),
   2989                             const XML_Char *UNUSED_P(systemId),
   2990                             const XML_Char *UNUSED_P(publicId))
   2991 {
   2992     return XML_STATUS_OK;
   2993 }
   2994 
   2995 START_TEST(test_foreign_dtd_without_external_subset)
   2996 {
   2997     const char *text =
   2998         "<!DOCTYPE doc [<!ENTITY foo 'bar'>]>\n"
   2999         "<doc>&foo;</doc>";
   3000 
   3001     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3002     XML_SetUserData(parser, NULL);
   3003     XML_SetExternalEntityRefHandler(parser, external_entity_null_loader);
   3004     XML_UseForeignDTD(parser, XML_TRUE);
   3005     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3006                                 XML_TRUE) == XML_STATUS_ERROR)
   3007         xml_failure(parser);
   3008 }
   3009 END_TEST
   3010 
   3011 START_TEST(test_empty_foreign_dtd)
   3012 {
   3013     const char *text =
   3014         "<?xml version='1.0' encoding='us-ascii'?>\n"
   3015         "<doc>&entity;</doc>";
   3016 
   3017     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3018     XML_SetExternalEntityRefHandler(parser, external_entity_null_loader);
   3019     XML_UseForeignDTD(parser, XML_TRUE);
   3020     expect_failure(text, XML_ERROR_UNDEFINED_ENTITY,
   3021                    "Undefined entity not faulted");
   3022 }
   3023 END_TEST
   3024 
   3025 /* Test XML Base is set and unset appropriately */
   3026 START_TEST(test_set_base)
   3027 {
   3028     const XML_Char *old_base;
   3029     const XML_Char *new_base = XCS("/local/file/name.xml");
   3030 
   3031     old_base = XML_GetBase(parser);
   3032     if (XML_SetBase(parser, new_base) != XML_STATUS_OK)
   3033         fail("Unable to set base");
   3034     if (xcstrcmp(XML_GetBase(parser), new_base) != 0)
   3035         fail("Base setting not correct");
   3036     if (XML_SetBase(parser, NULL) != XML_STATUS_OK)
   3037         fail("Unable to NULL base");
   3038     if (XML_GetBase(parser) != NULL)
   3039         fail("Base setting not nulled");
   3040     XML_SetBase(parser, old_base);
   3041 }
   3042 END_TEST
   3043 
   3044 /* Test attribute counts, indexing, etc */
   3045 typedef struct attrInfo {
   3046     const XML_Char *name;
   3047     const XML_Char *value;
   3048 } AttrInfo;
   3049 
   3050 typedef struct elementInfo {
   3051     const XML_Char *name;
   3052     int attr_count;
   3053     const XML_Char *id_name;
   3054     AttrInfo *attributes;
   3055 } ElementInfo;
   3056 
   3057 static void XMLCALL
   3058 counting_start_element_handler(void *userData,
   3059                                const XML_Char *name,
   3060                                const XML_Char **atts)
   3061 {
   3062     ElementInfo *info = (ElementInfo *)userData;
   3063     AttrInfo *attr;
   3064     int count, id, i;
   3065 
   3066     while (info->name != NULL) {
   3067         if (!xcstrcmp(name, info->name))
   3068             break;
   3069         info++;
   3070     }
   3071     if (info->name == NULL)
   3072         fail("Element not recognised");
   3073     /* The attribute count is twice what you might expect.  It is a
   3074      * count of items in atts, an array which contains alternating
   3075      * attribute names and attribute values.  For the naive user this
   3076      * is possibly a little unexpected, but it is what the
   3077      * documentation in expat.h tells us to expect.
   3078      */
   3079     count = XML_GetSpecifiedAttributeCount(parser);
   3080     if (info->attr_count * 2 != count) {
   3081         fail("Not got expected attribute count");
   3082         return;
   3083     }
   3084     id = XML_GetIdAttributeIndex(parser);
   3085     if (id == -1 && info->id_name != NULL) {
   3086         fail("ID not present");
   3087         return;
   3088     }
   3089     if (id != -1 && xcstrcmp(atts[id], info->id_name)) {
   3090         fail("ID does not have the correct name");
   3091         return;
   3092     }
   3093     for (i = 0; i < info->attr_count; i++) {
   3094         attr = info->attributes;
   3095         while (attr->name != NULL) {
   3096             if (!xcstrcmp(atts[0], attr->name))
   3097                 break;
   3098             attr++;
   3099         }
   3100         if (attr->name == NULL) {
   3101             fail("Attribute not recognised");
   3102             return;
   3103         }
   3104         if (xcstrcmp(atts[1], attr->value)) {
   3105             fail("Attribute has wrong value");
   3106             return;
   3107         }
   3108         /* Remember, two entries in atts per attribute (see above) */
   3109         atts += 2;
   3110     }
   3111 }
   3112 
   3113 START_TEST(test_attributes)
   3114 {
   3115     const char *text =
   3116         "<!DOCTYPE doc [\n"
   3117         "<!ELEMENT doc (tag)>\n"
   3118         "<!ATTLIST doc id ID #REQUIRED>\n"
   3119         "]>"
   3120         "<doc a='1' id='one' b='2'>"
   3121         "<tag c='3'/>"
   3122         "</doc>";
   3123     AttrInfo doc_info[] = {
   3124         { XCS("a"),  XCS("1") },
   3125         { XCS("b"),  XCS("2") },
   3126         { XCS("id"), XCS("one") },
   3127         { NULL, NULL }
   3128     };
   3129     AttrInfo tag_info[] = {
   3130         { XCS("c"),  XCS("3") },
   3131         { NULL, NULL }
   3132     };
   3133     ElementInfo info[] = {
   3134         { XCS("doc"), 3, XCS("id"), NULL },
   3135         { XCS("tag"), 1, NULL, NULL },
   3136         { NULL, 0, NULL, NULL }
   3137     };
   3138     info[0].attributes = doc_info;
   3139     info[1].attributes = tag_info;
   3140 
   3141     XML_SetStartElementHandler(parser, counting_start_element_handler);
   3142     XML_SetUserData(parser, info);
   3143     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   3144         xml_failure(parser);
   3145 }
   3146 END_TEST
   3147 
   3148 /* Test reset works correctly in the middle of processing an internal
   3149  * entity.  Exercises some obscure code in XML_ParserReset().
   3150  */
   3151 START_TEST(test_reset_in_entity)
   3152 {
   3153     const char *text =
   3154         "<!DOCTYPE doc [\n"
   3155         "<!ENTITY wombat 'wom'>\n"
   3156         "<!ENTITY entity 'hi &wom; there'>\n"
   3157         "]>\n"
   3158         "<doc>&entity;</doc>";
   3159     XML_ParsingStatus status;
   3160 
   3161     resumable = XML_TRUE;
   3162     XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
   3163     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
   3164         xml_failure(parser);
   3165     XML_GetParsingStatus(parser, &status);
   3166     if (status.parsing != XML_SUSPENDED)
   3167         fail("Parsing status not SUSPENDED");
   3168     XML_ParserReset(parser, NULL);
   3169     XML_GetParsingStatus(parser, &status);
   3170     if (status.parsing != XML_INITIALIZED)
   3171         fail("Parsing status doesn't reset to INITIALIZED");
   3172 }
   3173 END_TEST
   3174 
   3175 /* Test that resume correctly passes through parse errors */
   3176 START_TEST(test_resume_invalid_parse)
   3177 {
   3178     const char *text = "<doc>Hello</doc"; /* Missing closing wedge */
   3179 
   3180     resumable = XML_TRUE;
   3181     XML_SetCharacterDataHandler(parser,
   3182                                 clearing_aborting_character_handler);
   3183     if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   3184         xml_failure(parser);
   3185     if (XML_ResumeParser(parser) == XML_STATUS_OK)
   3186         fail("Resumed invalid parse not faulted");
   3187     if (XML_GetErrorCode(parser) != XML_ERROR_UNCLOSED_TOKEN)
   3188         fail("Invalid parse not correctly faulted");
   3189 }
   3190 END_TEST
   3191 
   3192 /* Test that re-suspended parses are correctly passed through */
   3193 START_TEST(test_resume_resuspended)
   3194 {
   3195     const char *text = "<doc>Hello<meep/>world</doc>";
   3196 
   3197     resumable = XML_TRUE;
   3198     XML_SetCharacterDataHandler(parser,
   3199                                 clearing_aborting_character_handler);
   3200     if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   3201         xml_failure(parser);
   3202     resumable = XML_TRUE;
   3203     XML_SetCharacterDataHandler(parser,
   3204                                 clearing_aborting_character_handler);
   3205     if (XML_ResumeParser(parser) != XML_STATUS_SUSPENDED)
   3206         fail("Resumption not suspended");
   3207     /* This one should succeed and finish up */
   3208     if (XML_ResumeParser(parser) != XML_STATUS_OK)
   3209         xml_failure(parser);
   3210 }
   3211 END_TEST
   3212 
   3213 /* Test that CDATA shows up correctly through a default handler */
   3214 START_TEST(test_cdata_default)
   3215 {
   3216     const char *text = "<doc><![CDATA[Hello\nworld]]></doc>";
   3217     const XML_Char *expected = XCS("<doc><![CDATA[Hello\nworld]]></doc>");
   3218     CharData storage;
   3219 
   3220     CharData_Init(&storage);
   3221     XML_SetUserData(parser, &storage);
   3222     XML_SetDefaultHandler(parser, accumulate_characters);
   3223 
   3224     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3225                                 XML_TRUE) == XML_STATUS_ERROR)
   3226         xml_failure(parser);
   3227     CharData_CheckXMLChars(&storage, expected);
   3228 }
   3229 END_TEST
   3230 
   3231 /* Test resetting a subordinate parser does exactly nothing */
   3232 static int XMLCALL
   3233 external_entity_resetter(XML_Parser parser,
   3234                          const XML_Char *context,
   3235                          const XML_Char *UNUSED_P(base),
   3236                          const XML_Char *UNUSED_P(systemId),
   3237                          const XML_Char *UNUSED_P(publicId))
   3238 {
   3239     const char *text = "<!ELEMENT doc (#PCDATA)*>";
   3240     XML_Parser ext_parser;
   3241     XML_ParsingStatus status;
   3242 
   3243     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3244     if (ext_parser == NULL)
   3245         fail("Could not create external entity parser");
   3246     XML_GetParsingStatus(ext_parser, &status);
   3247     if (status.parsing != XML_INITIALIZED) {
   3248         fail("Parsing status is not INITIALIZED");
   3249         return XML_STATUS_ERROR;
   3250     }
   3251     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   3252                                 XML_TRUE) == XML_STATUS_ERROR) {
   3253         xml_failure(parser);
   3254         return XML_STATUS_ERROR;
   3255     }
   3256     XML_GetParsingStatus(ext_parser, &status);
   3257     if (status.parsing != XML_FINISHED) {
   3258         fail("Parsing status is not FINISHED");
   3259         return XML_STATUS_ERROR;
   3260     }
   3261     /* Check we can't parse here */
   3262     if (XML_Parse(ext_parser, text, strlen(text),
   3263                   XML_TRUE) != XML_STATUS_ERROR)
   3264         fail("Parsing when finished not faulted");
   3265     if (XML_GetErrorCode(ext_parser) != XML_ERROR_FINISHED)
   3266         fail("Parsing when finished faulted with wrong code");
   3267     XML_ParserReset(ext_parser, NULL);
   3268     XML_GetParsingStatus(ext_parser, &status);
   3269     if (status.parsing != XML_FINISHED) {
   3270         fail("Parsing status not still FINISHED");
   3271         return XML_STATUS_ERROR;
   3272     }
   3273     XML_ParserFree(ext_parser);
   3274     return XML_STATUS_OK;
   3275 }
   3276 
   3277 START_TEST(test_subordinate_reset)
   3278 {
   3279     const char *text =
   3280         "<?xml version='1.0' encoding='us-ascii'?>\n"
   3281         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   3282         "<doc>&entity;</doc>";
   3283 
   3284     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3285     XML_SetExternalEntityRefHandler(parser, external_entity_resetter);
   3286     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   3287         xml_failure(parser);
   3288 }
   3289 END_TEST
   3290 
   3291 
   3292 /* Test suspending a subordinate parser */
   3293 
   3294 static void XMLCALL
   3295 entity_suspending_decl_handler(void *userData,
   3296                                const XML_Char *UNUSED_P(name),
   3297                                XML_Content *model)
   3298 {
   3299     XML_Parser ext_parser = (XML_Parser)userData;
   3300 
   3301     if (XML_StopParser(ext_parser, XML_TRUE) != XML_STATUS_ERROR)
   3302         fail("Attempting to suspend a subordinate parser not faulted");
   3303     if (XML_GetErrorCode(ext_parser) != XML_ERROR_SUSPEND_PE)
   3304         fail("Suspending subordinate parser get wrong code");
   3305     XML_SetElementDeclHandler(ext_parser, NULL);
   3306     XML_FreeContentModel(parser, model);
   3307 }
   3308 
   3309 static int XMLCALL
   3310 external_entity_suspender(XML_Parser parser,
   3311                           const XML_Char *context,
   3312                           const XML_Char *UNUSED_P(base),
   3313                           const XML_Char *UNUSED_P(systemId),
   3314                           const XML_Char *UNUSED_P(publicId))
   3315 {
   3316     const char *text = "<!ELEMENT doc (#PCDATA)*>";
   3317     XML_Parser ext_parser;
   3318 
   3319     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3320     if (ext_parser == NULL)
   3321         fail("Could not create external entity parser");
   3322     XML_SetElementDeclHandler(ext_parser, entity_suspending_decl_handler);
   3323     XML_SetUserData(ext_parser, ext_parser);
   3324     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   3325                                 XML_TRUE) == XML_STATUS_ERROR) {
   3326         xml_failure(ext_parser);
   3327         return XML_STATUS_ERROR;
   3328     }
   3329     XML_ParserFree(ext_parser);
   3330     return XML_STATUS_OK;
   3331 }
   3332 
   3333 START_TEST(test_subordinate_suspend)
   3334 {
   3335     const char *text =
   3336         "<?xml version='1.0' encoding='us-ascii'?>\n"
   3337         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   3338         "<doc>&entity;</doc>";
   3339 
   3340     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3341     XML_SetExternalEntityRefHandler(parser, external_entity_suspender);
   3342     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   3343         xml_failure(parser);
   3344 }
   3345 END_TEST
   3346 
   3347 /* Test suspending a subordinate parser from an XML declaration */
   3348 /* Increases code coverage of the tests */
   3349 static void XMLCALL
   3350 entity_suspending_xdecl_handler(void *userData,
   3351                                 const XML_Char *UNUSED_P(version),
   3352                                 const XML_Char *UNUSED_P(encoding),
   3353                                 int UNUSED_P(standalone))
   3354 {
   3355     XML_Parser ext_parser = (XML_Parser)userData;
   3356 
   3357     XML_StopParser(ext_parser, resumable);
   3358     XML_SetXmlDeclHandler(ext_parser, NULL);
   3359 }
   3360 
   3361 static int XMLCALL
   3362 external_entity_suspend_xmldecl(XML_Parser parser,
   3363                                 const XML_Char *context,
   3364                                 const XML_Char *UNUSED_P(base),
   3365                                 const XML_Char *UNUSED_P(systemId),
   3366                                 const XML_Char *UNUSED_P(publicId))
   3367 {
   3368     const char *text = "<?xml version='1.0' encoding='us-ascii'?>";
   3369     XML_Parser ext_parser;
   3370     XML_ParsingStatus status;
   3371     enum XML_Status rc;
   3372 
   3373     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3374     if (ext_parser == NULL)
   3375         fail("Could not create external entity parser");
   3376     XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
   3377     XML_SetUserData(ext_parser, ext_parser);
   3378     rc = _XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text), XML_TRUE);
   3379     XML_GetParsingStatus(ext_parser, &status);
   3380     if (resumable) {
   3381         if (rc == XML_STATUS_ERROR)
   3382             xml_failure(ext_parser);
   3383         if (status.parsing != XML_SUSPENDED)
   3384             fail("Ext Parsing status not SUSPENDED");
   3385     } else {
   3386         if (rc != XML_STATUS_ERROR)
   3387             fail("Ext parsing not aborted");
   3388         if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED)
   3389             xml_failure(ext_parser);
   3390         if (status.parsing != XML_FINISHED)
   3391             fail("Ext Parsing status not FINISHED");
   3392     }
   3393 
   3394     XML_ParserFree(ext_parser);
   3395     return XML_STATUS_OK;
   3396 }
   3397 
   3398 START_TEST(test_subordinate_xdecl_suspend)
   3399 {
   3400     const char *text =
   3401         "<!DOCTYPE doc [\n"
   3402         "  <!ENTITY entity SYSTEM 'http://example.org/dummy.ent'>\n"
   3403         "]>\n"
   3404         "<doc>&entity;</doc>";
   3405 
   3406     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3407     XML_SetExternalEntityRefHandler(parser,
   3408                                     external_entity_suspend_xmldecl);
   3409     resumable = XML_TRUE;
   3410     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3411                                 XML_TRUE) == XML_STATUS_ERROR)
   3412         xml_failure(parser);
   3413 }
   3414 END_TEST
   3415 
   3416 START_TEST(test_subordinate_xdecl_abort)
   3417 {
   3418     const char *text =
   3419         "<!DOCTYPE doc [\n"
   3420         "  <!ENTITY entity SYSTEM 'http://example.org/dummy.ent'>\n"
   3421         "]>\n"
   3422         "<doc>&entity;</doc>";
   3423 
   3424     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3425     XML_SetExternalEntityRefHandler(parser,
   3426                                     external_entity_suspend_xmldecl);
   3427     resumable = XML_FALSE;
   3428     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3429                                 XML_TRUE) == XML_STATUS_ERROR)
   3430         xml_failure(parser);
   3431 }
   3432 END_TEST
   3433 
   3434 /* Test external entity fault handling with suspension */
   3435 static int XMLCALL
   3436 external_entity_suspending_faulter(XML_Parser parser,
   3437                                    const XML_Char *context,
   3438                                    const XML_Char *UNUSED_P(base),
   3439                                    const XML_Char *UNUSED_P(systemId),
   3440                                    const XML_Char *UNUSED_P(publicId))
   3441 {
   3442     XML_Parser ext_parser;
   3443     ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser);
   3444     void *buffer;
   3445     int parse_len = strlen(fault->parse_text);
   3446 
   3447     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3448     if (ext_parser == NULL)
   3449         fail("Could not create external entity parser");
   3450     XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
   3451     XML_SetUserData(ext_parser, ext_parser);
   3452     resumable = XML_TRUE;
   3453     buffer = XML_GetBuffer(ext_parser, parse_len);
   3454     if (buffer == NULL)
   3455         fail("Could not allocate parse buffer");
   3456     memcpy(buffer, fault->parse_text, parse_len);
   3457     if (XML_ParseBuffer(ext_parser, parse_len,
   3458                         XML_FALSE) != XML_STATUS_SUSPENDED)
   3459         fail("XML declaration did not suspend");
   3460     if (XML_ResumeParser(ext_parser) != XML_STATUS_OK)
   3461         xml_failure(ext_parser);
   3462     if (XML_ParseBuffer(ext_parser, 0, XML_TRUE) != XML_STATUS_ERROR)
   3463         fail(fault->fail_text);
   3464     if (XML_GetErrorCode(ext_parser) != fault->error)
   3465         xml_failure(ext_parser);
   3466 
   3467     XML_ParserFree(ext_parser);
   3468     return XML_STATUS_ERROR;
   3469 }
   3470 
   3471 START_TEST(test_ext_entity_invalid_suspended_parse)
   3472 {
   3473     const char *text =
   3474         "<!DOCTYPE doc [\n"
   3475         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   3476         "]>\n"
   3477         "<doc>&en;</doc>";
   3478     ExtFaults faults[] = {
   3479         {
   3480             "<?xml version='1.0' encoding='us-ascii'?><",
   3481             "Incomplete element declaration not faulted",
   3482             NULL,
   3483             XML_ERROR_UNCLOSED_TOKEN
   3484         },
   3485         {
   3486             /* First two bytes of a three-byte char */
   3487             "<?xml version='1.0' encoding='utf-8'?>\xe2\x82",
   3488             "Incomplete character not faulted",
   3489             NULL,
   3490             XML_ERROR_PARTIAL_CHAR
   3491         },
   3492         { NULL, NULL, NULL, XML_ERROR_NONE }
   3493     };
   3494     ExtFaults *fault;
   3495 
   3496     for (fault = &faults[0]; fault->parse_text != NULL; fault++) {
   3497         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3498         XML_SetExternalEntityRefHandler(parser,
   3499                                         external_entity_suspending_faulter);
   3500         XML_SetUserData(parser, fault);
   3501         expect_failure(text,
   3502                        XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   3503                        "Parser did not report external entity error");
   3504         XML_ParserReset(parser, NULL);
   3505     }
   3506 }
   3507 END_TEST
   3508 
   3509 
   3510 
   3511 /* Test setting an explicit encoding */
   3512 START_TEST(test_explicit_encoding)
   3513 {
   3514     const char *text1 = "<doc>Hello ";
   3515     const char *text2 = " World</doc>";
   3516 
   3517     /* Just check that we can set the encoding to NULL before starting */
   3518     if (XML_SetEncoding(parser, NULL) != XML_STATUS_OK)
   3519         fail("Failed to initialise encoding to NULL");
   3520     /* Say we are UTF-8 */
   3521     if (XML_SetEncoding(parser, XCS("utf-8")) != XML_STATUS_OK)
   3522         fail("Failed to set explicit encoding");
   3523     if (_XML_Parse_SINGLE_BYTES(parser, text1, strlen(text1),
   3524                                 XML_FALSE) == XML_STATUS_ERROR)
   3525         xml_failure(parser);
   3526     /* Try to switch encodings mid-parse */
   3527     if (XML_SetEncoding(parser, XCS("us-ascii")) != XML_STATUS_ERROR)
   3528         fail("Allowed encoding change");
   3529     if (_XML_Parse_SINGLE_BYTES(parser, text2, strlen(text2),
   3530                                 XML_TRUE) == XML_STATUS_ERROR)
   3531         xml_failure(parser);
   3532     /* Try now the parse is over */
   3533     if (XML_SetEncoding(parser, NULL) != XML_STATUS_OK)
   3534         fail("Failed to unset encoding");
   3535 }
   3536 END_TEST
   3537 
   3538 
   3539 /* Test handling of trailing CR (rather than newline) */
   3540 static void XMLCALL
   3541 cr_cdata_handler(void *userData, const XML_Char *s, int len)
   3542 {
   3543     int *pfound = (int *)userData;
   3544 
   3545     /* Internal processing turns the CR into a newline for the
   3546      * character data handler, but not for the default handler
   3547      */
   3548     if (len == 1 && (*s == XCS('\n') || *s == XCS('\r')))
   3549         *pfound = 1;
   3550 }
   3551 
   3552 START_TEST(test_trailing_cr)
   3553 {
   3554     const char *text = "<doc>\r";
   3555     int found_cr;
   3556 
   3557     /* Try with a character handler, for code coverage */
   3558     XML_SetCharacterDataHandler(parser, cr_cdata_handler);
   3559     XML_SetUserData(parser, &found_cr);
   3560     found_cr = 0;
   3561     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3562                                 XML_TRUE) == XML_STATUS_OK)
   3563         fail("Failed to fault unclosed doc");
   3564     if (found_cr == 0)
   3565         fail("Did not catch the carriage return");
   3566     XML_ParserReset(parser, NULL);
   3567 
   3568     /* Now with a default handler instead */
   3569     XML_SetDefaultHandler(parser, cr_cdata_handler);
   3570     XML_SetUserData(parser, &found_cr);
   3571     found_cr = 0;
   3572     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3573                                 XML_TRUE) == XML_STATUS_OK)
   3574         fail("Failed to fault unclosed doc");
   3575     if (found_cr == 0)
   3576         fail("Did not catch default carriage return");
   3577 }
   3578 END_TEST
   3579 
   3580 /* Test trailing CR in an external entity parse */
   3581 static int XMLCALL
   3582 external_entity_cr_catcher(XML_Parser parser,
   3583                            const XML_Char *context,
   3584                            const XML_Char *UNUSED_P(base),
   3585                            const XML_Char *UNUSED_P(systemId),
   3586                            const XML_Char *UNUSED_P(publicId))
   3587 {
   3588     const char *text = "\r";
   3589     XML_Parser ext_parser;
   3590 
   3591     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3592     if (ext_parser == NULL)
   3593         fail("Could not create external entity parser");
   3594     XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler);
   3595     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   3596                                 XML_TRUE) == XML_STATUS_ERROR)
   3597         xml_failure(ext_parser);
   3598     XML_ParserFree(ext_parser);
   3599     return XML_STATUS_OK;
   3600 }
   3601 
   3602 static int XMLCALL
   3603 external_entity_bad_cr_catcher(XML_Parser parser,
   3604                                const XML_Char *context,
   3605                                const XML_Char *UNUSED_P(base),
   3606                                const XML_Char *UNUSED_P(systemId),
   3607                                const XML_Char *UNUSED_P(publicId))
   3608 {
   3609     const char *text = "<tag>\r";
   3610     XML_Parser ext_parser;
   3611 
   3612     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3613     if (ext_parser == NULL)
   3614         fail("Could not create external entity parser");
   3615     XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler);
   3616     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   3617                                 XML_TRUE) == XML_STATUS_OK)
   3618         fail("Async entity error not caught");
   3619     if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY)
   3620         xml_failure(ext_parser);
   3621     XML_ParserFree(ext_parser);
   3622     return XML_STATUS_OK;
   3623 }
   3624 
   3625 START_TEST(test_ext_entity_trailing_cr)
   3626 {
   3627     const char *text =
   3628         "<!DOCTYPE doc [\n"
   3629         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   3630         "]>\n"
   3631         "<doc>&en;</doc>";
   3632     int found_cr;
   3633 
   3634     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3635     XML_SetExternalEntityRefHandler(parser, external_entity_cr_catcher);
   3636     XML_SetUserData(parser, &found_cr);
   3637     found_cr = 0;
   3638     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3639                                 XML_TRUE) != XML_STATUS_OK)
   3640         xml_failure(parser);
   3641     if (found_cr == 0)
   3642         fail("No carriage return found");
   3643     XML_ParserReset(parser, NULL);
   3644 
   3645     /* Try again with a different trailing CR */
   3646     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3647     XML_SetExternalEntityRefHandler(parser, external_entity_bad_cr_catcher);
   3648     XML_SetUserData(parser, &found_cr);
   3649     found_cr = 0;
   3650     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3651                                 XML_TRUE) != XML_STATUS_OK)
   3652         xml_failure(parser);
   3653     if (found_cr == 0)
   3654         fail("No carriage return found");
   3655 }
   3656 END_TEST
   3657 
   3658 /* Test handling of trailing square bracket */
   3659 static void XMLCALL
   3660 rsqb_handler(void *userData, const XML_Char *s, int len)
   3661 {
   3662     int *pfound = (int *)userData;
   3663 
   3664     if (len == 1 && *s == XCS(']'))
   3665         *pfound = 1;
   3666 }
   3667 
   3668 START_TEST(test_trailing_rsqb)
   3669 {
   3670     const char *text8 = "<doc>]";
   3671     const char text16[] = "\xFF\xFE<\000d\000o\000c\000>\000]\000";
   3672     int found_rsqb;
   3673     int text8_len = strlen(text8);
   3674 
   3675     XML_SetCharacterDataHandler(parser, rsqb_handler);
   3676     XML_SetUserData(parser, &found_rsqb);
   3677     found_rsqb = 0;
   3678     if (_XML_Parse_SINGLE_BYTES(parser, text8, text8_len,
   3679                                 XML_TRUE) == XML_STATUS_OK)
   3680         fail("Failed to fault unclosed doc");
   3681     if (found_rsqb == 0)
   3682         fail("Did not catch the right square bracket");
   3683 
   3684     /* Try again with a different encoding */
   3685     XML_ParserReset(parser, NULL);
   3686     XML_SetCharacterDataHandler(parser, rsqb_handler);
   3687     XML_SetUserData(parser, &found_rsqb);
   3688     found_rsqb = 0;
   3689     if (_XML_Parse_SINGLE_BYTES(parser, text16, sizeof(text16)-1,
   3690                                 XML_TRUE) == XML_STATUS_OK)
   3691         fail("Failed to fault unclosed doc");
   3692     if (found_rsqb == 0)
   3693         fail("Did not catch the right square bracket");
   3694 
   3695     /* And finally with a default handler */
   3696     XML_ParserReset(parser, NULL);
   3697     XML_SetDefaultHandler(parser, rsqb_handler);
   3698     XML_SetUserData(parser, &found_rsqb);
   3699     found_rsqb = 0;
   3700     if (_XML_Parse_SINGLE_BYTES(parser, text16, sizeof(text16)-1,
   3701                                 XML_TRUE) == XML_STATUS_OK)
   3702         fail("Failed to fault unclosed doc");
   3703     if (found_rsqb == 0)
   3704         fail("Did not catch the right square bracket");
   3705 }
   3706 END_TEST
   3707 
   3708 /* Test trailing right square bracket in an external entity parse */
   3709 static int XMLCALL
   3710 external_entity_rsqb_catcher(XML_Parser parser,
   3711                              const XML_Char *context,
   3712                              const XML_Char *UNUSED_P(base),
   3713                              const XML_Char *UNUSED_P(systemId),
   3714                              const XML_Char *UNUSED_P(publicId))
   3715 {
   3716     const char *text = "<tag>]";
   3717     XML_Parser ext_parser;
   3718 
   3719     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3720     if (ext_parser == NULL)
   3721         fail("Could not create external entity parser");
   3722     XML_SetCharacterDataHandler(ext_parser, rsqb_handler);
   3723     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   3724                                 XML_TRUE) != XML_STATUS_ERROR)
   3725         fail("Async entity error not caught");
   3726     if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY)
   3727         xml_failure(ext_parser);
   3728     XML_ParserFree(ext_parser);
   3729     return XML_STATUS_OK;
   3730 }
   3731 
   3732 START_TEST(test_ext_entity_trailing_rsqb)
   3733 {
   3734     const char *text =
   3735         "<!DOCTYPE doc [\n"
   3736         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   3737         "]>\n"
   3738         "<doc>&en;</doc>";
   3739     int found_rsqb;
   3740 
   3741     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3742     XML_SetExternalEntityRefHandler(parser, external_entity_rsqb_catcher);
   3743     XML_SetUserData(parser, &found_rsqb);
   3744     found_rsqb = 0;
   3745     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3746                                 XML_TRUE) != XML_STATUS_OK)
   3747         xml_failure(parser);
   3748     if (found_rsqb == 0)
   3749         fail("No right square bracket found");
   3750 }
   3751 END_TEST
   3752 
   3753 /* Test CDATA handling in an external entity */
   3754 static int XMLCALL
   3755 external_entity_good_cdata_ascii(XML_Parser parser,
   3756                                  const XML_Char *context,
   3757                                  const XML_Char *UNUSED_P(base),
   3758                                  const XML_Char *UNUSED_P(systemId),
   3759                                  const XML_Char *UNUSED_P(publicId))
   3760 {
   3761     const char *text =
   3762         "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>";
   3763     const XML_Char *expected = XCS("<greeting>Hello, world!</greeting>");
   3764     CharData storage;
   3765     XML_Parser ext_parser;
   3766 
   3767     CharData_Init(&storage);
   3768     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3769     if (ext_parser == NULL)
   3770         fail("Could not create external entity parser");
   3771     XML_SetUserData(ext_parser, &storage);
   3772     XML_SetCharacterDataHandler(ext_parser, accumulate_characters);
   3773 
   3774     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   3775                                 XML_TRUE) == XML_STATUS_ERROR)
   3776         xml_failure(ext_parser);
   3777     CharData_CheckXMLChars(&storage, expected);
   3778 
   3779     XML_ParserFree(ext_parser);
   3780     return XML_STATUS_OK;
   3781 }
   3782 
   3783 START_TEST(test_ext_entity_good_cdata)
   3784 {
   3785     const char *text =
   3786         "<!DOCTYPE doc [\n"
   3787         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   3788         "]>\n"
   3789         "<doc>&en;</doc>";
   3790 
   3791     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3792     XML_SetExternalEntityRefHandler(parser,
   3793                                     external_entity_good_cdata_ascii);
   3794     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3795                                 XML_TRUE) != XML_STATUS_OK)
   3796         xml_failure(parser);
   3797 }
   3798 END_TEST
   3799 
   3800 /* Test user parameter settings */
   3801 /* Variable holding the expected handler userData */
   3802 static void *handler_data = NULL;
   3803 /* Count of the number of times the comment handler has been invoked */
   3804 static int comment_count = 0;
   3805 /* Count of the number of skipped entities */
   3806 static int skip_count = 0;
   3807 /* Count of the number of times the XML declaration handler is invoked */
   3808 static int xdecl_count = 0;
   3809 
   3810 static void XMLCALL
   3811 xml_decl_handler(void *userData,
   3812                  const XML_Char *UNUSED_P(version),
   3813                  const XML_Char *UNUSED_P(encoding),
   3814                  int standalone)
   3815 {
   3816     if (userData != handler_data)
   3817         fail("User data (xml decl) not correctly set");
   3818     if (standalone != -1)
   3819         fail("Standalone not flagged as not present in XML decl");
   3820     xdecl_count++;
   3821 }
   3822 
   3823 static void XMLCALL
   3824 param_check_skip_handler(void *userData,
   3825                          const XML_Char *UNUSED_P(entityName),
   3826                          int UNUSED_P(is_parameter_entity))
   3827 {
   3828     if (userData != handler_data)
   3829         fail("User data (skip) not correctly set");
   3830     skip_count++;
   3831 }
   3832 
   3833 static void XMLCALL
   3834 data_check_comment_handler(void *userData, const XML_Char *UNUSED_P(data))
   3835 {
   3836     /* Check that the userData passed through is what we expect */
   3837     if (userData != handler_data)
   3838         fail("User data (parser) not correctly set");
   3839     /* Check that the user data in the parser is appropriate */
   3840     if (XML_GetUserData(userData) != (void *)1)
   3841         fail("User data in parser not correctly set");
   3842     comment_count++;
   3843 }
   3844 
   3845 static int XMLCALL
   3846 external_entity_param_checker(XML_Parser parser,
   3847                               const XML_Char *context,
   3848                               const XML_Char *UNUSED_P(base),
   3849                               const XML_Char *UNUSED_P(systemId),
   3850                               const XML_Char *UNUSED_P(publicId))
   3851 {
   3852     const char *text =
   3853         "<!-- Subordinate parser -->\n"
   3854         "<!ELEMENT doc (#PCDATA)*>";
   3855     XML_Parser ext_parser;
   3856 
   3857     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3858     if (ext_parser == NULL)
   3859         fail("Could not create external entity parser");
   3860     handler_data = ext_parser;
   3861     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   3862                                 XML_TRUE) == XML_STATUS_ERROR) {
   3863         xml_failure(parser);
   3864         return XML_STATUS_ERROR;
   3865     }
   3866     handler_data = parser;
   3867     XML_ParserFree(ext_parser);
   3868     return XML_STATUS_OK;
   3869 }
   3870 
   3871 START_TEST(test_user_parameters)
   3872 {
   3873     const char *text =
   3874         "<?xml version='1.0' encoding='us-ascii'?>\n"
   3875         "<!-- Primary parse -->\n"
   3876         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   3877         "<doc>&entity;";
   3878     const char *epilog =
   3879         "<!-- Back to primary parser -->\n"
   3880         "</doc>";
   3881 
   3882     comment_count = 0;
   3883     skip_count = 0;
   3884     xdecl_count = 0;
   3885     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3886     XML_SetXmlDeclHandler(parser, xml_decl_handler);
   3887     XML_SetExternalEntityRefHandler(parser, external_entity_param_checker);
   3888     XML_SetCommentHandler(parser, data_check_comment_handler);
   3889     XML_SetSkippedEntityHandler(parser, param_check_skip_handler);
   3890     XML_UseParserAsHandlerArg(parser);
   3891     XML_SetUserData(parser, (void *)1);
   3892     handler_data = parser;
   3893     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3894                                 XML_FALSE) == XML_STATUS_ERROR)
   3895         xml_failure(parser);
   3896     if (comment_count != 2)
   3897         fail("Comment handler not invoked enough times");
   3898     /* Ensure we can't change policy mid-parse */
   3899     if (XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_NEVER))
   3900         fail("Changed param entity parsing policy while parsing");
   3901     if (_XML_Parse_SINGLE_BYTES(parser, epilog, strlen(epilog),
   3902                                 XML_TRUE) == XML_STATUS_ERROR)
   3903         xml_failure(parser);
   3904     if (comment_count != 3)
   3905         fail("Comment handler not invoked enough times");
   3906     if (skip_count != 1)
   3907         fail("Skip handler not invoked enough times");
   3908     if (xdecl_count != 1)
   3909         fail("XML declaration handler not invoked");
   3910 }
   3911 END_TEST
   3912 
   3913 /* Test that an explicit external entity handler argument replaces
   3914  * the parser as the first argument.
   3915  *
   3916  * We do not call the first parameter to the external entity handler
   3917  * 'parser' for once, since the first time the handler is called it
   3918  * will actually be a text string.  We need to be able to access the
   3919  * global 'parser' variable to create our external entity parser from,
   3920  * since there are code paths we need to ensure get executed.
   3921  */
   3922 static int XMLCALL
   3923 external_entity_ref_param_checker(XML_Parser parameter,
   3924                                   const XML_Char *context,
   3925                                   const XML_Char *UNUSED_P(base),
   3926                                   const XML_Char *UNUSED_P(systemId),
   3927                                   const XML_Char *UNUSED_P(publicId))
   3928 {
   3929     const char *text = "<!ELEMENT doc (#PCDATA)*>";
   3930     XML_Parser ext_parser;
   3931 
   3932     if ((void *)parameter != handler_data)
   3933         fail("External entity ref handler parameter not correct");
   3934 
   3935     /* Here we use the global 'parser' variable */
   3936     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   3937     if (ext_parser == NULL)
   3938         fail("Could not create external entity parser");
   3939     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   3940                                 XML_TRUE) == XML_STATUS_ERROR)
   3941         xml_failure(ext_parser);
   3942 
   3943     XML_ParserFree(ext_parser);
   3944     return XML_STATUS_OK;
   3945 }
   3946 
   3947 START_TEST(test_ext_entity_ref_parameter)
   3948 {
   3949     const char *text =
   3950         "<?xml version='1.0' encoding='us-ascii'?>\n"
   3951         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   3952         "<doc>&entity;</doc>";
   3953 
   3954     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3955     XML_SetExternalEntityRefHandler(parser,
   3956                                     external_entity_ref_param_checker);
   3957     /* Set a handler arg that is not NULL and not parser (which is
   3958      * what NULL would cause to be passed.
   3959      */
   3960     XML_SetExternalEntityRefHandlerArg(parser, (void *)text);
   3961     handler_data = (void *)text;
   3962     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3963                                 XML_TRUE) == XML_STATUS_ERROR)
   3964         xml_failure(parser);
   3965 
   3966     /* Now try again with unset args */
   3967     XML_ParserReset(parser, NULL);
   3968     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   3969     XML_SetExternalEntityRefHandler(parser,
   3970                                     external_entity_ref_param_checker);
   3971     XML_SetExternalEntityRefHandlerArg(parser, NULL);
   3972     handler_data = (void *)parser;
   3973     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3974                                 XML_TRUE) == XML_STATUS_ERROR)
   3975         xml_failure(parser);
   3976 }
   3977 END_TEST
   3978 
   3979 /* Test the parsing of an empty string */
   3980 START_TEST(test_empty_parse)
   3981 {
   3982     const char *text = "<doc></doc>";
   3983     const char *partial = "<doc>";
   3984 
   3985     if (XML_Parse(parser, NULL, 0, XML_FALSE) == XML_STATUS_ERROR)
   3986         fail("Parsing empty string faulted");
   3987     if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR)
   3988         fail("Parsing final empty string not faulted");
   3989     if (XML_GetErrorCode(parser) != XML_ERROR_NO_ELEMENTS)
   3990         fail("Parsing final empty string faulted for wrong reason");
   3991 
   3992     /* Now try with valid text before the empty end */
   3993     XML_ParserReset(parser, NULL);
   3994     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   3995                                 XML_FALSE) == XML_STATUS_ERROR)
   3996         xml_failure(parser);
   3997     if (XML_Parse(parser, NULL, 0, XML_TRUE) == XML_STATUS_ERROR)
   3998         fail("Parsing final empty string faulted");
   3999 
   4000     /* Now try with invalid text before the empty end */
   4001     XML_ParserReset(parser, NULL);
   4002     if (_XML_Parse_SINGLE_BYTES(parser, partial, strlen(partial),
   4003                                 XML_FALSE) == XML_STATUS_ERROR)
   4004         xml_failure(parser);
   4005     if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR)
   4006         fail("Parsing final incomplete empty string not faulted");
   4007 }
   4008 END_TEST
   4009 
   4010 /* Test odd corners of the XML_GetBuffer interface */
   4011 static enum XML_Status
   4012 get_feature(enum XML_FeatureEnum feature_id, long *presult)
   4013 {
   4014     const XML_Feature *feature = XML_GetFeatureList();
   4015 
   4016     if (feature == NULL)
   4017         return XML_STATUS_ERROR;
   4018     for (; feature->feature != XML_FEATURE_END; feature++) {
   4019         if (feature->feature == feature_id) {
   4020             *presult = feature->value;
   4021             return XML_STATUS_OK;
   4022         }
   4023     }
   4024     return XML_STATUS_ERROR;
   4025 }
   4026 
   4027 /* Having an element name longer than 1024 characters exercises some
   4028  * of the pool allocation code in the parser that otherwise does not
   4029  * get executed.  The count at the end of the line is the number of
   4030  * characters (bytes) in the element name by that point.x
   4031  */
   4032 static const char *get_buffer_test_text =
   4033         "<documentwitharidiculouslylongelementnametotease" /* 0x030 */
   4034         "aparticularcorneroftheallocationinXML_GetBuffers" /* 0x060 */
   4035         "othatwecanimprovethecoverageyetagain012345678901" /* 0x090 */
   4036         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0c0 */
   4037         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0f0 */
   4038         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x120 */
   4039         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x150 */
   4040         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x180 */
   4041         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1b0 */
   4042         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1e0 */
   4043         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x210 */
   4044         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x240 */
   4045         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x270 */
   4046         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2a0 */
   4047         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2d0 */
   4048         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x300 */
   4049         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x330 */
   4050         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x360 */
   4051         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x390 */
   4052         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3c0 */
   4053         "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3f0 */
   4054         "123456789abcdef0123456789abcdef0123456789>\n<ef0"; /* 0x420 */
   4055 
   4056 /* Test odd corners of the XML_GetBuffer interface */
   4057 START_TEST(test_get_buffer_1)
   4058 {
   4059     const char *text = get_buffer_test_text;
   4060     void *buffer;
   4061     long context_bytes;
   4062 
   4063     /* Attempt to allocate a negative length buffer */
   4064     if (XML_GetBuffer(parser, -12) != NULL)
   4065         fail("Negative length buffer not failed");
   4066 
   4067     /* Now get a small buffer and extend it past valid length */
   4068     buffer = XML_GetBuffer(parser, 1536);
   4069     if (buffer == NULL)
   4070         fail("1.5K buffer failed");
   4071     memcpy(buffer, text, strlen(text));
   4072     if (XML_ParseBuffer(parser, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
   4073         xml_failure(parser);
   4074     if (XML_GetBuffer(parser, INT_MAX) != NULL)
   4075         fail("INT_MAX buffer not failed");
   4076 
   4077     /* Now try extending it a more reasonable but still too large
   4078      * amount.  The allocator in XML_GetBuffer() doubles the buffer
   4079      * size until it exceeds the requested amount or INT_MAX.  If it
   4080      * exceeds INT_MAX, it rejects the request, so we want a request
   4081      * between INT_MAX and INT_MAX/2.  A gap of 1K seems comfortable,
   4082      * with an extra byte just to ensure that the request is off any
   4083      * boundary.  The request will be inflated internally by
   4084      * XML_CONTEXT_BYTES (if defined), so we subtract that from our
   4085      * request.
   4086      */
   4087     if (get_feature(XML_FEATURE_CONTEXT_BYTES,
   4088                     &context_bytes) != XML_STATUS_OK)
   4089         context_bytes = 0;
   4090     if (XML_GetBuffer(parser, INT_MAX - (context_bytes + 1025)) != NULL)
   4091         fail("INT_MAX- buffer not failed");
   4092 
   4093     /* Now try extending it a carefully crafted amount */
   4094     if (XML_GetBuffer(parser, 1000) == NULL)
   4095         fail("1000 buffer failed");
   4096 }
   4097 END_TEST
   4098 
   4099 /* Test more corners of the XML_GetBuffer interface */
   4100 START_TEST(test_get_buffer_2)
   4101 {
   4102     const char *text = get_buffer_test_text;
   4103     void *buffer;
   4104 
   4105     /* Now get a decent buffer */
   4106     buffer = XML_GetBuffer(parser, 1536);
   4107     if (buffer == NULL)
   4108         fail("1.5K buffer failed");
   4109     memcpy(buffer, text, strlen(text));
   4110     if (XML_ParseBuffer(parser, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
   4111         xml_failure(parser);
   4112 
   4113     /* Extend it, to catch a different code path */
   4114     if (XML_GetBuffer(parser, 1024) == NULL)
   4115         fail("1024 buffer failed");
   4116 }
   4117 END_TEST
   4118 
   4119 /* Test position information macros */
   4120 START_TEST(test_byte_info_at_end)
   4121 {
   4122     const char *text = "<doc></doc>";
   4123 
   4124     if (XML_GetCurrentByteIndex(parser) != -1 ||
   4125         XML_GetCurrentByteCount(parser) != 0)
   4126         fail("Byte index/count incorrect at start of parse");
   4127     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4128                                 XML_TRUE) == XML_STATUS_ERROR)
   4129         xml_failure(parser);
   4130     /* At end, the count will be zero and the index the end of string */
   4131     if (XML_GetCurrentByteCount(parser) != 0)
   4132         fail("Terminal byte count incorrect");
   4133     if (XML_GetCurrentByteIndex(parser) != (XML_Index)strlen(text))
   4134         fail("Terminal byte index incorrect");
   4135 }
   4136 END_TEST
   4137 
   4138 /* Test position information from errors */
   4139 #define PRE_ERROR_STR  "<doc></"
   4140 #define POST_ERROR_STR "wombat></doc>"
   4141 START_TEST(test_byte_info_at_error)
   4142 {
   4143     const char *text = PRE_ERROR_STR POST_ERROR_STR;
   4144 
   4145     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4146                                 XML_TRUE) == XML_STATUS_OK)
   4147         fail("Syntax error not faulted");
   4148     if (XML_GetCurrentByteCount(parser) != 0)
   4149         fail("Error byte count incorrect");
   4150     if (XML_GetCurrentByteIndex(parser) != strlen(PRE_ERROR_STR))
   4151         fail("Error byte index incorrect");
   4152 }
   4153 END_TEST
   4154 #undef PRE_ERROR_STR
   4155 #undef POST_ERROR_STR
   4156 
   4157 /* Test position information in handler */
   4158 typedef struct ByteTestData {
   4159     int start_element_len;
   4160     int cdata_len;
   4161     int total_string_len;
   4162 } ByteTestData;
   4163 
   4164 static void
   4165 byte_character_handler(void *userData,
   4166                        const XML_Char *UNUSED_P(s),
   4167                        int len)
   4168 {
   4169 #ifdef XML_CONTEXT_BYTES
   4170     int offset, size;
   4171     const char *buffer;
   4172     ByteTestData *data = (ByteTestData *)userData;
   4173 
   4174     buffer = XML_GetInputContext(parser, &offset, &size);
   4175     if (buffer == NULL)
   4176         fail("Failed to get context buffer");
   4177     if (offset != data->start_element_len)
   4178         fail("Context offset in unexpected position");
   4179     if (len != data->cdata_len)
   4180         fail("CDATA length reported incorrectly");
   4181     if (size != data->total_string_len)
   4182         fail("Context size is not full buffer");
   4183     if (XML_GetCurrentByteIndex(parser) != offset)
   4184         fail("Character byte index incorrect");
   4185     if (XML_GetCurrentByteCount(parser) != len)
   4186         fail("Character byte count incorrect");
   4187 #else
   4188     (void)userData;
   4189     (void)len;
   4190 #endif
   4191 }
   4192 
   4193 #define START_ELEMENT "<e>"
   4194 #define CDATA_TEXT    "Hello"
   4195 #define END_ELEMENT   "</e>"
   4196 START_TEST(test_byte_info_at_cdata)
   4197 {
   4198     const char *text = START_ELEMENT CDATA_TEXT END_ELEMENT;
   4199     int offset, size;
   4200     ByteTestData data;
   4201 
   4202     /* Check initial context is empty */
   4203     if (XML_GetInputContext(parser, &offset, &size) != NULL)
   4204         fail("Unexpected context at start of parse");
   4205 
   4206     data.start_element_len = strlen(START_ELEMENT);
   4207     data.cdata_len = strlen(CDATA_TEXT);
   4208     data.total_string_len = strlen(text);
   4209     XML_SetCharacterDataHandler(parser, byte_character_handler);
   4210     XML_SetUserData(parser, &data);
   4211     if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_OK)
   4212         xml_failure(parser);
   4213 }
   4214 END_TEST
   4215 #undef START_ELEMENT
   4216 #undef CDATA_TEXT
   4217 #undef END_ELEMENT
   4218 
   4219 /* Test predefined entities are correctly recognised */
   4220 START_TEST(test_predefined_entities)
   4221 {
   4222     const char *text = "<doc>&lt;&gt;&amp;&quot;&apos;</doc>";
   4223     const XML_Char *expected = XCS("<doc>&lt;&gt;&amp;&quot;&apos;</doc>");
   4224     const XML_Char *result = XCS("<>&\"'");
   4225     CharData storage;
   4226 
   4227     XML_SetDefaultHandler(parser, accumulate_characters);
   4228     /* run_character_check uses XML_SetCharacterDataHandler(), which
   4229      * unfortunately heads off a code path that we need to exercise.
   4230      */
   4231     CharData_Init(&storage);
   4232     XML_SetUserData(parser, &storage);
   4233     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4234                                 XML_TRUE) == XML_STATUS_ERROR)
   4235         xml_failure(parser);
   4236     /* The default handler doesn't translate the entities */
   4237     CharData_CheckXMLChars(&storage, expected);
   4238 
   4239     /* Now try again and check the translation */
   4240     XML_ParserReset(parser, NULL);
   4241     run_character_check(text, result);
   4242 }
   4243 END_TEST
   4244 
   4245 /* Regression test that an invalid tag in an external parameter
   4246  * reference in an external DTD is correctly faulted.
   4247  *
   4248  * Only a few specific tags are legal in DTDs ignoring comments and
   4249  * processing instructions, all of which begin with an exclamation
   4250  * mark.  "<el/>" is not one of them, so the parser should raise an
   4251  * error on encountering it.
   4252  */
   4253 static int XMLCALL
   4254 external_entity_param(XML_Parser parser,
   4255                       const XML_Char *context,
   4256                       const XML_Char *UNUSED_P(base),
   4257                       const XML_Char *systemId,
   4258                       const XML_Char *UNUSED_P(publicId))
   4259 {
   4260     const char *text1 =
   4261         "<!ELEMENT doc EMPTY>\n"
   4262         "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
   4263         "<!ENTITY % e2 '%e1;'>\n"
   4264         "%e1;\n";
   4265     const char *text2 =
   4266         "<!ELEMENT el EMPTY>\n"
   4267         "<el/>\n";
   4268     XML_Parser ext_parser;
   4269 
   4270     if (systemId == NULL)
   4271         return XML_STATUS_OK;
   4272 
   4273     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   4274     if (ext_parser == NULL)
   4275         fail("Could not create external entity parser");
   4276 
   4277     if (!xcstrcmp(systemId, XCS("004-1.ent"))) {
   4278         if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, strlen(text1),
   4279                                     XML_TRUE) != XML_STATUS_ERROR)
   4280             fail("Inner DTD with invalid tag not rejected");
   4281         if (XML_GetErrorCode(ext_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
   4282             xml_failure(ext_parser);
   4283     }
   4284     else if (!xcstrcmp(systemId, XCS("004-2.ent"))) {
   4285         if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, strlen(text2),
   4286                                     XML_TRUE) != XML_STATUS_ERROR)
   4287             fail("Invalid tag in external param not rejected");
   4288         if (XML_GetErrorCode(ext_parser) != XML_ERROR_SYNTAX)
   4289             xml_failure(ext_parser);
   4290     } else {
   4291         fail("Unknown system ID");
   4292     }
   4293 
   4294     XML_ParserFree(ext_parser);
   4295     return XML_STATUS_ERROR;
   4296 }
   4297 
   4298 START_TEST(test_invalid_tag_in_dtd)
   4299 {
   4300     const char *text =
   4301         "<!DOCTYPE doc SYSTEM '004-1.ent'>\n"
   4302         "<doc></doc>\n";
   4303 
   4304     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4305     XML_SetExternalEntityRefHandler(parser, external_entity_param);
   4306     expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   4307                    "Invalid tag IN DTD external param not rejected");
   4308 }
   4309 END_TEST
   4310 
   4311 /* Test entities not quite the predefined ones are not mis-recognised */
   4312 START_TEST(test_not_predefined_entities)
   4313 {
   4314     const char *text[] = {
   4315         "<doc>&pt;</doc>",
   4316         "<doc>&amo;</doc>",
   4317         "<doc>&quid;</doc>",
   4318         "<doc>&apod;</doc>",
   4319         NULL
   4320     };
   4321     int i = 0;
   4322 
   4323     while (text[i] != NULL) {
   4324         expect_failure(text[i], XML_ERROR_UNDEFINED_ENTITY,
   4325                        "Undefined entity not rejected");
   4326         XML_ParserReset(parser, NULL);
   4327         i++;
   4328     }
   4329 }
   4330 END_TEST
   4331 
   4332 /* Test conditional inclusion (IGNORE) */
   4333 static int XMLCALL
   4334 external_entity_load_ignore(XML_Parser parser,
   4335                             const XML_Char *context,
   4336                             const XML_Char *UNUSED_P(base),
   4337                             const XML_Char *UNUSED_P(systemId),
   4338                             const XML_Char *UNUSED_P(publicId))
   4339 {
   4340     const char *text = "<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>";
   4341     XML_Parser ext_parser;
   4342 
   4343     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   4344     if (ext_parser == NULL)
   4345         fail("Could not create external entity parser");
   4346     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   4347                                 XML_TRUE) == XML_STATUS_ERROR)
   4348         xml_failure(parser);
   4349 
   4350     XML_ParserFree(ext_parser);
   4351     return XML_STATUS_OK;
   4352 }
   4353 
   4354 START_TEST(test_ignore_section)
   4355 {
   4356     const char *text =
   4357         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   4358         "<doc><e>&entity;</e></doc>";
   4359     const XML_Char *expected =
   4360         XCS("<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>\n&entity;");
   4361     CharData storage;
   4362 
   4363     CharData_Init(&storage);
   4364     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4365     XML_SetUserData(parser, &storage);
   4366     XML_SetExternalEntityRefHandler(parser, external_entity_load_ignore);
   4367     XML_SetDefaultHandler(parser, accumulate_characters);
   4368     XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler);
   4369     XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler);
   4370     XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   4371     XML_SetStartElementHandler(parser, dummy_start_element);
   4372     XML_SetEndElementHandler(parser, dummy_end_element);
   4373     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4374                                 XML_TRUE) == XML_STATUS_ERROR)
   4375         xml_failure(parser);
   4376     CharData_CheckXMLChars(&storage, expected);
   4377 }
   4378 END_TEST
   4379 
   4380 static int XMLCALL
   4381 external_entity_load_ignore_utf16(XML_Parser parser,
   4382                                   const XML_Char *context,
   4383                                   const XML_Char *UNUSED_P(base),
   4384                                   const XML_Char *UNUSED_P(systemId),
   4385                                   const XML_Char *UNUSED_P(publicId))
   4386 {
   4387     const char text[] =
   4388         /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */
   4389         "<\0!\0[\0I\0G\0N\0O\0R\0E\0[\0"
   4390         "<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 \0"
   4391         "(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>\0";
   4392     XML_Parser ext_parser;
   4393 
   4394     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   4395     if (ext_parser == NULL)
   4396         fail("Could not create external entity parser");
   4397     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, sizeof(text)-1,
   4398                                 XML_TRUE) == XML_STATUS_ERROR)
   4399         xml_failure(parser);
   4400 
   4401     XML_ParserFree(ext_parser);
   4402     return XML_STATUS_OK;
   4403 }
   4404 
   4405 START_TEST(test_ignore_section_utf16)
   4406 {
   4407     const char text[] =
   4408         /* <!DOCTYPE d SYSTEM 's'> */
   4409         "<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 "
   4410         "\0S\0Y\0S\0T\0E\0M\0 \0'\0s\0'\0>\0\n\0"
   4411         /* <d><e>&en;</e></d> */
   4412         "<\0d\0>\0<\0e\0>\0&\0e\0n\0;\0<\0/\0e\0>\0<\0/\0d\0>\0";
   4413     const XML_Char *expected =
   4414         XCS("<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>\n&en;");
   4415     CharData storage;
   4416 
   4417     CharData_Init(&storage);
   4418     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4419     XML_SetUserData(parser, &storage);
   4420     XML_SetExternalEntityRefHandler(parser,
   4421                                     external_entity_load_ignore_utf16);
   4422     XML_SetDefaultHandler(parser, accumulate_characters);
   4423     XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler);
   4424     XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler);
   4425     XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   4426     XML_SetStartElementHandler(parser, dummy_start_element);
   4427     XML_SetEndElementHandler(parser, dummy_end_element);
   4428     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   4429                                 XML_TRUE) == XML_STATUS_ERROR)
   4430         xml_failure(parser);
   4431     CharData_CheckXMLChars(&storage, expected);
   4432 }
   4433 END_TEST
   4434 
   4435 static int XMLCALL
   4436 external_entity_load_ignore_utf16_be(XML_Parser parser,
   4437                                      const XML_Char *context,
   4438                                      const XML_Char *UNUSED_P(base),
   4439                                      const XML_Char *UNUSED_P(systemId),
   4440                                      const XML_Char *UNUSED_P(publicId))
   4441 {
   4442     const char text[] =
   4443         /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */
   4444         "\0<\0!\0[\0I\0G\0N\0O\0R\0E\0["
   4445         "\0<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 "
   4446         "\0(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>";
   4447     XML_Parser ext_parser;
   4448 
   4449     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   4450     if (ext_parser == NULL)
   4451         fail("Could not create external entity parser");
   4452     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, sizeof(text)-1,
   4453                                 XML_TRUE) == XML_STATUS_ERROR)
   4454         xml_failure(parser);
   4455 
   4456     XML_ParserFree(ext_parser);
   4457     return XML_STATUS_OK;
   4458 }
   4459 
   4460 START_TEST(test_ignore_section_utf16_be)
   4461 {
   4462     const char text[] =
   4463         /* <!DOCTYPE d SYSTEM 's'> */
   4464         "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 "
   4465         "\0S\0Y\0S\0T\0E\0M\0 \0'\0s\0'\0>\0\n"
   4466         /* <d><e>&en;</e></d> */
   4467         "\0<\0d\0>\0<\0e\0>\0&\0e\0n\0;\0<\0/\0e\0>\0<\0/\0d\0>";
   4468     const XML_Char *expected =
   4469         XCS("<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>\n&en;");
   4470     CharData storage;
   4471 
   4472     CharData_Init(&storage);
   4473     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4474     XML_SetUserData(parser, &storage);
   4475     XML_SetExternalEntityRefHandler(parser,
   4476                                     external_entity_load_ignore_utf16_be);
   4477     XML_SetDefaultHandler(parser, accumulate_characters);
   4478     XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler);
   4479     XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler);
   4480     XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   4481     XML_SetStartElementHandler(parser, dummy_start_element);
   4482     XML_SetEndElementHandler(parser, dummy_end_element);
   4483     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   4484                                 XML_TRUE) == XML_STATUS_ERROR)
   4485         xml_failure(parser);
   4486     CharData_CheckXMLChars(&storage, expected);
   4487 }
   4488 END_TEST
   4489 
   4490 /* Test mis-formatted conditional exclusion */
   4491 START_TEST(test_bad_ignore_section)
   4492 {
   4493     const char *text =
   4494         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   4495         "<doc><e>&entity;</e></doc>";
   4496     ExtFaults faults[] = {
   4497         {
   4498             "<![IGNORE[<!ELEM",
   4499             "Broken-off declaration not faulted",
   4500             NULL,
   4501             XML_ERROR_SYNTAX
   4502         },
   4503         {
   4504             "<![IGNORE[\x01]]>",
   4505             "Invalid XML character not faulted",
   4506             NULL,
   4507             XML_ERROR_INVALID_TOKEN
   4508         },
   4509         {
   4510             /* FIrst two bytes of a three-byte char */
   4511             "<![IGNORE[\xe2\x82",
   4512             "Partial XML character not faulted",
   4513             NULL,
   4514             XML_ERROR_PARTIAL_CHAR
   4515         },
   4516         { NULL, NULL, NULL, XML_ERROR_NONE }
   4517     };
   4518     ExtFaults *fault;
   4519 
   4520     for (fault = &faults[0]; fault->parse_text != NULL; fault++) {
   4521         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4522         XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
   4523         XML_SetUserData(parser, fault);
   4524         expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   4525                        "Incomplete IGNORE section not failed");
   4526         XML_ParserReset(parser, NULL);
   4527     }
   4528 }
   4529 END_TEST
   4530 
   4531 /* Test recursive parsing */
   4532 static int XMLCALL
   4533 external_entity_valuer(XML_Parser parser,
   4534                        const XML_Char *context,
   4535                        const XML_Char *UNUSED_P(base),
   4536                        const XML_Char *systemId,
   4537                        const XML_Char *UNUSED_P(publicId))
   4538 {
   4539     const char *text1 =
   4540         "<!ELEMENT doc EMPTY>\n"
   4541         "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
   4542         "<!ENTITY % e2 '%e1;'>\n"
   4543         "%e1;\n";
   4544     XML_Parser ext_parser;
   4545 
   4546     if (systemId == NULL)
   4547         return XML_STATUS_OK;
   4548     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   4549     if (ext_parser == NULL)
   4550         fail("Could not create external entity parser");
   4551     if (!xcstrcmp(systemId, XCS("004-1.ent"))) {
   4552         if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, strlen(text1),
   4553                                     XML_TRUE) == XML_STATUS_ERROR)
   4554             xml_failure(ext_parser);
   4555     }
   4556     else if (!xcstrcmp(systemId, XCS("004-2.ent"))) {
   4557         ExtFaults *fault = (ExtFaults *)XML_GetUserData(parser);
   4558         enum XML_Status status;
   4559         enum XML_Error error;
   4560 
   4561         status = _XML_Parse_SINGLE_BYTES(ext_parser,
   4562                                          fault->parse_text,
   4563                                          strlen(fault->parse_text),
   4564                                          XML_TRUE);
   4565         if (fault->error == XML_ERROR_NONE) {
   4566             if (status == XML_STATUS_ERROR)
   4567                 xml_failure(ext_parser);
   4568         } else {
   4569             if (status != XML_STATUS_ERROR)
   4570                 fail(fault->fail_text);
   4571             error = XML_GetErrorCode(ext_parser);
   4572             if (error != fault->error &&
   4573                 (fault->error != XML_ERROR_XML_DECL ||
   4574                  error != XML_ERROR_TEXT_DECL))
   4575                 xml_failure(ext_parser);
   4576         }
   4577     }
   4578 
   4579     XML_ParserFree(ext_parser);
   4580     return XML_STATUS_OK;
   4581 }
   4582 
   4583 START_TEST(test_external_entity_values)
   4584 {
   4585     const char *text =
   4586         "<!DOCTYPE doc SYSTEM '004-1.ent'>\n"
   4587         "<doc></doc>\n";
   4588     ExtFaults data_004_2[] = {
   4589         {
   4590             "<!ATTLIST doc a1 CDATA 'value'>",
   4591             NULL,
   4592             NULL,
   4593             XML_ERROR_NONE
   4594         },
   4595         {
   4596             "<!ATTLIST $doc a1 CDATA 'value'>",
   4597             "Invalid token not faulted",
   4598             NULL,
   4599             XML_ERROR_INVALID_TOKEN
   4600         },
   4601         {
   4602             "'wombat",
   4603             "Unterminated string not faulted",
   4604             NULL,
   4605             XML_ERROR_UNCLOSED_TOKEN
   4606         },
   4607         {
   4608             "\xe2\x82",
   4609             "Partial UTF-8 character not faulted",
   4610             NULL,
   4611             XML_ERROR_PARTIAL_CHAR
   4612         },
   4613         {
   4614             "<?xml version='1.0' encoding='utf-8'?>\n",
   4615             NULL,
   4616             NULL,
   4617             XML_ERROR_NONE
   4618         },
   4619         {
   4620             "<?xml?>",
   4621             "Malformed XML declaration not faulted",
   4622             NULL,
   4623             XML_ERROR_XML_DECL
   4624         },
   4625         {
   4626             /* UTF-8 BOM */
   4627             "\xEF\xBB\xBF<!ATTLIST doc a1 CDATA 'value'>",
   4628             NULL,
   4629             NULL,
   4630             XML_ERROR_NONE
   4631         },
   4632         {
   4633             "<?xml version='1.0' encoding='utf-8'?>\n$",
   4634             "Invalid token after text declaration not faulted",
   4635             NULL,
   4636             XML_ERROR_INVALID_TOKEN
   4637         },
   4638         {
   4639             "<?xml version='1.0' encoding='utf-8'?>\n'wombat",
   4640             "Unterminated string after text decl not faulted",
   4641             NULL,
   4642             XML_ERROR_UNCLOSED_TOKEN
   4643         },
   4644         {
   4645             "<?xml version='1.0' encoding='utf-8'?>\n\xe2\x82",
   4646             "Partial UTF-8 character after text decl not faulted",
   4647             NULL,
   4648             XML_ERROR_PARTIAL_CHAR
   4649         },
   4650         {
   4651             "%e1;",
   4652             "Recursive parameter entity not faulted",
   4653             NULL,
   4654             XML_ERROR_RECURSIVE_ENTITY_REF
   4655         },
   4656         { NULL, NULL, NULL, XML_ERROR_NONE }
   4657     };
   4658     int i;
   4659 
   4660     for (i = 0; data_004_2[i].parse_text != NULL; i++) {
   4661         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4662         XML_SetExternalEntityRefHandler(parser, external_entity_valuer);
   4663         XML_SetUserData(parser, &data_004_2[i]);
   4664         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4665                                     XML_TRUE) == XML_STATUS_ERROR)
   4666             xml_failure(parser);
   4667         XML_ParserReset(parser, NULL);
   4668     }
   4669 }
   4670 END_TEST
   4671 
   4672 /* Test the recursive parse interacts with a not standalone handler */
   4673 static int XMLCALL
   4674 external_entity_not_standalone(XML_Parser parser,
   4675                                const XML_Char *context,
   4676                                const XML_Char *UNUSED_P(base),
   4677                                const XML_Char *systemId,
   4678                                const XML_Char *UNUSED_P(publicId))
   4679 {
   4680     const char *text1 =
   4681         "<!ELEMENT doc EMPTY>\n"
   4682         "<!ENTITY % e1 SYSTEM 'bar'>\n"
   4683         "%e1;\n";
   4684     const char *text2 = "<!ATTLIST doc a1 CDATA 'value'>";
   4685     XML_Parser ext_parser;
   4686 
   4687     if (systemId == NULL)
   4688         return XML_STATUS_OK;
   4689     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   4690     if (ext_parser == NULL)
   4691         fail("Could not create external entity parser");
   4692     if (!xcstrcmp(systemId, XCS("foo"))) {
   4693         XML_SetNotStandaloneHandler(ext_parser,
   4694                                     reject_not_standalone_handler);
   4695         if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, strlen(text1),
   4696                                     XML_TRUE) != XML_STATUS_ERROR)
   4697             fail("Expected not standalone rejection");
   4698         if (XML_GetErrorCode(ext_parser) != XML_ERROR_NOT_STANDALONE)
   4699             xml_failure(ext_parser);
   4700         XML_SetNotStandaloneHandler(ext_parser, NULL);
   4701         XML_ParserFree(ext_parser);
   4702         return XML_STATUS_ERROR;
   4703     }
   4704     else if (!xcstrcmp(systemId, XCS("bar"))) {
   4705         if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, strlen(text2),
   4706                                     XML_TRUE) == XML_STATUS_ERROR)
   4707             xml_failure(ext_parser);
   4708     }
   4709 
   4710     XML_ParserFree(ext_parser);
   4711     return XML_STATUS_OK;
   4712 }
   4713 
   4714 START_TEST(test_ext_entity_not_standalone)
   4715 {
   4716     const char *text =
   4717         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   4718         "<doc></doc>";
   4719 
   4720     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4721     XML_SetExternalEntityRefHandler(parser, external_entity_not_standalone);
   4722     expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   4723                    "Standalone rejection not caught");
   4724 }
   4725 END_TEST
   4726 
   4727 static int XMLCALL
   4728 external_entity_value_aborter(XML_Parser parser,
   4729                               const XML_Char *context,
   4730                               const XML_Char *UNUSED_P(base),
   4731                               const XML_Char *systemId,
   4732                               const XML_Char *UNUSED_P(publicId))
   4733 {
   4734     const char *text1 =
   4735         "<!ELEMENT doc EMPTY>\n"
   4736         "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
   4737         "<!ENTITY % e2 '%e1;'>\n"
   4738         "%e1;\n";
   4739     const char *text2 =
   4740         "<?xml version='1.0' encoding='utf-8'?>";
   4741     XML_Parser ext_parser;
   4742 
   4743     if (systemId == NULL)
   4744         return XML_STATUS_OK;
   4745     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   4746     if (ext_parser == NULL)
   4747         fail("Could not create external entity parser");
   4748     if (!xcstrcmp(systemId, XCS("004-1.ent"))) {
   4749         if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, strlen(text1),
   4750                                     XML_TRUE) == XML_STATUS_ERROR)
   4751             xml_failure(ext_parser);
   4752     }
   4753     if (!xcstrcmp(systemId, XCS("004-2.ent"))) {
   4754         XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
   4755         XML_SetUserData(ext_parser, ext_parser);
   4756         if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, strlen(text2),
   4757                                     XML_TRUE) != XML_STATUS_ERROR)
   4758             fail("Aborted parse not faulted");
   4759         if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED)
   4760             xml_failure(ext_parser);
   4761     }
   4762 
   4763     XML_ParserFree(ext_parser);
   4764     return XML_STATUS_OK;
   4765 }
   4766 
   4767 START_TEST(test_ext_entity_value_abort)
   4768 {
   4769     const char *text =
   4770         "<!DOCTYPE doc SYSTEM '004-1.ent'>\n"
   4771         "<doc></doc>\n";
   4772 
   4773     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4774     XML_SetExternalEntityRefHandler(parser,
   4775                                     external_entity_value_aborter);
   4776     resumable = XML_FALSE;
   4777     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4778                                 XML_TRUE) == XML_STATUS_ERROR)
   4779         xml_failure(parser);
   4780 }
   4781 END_TEST
   4782 
   4783 START_TEST(test_bad_public_doctype)
   4784 {
   4785     const char *text =
   4786         "<?xml version='1.0' encoding='utf-8'?>\n"
   4787         "<!DOCTYPE doc PUBLIC '{BadName}' 'test'>\n"
   4788         "<doc></doc>";
   4789 
   4790     /* Setting a handler provokes a particular code path */
   4791     XML_SetDoctypeDeclHandler(parser,
   4792                               dummy_start_doctype_handler,
   4793                               dummy_end_doctype_handler);
   4794     expect_failure(text, XML_ERROR_PUBLICID, "Bad Public ID not failed");
   4795 }
   4796 END_TEST
   4797 
   4798 /* Test based on ibm/valid/P32/ibm32v04.xml */
   4799 START_TEST(test_attribute_enum_value)
   4800 {
   4801     const char *text =
   4802         "<?xml version='1.0' standalone='no'?>\n"
   4803         "<!DOCTYPE animal SYSTEM 'test.dtd'>\n"
   4804         "<animal>This is a \n    <a/>  \n\nyellow tiger</animal>";
   4805     ExtTest dtd_data = {
   4806         "<!ELEMENT animal (#PCDATA|a)*>\n"
   4807         "<!ELEMENT a EMPTY>\n"
   4808         "<!ATTLIST animal xml:space (default|preserve) 'preserve'>",
   4809         NULL,
   4810         NULL
   4811     };
   4812     const XML_Char *expected = XCS("This is a \n      \n\nyellow tiger");
   4813 
   4814     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   4815     XML_SetUserData(parser, &dtd_data);
   4816     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4817     /* An attribute list handler provokes a different code path */
   4818     XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
   4819     run_ext_character_check(text, &dtd_data, expected);
   4820 }
   4821 END_TEST
   4822 
   4823 /* Slightly bizarrely, the library seems to silently ignore entity
   4824  * definitions for predefined entities, even when they are wrong.  The
   4825  * language of the XML 1.0 spec is somewhat unhelpful as to what ought
   4826  * to happen, so this is currently treated as acceptable.
   4827  */
   4828 START_TEST(test_predefined_entity_redefinition)
   4829 {
   4830     const char *text =
   4831         "<!DOCTYPE doc [\n"
   4832         "<!ENTITY apos 'foo'>\n"
   4833         "]>\n"
   4834         "<doc>&apos;</doc>";
   4835     run_character_check(text, XCS("'"));
   4836 }
   4837 END_TEST
   4838 
   4839 /* Test that the parser stops processing the DTD after an unresolved
   4840  * parameter entity is encountered.
   4841  */
   4842 START_TEST(test_dtd_stop_processing)
   4843 {
   4844     const char *text =
   4845         "<!DOCTYPE doc [\n"
   4846         "%foo;\n"
   4847         "<!ENTITY bar 'bas'>\n"
   4848         "]><doc/>";
   4849 
   4850     XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
   4851     dummy_handler_flags = 0;
   4852     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4853                                 XML_TRUE) == XML_STATUS_ERROR)
   4854         xml_failure(parser);
   4855     if (dummy_handler_flags != 0)
   4856         fail("DTD processing still going after undefined PE");
   4857 }
   4858 END_TEST
   4859 
   4860 /* Test public notations with no system ID */
   4861 START_TEST(test_public_notation_no_sysid)
   4862 {
   4863     const char *text =
   4864         "<!DOCTYPE doc [\n"
   4865         "<!NOTATION note PUBLIC 'foo'>\n"
   4866         "<!ELEMENT doc EMPTY>\n"
   4867         "]>\n<doc/>";
   4868 
   4869     dummy_handler_flags = 0;
   4870     XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
   4871     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4872                                 XML_TRUE) == XML_STATUS_ERROR)
   4873         xml_failure(parser);
   4874     if (dummy_handler_flags != DUMMY_NOTATION_DECL_HANDLER_FLAG)
   4875         fail("Notation declaration handler not called");
   4876 }
   4877 END_TEST
   4878 
   4879 static void XMLCALL
   4880 record_element_start_handler(void *userData,
   4881                              const XML_Char *name,
   4882                              const XML_Char **UNUSED_P(atts))
   4883 {
   4884     CharData_AppendXMLChars((CharData *)userData, name, xcstrlen(name));
   4885 }
   4886 
   4887 START_TEST(test_nested_groups)
   4888 {
   4889     const char *text =
   4890         "<!DOCTYPE doc [\n"
   4891         "<!ELEMENT doc "
   4892         /* Sixteen elements per line */
   4893         "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,"
   4894         "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?"
   4895         "))))))))))))))))))))))))))))))))>\n"
   4896         "<!ELEMENT e EMPTY>"
   4897         "]>\n"
   4898         "<doc><e/></doc>";
   4899     CharData storage;
   4900 
   4901     CharData_Init(&storage);
   4902     XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   4903     XML_SetStartElementHandler(parser, record_element_start_handler);
   4904     XML_SetUserData(parser, &storage);
   4905     dummy_handler_flags = 0;
   4906     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4907                                 XML_TRUE) == XML_STATUS_ERROR)
   4908         xml_failure(parser);
   4909     CharData_CheckXMLChars(&storage, XCS("doce"));
   4910     if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
   4911         fail("Element handler not fired");
   4912 }
   4913 END_TEST
   4914 
   4915 START_TEST(test_group_choice)
   4916 {
   4917     const char *text =
   4918         "<!DOCTYPE doc [\n"
   4919         "<!ELEMENT doc (a|b|c)+>\n"
   4920         "<!ELEMENT a EMPTY>\n"
   4921         "<!ELEMENT b (#PCDATA)>\n"
   4922         "<!ELEMENT c ANY>\n"
   4923         "]>\n"
   4924         "<doc>\n"
   4925         "<a/>\n"
   4926         "<b attr='foo'>This is a foo</b>\n"
   4927         "<c></c>\n"
   4928         "</doc>\n";
   4929 
   4930     XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   4931     dummy_handler_flags = 0;
   4932     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4933                                 XML_TRUE) == XML_STATUS_ERROR)
   4934         xml_failure(parser);
   4935     if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
   4936         fail("Element handler flag not raised");
   4937 }
   4938 END_TEST
   4939 
   4940 static int XMLCALL
   4941 external_entity_public(XML_Parser parser,
   4942                        const XML_Char *context,
   4943                        const XML_Char *UNUSED_P(base),
   4944                        const XML_Char *systemId,
   4945                        const XML_Char *publicId)
   4946 {
   4947     const char *text1 = (const char *)XML_GetUserData(parser);
   4948     const char *text2 = "<!ATTLIST doc a CDATA 'value'>";
   4949     const char *text = NULL;
   4950     XML_Parser ext_parser;
   4951     int parse_res;
   4952 
   4953     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   4954     if (ext_parser == NULL)
   4955         return XML_STATUS_ERROR;
   4956     if (systemId != NULL && !xcstrcmp(systemId, XCS("http://example.org/"))) {
   4957         text = text1;
   4958     }
   4959     else if (publicId != NULL && !xcstrcmp(publicId, XCS("foo"))) {
   4960         text = text2;
   4961     }
   4962     else
   4963         fail("Unexpected parameters to external entity parser");
   4964     parse_res = _XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   4965                                    XML_TRUE);
   4966     XML_ParserFree(ext_parser);
   4967     return parse_res;
   4968 }
   4969 
   4970 START_TEST(test_standalone_parameter_entity)
   4971 {
   4972     const char *text =
   4973         "<?xml version='1.0' standalone='yes'?>\n"
   4974         "<!DOCTYPE doc SYSTEM 'http://example.org/' [\n"
   4975         "<!ENTITY % entity '<!ELEMENT doc (#PCDATA)>'>\n"
   4976         "%entity;\n"
   4977         "]>\n"
   4978         "<doc></doc>";
   4979     char dtd_data[] =
   4980         "<!ENTITY % e1 'foo'>\n";
   4981 
   4982     XML_SetUserData(parser, dtd_data);
   4983     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   4984     XML_SetExternalEntityRefHandler(parser, external_entity_public);
   4985     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   4986                                 XML_TRUE) == XML_STATUS_ERROR)
   4987         xml_failure(parser);
   4988 }
   4989 END_TEST
   4990 
   4991 /* Test skipping of parameter entity in an external DTD */
   4992 /* Derived from ibm/invalid/P69/ibm69i01.xml */
   4993 START_TEST(test_skipped_parameter_entity)
   4994 {
   4995     const char *text =
   4996         "<?xml version='1.0'?>\n"
   4997         "<!DOCTYPE root SYSTEM 'http://example.org/dtd.ent' [\n"
   4998         "<!ELEMENT root (#PCDATA|a)* >\n"
   4999         "]>\n"
   5000         "<root></root>";
   5001     ExtTest dtd_data = { "%pe2;", NULL, NULL };
   5002 
   5003     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   5004     XML_SetUserData(parser, &dtd_data);
   5005     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5006     XML_SetSkippedEntityHandler(parser, dummy_skip_handler);
   5007     dummy_handler_flags = 0;
   5008     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5009                                 XML_TRUE) == XML_STATUS_ERROR)
   5010         xml_failure(parser);
   5011     if (dummy_handler_flags != DUMMY_SKIP_HANDLER_FLAG)
   5012         fail("Skip handler not executed");
   5013 }
   5014 END_TEST
   5015 
   5016 /* Test recursive parameter entity definition rejected in external DTD */
   5017 START_TEST(test_recursive_external_parameter_entity)
   5018 {
   5019     const char *text =
   5020         "<?xml version='1.0'?>\n"
   5021         "<!DOCTYPE root SYSTEM 'http://example.org/dtd.ent' [\n"
   5022         "<!ELEMENT root (#PCDATA|a)* >\n"
   5023         "]>\n"
   5024         "<root></root>";
   5025     ExtFaults dtd_data = {
   5026         "<!ENTITY % pe2 '&#37;pe2;'>\n%pe2;",
   5027         "Recursive external parameter entity not faulted",
   5028         NULL,
   5029         XML_ERROR_RECURSIVE_ENTITY_REF
   5030     };
   5031 
   5032     XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
   5033     XML_SetUserData(parser, &dtd_data);
   5034     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5035     expect_failure(text,
   5036                    XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   5037                    "Recursive external parameter not spotted");
   5038 }
   5039 END_TEST
   5040 
   5041 /* Test undefined parameter entity in external entity handler */
   5042 static int XMLCALL
   5043 external_entity_devaluer(XML_Parser parser,
   5044                          const XML_Char *context,
   5045                          const XML_Char *UNUSED_P(base),
   5046                          const XML_Char *systemId,
   5047                          const XML_Char *UNUSED_P(publicId))
   5048 {
   5049     const char *text =
   5050         "<!ELEMENT doc EMPTY>\n"
   5051         "<!ENTITY % e1 SYSTEM 'bar'>\n"
   5052         "%e1;\n";
   5053     XML_Parser ext_parser;
   5054     int clear_handler = (intptr_t)XML_GetUserData(parser);
   5055 
   5056     if (systemId == NULL || !xcstrcmp(systemId, XCS("bar")))
   5057         return XML_STATUS_OK;
   5058     if (xcstrcmp(systemId, XCS("foo")))
   5059         fail("Unexpected system ID");
   5060     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   5061     if (ext_parser == NULL)
   5062         fail("Could note create external entity parser");
   5063     if (clear_handler)
   5064         XML_SetExternalEntityRefHandler(ext_parser, NULL);
   5065     if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   5066                                 XML_TRUE) == XML_STATUS_ERROR)
   5067         xml_failure(ext_parser);
   5068 
   5069     XML_ParserFree(ext_parser);
   5070     return XML_STATUS_OK;
   5071 }
   5072 
   5073 START_TEST(test_undefined_ext_entity_in_external_dtd)
   5074 {
   5075     const char *text =
   5076         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   5077         "<doc></doc>\n";
   5078 
   5079     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5080     XML_SetExternalEntityRefHandler(parser, external_entity_devaluer);
   5081     XML_SetUserData(parser, (void *)(intptr_t)XML_FALSE);
   5082     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5083                                 XML_TRUE) == XML_STATUS_ERROR)
   5084         xml_failure(parser);
   5085 
   5086     /* Now repeat without the external entity ref handler invoking
   5087      * another copy of itself.
   5088      */
   5089     XML_ParserReset(parser, NULL);
   5090     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5091     XML_SetExternalEntityRefHandler(parser, external_entity_devaluer);
   5092     XML_SetUserData(parser, (void *)(intptr_t)XML_TRUE);
   5093     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5094                                 XML_TRUE) == XML_STATUS_ERROR)
   5095         xml_failure(parser);
   5096 }
   5097 END_TEST
   5098 
   5099 
   5100 static void XMLCALL
   5101 aborting_xdecl_handler(void           *UNUSED_P(userData),
   5102                        const XML_Char *UNUSED_P(version),
   5103                        const XML_Char *UNUSED_P(encoding),
   5104                        int             UNUSED_P(standalone))
   5105 {
   5106     XML_StopParser(parser, resumable);
   5107     XML_SetXmlDeclHandler(parser, NULL);
   5108 }
   5109 
   5110 /* Test suspending the parse on receiving an XML declaration works */
   5111 START_TEST(test_suspend_xdecl)
   5112 {
   5113     const char *text = long_character_data_text;
   5114 
   5115     XML_SetXmlDeclHandler(parser, aborting_xdecl_handler);
   5116     resumable = XML_TRUE;
   5117     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5118                                 XML_TRUE) != XML_STATUS_SUSPENDED)
   5119         xml_failure(parser);
   5120     if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
   5121         xml_failure(parser);
   5122     /* Attempt to start a new parse while suspended */
   5123     if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
   5124         fail("Attempt to parse while suspended not faulted");
   5125     if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
   5126         fail("Suspended parse not faulted with correct error");
   5127 }
   5128 END_TEST
   5129 
   5130 /* Test aborting the parse in an epilog works */
   5131 static void XMLCALL
   5132 selective_aborting_default_handler(void *userData,
   5133                                    const XML_Char *s,
   5134                                    int len)
   5135 {
   5136     const XML_Char *match = (const XML_Char *)userData;
   5137 
   5138     if (match == NULL ||
   5139         (xcstrlen(match) == (unsigned)len &&
   5140          !xcstrncmp(match, s, len))) {
   5141         XML_StopParser(parser, resumable);
   5142         XML_SetDefaultHandler(parser, NULL);
   5143     }
   5144 }
   5145 
   5146 START_TEST(test_abort_epilog)
   5147 {
   5148     const char *text = "<doc></doc>\n\r\n";
   5149     XML_Char match[] = XCS("\r");
   5150 
   5151     XML_SetDefaultHandler(parser, selective_aborting_default_handler);
   5152     XML_SetUserData(parser, match);
   5153     resumable = XML_FALSE;
   5154     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5155                                 XML_TRUE) != XML_STATUS_ERROR)
   5156         fail("Abort not triggered");
   5157     if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED)
   5158         xml_failure(parser);
   5159 }
   5160 END_TEST
   5161 
   5162 /* Test a different code path for abort in the epilog */
   5163 START_TEST(test_abort_epilog_2)
   5164 {
   5165     const char *text = "<doc></doc>\n";
   5166     XML_Char match[] = XCS("\n");
   5167 
   5168     XML_SetDefaultHandler(parser, selective_aborting_default_handler);
   5169     XML_SetUserData(parser, match);
   5170     resumable = XML_FALSE;
   5171     expect_failure(text, XML_ERROR_ABORTED, "Abort not triggered");
   5172 }
   5173 END_TEST
   5174 
   5175 /* Test suspension from the epilog */
   5176 START_TEST(test_suspend_epilog)
   5177 {
   5178     const char *text = "<doc></doc>\n";
   5179     XML_Char match[] = XCS("\n");
   5180 
   5181     XML_SetDefaultHandler(parser, selective_aborting_default_handler);
   5182     XML_SetUserData(parser, match);
   5183     resumable = XML_TRUE;
   5184     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5185                                 XML_TRUE) != XML_STATUS_SUSPENDED)
   5186         xml_failure(parser);
   5187 }
   5188 END_TEST
   5189 
   5190 START_TEST(test_unfinished_epilog)
   5191 {
   5192     const char *text = "<doc></doc><";
   5193 
   5194     expect_failure(text, XML_ERROR_UNCLOSED_TOKEN,
   5195                    "Incomplete epilog entry not faulted");
   5196 }
   5197 END_TEST
   5198 
   5199 START_TEST(test_partial_char_in_epilog)
   5200 {
   5201     const char *text = "<doc></doc>\xe2\x82";
   5202 
   5203     /* First check that no fault is raised if the parse is not finished */
   5204     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5205                                 XML_FALSE) == XML_STATUS_ERROR)
   5206         xml_failure(parser);
   5207     /* Now check that it is faulted once we finish */
   5208     if (XML_ParseBuffer(parser, 0, XML_TRUE) != XML_STATUS_ERROR)
   5209         fail("Partial character in epilog not faulted");
   5210     if (XML_GetErrorCode(parser) != XML_ERROR_PARTIAL_CHAR)
   5211         xml_failure(parser);
   5212 }
   5213 END_TEST
   5214 
   5215 START_TEST(test_hash_collision)
   5216 {
   5217     /* For full coverage of the lookup routine, we need to ensure a
   5218      * hash collision even though we can only tell that we have one
   5219      * through breakpoint debugging or coverage statistics.  The
   5220      * following will cause a hash collision on machines with a 64-bit
   5221      * long type; others will have to experiment.  The full coverage
   5222      * tests invoked from qa.sh usually provide a hash collision, but
   5223      * not always.  This is an attempt to provide insurance.
   5224      */
   5225 #define COLLIDING_HASH_SALT (unsigned long)_SIP_ULL(0xffffffffU, 0xff99fc90U)
   5226     const char * text =
   5227         "<doc>\n"
   5228         "<a1/><a2/><a3/><a4/><a5/><a6/><a7/><a8/>\n"
   5229         "<b1></b1><b2 attr='foo'>This is a foo</b2><b3></b3><b4></b4>\n"
   5230         "<b5></b5><b6></b6><b7></b7><b8></b8>\n"
   5231         "<c1/><c2/><c3/><c4/><c5/><c6/><c7/><c8/>\n"
   5232         "<d1/><d2/><d3/><d4/><d5/><d6/><d7/>\n"
   5233         "<d8>This triggers the table growth and collides with b2</d8>\n"
   5234         "</doc>\n";
   5235 
   5236     XML_SetHashSalt(parser, COLLIDING_HASH_SALT);
   5237     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5238                                 XML_TRUE) == XML_STATUS_ERROR)
   5239         xml_failure(parser);
   5240 }
   5241 END_TEST
   5242 #undef COLLIDING_HASH_SALT
   5243 
   5244 /* Test resuming a parse suspended in entity substitution */
   5245 static void XMLCALL
   5246 start_element_suspender(void *UNUSED_P(userData),
   5247                         const XML_Char *name,
   5248                         const XML_Char **UNUSED_P(atts))
   5249 {
   5250     if (!xcstrcmp(name, XCS("suspend")))
   5251         XML_StopParser(parser, XML_TRUE);
   5252     if (!xcstrcmp(name, XCS("abort")))
   5253         XML_StopParser(parser, XML_FALSE);
   5254 }
   5255 
   5256 START_TEST(test_suspend_resume_internal_entity)
   5257 {
   5258     const char *text =
   5259         "<!DOCTYPE doc [\n"
   5260         "<!ENTITY foo '<suspend>Hi<suspend>Ho</suspend></suspend>'>\n"
   5261         "]>\n"
   5262         "<doc>&foo;</doc>\n";
   5263     const XML_Char *expected1 = XCS("Hi");
   5264     const XML_Char *expected2 = XCS("HiHo");
   5265     CharData storage;
   5266 
   5267     CharData_Init(&storage);
   5268     XML_SetStartElementHandler(parser, start_element_suspender);
   5269     XML_SetCharacterDataHandler(parser, accumulate_characters);
   5270     XML_SetUserData(parser, &storage);
   5271     if (XML_Parse(parser, text, strlen(text),
   5272                   XML_TRUE) != XML_STATUS_SUSPENDED)
   5273         xml_failure(parser);
   5274     CharData_CheckXMLChars(&storage, XCS(""));
   5275     if (XML_ResumeParser(parser) != XML_STATUS_SUSPENDED)
   5276         xml_failure(parser);
   5277     CharData_CheckXMLChars(&storage, expected1);
   5278     if (XML_ResumeParser(parser) != XML_STATUS_OK)
   5279         xml_failure(parser);
   5280     CharData_CheckXMLChars(&storage, expected2);
   5281 }
   5282 END_TEST
   5283 
   5284 /* Test syntax error is caught at parse resumption */
   5285 START_TEST(test_resume_entity_with_syntax_error)
   5286 {
   5287     const char *text =
   5288         "<!DOCTYPE doc [\n"
   5289         "<!ENTITY foo '<suspend>Hi</wombat>'>\n"
   5290         "]>\n"
   5291         "<doc>&foo;</doc>\n";
   5292 
   5293     XML_SetStartElementHandler(parser, start_element_suspender);
   5294     if (XML_Parse(parser, text, strlen(text),
   5295                   XML_TRUE) != XML_STATUS_SUSPENDED)
   5296         xml_failure(parser);
   5297     if (XML_ResumeParser(parser) != XML_STATUS_ERROR)
   5298         fail("Syntax error in entity not faulted");
   5299     if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
   5300         xml_failure(parser);
   5301 }
   5302 END_TEST
   5303 
   5304 /* Test suspending and resuming in a parameter entity substitution */
   5305 static void XMLCALL
   5306 element_decl_suspender(void *UNUSED_P(userData),
   5307                        const XML_Char *UNUSED_P(name),
   5308                        XML_Content *model)
   5309 {
   5310     XML_StopParser(parser, XML_TRUE);
   5311     XML_FreeContentModel(parser, model);
   5312 }
   5313 
   5314 START_TEST(test_suspend_resume_parameter_entity)
   5315 {
   5316     const char *text =
   5317         "<!DOCTYPE doc [\n"
   5318         "<!ENTITY % foo '<!ELEMENT doc (#PCDATA)*>'>\n"
   5319         "%foo;\n"
   5320         "]>\n"
   5321         "<doc>Hello, world</doc>";
   5322     const XML_Char *expected = XCS("Hello, world");
   5323     CharData storage;
   5324 
   5325     CharData_Init(&storage);
   5326     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5327     XML_SetElementDeclHandler(parser, element_decl_suspender);
   5328     XML_SetCharacterDataHandler(parser, accumulate_characters);
   5329     XML_SetUserData(parser, &storage);
   5330     if (XML_Parse(parser, text, strlen(text),
   5331                   XML_TRUE) != XML_STATUS_SUSPENDED)
   5332         xml_failure(parser);
   5333     CharData_CheckXMLChars(&storage, XCS(""));
   5334     if (XML_ResumeParser(parser) != XML_STATUS_OK)
   5335         xml_failure(parser);
   5336     CharData_CheckXMLChars(&storage, expected);
   5337 }
   5338 END_TEST
   5339 
   5340 /* Test attempting to use parser after an error is faulted */
   5341 START_TEST(test_restart_on_error)
   5342 {
   5343     const char *text = "<$doc><doc></doc>";
   5344 
   5345     if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
   5346         fail("Invalid tag name not faulted");
   5347     if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
   5348         xml_failure(parser);
   5349     if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR)
   5350         fail("Restarting invalid parse not faulted");
   5351     if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
   5352         xml_failure(parser);
   5353 }
   5354 END_TEST
   5355 
   5356 /* Test that angle brackets in an attribute default value are faulted */
   5357 START_TEST(test_reject_lt_in_attribute_value)
   5358 {
   5359     const char *text =
   5360         "<!DOCTYPE doc [<!ATTLIST doc a CDATA '<bar>'>]>\n"
   5361         "<doc></doc>";
   5362 
   5363     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   5364                    "Bad attribute default not faulted");
   5365 }
   5366 END_TEST
   5367 
   5368 START_TEST(test_reject_unfinished_param_in_att_value)
   5369 {
   5370     const char *text =
   5371         "<!DOCTYPE doc [<!ATTLIST doc a CDATA '&foo'>]>\n"
   5372         "<doc></doc>";
   5373 
   5374     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   5375                    "Bad attribute default not faulted");
   5376 }
   5377 END_TEST
   5378 
   5379 START_TEST(test_trailing_cr_in_att_value)
   5380 {
   5381     const char *text = "<doc a='value\r'/>";
   5382 
   5383     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5384                                 XML_TRUE) == XML_STATUS_ERROR)
   5385         xml_failure(parser);
   5386 }
   5387 END_TEST
   5388 
   5389 /* Try parsing a general entity within a parameter entity in a
   5390  * standalone internal DTD.  Covers a corner case in the parser.
   5391  */
   5392 START_TEST(test_standalone_internal_entity)
   5393 {
   5394     const char *text =
   5395         "<?xml version='1.0' standalone='yes' ?>\n"
   5396         "<!DOCTYPE doc [\n"
   5397         "  <!ELEMENT doc (#PCDATA)>\n"
   5398         "  <!ENTITY % pe '<!ATTLIST doc att2 CDATA \"&ge;\">'>\n"
   5399         "  <!ENTITY ge 'AttDefaultValue'>\n"
   5400         "  %pe;\n"
   5401         "]>\n"
   5402         "<doc att2='any'/>";
   5403 
   5404     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5405     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5406                                 XML_TRUE) == XML_STATUS_ERROR)
   5407         xml_failure(parser);
   5408 }
   5409 END_TEST
   5410 
   5411 /* Test that a reference to an unknown external entity is skipped */
   5412 START_TEST(test_skipped_external_entity)
   5413 {
   5414     const char *text =
   5415         "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
   5416         "<doc></doc>\n";
   5417     ExtTest test_data = {
   5418         "<!ELEMENT doc EMPTY>\n"
   5419         "<!ENTITY % e2 '%e1;'>\n",
   5420         NULL,
   5421         NULL
   5422     };
   5423 
   5424     XML_SetUserData(parser, &test_data);
   5425     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5426     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   5427     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5428                                 XML_TRUE) == XML_STATUS_ERROR)
   5429         xml_failure(parser);
   5430 }
   5431 END_TEST
   5432 
   5433 /* Test a different form of unknown external entity */
   5434 typedef struct ext_hdlr_data {
   5435     const char *parse_text;
   5436     XML_ExternalEntityRefHandler handler;
   5437 } ExtHdlrData;
   5438 
   5439 static int XMLCALL
   5440 external_entity_oneshot_loader(XML_Parser parser,
   5441                                const XML_Char *context,
   5442                                const XML_Char *UNUSED_P(base),
   5443                                const XML_Char *UNUSED_P(systemId),
   5444                                const XML_Char *UNUSED_P(publicId))
   5445 {
   5446     ExtHdlrData *test_data = (ExtHdlrData *)XML_GetUserData(parser);
   5447     XML_Parser ext_parser;
   5448 
   5449     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   5450     if (ext_parser == NULL)
   5451         fail("Could not create external entity parser.");
   5452     /* Use the requested entity parser for further externals */
   5453     XML_SetExternalEntityRefHandler(ext_parser, test_data->handler);
   5454     if ( _XML_Parse_SINGLE_BYTES(ext_parser,
   5455                                  test_data->parse_text,
   5456                                  strlen(test_data->parse_text),
   5457                                  XML_TRUE) == XML_STATUS_ERROR) {
   5458         xml_failure(ext_parser);
   5459     }
   5460 
   5461     XML_ParserFree(ext_parser);
   5462     return XML_STATUS_OK;
   5463 }
   5464 
   5465 START_TEST(test_skipped_null_loaded_ext_entity)
   5466 {
   5467     const char *text =
   5468         "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n"
   5469         "<doc />";
   5470     ExtHdlrData test_data = {
   5471         "<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n"
   5472         "<!ENTITY % pe2 '%pe1;'>\n"
   5473         "%pe2;\n",
   5474         external_entity_null_loader
   5475     };
   5476 
   5477     XML_SetUserData(parser, &test_data);
   5478     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5479     XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader);
   5480     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5481                                 XML_TRUE) == XML_STATUS_ERROR)
   5482         xml_failure(parser);
   5483 }
   5484 END_TEST
   5485 
   5486 START_TEST(test_skipped_unloaded_ext_entity)
   5487 {
   5488     const char *text =
   5489         "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n"
   5490         "<doc />";
   5491     ExtHdlrData test_data = {
   5492         "<!ENTITY % pe1 SYSTEM 'http://example.org/two.ent'>\n"
   5493         "<!ENTITY % pe2 '%pe1;'>\n"
   5494         "%pe2;\n",
   5495         NULL
   5496     };
   5497 
   5498     XML_SetUserData(parser, &test_data);
   5499     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5500     XML_SetExternalEntityRefHandler(parser, external_entity_oneshot_loader);
   5501     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5502                                 XML_TRUE) == XML_STATUS_ERROR)
   5503         xml_failure(parser);
   5504 }
   5505 END_TEST
   5506 
   5507 /* Test that a parameter entity value ending with a carriage return
   5508  * has it translated internally into a newline.
   5509  */
   5510 START_TEST(test_param_entity_with_trailing_cr)
   5511 {
   5512 #define PARAM_ENTITY_NAME "pe"
   5513 #define PARAM_ENTITY_CORE_VALUE "<!ATTLIST doc att CDATA \"default\">"
   5514     const char *text =
   5515         "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
   5516         "<doc/>";
   5517     ExtTest test_data = {
   5518         "<!ENTITY % " PARAM_ENTITY_NAME
   5519         " '" PARAM_ENTITY_CORE_VALUE "\r'>\n"
   5520         "%" PARAM_ENTITY_NAME ";\n",
   5521         NULL,
   5522         NULL
   5523     };
   5524 
   5525     XML_SetUserData(parser, &test_data);
   5526     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   5527     XML_SetExternalEntityRefHandler(parser, external_entity_loader);
   5528     XML_SetEntityDeclHandler(parser, param_entity_match_handler);
   5529     entity_name_to_match = XCS(PARAM_ENTITY_NAME);
   5530     entity_value_to_match = XCS(PARAM_ENTITY_CORE_VALUE) XCS("\n");
   5531     entity_match_flag = ENTITY_MATCH_NOT_FOUND;
   5532     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5533                                 XML_TRUE) == XML_STATUS_ERROR)
   5534         xml_failure(parser);
   5535     if (entity_match_flag == ENTITY_MATCH_FAIL)
   5536         fail("Parameter entity CR->NEWLINE conversion failed");
   5537     else if (entity_match_flag == ENTITY_MATCH_NOT_FOUND)
   5538         fail("Parameter entity not parsed");
   5539 }
   5540 #undef PARAM_ENTITY_NAME
   5541 #undef PARAM_ENTITY_CORE_VALUE
   5542 END_TEST
   5543 
   5544 START_TEST(test_invalid_character_entity)
   5545 {
   5546     const char *text =
   5547         "<!DOCTYPE doc [\n"
   5548         "  <!ENTITY entity '&#x110000;'>\n"
   5549         "]>\n"
   5550         "<doc>&entity;</doc>";
   5551 
   5552     expect_failure(text, XML_ERROR_BAD_CHAR_REF,
   5553                    "Out of range character reference not faulted");
   5554 }
   5555 END_TEST
   5556 
   5557 START_TEST(test_invalid_character_entity_2)
   5558 {
   5559     const char *text =
   5560         "<!DOCTYPE doc [\n"
   5561         "  <!ENTITY entity '&#xg0;'>\n"
   5562         "]>\n"
   5563         "<doc>&entity;</doc>";
   5564 
   5565     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   5566                    "Out of range character reference not faulted");
   5567 }
   5568 END_TEST
   5569 
   5570 START_TEST(test_invalid_character_entity_3)
   5571 {
   5572     const char text[] =
   5573         /* <!DOCTYPE doc [\n */
   5574         "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0o\0c\0 \0[\0\n"
   5575         /* U+0E04 = KHO KHWAI
   5576          * U+0E08 = CHO CHAN */
   5577         /* <!ENTITY entity '&\u0e04\u0e08;'>\n */
   5578         "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0e\0n\0t\0i\0t\0y\0 "
   5579         "\0'\0&\x0e\x04\x0e\x08\0;\0'\0>\0\n"
   5580         /* ]>\n */
   5581         "\0]\0>\0\n"
   5582         /* <doc>&entity;</doc> */
   5583         "\0<\0d\0o\0c\0>\0&\0e\0n\0t\0i\0t\0y\0;\0<\0/\0d\0o\0c\0>";
   5584 
   5585     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   5586                                 XML_TRUE) != XML_STATUS_ERROR)
   5587         fail("Invalid start of entity name not faulted");
   5588     if (XML_GetErrorCode(parser) != XML_ERROR_UNDEFINED_ENTITY)
   5589         xml_failure(parser);
   5590 }
   5591 END_TEST
   5592 
   5593 START_TEST(test_invalid_character_entity_4)
   5594 {
   5595     const char *text =
   5596         "<!DOCTYPE doc [\n"
   5597         "  <!ENTITY entity '&#1114112;'>\n" /* = &#x110000 */
   5598         "]>\n"
   5599         "<doc>&entity;</doc>";
   5600 
   5601     expect_failure(text, XML_ERROR_BAD_CHAR_REF,
   5602                    "Out of range character reference not faulted");
   5603 }
   5604 END_TEST
   5605 
   5606 
   5607 /* Test that processing instructions are picked up by a default handler */
   5608 START_TEST(test_pi_handled_in_default)
   5609 {
   5610     const char *text = "<?test processing instruction?>\n<doc/>";
   5611     const XML_Char *expected = XCS("<?test processing instruction?>\n<doc/>");
   5612     CharData storage;
   5613 
   5614     CharData_Init(&storage);
   5615     XML_SetDefaultHandler(parser, accumulate_characters);
   5616     XML_SetUserData(parser, &storage);
   5617     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5618                                 XML_TRUE)== XML_STATUS_ERROR)
   5619         xml_failure(parser);
   5620     CharData_CheckXMLChars(&storage, expected);
   5621 }
   5622 END_TEST
   5623 
   5624 
   5625 /* Test that comments are picked up by a default handler */
   5626 START_TEST(test_comment_handled_in_default)
   5627 {
   5628     const char *text = "<!-- This is a comment -->\n<doc/>";
   5629     const XML_Char *expected = XCS("<!-- This is a comment -->\n<doc/>");
   5630     CharData storage;
   5631 
   5632     CharData_Init(&storage);
   5633     XML_SetDefaultHandler(parser, accumulate_characters);
   5634     XML_SetUserData(parser, &storage);
   5635     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5636                                 XML_TRUE) == XML_STATUS_ERROR)
   5637         xml_failure(parser);
   5638     CharData_CheckXMLChars(&storage, expected);
   5639 }
   5640 END_TEST
   5641 
   5642 /* Test PIs that look almost but not quite like XML declarations */
   5643 static void XMLCALL
   5644 accumulate_pi_characters(void *userData,
   5645                          const XML_Char *target,
   5646                          const XML_Char *data)
   5647 {
   5648     CharData *storage = (CharData *)userData;
   5649 
   5650     CharData_AppendXMLChars(storage, target, -1);
   5651     CharData_AppendXMLChars(storage, XCS(": "), 2);
   5652     CharData_AppendXMLChars(storage, data, -1);
   5653     CharData_AppendXMLChars(storage, XCS("\n"), 1);
   5654 }
   5655 
   5656 START_TEST(test_pi_yml)
   5657 {
   5658     const char *text = "<?yml something like data?><doc/>";
   5659     const XML_Char *expected = XCS("yml: something like data\n");
   5660     CharData storage;
   5661 
   5662     CharData_Init(&storage);
   5663     XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
   5664     XML_SetUserData(parser, &storage);
   5665     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5666                                 XML_TRUE) == XML_STATUS_ERROR)
   5667         xml_failure(parser);
   5668     CharData_CheckXMLChars(&storage, expected);
   5669 }
   5670 END_TEST
   5671 
   5672 START_TEST(test_pi_xnl)
   5673 {
   5674     const char *text = "<?xnl nothing like data?><doc/>";
   5675     const XML_Char *expected = XCS("xnl: nothing like data\n");
   5676     CharData storage;
   5677 
   5678     CharData_Init(&storage);
   5679     XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
   5680     XML_SetUserData(parser, &storage);
   5681     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5682                                 XML_TRUE) == XML_STATUS_ERROR)
   5683         xml_failure(parser);
   5684     CharData_CheckXMLChars(&storage, expected);
   5685 }
   5686 END_TEST
   5687 
   5688 START_TEST(test_pi_xmm)
   5689 {
   5690     const char *text = "<?xmm everything like data?><doc/>";
   5691     const XML_Char *expected = XCS("xmm: everything like data\n");
   5692     CharData storage;
   5693 
   5694     CharData_Init(&storage);
   5695     XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
   5696     XML_SetUserData(parser, &storage);
   5697     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5698                                 XML_TRUE) == XML_STATUS_ERROR)
   5699         xml_failure(parser);
   5700     CharData_CheckXMLChars(&storage, expected);
   5701 }
   5702 END_TEST
   5703 
   5704 START_TEST(test_utf16_pi)
   5705 {
   5706     const char text[] =
   5707         /* <?{KHO KHWAI}{CHO CHAN}?>
   5708          * where {KHO KHWAI} = U+0E04
   5709          * and   {CHO CHAN}  = U+0E08
   5710          */
   5711         "<\0?\0\x04\x0e\x08\x0e?\0>\0"
   5712         /* <q/> */
   5713         "<\0q\0/\0>\0";
   5714 #ifdef XML_UNICODE
   5715     const XML_Char *expected = XCS("\x0e04\x0e08: \n");
   5716 #else
   5717     const XML_Char *expected = XCS("\xe0\xb8\x84\xe0\xb8\x88: \n");
   5718 #endif
   5719     CharData storage;
   5720 
   5721     CharData_Init(&storage);
   5722     XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
   5723     XML_SetUserData(parser, &storage);
   5724     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   5725                                 XML_TRUE) == XML_STATUS_ERROR)
   5726         xml_failure(parser);
   5727     CharData_CheckXMLChars(&storage, expected);
   5728 }
   5729 END_TEST
   5730 
   5731 START_TEST(test_utf16_be_pi)
   5732 {
   5733     const char text[] =
   5734         /* <?{KHO KHWAI}{CHO CHAN}?>
   5735          * where {KHO KHWAI} = U+0E04
   5736          * and   {CHO CHAN}  = U+0E08
   5737          */
   5738         "\0<\0?\x0e\x04\x0e\x08\0?\0>"
   5739         /* <q/> */
   5740         "\0<\0q\0/\0>";
   5741 #ifdef XML_UNICODE
   5742     const XML_Char *expected = XCS("\x0e04\x0e08: \n");
   5743 #else
   5744     const XML_Char *expected = XCS("\xe0\xb8\x84\xe0\xb8\x88: \n");
   5745 #endif
   5746     CharData storage;
   5747 
   5748     CharData_Init(&storage);
   5749     XML_SetProcessingInstructionHandler(parser, accumulate_pi_characters);
   5750     XML_SetUserData(parser, &storage);
   5751     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   5752                                 XML_TRUE) == XML_STATUS_ERROR)
   5753         xml_failure(parser);
   5754     CharData_CheckXMLChars(&storage, expected);
   5755 }
   5756 END_TEST
   5757 
   5758 /* Test that comments can be picked up and translated */
   5759 static void XMLCALL
   5760 accumulate_comment(void *userData,
   5761                    const XML_Char *data)
   5762 {
   5763     CharData *storage = (CharData *)userData;
   5764 
   5765     CharData_AppendXMLChars(storage, data, -1);
   5766 }
   5767 
   5768 START_TEST(test_utf16_be_comment)
   5769 {
   5770     const char text[] =
   5771         /* <!-- Comment A --> */
   5772         "\0<\0!\0-\0-\0 \0C\0o\0m\0m\0e\0n\0t\0 \0A\0 \0-\0-\0>\0\n"
   5773         /* <doc/> */
   5774         "\0<\0d\0o\0c\0/\0>";
   5775     const XML_Char *expected = XCS(" Comment A ");
   5776     CharData storage;
   5777 
   5778     CharData_Init(&storage);
   5779     XML_SetCommentHandler(parser, accumulate_comment);
   5780     XML_SetUserData(parser, &storage);
   5781     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   5782                                 XML_TRUE) == XML_STATUS_ERROR)
   5783         xml_failure(parser);
   5784     CharData_CheckXMLChars(&storage, expected);
   5785 }
   5786 END_TEST
   5787 
   5788 START_TEST(test_utf16_le_comment)
   5789 {
   5790     const char text[] =
   5791         /* <!-- Comment B --> */
   5792         "<\0!\0-\0-\0 \0C\0o\0m\0m\0e\0n\0t\0 \0B\0 \0-\0-\0>\0\n\0"
   5793         /* <doc/> */
   5794         "<\0d\0o\0c\0/\0>\0";
   5795     const XML_Char *expected = XCS(" Comment B ");
   5796     CharData storage;
   5797 
   5798     CharData_Init(&storage);
   5799     XML_SetCommentHandler(parser, accumulate_comment);
   5800     XML_SetUserData(parser, &storage);
   5801     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   5802                                 XML_TRUE) == XML_STATUS_ERROR)
   5803         xml_failure(parser);
   5804     CharData_CheckXMLChars(&storage, expected);
   5805 }
   5806 END_TEST
   5807 
   5808 /* Test that the unknown encoding handler with map entries that expect
   5809  * conversion but no conversion function is faulted
   5810  */
   5811 static int XMLCALL
   5812 failing_converter(void *UNUSED_P(data), const char *UNUSED_P(s))
   5813 {
   5814     /* Always claim to have failed */
   5815     return -1;
   5816 }
   5817 
   5818 static int XMLCALL
   5819 prefix_converter(void *UNUSED_P(data), const char *s)
   5820 {
   5821     /* If the first byte is 0xff, raise an error */
   5822     if (s[0] == (char)-1)
   5823         return -1;
   5824     /* Just add the low bits of the first byte to the second */
   5825     return (s[1] + (s[0] & 0x7f)) & 0x01ff;
   5826 }
   5827 
   5828 static int XMLCALL
   5829 MiscEncodingHandler(void *data,
   5830                     const XML_Char *encoding,
   5831                     XML_Encoding *info)
   5832 {
   5833     int i;
   5834     int high_map = -2; /* Assume a 2-byte sequence */
   5835 
   5836     if (!xcstrcmp(encoding, XCS("invalid-9")) ||
   5837         !xcstrcmp(encoding, XCS("ascii-like")) ||
   5838         !xcstrcmp(encoding, XCS("invalid-len")) ||
   5839         !xcstrcmp(encoding, XCS("invalid-a")) ||
   5840         !xcstrcmp(encoding, XCS("invalid-surrogate")) ||
   5841         !xcstrcmp(encoding, XCS("invalid-high")))
   5842         high_map = -1;
   5843 
   5844     for (i = 0; i < 128; ++i)
   5845         info->map[i] = i;
   5846     for (; i < 256; ++i)
   5847         info->map[i] = high_map;
   5848 
   5849     /* If required, put an invalid value in the ASCII entries */
   5850     if (!xcstrcmp(encoding, XCS("invalid-9")))
   5851         info->map[9] = 5;
   5852     /* If required, have a top-bit set character starts a 5-byte sequence */
   5853     if (!xcstrcmp(encoding, XCS("invalid-len")))
   5854         info->map[0x81] = -5;
   5855     /* If required, make a top-bit set character a valid ASCII character */
   5856     if (!xcstrcmp(encoding, XCS("invalid-a")))
   5857         info->map[0x82] = 'a';
   5858     /* If required, give a top-bit set character a forbidden value,
   5859      * what would otherwise be the first of a surrogate pair.
   5860      */
   5861     if (!xcstrcmp(encoding, XCS("invalid-surrogate")))
   5862         info->map[0x83] = 0xd801;
   5863     /* If required, give a top-bit set character too high a value */
   5864     if (!xcstrcmp(encoding, XCS("invalid-high")))
   5865         info->map[0x84] = 0x010101;
   5866 
   5867     info->data = data;
   5868     info->release = NULL;
   5869     if (!xcstrcmp(encoding, XCS("failing-conv")))
   5870         info->convert = failing_converter;
   5871     else if (!xcstrcmp(encoding, XCS("prefix-conv")))
   5872         info->convert = prefix_converter;
   5873     else
   5874         info->convert = NULL;
   5875     return XML_STATUS_OK;
   5876 }
   5877 
   5878 START_TEST(test_missing_encoding_conversion_fn)
   5879 {
   5880     const char *text =
   5881         "<?xml version='1.0' encoding='no-conv'?>\n"
   5882         "<doc>\x81</doc>";
   5883 
   5884     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   5885     /* MiscEncodingHandler sets up an encoding with every top-bit-set
   5886      * character introducing a two-byte sequence.  For this, it
   5887      * requires a convert function.  The above function call doesn't
   5888      * pass one through, so when BadEncodingHandler actually gets
   5889      * called it should supply an invalid encoding.
   5890      */
   5891     expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
   5892                    "Encoding with missing convert() not faulted");
   5893 }
   5894 END_TEST
   5895 
   5896 START_TEST(test_failing_encoding_conversion_fn)
   5897 {
   5898     const char *text =
   5899         "<?xml version='1.0' encoding='failing-conv'?>\n"
   5900         "<doc>\x81</doc>";
   5901 
   5902     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   5903     /* BadEncodingHandler sets up an encoding with every top-bit-set
   5904      * character introducing a two-byte sequence.  For this, it
   5905      * requires a convert function.  The above function call passes
   5906      * one that insists all possible sequences are invalid anyway.
   5907      */
   5908     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   5909                    "Encoding with failing convert() not faulted");
   5910 }
   5911 END_TEST
   5912 
   5913 /* Test unknown encoding conversions */
   5914 START_TEST(test_unknown_encoding_success)
   5915 {
   5916     const char *text =
   5917         "<?xml version='1.0' encoding='prefix-conv'?>\n"
   5918         /* Equivalent to <eoc>Hello, world</eoc> */
   5919         "<\x81\x64\x80oc>Hello, world</\x81\x64\x80oc>";
   5920 
   5921     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   5922     run_character_check(text, XCS("Hello, world"));
   5923 }
   5924 END_TEST
   5925 
   5926 /* Test bad name character in unknown encoding */
   5927 START_TEST(test_unknown_encoding_bad_name)
   5928 {
   5929     const char *text =
   5930         "<?xml version='1.0' encoding='prefix-conv'?>\n"
   5931         "<\xff\x64oc>Hello, world</\xff\x64oc>";
   5932 
   5933     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   5934     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   5935                    "Bad name start in unknown encoding not faulted");
   5936 }
   5937 END_TEST
   5938 
   5939 /* Test bad mid-name character in unknown encoding */
   5940 START_TEST(test_unknown_encoding_bad_name_2)
   5941 {
   5942     const char *text =
   5943         "<?xml version='1.0' encoding='prefix-conv'?>\n"
   5944         "<d\xffoc>Hello, world</d\xffoc>";
   5945 
   5946     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   5947     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   5948                    "Bad name in unknown encoding not faulted");
   5949 }
   5950 END_TEST
   5951 
   5952 /* Test element name that is long enough to fill the conversion buffer
   5953  * in an unknown encoding, finishing with an encoded character.
   5954  */
   5955 START_TEST(test_unknown_encoding_long_name_1)
   5956 {
   5957     const char *text =
   5958         "<?xml version='1.0' encoding='prefix-conv'?>\n"
   5959         "<abcdefghabcdefghabcdefghijkl\x80m\x80n\x80o\x80p>"
   5960         "Hi"
   5961         "</abcdefghabcdefghabcdefghijkl\x80m\x80n\x80o\x80p>";
   5962     const XML_Char *expected = XCS("abcdefghabcdefghabcdefghijklmnop");
   5963     CharData storage;
   5964 
   5965     CharData_Init(&storage);
   5966     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   5967     XML_SetStartElementHandler(parser, record_element_start_handler);
   5968     XML_SetUserData(parser, &storage);
   5969     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5970                                 XML_TRUE) == XML_STATUS_ERROR)
   5971         xml_failure(parser);
   5972     CharData_CheckXMLChars(&storage, expected);
   5973 }
   5974 END_TEST
   5975 
   5976 /* Test element name that is long enough to fill the conversion buffer
   5977  * in an unknown encoding, finishing with an simple character.
   5978  */
   5979 START_TEST(test_unknown_encoding_long_name_2)
   5980 {
   5981     const char *text =
   5982         "<?xml version='1.0' encoding='prefix-conv'?>\n"
   5983         "<abcdefghabcdefghabcdefghijklmnop>"
   5984         "Hi"
   5985         "</abcdefghabcdefghabcdefghijklmnop>";
   5986     const XML_Char *expected = XCS("abcdefghabcdefghabcdefghijklmnop");
   5987     CharData storage;
   5988 
   5989     CharData_Init(&storage);
   5990     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   5991     XML_SetStartElementHandler(parser, record_element_start_handler);
   5992     XML_SetUserData(parser, &storage);
   5993     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   5994                                 XML_TRUE) == XML_STATUS_ERROR)
   5995         xml_failure(parser);
   5996     CharData_CheckXMLChars(&storage, expected);
   5997 }
   5998 END_TEST
   5999 
   6000 START_TEST(test_invalid_unknown_encoding)
   6001 {
   6002     const char *text =
   6003         "<?xml version='1.0' encoding='invalid-9'?>\n"
   6004         "<doc>Hello world</doc>";
   6005 
   6006     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6007     expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
   6008                    "Invalid unknown encoding not faulted");
   6009 }
   6010 END_TEST
   6011 
   6012 START_TEST(test_unknown_ascii_encoding_ok)
   6013 {
   6014     const char *text =
   6015         "<?xml version='1.0' encoding='ascii-like'?>\n"
   6016         "<doc>Hello, world</doc>";
   6017 
   6018     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6019     run_character_check(text, XCS("Hello, world"));
   6020 }
   6021 END_TEST
   6022 
   6023 START_TEST(test_unknown_ascii_encoding_fail)
   6024 {
   6025     const char *text =
   6026         "<?xml version='1.0' encoding='ascii-like'?>\n"
   6027         "<doc>Hello, \x80 world</doc>";
   6028 
   6029     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6030     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   6031                    "Invalid character not faulted");
   6032 }
   6033 END_TEST
   6034 
   6035 START_TEST(test_unknown_encoding_invalid_length)
   6036 {
   6037     const char *text =
   6038         "<?xml version='1.0' encoding='invalid-len'?>\n"
   6039         "<doc>Hello, world</doc>";
   6040 
   6041     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6042     expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
   6043                    "Invalid unknown encoding not faulted");
   6044 }
   6045 END_TEST
   6046 
   6047 START_TEST(test_unknown_encoding_invalid_topbit)
   6048 {
   6049     const char *text =
   6050         "<?xml version='1.0' encoding='invalid-a'?>\n"
   6051         "<doc>Hello, world</doc>";
   6052 
   6053     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6054     expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
   6055                    "Invalid unknown encoding not faulted");
   6056 }
   6057 END_TEST
   6058 
   6059 START_TEST(test_unknown_encoding_invalid_surrogate)
   6060 {
   6061     const char *text =
   6062         "<?xml version='1.0' encoding='invalid-surrogate'?>\n"
   6063         "<doc>Hello, \x82 world</doc>";
   6064 
   6065     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6066     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   6067                    "Invalid unknown encoding not faulted");
   6068 }
   6069 END_TEST
   6070 
   6071 START_TEST(test_unknown_encoding_invalid_high)
   6072 {
   6073     const char *text =
   6074         "<?xml version='1.0' encoding='invalid-high'?>\n"
   6075         "<doc>Hello, world</doc>";
   6076 
   6077     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6078     expect_failure(text, XML_ERROR_UNKNOWN_ENCODING,
   6079                    "Invalid unknown encoding not faulted");
   6080 }
   6081 END_TEST
   6082 
   6083 START_TEST(test_unknown_encoding_invalid_attr_value)
   6084 {
   6085     const char *text =
   6086         "<?xml version='1.0' encoding='prefix-conv'?>\n"
   6087         "<doc attr='\xff\x30'/>";
   6088 
   6089     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6090     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   6091                    "Invalid attribute valid not faulted");
   6092 }
   6093 END_TEST
   6094 
   6095 /* Test an external entity parser set to use latin-1 detects UTF-16
   6096  * BOMs correctly.
   6097  */
   6098 enum ee_parse_flags {
   6099     EE_PARSE_NONE = 0x00,
   6100     EE_PARSE_FULL_BUFFER = 0x01
   6101 };
   6102 
   6103 typedef struct ExtTest2 {
   6104     const char *parse_text;
   6105     int parse_len;
   6106     const XML_Char *encoding;
   6107     CharData *storage;
   6108     enum ee_parse_flags flags;
   6109 } ExtTest2;
   6110 
   6111 static int XMLCALL
   6112 external_entity_loader2(XML_Parser parser,
   6113                         const XML_Char *context,
   6114                         const XML_Char *UNUSED_P(base),
   6115                         const XML_Char *UNUSED_P(systemId),
   6116                         const XML_Char *UNUSED_P(publicId))
   6117 {
   6118     ExtTest2 *test_data = (ExtTest2 *)XML_GetUserData(parser);
   6119     XML_Parser extparser;
   6120 
   6121     extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
   6122     if (extparser == NULL)
   6123         fail("Coulr not create external entity parser");
   6124     if (test_data->encoding != NULL) {
   6125         if (!XML_SetEncoding(extparser, test_data->encoding))
   6126             fail("XML_SetEncoding() ignored for external entity");
   6127     }
   6128     if (test_data->flags & EE_PARSE_FULL_BUFFER) {
   6129         if (XML_Parse(extparser,
   6130                       test_data->parse_text,
   6131                       test_data->parse_len,
   6132                       XML_TRUE) == XML_STATUS_ERROR) {
   6133             xml_failure(extparser);
   6134         }
   6135     }
   6136     else if (_XML_Parse_SINGLE_BYTES(extparser,
   6137                                      test_data->parse_text,
   6138                                      test_data->parse_len,
   6139                                      XML_TRUE) == XML_STATUS_ERROR) {
   6140         xml_failure(extparser);
   6141     }
   6142 
   6143     XML_ParserFree(extparser);
   6144     return XML_STATUS_OK;
   6145 }
   6146 
   6147 /* Test that UTF-16 BOM does not select UTF-16 given explicit encoding */
   6148 static void XMLCALL
   6149 ext2_accumulate_characters(void *userData, const XML_Char *s, int len)
   6150 {
   6151     ExtTest2 *test_data = (ExtTest2 *)userData;
   6152     accumulate_characters(test_data->storage, s, len);
   6153 }
   6154 
   6155 START_TEST(test_ext_entity_latin1_utf16le_bom)
   6156 {
   6157     const char *text =
   6158         "<!DOCTYPE doc [\n"
   6159         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   6160         "]>\n"
   6161         "<doc>&en;</doc>";
   6162     ExtTest2 test_data = {
   6163         /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */
   6164         /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn,
   6165          *   0x4c = L and 0x20 is a space
   6166          */
   6167         "\xff\xfe\x4c\x20",
   6168         4,
   6169         XCS("iso-8859-1"),
   6170         NULL,
   6171         EE_PARSE_NONE
   6172     };
   6173 #ifdef XML_UNICODE
   6174     const XML_Char *expected = XCS("\x00ff\x00feL ");
   6175 #else
   6176     /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */
   6177     const XML_Char *expected = XCS("\xc3\xbf\xc3\xbeL ");
   6178 #endif
   6179     CharData storage;
   6180 
   6181 
   6182     CharData_Init(&storage);
   6183     test_data.storage = &storage;
   6184     XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
   6185     XML_SetUserData(parser, &test_data);
   6186     XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
   6187     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   6188                                 XML_TRUE) == XML_STATUS_ERROR)
   6189         xml_failure(parser);
   6190     CharData_CheckXMLChars(&storage, expected);
   6191 }
   6192 END_TEST
   6193 
   6194 START_TEST(test_ext_entity_latin1_utf16be_bom)
   6195 {
   6196     const char *text =
   6197         "<!DOCTYPE doc [\n"
   6198         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   6199         "]>\n"
   6200         "<doc>&en;</doc>";
   6201     ExtTest2 test_data = {
   6202         /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */
   6203         /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn,
   6204          *   0x4c = L and 0x20 is a space
   6205          */
   6206         "\xfe\xff\x20\x4c",
   6207         4,
   6208         XCS("iso-8859-1"),
   6209         NULL,
   6210         EE_PARSE_NONE
   6211     };
   6212 #ifdef XML_UNICODE
   6213     const XML_Char *expected = XCS("\x00fe\x00ff L");
   6214 #else
   6215     /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */
   6216     const XML_Char *expected = XCS("\xc3\xbe\xc3\xbf L");
   6217 #endif
   6218     CharData storage;
   6219 
   6220 
   6221     CharData_Init(&storage);
   6222     test_data.storage = &storage;
   6223     XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
   6224     XML_SetUserData(parser, &test_data);
   6225     XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
   6226     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   6227                                 XML_TRUE) == XML_STATUS_ERROR)
   6228         xml_failure(parser);
   6229     CharData_CheckXMLChars(&storage, expected);
   6230 }
   6231 END_TEST
   6232 
   6233 
   6234 /* Parsing the full buffer rather than a byte at a time makes a
   6235  * difference to the encoding scanning code, so repeat the above tests
   6236  * without breaking them down by byte.
   6237  */
   6238 START_TEST(test_ext_entity_latin1_utf16le_bom2)
   6239 {
   6240     const char *text =
   6241         "<!DOCTYPE doc [\n"
   6242         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   6243         "]>\n"
   6244         "<doc>&en;</doc>";
   6245     ExtTest2 test_data = {
   6246         /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */
   6247         /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn,
   6248          *   0x4c = L and 0x20 is a space
   6249          */
   6250         "\xff\xfe\x4c\x20",
   6251         4,
   6252         XCS("iso-8859-1"),
   6253         NULL,
   6254         EE_PARSE_FULL_BUFFER
   6255     };
   6256 #ifdef XML_UNICODE
   6257     const XML_Char *expected = XCS("\x00ff\x00feL ");
   6258 #else
   6259     /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */
   6260     const XML_Char *expected = XCS("\xc3\xbf\xc3\xbeL ");
   6261 #endif
   6262     CharData storage;
   6263 
   6264 
   6265     CharData_Init(&storage);
   6266     test_data.storage = &storage;
   6267     XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
   6268     XML_SetUserData(parser, &test_data);
   6269     XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
   6270     if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   6271         xml_failure(parser);
   6272     CharData_CheckXMLChars(&storage, expected);
   6273 }
   6274 END_TEST
   6275 
   6276 START_TEST(test_ext_entity_latin1_utf16be_bom2)
   6277 {
   6278     const char *text =
   6279         "<!DOCTYPE doc [\n"
   6280         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   6281         "]>\n"
   6282         "<doc>&en;</doc>";
   6283     ExtTest2 test_data = {
   6284         /* If UTF-16, 0xfeff is the BOM and 0x204c is black left bullet */
   6285         /* If Latin-1, 0xff = Y-diaeresis, 0xfe = lowercase thorn,
   6286          *   0x4c = L and 0x20 is a space
   6287          */
   6288         "\xfe\xff\x20\x4c",
   6289         4,
   6290         XCS("iso-8859-1"),
   6291         NULL,
   6292         EE_PARSE_FULL_BUFFER
   6293     };
   6294 #ifdef XML_UNICODE
   6295     const XML_Char *expected = XCS("\x00fe\x00ff L");
   6296 #else
   6297     /* In UTF-8, y-diaeresis is 0xc3 0xbf, lowercase thorn is 0xc3 0xbe */
   6298     const XML_Char *expected = "\xc3\xbe\xc3\xbf L";
   6299 #endif
   6300     CharData storage;
   6301 
   6302 
   6303     CharData_Init(&storage);
   6304     test_data.storage = &storage;
   6305     XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
   6306     XML_SetUserData(parser, &test_data);
   6307     XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
   6308     if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   6309         xml_failure(parser);
   6310     CharData_CheckXMLChars(&storage, expected);
   6311 }
   6312 END_TEST
   6313 
   6314 /* Test little-endian UTF-16 given an explicit big-endian encoding */
   6315 START_TEST(test_ext_entity_utf16_be)
   6316 {
   6317     const char *text =
   6318         "<!DOCTYPE doc [\n"
   6319         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   6320         "]>\n"
   6321         "<doc>&en;</doc>";
   6322     ExtTest2 test_data = {
   6323         "<\0e\0/\0>\0",
   6324         8,
   6325         XCS("utf-16be"),
   6326         NULL,
   6327         EE_PARSE_NONE
   6328     };
   6329 #ifdef XML_UNICODE
   6330     const XML_Char *expected = XCS("\x3c00\x6500\x2f00\x3e00");
   6331 #else
   6332     const XML_Char *expected =
   6333         XCS("\xe3\xb0\x80"   /* U+3C00 */
   6334             "\xe6\x94\x80"   /* U+6500 */
   6335             "\xe2\xbc\x80"   /* U+2F00 */
   6336             "\xe3\xb8\x80"); /* U+3E00 */
   6337 #endif
   6338     CharData storage;
   6339 
   6340     CharData_Init(&storage);
   6341     test_data.storage = &storage;
   6342     XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
   6343     XML_SetUserData(parser, &test_data);
   6344     XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
   6345     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   6346                                 XML_TRUE) == XML_STATUS_ERROR)
   6347         xml_failure(parser);
   6348     CharData_CheckXMLChars(&storage, expected);
   6349 }
   6350 END_TEST
   6351 
   6352 /* Test big-endian UTF-16 given an explicit little-endian encoding */
   6353 START_TEST(test_ext_entity_utf16_le)
   6354 {
   6355     const char *text =
   6356         "<!DOCTYPE doc [\n"
   6357         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   6358         "]>\n"
   6359         "<doc>&en;</doc>";
   6360     ExtTest2 test_data = {
   6361         "\0<\0e\0/\0>",
   6362         8,
   6363         XCS("utf-16le"),
   6364         NULL,
   6365         EE_PARSE_NONE
   6366     };
   6367 #ifdef XML_UNICODE
   6368     const XML_Char *expected = XCS("\x3c00\x6500\x2f00\x3e00");
   6369 #else
   6370     const XML_Char *expected =
   6371         XCS("\xe3\xb0\x80"   /* U+3C00 */
   6372             "\xe6\x94\x80"   /* U+6500 */
   6373             "\xe2\xbc\x80"   /* U+2F00 */
   6374             "\xe3\xb8\x80"); /* U+3E00 */
   6375 #endif
   6376     CharData storage;
   6377 
   6378     CharData_Init(&storage);
   6379     test_data.storage = &storage;
   6380     XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
   6381     XML_SetUserData(parser, &test_data);
   6382     XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
   6383     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   6384                                 XML_TRUE) == XML_STATUS_ERROR)
   6385         xml_failure(parser);
   6386     CharData_CheckXMLChars(&storage, expected);
   6387 }
   6388 END_TEST
   6389 
   6390 /* Test little-endian UTF-16 given no explicit encoding.
   6391  * The existing default encoding (UTF-8) is assumed to hold without a
   6392  * BOM to contradict it, so the entity value will in fact provoke an
   6393  * error because 0x00 is not a valid XML character.  We parse the
   6394  * whole buffer in one go rather than feeding it in byte by byte to
   6395  * exercise different code paths in the initial scanning routines.
   6396  */
   6397 typedef struct ExtFaults2 {
   6398     const char *parse_text;
   6399     int parse_len;
   6400     const char *fail_text;
   6401     const XML_Char *encoding;
   6402     enum XML_Error error;
   6403 } ExtFaults2;
   6404 
   6405 static int XMLCALL
   6406 external_entity_faulter2(XML_Parser parser,
   6407                          const XML_Char *context,
   6408                          const XML_Char *UNUSED_P(base),
   6409                          const XML_Char *UNUSED_P(systemId),
   6410                          const XML_Char *UNUSED_P(publicId))
   6411 {
   6412     ExtFaults2 *test_data = (ExtFaults2 *)XML_GetUserData(parser);
   6413     XML_Parser extparser;
   6414 
   6415     extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
   6416     if (extparser == NULL)
   6417         fail("Could not create external entity parser");
   6418     if (test_data->encoding != NULL) {
   6419         if (!XML_SetEncoding(extparser, test_data->encoding))
   6420             fail("XML_SetEncoding() ignored for external entity");
   6421     }
   6422     if (XML_Parse(extparser,
   6423                   test_data->parse_text,
   6424                   test_data->parse_len,
   6425                   XML_TRUE) != XML_STATUS_ERROR)
   6426         fail(test_data->fail_text);
   6427     if (XML_GetErrorCode(extparser) != test_data->error)
   6428         xml_failure(extparser);
   6429 
   6430     XML_ParserFree(extparser);
   6431     return XML_STATUS_ERROR;
   6432 }
   6433 
   6434 START_TEST(test_ext_entity_utf16_unknown)
   6435 {
   6436     const char *text =
   6437         "<!DOCTYPE doc [\n"
   6438         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   6439         "]>\n"
   6440         "<doc>&en;</doc>";
   6441     ExtFaults2 test_data = {
   6442         "a\0b\0c\0",
   6443         6,
   6444         "Invalid character in entity not faulted",
   6445         NULL,
   6446         XML_ERROR_INVALID_TOKEN
   6447     };
   6448 
   6449     XML_SetExternalEntityRefHandler(parser, external_entity_faulter2);
   6450     XML_SetUserData(parser, &test_data);
   6451     expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   6452                    "Invalid character should not have been accepted");
   6453 }
   6454 END_TEST
   6455 
   6456 /* Test not-quite-UTF-8 BOM (0xEF 0xBB 0xBF) */
   6457 START_TEST(test_ext_entity_utf8_non_bom)
   6458 {
   6459     const char *text =
   6460         "<!DOCTYPE doc [\n"
   6461         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   6462         "]>\n"
   6463         "<doc>&en;</doc>";
   6464     ExtTest2 test_data = {
   6465         "\xef\xbb\x80", /* Arabic letter DAD medial form, U+FEC0 */
   6466         3,
   6467         NULL,
   6468         NULL,
   6469         EE_PARSE_NONE
   6470     };
   6471 #ifdef XML_UNICODE
   6472     const XML_Char *expected = XCS("\xfec0");
   6473 #else
   6474     const XML_Char *expected = XCS("\xef\xbb\x80");
   6475 #endif
   6476     CharData storage;
   6477 
   6478     CharData_Init(&storage);
   6479     test_data.storage = &storage;
   6480     XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
   6481     XML_SetUserData(parser, &test_data);
   6482     XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
   6483     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   6484                                 XML_TRUE) == XML_STATUS_ERROR)
   6485         xml_failure(parser);
   6486     CharData_CheckXMLChars(&storage, expected);
   6487 }
   6488 END_TEST
   6489 
   6490 /* Test that UTF-8 in a CDATA section is correctly passed through */
   6491 START_TEST(test_utf8_in_cdata_section)
   6492 {
   6493     const char *text = "<doc><![CDATA[one \xc3\xa9 two]]></doc>";
   6494 #ifdef XML_UNICODE
   6495     const XML_Char *expected = XCS("one \x00e9 two");
   6496 #else
   6497     const XML_Char *expected = XCS("one \xc3\xa9 two");
   6498 #endif
   6499 
   6500     run_character_check(text, expected);
   6501 }
   6502 END_TEST
   6503 
   6504 /* Test that little-endian UTF-16 in a CDATA section is handled */
   6505 START_TEST(test_utf8_in_cdata_section_2)
   6506 {
   6507     const char *text = "<doc><![CDATA[\xc3\xa9]\xc3\xa9two]]></doc>";
   6508 #ifdef XML_UNICODE
   6509     const XML_Char *expected = XCS("\x00e9]\x00e9two");
   6510 #else
   6511     const XML_Char *expected = XCS("\xc3\xa9]\xc3\xa9two");
   6512 #endif
   6513 
   6514     run_character_check(text, expected);
   6515 }
   6516 END_TEST
   6517 
   6518 /* Test trailing spaces in elements are accepted */
   6519 static void XMLCALL
   6520 record_element_end_handler(void *userData,
   6521                            const XML_Char *name)
   6522 {
   6523     CharData *storage = (CharData *)userData;
   6524 
   6525     CharData_AppendXMLChars(storage, XCS("/"), 1);
   6526     CharData_AppendXMLChars(storage, name, -1);
   6527 }
   6528 
   6529 START_TEST(test_trailing_spaces_in_elements)
   6530 {
   6531     const char *text = "<doc   >Hi</doc >";
   6532     const XML_Char *expected = XCS("doc/doc");
   6533     CharData storage;
   6534 
   6535     CharData_Init(&storage);
   6536     XML_SetElementHandler(parser, record_element_start_handler,
   6537                           record_element_end_handler);
   6538     XML_SetUserData(parser, &storage);
   6539     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   6540                                 XML_TRUE) == XML_STATUS_ERROR)
   6541         xml_failure(parser);
   6542     CharData_CheckXMLChars(&storage, expected);
   6543 }
   6544 END_TEST
   6545 
   6546 START_TEST(test_utf16_attribute)
   6547 {
   6548     const char text[] =
   6549         /* <d {KHO KHWAI}{CHO CHAN}='a'/>
   6550          * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
   6551          * and   {CHO CHAN}  = U+0E08 = 0xe0 0xb8 0x88 in UTF-8
   6552          */
   6553         "<\0d\0 \0\x04\x0e\x08\x0e=\0'\0a\0'\0/\0>\0";
   6554     const XML_Char *expected = XCS("a");
   6555     CharData storage;
   6556 
   6557     CharData_Init(&storage);
   6558     XML_SetStartElementHandler(parser, accumulate_attribute);
   6559     XML_SetUserData(parser, &storage);
   6560     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   6561                                 XML_TRUE) == XML_STATUS_ERROR)
   6562         xml_failure(parser);
   6563     CharData_CheckXMLChars(&storage, expected);
   6564 }
   6565 END_TEST
   6566 
   6567 START_TEST(test_utf16_second_attr)
   6568 {
   6569     /* <d a='1' {KHO KHWAI}{CHO CHAN}='2'/>
   6570          * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
   6571          * and   {CHO CHAN}  = U+0E08 = 0xe0 0xb8 0x88 in UTF-8
   6572          */
   6573     const char text[] =
   6574         "<\0d\0 \0a\0=\0'\0\x31\0'\0 \0"
   6575         "\x04\x0e\x08\x0e=\0'\0\x32\0'\0/\0>\0";
   6576     const XML_Char *expected = XCS("1");
   6577     CharData storage;
   6578 
   6579     CharData_Init(&storage);
   6580     XML_SetStartElementHandler(parser, accumulate_attribute);
   6581     XML_SetUserData(parser, &storage);
   6582     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   6583                                 XML_TRUE) == XML_STATUS_ERROR)
   6584         xml_failure(parser);
   6585     CharData_CheckXMLChars(&storage, expected);
   6586 }
   6587 END_TEST
   6588 
   6589 START_TEST(test_attr_after_solidus)
   6590 {
   6591     const char *text = "<doc attr1='a' / attr2='b'>";
   6592 
   6593     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   6594                    "Misplaced / not faulted");
   6595 }
   6596 END_TEST
   6597 
   6598 static void XMLCALL
   6599 accumulate_entity_decl(void *userData,
   6600                        const XML_Char *entityName,
   6601                        int UNUSED_P(is_parameter_entity),
   6602                        const XML_Char *value,
   6603                        int value_length,
   6604                        const XML_Char *UNUSED_P(base),
   6605                        const XML_Char *UNUSED_P(systemId),
   6606                        const XML_Char *UNUSED_P(publicId),
   6607                        const XML_Char *UNUSED_P(notationName))
   6608 {
   6609     CharData *storage = (CharData *)userData;
   6610 
   6611     CharData_AppendXMLChars(storage, entityName, -1);
   6612     CharData_AppendXMLChars(storage, XCS("="), 1);
   6613     CharData_AppendXMLChars(storage, value, value_length);
   6614     CharData_AppendXMLChars(storage, XCS("\n"), 1);
   6615 }
   6616 
   6617 
   6618 START_TEST(test_utf16_pe)
   6619 {
   6620     /* <!DOCTYPE doc [
   6621      * <!ENTITY % {KHO KHWAI}{CHO CHAN} '<!ELEMENT doc (#PCDATA)>'>
   6622      * %{KHO KHWAI}{CHO CHAN};
   6623      * ]>
   6624      * <doc></doc>
   6625      *
   6626      * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
   6627      * and   {CHO CHAN}  = U+0E08 = 0xe0 0xb8 0x88 in UTF-8
   6628      */
   6629     const char text[] =
   6630         "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0o\0c\0 \0[\0\n"
   6631         "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0%\0 \x0e\x04\x0e\x08\0 "
   6632         "\0'\0<\0!\0E\0L\0E\0M\0E\0N\0T\0 "
   6633         "\0d\0o\0c\0 \0(\0#\0P\0C\0D\0A\0T\0A\0)\0>\0'\0>\0\n"
   6634         "\0%\x0e\x04\x0e\x08\0;\0\n"
   6635         "\0]\0>\0\n"
   6636         "\0<\0d\0o\0c\0>\0<\0/\0d\0o\0c\0>";
   6637 #ifdef XML_UNICODE
   6638     const XML_Char *expected =
   6639         XCS("\x0e04\x0e08=<!ELEMENT doc (#PCDATA)>\n");
   6640 #else
   6641     const XML_Char *expected =
   6642         XCS("\xe0\xb8\x84\xe0\xb8\x88=<!ELEMENT doc (#PCDATA)>\n");
   6643 #endif
   6644     CharData storage;
   6645 
   6646     CharData_Init(&storage);
   6647     XML_SetUserData(parser, &storage);
   6648     XML_SetEntityDeclHandler(parser, accumulate_entity_decl);
   6649     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   6650                                 XML_TRUE) == XML_STATUS_ERROR)
   6651         xml_failure(parser);
   6652     CharData_CheckXMLChars(&storage, expected);
   6653 }
   6654 END_TEST
   6655 
   6656 /* Test that duff attribute description keywords are rejected */
   6657 START_TEST(test_bad_attr_desc_keyword)
   6658 {
   6659     const char *text =
   6660         "<!DOCTYPE doc [\n"
   6661         "  <!ATTLIST doc attr CDATA #!IMPLIED>\n"
   6662         "]>\n"
   6663         "<doc />";
   6664 
   6665     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   6666                    "Bad keyword !IMPLIED not faulted");
   6667 }
   6668 END_TEST
   6669 
   6670 /* Test that an invalid attribute description keyword consisting of
   6671  * UTF-16 characters with their top bytes non-zero are correctly
   6672  * faulted
   6673  */
   6674 START_TEST(test_bad_attr_desc_keyword_utf16)
   6675 {
   6676     /* <!DOCTYPE d [
   6677      * <!ATTLIST d a CDATA #{KHO KHWAI}{CHO CHAN}>
   6678      * ]><d/>
   6679      *
   6680      * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
   6681      * and   {CHO CHAN}  = U+0E08 = 0xe0 0xb8 0x88 in UTF-8
   6682      */
   6683     const char text[] =
   6684         "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n"
   6685         "\0<\0!\0A\0T\0T\0L\0I\0S\0T\0 \0d\0 \0a\0 \0C\0D\0A\0T\0A\0 "
   6686         "\0#\x0e\x04\x0e\x08\0>\0\n"
   6687         "\0]\0>\0<\0d\0/\0>";
   6688 
   6689     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   6690                                 XML_TRUE) != XML_STATUS_ERROR)
   6691         fail("Invalid UTF16 attribute keyword not faulted");
   6692     if (XML_GetErrorCode(parser) != XML_ERROR_SYNTAX)
   6693         xml_failure(parser);
   6694 }
   6695 END_TEST
   6696 
   6697 /* Test that invalid syntax in a <!DOCTYPE> is rejected.  Do this
   6698  * using prefix-encoding (see above) to trigger specific code paths
   6699  */
   6700 START_TEST(test_bad_doctype)
   6701 {
   6702     const char *text =
   6703         "<?xml version='1.0' encoding='prefix-conv'?>\n"
   6704         "<!DOCTYPE doc [ \x80\x44 ]><doc/>";
   6705 
   6706     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6707     expect_failure(text, XML_ERROR_SYNTAX,
   6708                    "Invalid bytes in DOCTYPE not faulted");
   6709 }
   6710 END_TEST
   6711 
   6712 START_TEST(test_bad_doctype_utf16)
   6713 {
   6714     const char text[] =
   6715         /* <!DOCTYPE doc [ \x06f2 ]><doc/>
   6716          *
   6717          * U+06F2 = EXTENDED ARABIC-INDIC DIGIT TWO, a valid number
   6718          * (name character) but not a valid letter (name start character)
   6719          */
   6720         "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0o\0c\0 \0[\0 "
   6721         "\x06\xf2"
   6722         "\0 \0]\0>\0<\0d\0o\0c\0/\0>";
   6723 
   6724     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   6725                                 XML_TRUE) != XML_STATUS_ERROR)
   6726         fail("Invalid bytes in DOCTYPE not faulted");
   6727     if (XML_GetErrorCode(parser) != XML_ERROR_SYNTAX)
   6728         xml_failure(parser);
   6729 }
   6730 END_TEST
   6731 
   6732 START_TEST(test_bad_doctype_plus)
   6733 {
   6734     const char *text =
   6735         "<!DOCTYPE 1+ [ <!ENTITY foo 'bar'> ]>\n"
   6736         "<1+>&foo;</1+>";
   6737 
   6738     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   6739                    "'+' in document name not faulted");
   6740 }
   6741 END_TEST
   6742 
   6743 START_TEST(test_bad_doctype_star)
   6744 {
   6745     const char *text =
   6746         "<!DOCTYPE 1* [ <!ENTITY foo 'bar'> ]>\n"
   6747         "<1*>&foo;</1*>";
   6748 
   6749     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   6750                    "'*' in document name not faulted");
   6751 }
   6752 END_TEST
   6753 
   6754 START_TEST(test_bad_doctype_query)
   6755 {
   6756     const char *text =
   6757         "<!DOCTYPE 1? [ <!ENTITY foo 'bar'> ]>\n"
   6758         "<1?>&foo;</1?>";
   6759 
   6760     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   6761                    "'?' in document name not faulted");
   6762 }
   6763 END_TEST
   6764 
   6765 START_TEST(test_unknown_encoding_bad_ignore)
   6766 {
   6767     const char *text =
   6768         "<?xml version='1.0' encoding='prefix-conv'?>"
   6769         "<!DOCTYPE doc SYSTEM 'foo'>"
   6770         "<doc><e>&entity;</e></doc>";
   6771     ExtFaults fault = {
   6772         "<![IGNORE[<!ELEMENT \xffG (#PCDATA)*>]]>",
   6773         "Invalid character not faulted",
   6774         XCS("prefix-conv"),
   6775         XML_ERROR_INVALID_TOKEN
   6776     };
   6777 
   6778     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   6779     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   6780     XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
   6781     XML_SetUserData(parser, &fault);
   6782     expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   6783                    "Bad IGNORE section with unknown encoding not failed");
   6784 }
   6785 END_TEST
   6786 
   6787 START_TEST(test_entity_in_utf16_be_attr)
   6788 {
   6789     const char text[] =
   6790         /* <e a='&#228; &#x00E4;'></e> */
   6791         "\0<\0e\0 \0a\0=\0'\0&\0#\0\x32\0\x32\0\x38\0;\0 "
   6792         "\0&\0#\0x\0\x30\0\x30\0E\0\x34\0;\0'\0>\0<\0/\0e\0>";
   6793 #ifdef XML_UNICODE
   6794     const XML_Char *expected = XCS("\x00e4 \x00e4");
   6795 #else
   6796     const XML_Char *expected = XCS("\xc3\xa4 \xc3\xa4");
   6797 #endif
   6798     CharData storage;
   6799 
   6800     CharData_Init(&storage);
   6801     XML_SetUserData(parser, &storage);
   6802     XML_SetStartElementHandler(parser, accumulate_attribute);
   6803     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   6804                                 XML_TRUE) == XML_STATUS_ERROR)
   6805         xml_failure(parser);
   6806     CharData_CheckXMLChars(&storage, expected);
   6807 }
   6808 END_TEST
   6809 
   6810 START_TEST(test_entity_in_utf16_le_attr)
   6811 {
   6812     const char text[] =
   6813         /* <e a='&#228; &#x00E4;'></e> */
   6814         "<\0e\0 \0a\0=\0'\0&\0#\0\x32\0\x32\0\x38\0;\0 \0"
   6815         "&\0#\0x\0\x30\0\x30\0E\0\x34\0;\0'\0>\0<\0/\0e\0>\0";
   6816 #ifdef XML_UNICODE
   6817     const XML_Char *expected = XCS("\x00e4 \x00e4");
   6818 #else
   6819     const XML_Char *expected = XCS("\xc3\xa4 \xc3\xa4");
   6820 #endif
   6821     CharData storage;
   6822 
   6823     CharData_Init(&storage);
   6824     XML_SetUserData(parser, &storage);
   6825     XML_SetStartElementHandler(parser, accumulate_attribute);
   6826     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   6827                                 XML_TRUE) == XML_STATUS_ERROR)
   6828         xml_failure(parser);
   6829     CharData_CheckXMLChars(&storage, expected);
   6830 }
   6831 END_TEST
   6832 
   6833 START_TEST(test_entity_public_utf16_be)
   6834 {
   6835     const char text[] =
   6836         /* <!DOCTYPE d [ */
   6837         "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n"
   6838         /* <!ENTITY % e PUBLIC 'foo' 'bar.ent'> */
   6839         "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0%\0 \0e\0 \0P\0U\0B\0L\0I\0C\0 "
   6840         "\0'\0f\0o\0o\0'\0 \0'\0b\0a\0r\0.\0e\0n\0t\0'\0>\0\n"
   6841         /* %e; */
   6842         "\0%\0e\0;\0\n"
   6843         /* ]> */
   6844         "\0]\0>\0\n"
   6845         /* <d>&j;</d> */
   6846         "\0<\0d\0>\0&\0j\0;\0<\0/\0d\0>";
   6847     ExtTest2 test_data = {
   6848         /* <!ENTITY j 'baz'> */
   6849         "\0<\0!\0E\0N\0T\0I\0T\0Y\0 \0j\0 \0'\0b\0a\0z\0'\0>",
   6850         34,
   6851         NULL,
   6852         NULL,
   6853         EE_PARSE_NONE
   6854     };
   6855     const XML_Char *expected = XCS("baz");
   6856     CharData storage;
   6857 
   6858     CharData_Init(&storage);
   6859     test_data.storage = &storage;
   6860     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   6861     XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
   6862     XML_SetUserData(parser, &test_data);
   6863     XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
   6864     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   6865                                 XML_TRUE) == XML_STATUS_ERROR)
   6866         xml_failure(parser);
   6867     CharData_CheckXMLChars(&storage, expected);
   6868 }
   6869 END_TEST
   6870 
   6871 START_TEST(test_entity_public_utf16_le)
   6872 {
   6873     const char text[] =
   6874         /* <!DOCTYPE d [ */
   6875         "<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0d\0 \0[\0\n\0"
   6876         /* <!ENTITY % e PUBLIC 'foo' 'bar.ent'> */
   6877         "<\0!\0E\0N\0T\0I\0T\0Y\0 \0%\0 \0e\0 \0P\0U\0B\0L\0I\0C\0 \0"
   6878         "'\0f\0o\0o\0'\0 \0'\0b\0a\0r\0.\0e\0n\0t\0'\0>\0\n\0"
   6879         /* %e; */
   6880         "%\0e\0;\0\n\0"
   6881         /* ]> */
   6882         "]\0>\0\n\0"
   6883         /* <d>&j;</d> */
   6884         "<\0d\0>\0&\0j\0;\0<\0/\0d\0>\0";
   6885     ExtTest2 test_data = {
   6886         /* <!ENTITY j 'baz'> */
   6887         "<\0!\0E\0N\0T\0I\0T\0Y\0 \0j\0 \0'\0b\0a\0z\0'\0>\0",
   6888         34,
   6889         NULL,
   6890         NULL,
   6891         EE_PARSE_NONE
   6892     };
   6893     const XML_Char *expected = XCS("baz");
   6894     CharData storage;
   6895 
   6896     CharData_Init(&storage);
   6897     test_data.storage = &storage;
   6898     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   6899     XML_SetExternalEntityRefHandler(parser, external_entity_loader2);
   6900     XML_SetUserData(parser, &test_data);
   6901     XML_SetCharacterDataHandler(parser, ext2_accumulate_characters);
   6902     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   6903                                 XML_TRUE) == XML_STATUS_ERROR)
   6904         xml_failure(parser);
   6905     CharData_CheckXMLChars(&storage, expected);
   6906 }
   6907 END_TEST
   6908 
   6909 /* Test that a doctype with neither an internal nor external subset is
   6910  * faulted
   6911  */
   6912 START_TEST(test_short_doctype)
   6913 {
   6914     const char *text = "<!DOCTYPE doc></doc>";
   6915     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   6916                    "DOCTYPE without subset not rejected");
   6917 }
   6918 END_TEST
   6919 
   6920 START_TEST(test_short_doctype_2)
   6921 {
   6922     const char *text = "<!DOCTYPE doc PUBLIC></doc>";
   6923     expect_failure(text, XML_ERROR_SYNTAX,
   6924                    "DOCTYPE without Public ID not rejected");
   6925 }
   6926 END_TEST
   6927 
   6928 START_TEST(test_short_doctype_3)
   6929 {
   6930     const char *text = "<!DOCTYPE doc SYSTEM></doc>";
   6931     expect_failure(text, XML_ERROR_SYNTAX,
   6932                    "DOCTYPE without System ID not rejected");
   6933 }
   6934 END_TEST
   6935 
   6936 START_TEST(test_long_doctype)
   6937 {
   6938     const char *text = "<!DOCTYPE doc PUBLIC 'foo' 'bar' 'baz'></doc>";
   6939     expect_failure(text, XML_ERROR_SYNTAX,
   6940                    "DOCTYPE with extra ID not rejected");
   6941 }
   6942 END_TEST
   6943 
   6944 START_TEST(test_bad_entity)
   6945 {
   6946     const char *text =
   6947         "<!DOCTYPE doc [\n"
   6948         "  <!ENTITY foo PUBLIC>\n"
   6949         "]>\n"
   6950         "<doc/>";
   6951     expect_failure(text, XML_ERROR_SYNTAX,
   6952                    "ENTITY without Public ID is not rejected");
   6953 }
   6954 END_TEST
   6955 
   6956 /* Test unquoted value is faulted */
   6957 START_TEST(test_bad_entity_2)
   6958 {
   6959     const char *text =
   6960         "<!DOCTYPE doc [\n"
   6961         "  <!ENTITY % foo bar>\n"
   6962         "]>\n"
   6963         "<doc/>";
   6964     expect_failure(text, XML_ERROR_SYNTAX,
   6965                    "ENTITY without Public ID is not rejected");
   6966 }
   6967 END_TEST
   6968 
   6969 START_TEST(test_bad_entity_3)
   6970 {
   6971     const char *text =
   6972         "<!DOCTYPE doc [\n"
   6973         "  <!ENTITY % foo PUBLIC>\n"
   6974         "]>\n"
   6975         "<doc/>";
   6976     expect_failure(text, XML_ERROR_SYNTAX,
   6977                    "Parameter ENTITY without Public ID is not rejected");
   6978 }
   6979 END_TEST
   6980 
   6981 START_TEST(test_bad_entity_4)
   6982 {
   6983     const char *text =
   6984         "<!DOCTYPE doc [\n"
   6985         "  <!ENTITY % foo SYSTEM>\n"
   6986         "]>\n"
   6987         "<doc/>";
   6988     expect_failure(text, XML_ERROR_SYNTAX,
   6989                    "Parameter ENTITY without Public ID is not rejected");
   6990 }
   6991 END_TEST
   6992 
   6993 START_TEST(test_bad_notation)
   6994 {
   6995     const char *text =
   6996         "<!DOCTYPE doc [\n"
   6997         "  <!NOTATION n SYSTEM>\n"
   6998         "]>\n"
   6999         "<doc/>";
   7000     expect_failure(text, XML_ERROR_SYNTAX,
   7001                    "Notation without System ID is not rejected");
   7002 }
   7003 END_TEST
   7004 
   7005 /* Test for issue #11, wrongly suppressed default handler */
   7006 typedef struct default_check {
   7007     const XML_Char *expected;
   7008     const int expectedLen;
   7009     XML_Bool seen;
   7010 } DefaultCheck;
   7011 
   7012 static void XMLCALL
   7013 checking_default_handler(void *userData,
   7014                          const XML_Char *s,
   7015                          int len)
   7016 {
   7017     DefaultCheck *data = (DefaultCheck *)userData;
   7018     int i;
   7019 
   7020     for (i = 0; data[i].expected != NULL; i++) {
   7021         if (data[i].expectedLen == len &&
   7022             !memcmp(data[i].expected, s, len * sizeof(XML_Char))) {
   7023             data[i].seen = XML_TRUE;
   7024             break;
   7025         }
   7026     }
   7027 }
   7028 
   7029 START_TEST(test_default_doctype_handler)
   7030 {
   7031     const char *text =
   7032         "<!DOCTYPE doc PUBLIC 'pubname' 'test.dtd' [\n"
   7033         "  <!ENTITY foo 'bar'>\n"
   7034         "]>\n"
   7035         "<doc>&foo;</doc>";
   7036     DefaultCheck test_data[] = {
   7037         {
   7038             XCS("'pubname'"),
   7039             9,
   7040             XML_FALSE
   7041         },
   7042         {
   7043             XCS("'test.dtd'"),
   7044             10,
   7045             XML_FALSE
   7046         },
   7047         { NULL, 0, XML_FALSE }
   7048     };
   7049     int i;
   7050 
   7051     XML_SetUserData(parser, &test_data);
   7052     XML_SetDefaultHandler(parser, checking_default_handler);
   7053     XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
   7054     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   7055                                 XML_TRUE) == XML_STATUS_ERROR)
   7056         xml_failure(parser);
   7057     for (i = 0; test_data[i].expected != NULL; i++)
   7058         if (!test_data[i].seen)
   7059             fail("Default handler not run for public !DOCTYPE");
   7060 }
   7061 END_TEST
   7062 
   7063 START_TEST(test_empty_element_abort)
   7064 {
   7065     const char *text = "<abort/>";
   7066 
   7067     XML_SetStartElementHandler(parser, start_element_suspender);
   7068     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   7069                                 XML_TRUE) != XML_STATUS_ERROR)
   7070         fail("Expected to error on abort");
   7071 }
   7072 END_TEST
   7073 
   7074 /*
   7075  * Namespaces tests.
   7076  */
   7077 
   7078 static void
   7079 namespace_setup(void)
   7080 {
   7081     parser = XML_ParserCreateNS(NULL, XCS(' '));
   7082     if (parser == NULL)
   7083         fail("Parser not created.");
   7084 }
   7085 
   7086 static void
   7087 namespace_teardown(void)
   7088 {
   7089     basic_teardown();
   7090 }
   7091 
   7092 /* Check that an element name and attribute name match the expected values.
   7093    The expected values are passed as an array reference of string pointers
   7094    provided as the userData argument; the first is the expected
   7095    element name, and the second is the expected attribute name.
   7096 */
   7097 static int triplet_start_flag = XML_FALSE;
   7098 static int triplet_end_flag = XML_FALSE;
   7099 
   7100 static void XMLCALL
   7101 triplet_start_checker(void *userData, const XML_Char *name,
   7102                       const XML_Char **atts)
   7103 {
   7104     XML_Char **elemstr = (XML_Char **)userData;
   7105     char buffer[1024];
   7106     if (xcstrcmp(elemstr[0], name) != 0) {
   7107         sprintf(buffer, "unexpected start string: '%" XML_FMT_STR "'", name);
   7108         fail(buffer);
   7109     }
   7110     if (xcstrcmp(elemstr[1], atts[0]) != 0) {
   7111         sprintf(buffer, "unexpected attribute string: '%" XML_FMT_STR "'",
   7112                 atts[0]);
   7113         fail(buffer);
   7114     }
   7115     triplet_start_flag = XML_TRUE;
   7116 }
   7117 
   7118 /* Check that the element name passed to the end-element handler matches
   7119    the expected value.  The expected value is passed as the first element
   7120    in an array of strings passed as the userData argument.
   7121 */
   7122 static void XMLCALL
   7123 triplet_end_checker(void *userData, const XML_Char *name)
   7124 {
   7125     XML_Char **elemstr = (XML_Char **)userData;
   7126     if (xcstrcmp(elemstr[0], name) != 0) {
   7127         char buffer[1024];
   7128         sprintf(buffer, "unexpected end string: '%" XML_FMT_STR "'", name);
   7129         fail(buffer);
   7130     }
   7131     triplet_end_flag = XML_TRUE;
   7132 }
   7133 
   7134 START_TEST(test_return_ns_triplet)
   7135 {
   7136     const char *text =
   7137         "<foo:e xmlns:foo='http://example.org/' bar:a='12'\n"
   7138         "       xmlns:bar='http://example.org/'>";
   7139     const char *epilog = "</foo:e>";
   7140     const XML_Char *elemstr[] = {
   7141         XCS("http://example.org/ e foo"),
   7142         XCS("http://example.org/ a bar")
   7143     };
   7144     XML_SetReturnNSTriplet(parser, XML_TRUE);
   7145     XML_SetUserData(parser, elemstr);
   7146     XML_SetElementHandler(parser, triplet_start_checker,
   7147                           triplet_end_checker);
   7148     XML_SetNamespaceDeclHandler(parser,
   7149                                 dummy_start_namespace_decl_handler,
   7150                                 dummy_end_namespace_decl_handler);
   7151     triplet_start_flag = XML_FALSE;
   7152     triplet_end_flag = XML_FALSE;
   7153     dummy_handler_flags = 0;
   7154     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   7155                                 XML_FALSE) == XML_STATUS_ERROR)
   7156         xml_failure(parser);
   7157     if (!triplet_start_flag)
   7158         fail("triplet_start_checker not invoked");
   7159     /* Check that unsetting "return triplets" fails while still parsing */
   7160     XML_SetReturnNSTriplet(parser, XML_FALSE);
   7161     if (_XML_Parse_SINGLE_BYTES(parser, epilog, strlen(epilog),
   7162                                 XML_TRUE) == XML_STATUS_ERROR)
   7163         xml_failure(parser);
   7164     if (!triplet_end_flag)
   7165         fail("triplet_end_checker not invoked");
   7166     if (dummy_handler_flags != (DUMMY_START_NS_DECL_HANDLER_FLAG |
   7167                                 DUMMY_END_NS_DECL_HANDLER_FLAG))
   7168         fail("Namespace handlers not called");
   7169 }
   7170 END_TEST
   7171 
   7172 static void XMLCALL
   7173 overwrite_start_checker(void *userData, const XML_Char *name,
   7174                         const XML_Char **atts)
   7175 {
   7176     CharData *storage = (CharData *) userData;
   7177     CharData_AppendXMLChars(storage, XCS("start "), 6);
   7178     CharData_AppendXMLChars(storage, name, -1);
   7179     while (*atts != NULL) {
   7180         CharData_AppendXMLChars(storage, XCS("\nattribute "), 11);
   7181         CharData_AppendXMLChars(storage, *atts, -1);
   7182         atts += 2;
   7183     }
   7184     CharData_AppendXMLChars(storage, XCS("\n"), 1);
   7185 }
   7186 
   7187 static void XMLCALL
   7188 overwrite_end_checker(void *userData, const XML_Char *name)
   7189 {
   7190     CharData *storage = (CharData *) userData;
   7191     CharData_AppendXMLChars(storage, XCS("end "), 4);
   7192     CharData_AppendXMLChars(storage, name, -1);
   7193     CharData_AppendXMLChars(storage, XCS("\n"), 1);
   7194 }
   7195 
   7196 static void
   7197 run_ns_tagname_overwrite_test(const char *text, const XML_Char *result)
   7198 {
   7199     CharData storage;
   7200     CharData_Init(&storage);
   7201     XML_SetUserData(parser, &storage);
   7202     XML_SetElementHandler(parser,
   7203                           overwrite_start_checker, overwrite_end_checker);
   7204     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   7205         xml_failure(parser);
   7206     CharData_CheckXMLChars(&storage, result);
   7207 }
   7208 
   7209 /* Regression test for SF bug #566334. */
   7210 START_TEST(test_ns_tagname_overwrite)
   7211 {
   7212     const char *text =
   7213         "<n:e xmlns:n='http://example.org/'>\n"
   7214         "  <n:f n:attr='foo'/>\n"
   7215         "  <n:g n:attr2='bar'/>\n"
   7216         "</n:e>";
   7217     const XML_Char *result =
   7218         XCS("start http://example.org/ e\n")
   7219         XCS("start http://example.org/ f\n")
   7220         XCS("attribute http://example.org/ attr\n")
   7221         XCS("end http://example.org/ f\n")
   7222         XCS("start http://example.org/ g\n")
   7223         XCS("attribute http://example.org/ attr2\n")
   7224         XCS("end http://example.org/ g\n")
   7225         XCS("end http://example.org/ e\n");
   7226     run_ns_tagname_overwrite_test(text, result);
   7227 }
   7228 END_TEST
   7229 
   7230 /* Regression test for SF bug #566334. */
   7231 START_TEST(test_ns_tagname_overwrite_triplet)
   7232 {
   7233     const char *text =
   7234         "<n:e xmlns:n='http://example.org/'>\n"
   7235         "  <n:f n:attr='foo'/>\n"
   7236         "  <n:g n:attr2='bar'/>\n"
   7237         "</n:e>";
   7238     const XML_Char *result =
   7239         XCS("start http://example.org/ e n\n")
   7240         XCS("start http://example.org/ f n\n")
   7241         XCS("attribute http://example.org/ attr n\n")
   7242         XCS("end http://example.org/ f n\n")
   7243         XCS("start http://example.org/ g n\n")
   7244         XCS("attribute http://example.org/ attr2 n\n")
   7245         XCS("end http://example.org/ g n\n")
   7246         XCS("end http://example.org/ e n\n");
   7247     XML_SetReturnNSTriplet(parser, XML_TRUE);
   7248     run_ns_tagname_overwrite_test(text, result);
   7249 }
   7250 END_TEST
   7251 
   7252 
   7253 /* Regression test for SF bug #620343. */
   7254 static void XMLCALL
   7255 start_element_fail(void *UNUSED_P(userData),
   7256                    const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
   7257 {
   7258     /* We should never get here. */
   7259     fail("should never reach start_element_fail()");
   7260 }
   7261 
   7262 static void XMLCALL
   7263 start_ns_clearing_start_element(void *userData,
   7264                                 const XML_Char *UNUSED_P(prefix),
   7265                                 const XML_Char *UNUSED_P(uri))
   7266 {
   7267     XML_SetStartElementHandler((XML_Parser) userData, NULL);
   7268 }
   7269 
   7270 START_TEST(test_start_ns_clears_start_element)
   7271 {
   7272     /* This needs to use separate start/end tags; using the empty tag
   7273        syntax doesn't cause the problematic path through Expat to be
   7274        taken.
   7275     */
   7276     const char *text = "<e xmlns='http://example.org/'></e>";
   7277 
   7278     XML_SetStartElementHandler(parser, start_element_fail);
   7279     XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element);
   7280     XML_SetEndNamespaceDeclHandler(parser, dummy_end_namespace_decl_handler);
   7281     XML_UseParserAsHandlerArg(parser);
   7282     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   7283         xml_failure(parser);
   7284 }
   7285 END_TEST
   7286 
   7287 /* Regression test for SF bug #616863. */
   7288 static int XMLCALL
   7289 external_entity_handler(XML_Parser parser,
   7290                         const XML_Char *context,
   7291                         const XML_Char *UNUSED_P(base),
   7292                         const XML_Char *UNUSED_P(systemId),
   7293                         const XML_Char *UNUSED_P(publicId))
   7294 {
   7295     intptr_t callno = 1 + (intptr_t)XML_GetUserData(parser);
   7296     const char *text;
   7297     XML_Parser p2;
   7298 
   7299     if (callno == 1)
   7300         text = ("<!ELEMENT doc (e+)>\n"
   7301                 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
   7302                 "<!ELEMENT e EMPTY>\n");
   7303     else
   7304         text = ("<?xml version='1.0' encoding='us-ascii'?>"
   7305                 "<e/>");
   7306 
   7307     XML_SetUserData(parser, (void *) callno);
   7308     p2 = XML_ExternalEntityParserCreate(parser, context, NULL);
   7309     if (_XML_Parse_SINGLE_BYTES(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
   7310         xml_failure(p2);
   7311         return XML_STATUS_ERROR;
   7312     }
   7313     XML_ParserFree(p2);
   7314     return XML_STATUS_OK;
   7315 }
   7316 
   7317 START_TEST(test_default_ns_from_ext_subset_and_ext_ge)
   7318 {
   7319     const char *text =
   7320         "<?xml version='1.0'?>\n"
   7321         "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
   7322         "  <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
   7323         "]>\n"
   7324         "<doc xmlns='http://example.org/ns1'>\n"
   7325         "&en;\n"
   7326         "</doc>";
   7327 
   7328     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   7329     XML_SetExternalEntityRefHandler(parser, external_entity_handler);
   7330     /* We actually need to set this handler to tickle this bug. */
   7331     XML_SetStartElementHandler(parser, dummy_start_element);
   7332     XML_SetUserData(parser, NULL);
   7333     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   7334         xml_failure(parser);
   7335 }
   7336 END_TEST
   7337 
   7338 /* Regression test #1 for SF bug #673791. */
   7339 START_TEST(test_ns_prefix_with_empty_uri_1)
   7340 {
   7341     const char *text =
   7342         "<doc xmlns:prefix='http://example.org/'>\n"
   7343         "  <e xmlns:prefix=''/>\n"
   7344         "</doc>";
   7345 
   7346     expect_failure(text,
   7347                    XML_ERROR_UNDECLARING_PREFIX,
   7348                    "Did not report re-setting namespace"
   7349                    " URI with prefix to ''.");
   7350 }
   7351 END_TEST
   7352 
   7353 /* Regression test #2 for SF bug #673791. */
   7354 START_TEST(test_ns_prefix_with_empty_uri_2)
   7355 {
   7356     const char *text =
   7357         "<?xml version='1.0'?>\n"
   7358         "<docelem xmlns:pre=''/>";
   7359 
   7360     expect_failure(text,
   7361                    XML_ERROR_UNDECLARING_PREFIX,
   7362                    "Did not report setting namespace URI with prefix to ''.");
   7363 }
   7364 END_TEST
   7365 
   7366 /* Regression test #3 for SF bug #673791. */
   7367 START_TEST(test_ns_prefix_with_empty_uri_3)
   7368 {
   7369     const char *text =
   7370         "<!DOCTYPE doc [\n"
   7371         "  <!ELEMENT doc EMPTY>\n"
   7372         "  <!ATTLIST doc\n"
   7373         "    xmlns:prefix CDATA ''>\n"
   7374         "]>\n"
   7375         "<doc/>";
   7376 
   7377     expect_failure(text,
   7378                    XML_ERROR_UNDECLARING_PREFIX,
   7379                    "Didn't report attr default setting NS w/ prefix to ''.");
   7380 }
   7381 END_TEST
   7382 
   7383 /* Regression test #4 for SF bug #673791. */
   7384 START_TEST(test_ns_prefix_with_empty_uri_4)
   7385 {
   7386     const char *text =
   7387         "<!DOCTYPE doc [\n"
   7388         "  <!ELEMENT prefix:doc EMPTY>\n"
   7389         "  <!ATTLIST prefix:doc\n"
   7390         "    xmlns:prefix CDATA 'http://example.org/'>\n"
   7391         "]>\n"
   7392         "<prefix:doc/>";
   7393     /* Packaged info expected by the end element handler;
   7394        the weird structuring lets us re-use the triplet_end_checker()
   7395        function also used for another test. */
   7396     const XML_Char *elemstr[] = {
   7397         XCS("http://example.org/ doc prefix")
   7398     };
   7399     XML_SetReturnNSTriplet(parser, XML_TRUE);
   7400     XML_SetUserData(parser, elemstr);
   7401     XML_SetEndElementHandler(parser, triplet_end_checker);
   7402     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   7403         xml_failure(parser);
   7404 }
   7405 END_TEST
   7406 
   7407 /* Test with non-xmlns prefix */
   7408 START_TEST(test_ns_unbound_prefix)
   7409 {
   7410     const char *text =
   7411         "<!DOCTYPE doc [\n"
   7412         "  <!ELEMENT prefix:doc EMPTY>\n"
   7413         "  <!ATTLIST prefix:doc\n"
   7414         "    notxmlns:prefix CDATA 'http://example.org/'>\n"
   7415         "]>\n"
   7416         "<prefix:doc/>";
   7417 
   7418     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   7419                                 XML_TRUE) != XML_STATUS_ERROR)
   7420         fail("Unbound prefix incorrectly passed");
   7421     if (XML_GetErrorCode(parser) != XML_ERROR_UNBOUND_PREFIX)
   7422         xml_failure(parser);
   7423 }
   7424 END_TEST
   7425 
   7426 START_TEST(test_ns_default_with_empty_uri)
   7427 {
   7428     const char *text =
   7429         "<doc xmlns='http://example.org/'>\n"
   7430         "  <e xmlns=''/>\n"
   7431         "</doc>";
   7432     /* Add some handlers to exercise extra code paths */
   7433     XML_SetStartNamespaceDeclHandler(parser,
   7434                                      dummy_start_namespace_decl_handler);
   7435     XML_SetEndNamespaceDeclHandler(parser,
   7436                                    dummy_end_namespace_decl_handler);
   7437     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   7438         xml_failure(parser);
   7439 }
   7440 END_TEST
   7441 
   7442 /* Regression test for SF bug #692964: two prefixes for one namespace. */
   7443 START_TEST(test_ns_duplicate_attrs_diff_prefixes)
   7444 {
   7445     const char *text =
   7446         "<doc xmlns:a='http://example.org/a'\n"
   7447         "     xmlns:b='http://example.org/a'\n"
   7448         "     a:a='v' b:a='v' />";
   7449     expect_failure(text,
   7450                    XML_ERROR_DUPLICATE_ATTRIBUTE,
   7451                    "did not report multiple attributes with same URI+name");
   7452 }
   7453 END_TEST
   7454 
   7455 START_TEST(test_ns_duplicate_hashes)
   7456 {
   7457     /* The hash of an attribute is calculated as the hash of its URI
   7458      * concatenated with a space followed by its name (after the
   7459      * colon).  We wish to generate attributes with the same hash
   7460      * value modulo the attribute table size so that we can check that
   7461      * the attribute hash table works correctly.  The attribute hash
   7462      * table size will be the smallest power of two greater than the
   7463      * number of attributes, but at least eight.  There is
   7464      * unfortunately no programmatic way of getting the hash or the
   7465      * table size at user level, but the test code coverage percentage
   7466      * will drop if the hashes cease to point to the same row.
   7467      *
   7468      * The cunning plan is to have few enough attributes to have a
   7469      * reliable table size of 8, and have the single letter attribute
   7470      * names be 8 characters apart, producing a hash which will be the
   7471      * same modulo 8.
   7472      */
   7473     const char *text =
   7474         "<doc xmlns:a='http://example.org/a'\n"
   7475         "     a:a='v' a:i='w' />";
   7476     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   7477                                 XML_TRUE) == XML_STATUS_ERROR)
   7478         xml_failure(parser);
   7479 }
   7480 END_TEST
   7481 
   7482 /* Regression test for SF bug #695401: unbound prefix. */
   7483 START_TEST(test_ns_unbound_prefix_on_attribute)
   7484 {
   7485     const char *text = "<doc a:attr=''/>";
   7486     expect_failure(text,
   7487                    XML_ERROR_UNBOUND_PREFIX,
   7488                    "did not report unbound prefix on attribute");
   7489 }
   7490 END_TEST
   7491 
   7492 /* Regression test for SF bug #695401: unbound prefix. */
   7493 START_TEST(test_ns_unbound_prefix_on_element)
   7494 {
   7495     const char *text = "<a:doc/>";
   7496     expect_failure(text,
   7497                    XML_ERROR_UNBOUND_PREFIX,
   7498                    "did not report unbound prefix on element");
   7499 }
   7500 END_TEST
   7501 
   7502 /* Test that the parsing status is correctly reset by XML_ParserReset().
   7503  * We usE test_return_ns_triplet() for our example parse to improve
   7504  * coverage of tidying up code executed.
   7505  */
   7506 START_TEST(test_ns_parser_reset)
   7507 {
   7508     XML_ParsingStatus status;
   7509 
   7510     XML_GetParsingStatus(parser, &status);
   7511     if (status.parsing != XML_INITIALIZED)
   7512         fail("parsing status doesn't start INITIALIZED");
   7513     test_return_ns_triplet();
   7514     XML_GetParsingStatus(parser, &status);
   7515     if (status.parsing != XML_FINISHED)
   7516         fail("parsing status doesn't end FINISHED");
   7517     XML_ParserReset(parser, NULL);
   7518     XML_GetParsingStatus(parser, &status);
   7519     if (status.parsing != XML_INITIALIZED)
   7520         fail("parsing status doesn't reset to INITIALIZED");
   7521 }
   7522 END_TEST
   7523 
   7524 /* Test that long element names with namespaces are handled correctly */
   7525 START_TEST(test_ns_long_element)
   7526 {
   7527     const char *text =
   7528         "<foo:thisisalongenoughelementnametotriggerareallocation\n"
   7529         " xmlns:foo='http://example.org/' bar:a='12'\n"
   7530         " xmlns:bar='http://example.org/'>"
   7531         "</foo:thisisalongenoughelementnametotriggerareallocation>";
   7532     const XML_Char *elemstr[] = {
   7533         XCS("http://example.org/")
   7534         XCS(" thisisalongenoughelementnametotriggerareallocation foo"),
   7535         XCS("http://example.org/ a bar")
   7536     };
   7537 
   7538     XML_SetReturnNSTriplet(parser, XML_TRUE);
   7539     XML_SetUserData(parser, elemstr);
   7540     XML_SetElementHandler(parser,
   7541                           triplet_start_checker,
   7542                           triplet_end_checker);
   7543     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   7544                                 XML_TRUE) == XML_STATUS_ERROR)
   7545         xml_failure(parser);
   7546 }
   7547 END_TEST
   7548 
   7549 /* Test mixed population of prefixed and unprefixed attributes */
   7550 START_TEST(test_ns_mixed_prefix_atts)
   7551 {
   7552     const char *text =
   7553         "<e a='12' bar:b='13'\n"
   7554         " xmlns:bar='http://example.org/'>"
   7555         "</e>";
   7556 
   7557     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   7558                                 XML_TRUE) == XML_STATUS_ERROR)
   7559         xml_failure(parser);
   7560 }
   7561 END_TEST
   7562 
   7563 /* Test having a long namespaced element name inside a short one.
   7564  * This exercises some internal buffer reallocation that is shared
   7565  * across elements with the same namespace URI.
   7566  */
   7567 START_TEST(test_ns_extend_uri_buffer)
   7568 {
   7569     const char *text =
   7570         "<foo:e xmlns:foo='http://example.org/'>"
   7571         " <foo:thisisalongenoughnametotriggerallocationaction"
   7572         "   foo:a='12' />"
   7573         "</foo:e>";
   7574     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   7575                                 XML_TRUE) == XML_STATUS_ERROR)
   7576         xml_failure(parser);
   7577 }
   7578 END_TEST
   7579 
   7580 /* Test that xmlns is correctly rejected as an attribute in the xmlns
   7581  * namespace, but not in other namespaces
   7582  */
   7583 START_TEST(test_ns_reserved_attributes)
   7584 {
   7585     const char *text1 =
   7586         "<foo:e xmlns:foo='http://example.org/' xmlns:xmlns='12' />";
   7587     const char *text2 =
   7588         "<foo:e xmlns:foo='http://example.org/' foo:xmlns='12' />";
   7589     expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XMLNS,
   7590                    "xmlns not rejected as an attribute");
   7591     XML_ParserReset(parser, NULL);
   7592     if (_XML_Parse_SINGLE_BYTES(parser, text2, strlen(text2),
   7593                                 XML_TRUE) == XML_STATUS_ERROR)
   7594         xml_failure(parser);
   7595 }
   7596 END_TEST
   7597 
   7598 /* Test more reserved attributes */
   7599 START_TEST(test_ns_reserved_attributes_2)
   7600 {
   7601     const char *text1 =
   7602         "<foo:e xmlns:foo='http://example.org/'"
   7603         "  xmlns:xml='http://example.org/' />";
   7604     const char *text2 =
   7605         "<foo:e xmlns:foo='http://www.w3.org/XML/1998/namespace' />";
   7606     const char *text3 =
   7607         "<foo:e xmlns:foo='http://www.w3.org/2000/xmlns/' />";
   7608 
   7609     expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XML,
   7610                    "xml not rejected as an attribute");
   7611     XML_ParserReset(parser, NULL);
   7612     expect_failure(text2, XML_ERROR_RESERVED_NAMESPACE_URI,
   7613                    "Use of w3.org URL not faulted");
   7614     XML_ParserReset(parser, NULL);
   7615     expect_failure(text3, XML_ERROR_RESERVED_NAMESPACE_URI,
   7616                    "Use of w3.org xmlns URL not faulted");
   7617 }
   7618 END_TEST
   7619 
   7620 /* Test string pool handling of namespace names of 2048 characters */
   7621 /* Exercises a particular string pool growth path */
   7622 START_TEST(test_ns_extremely_long_prefix)
   7623 {
   7624     /* C99 compilers are only required to support 4095-character
   7625      * strings, so the following needs to be split in two to be safe
   7626      * for all compilers.
   7627      */
   7628     const char *text1 =
   7629         "<doc "
   7630         /* 64 character on each line */
   7631         /* ...gives a total length of 2048 */
   7632         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7633         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7634         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7635         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7636         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7637         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7638         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7639         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7640         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7641         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7642         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7643         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7644         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7645         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7646         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7647         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7648         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7649         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7650         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7651         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7652         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7653         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7654         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7655         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7656         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7657         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7658         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7659         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7660         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7661         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7662         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7663         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7664         ":a='12'";
   7665     const char *text2 =
   7666         " xmlns:"
   7667         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7668         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7669         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7670         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7671         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7672         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7673         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7674         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7675         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7676         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7677         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7678         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7679         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7680         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7681         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7682         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7683         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7684         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7685         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7686         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7687         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7688         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7689         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7690         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7691         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7692         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7693         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7694         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7695         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7696         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7697         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7698         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   7699         "='foo'\n>"
   7700         "</doc>";
   7701 
   7702     if (_XML_Parse_SINGLE_BYTES(parser, text1, strlen(text1),
   7703                                 XML_FALSE) == XML_STATUS_ERROR)
   7704         xml_failure(parser);
   7705     if (_XML_Parse_SINGLE_BYTES(parser, text2, strlen(text2),
   7706                                 XML_TRUE) == XML_STATUS_ERROR)
   7707         xml_failure(parser);
   7708 }
   7709 END_TEST
   7710 
   7711 /* Test unknown encoding handlers in namespace setup */
   7712 START_TEST(test_ns_unknown_encoding_success)
   7713 {
   7714     const char *text =
   7715         "<?xml version='1.0' encoding='prefix-conv'?>\n"
   7716         "<foo:e xmlns:foo='http://example.org/'>Hi</foo:e>";
   7717 
   7718     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   7719     run_character_check(text, XCS("Hi"));
   7720 }
   7721 END_TEST
   7722 
   7723 /* Test that too many colons are rejected */
   7724 START_TEST(test_ns_double_colon)
   7725 {
   7726     const char *text =
   7727         "<foo:e xmlns:foo='http://example.org/' foo:a:b='bar' />";
   7728 
   7729     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   7730                    "Double colon in attribute name not faulted");
   7731 }
   7732 END_TEST
   7733 
   7734 START_TEST(test_ns_double_colon_element)
   7735 {
   7736     const char *text =
   7737         "<foo:bar:e xmlns:foo='http://example.org/' />";
   7738 
   7739     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   7740                    "Double colon in element name not faulted");
   7741 }
   7742 END_TEST
   7743 
   7744 /* Test that non-name characters after a colon are rejected */
   7745 START_TEST(test_ns_bad_attr_leafname)
   7746 {
   7747     const char *text =
   7748         "<foo:e xmlns:foo='http://example.org/' foo:?ar='baz' />";
   7749 
   7750     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   7751                    "Invalid character in leafname not faulted");
   7752 }
   7753 END_TEST
   7754 
   7755 START_TEST(test_ns_bad_element_leafname)
   7756 {
   7757     const char *text =
   7758         "<foo:?oc xmlns:foo='http://example.org/' />";
   7759 
   7760     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   7761                    "Invalid character in element leafname not faulted");
   7762 }
   7763 END_TEST
   7764 
   7765 /* Test high-byte-set UTF-16 characters are valid in a leafname */
   7766 START_TEST(test_ns_utf16_leafname)
   7767 {
   7768     const char text[] =
   7769         /* <n:e xmlns:n='URI' n:{KHO KHWAI}='a' />
   7770          * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
   7771          */
   7772         "<\0n\0:\0e\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0 \0"
   7773         "n\0:\0\x04\x0e=\0'\0a\0'\0 \0/\0>\0";
   7774     const XML_Char *expected = XCS("a");
   7775     CharData storage;
   7776 
   7777     CharData_Init(&storage);
   7778     XML_SetStartElementHandler(parser, accumulate_attribute);
   7779     XML_SetUserData(parser, &storage);
   7780     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   7781                                 XML_TRUE) == XML_STATUS_ERROR)
   7782         xml_failure(parser);
   7783     CharData_CheckXMLChars(&storage, expected);
   7784 }
   7785 END_TEST
   7786 
   7787 START_TEST(test_ns_utf16_element_leafname)
   7788 {
   7789     const char text[] =
   7790         /* <n:{KHO KHWAI} xmlns:n='URI'/>
   7791          * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
   7792          */
   7793         "\0<\0n\0:\x0e\x04\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0/\0>";
   7794 #ifdef XML_UNICODE
   7795     const XML_Char *expected = XCS("URI \x0e04");
   7796 #else
   7797     const XML_Char *expected = XCS("URI \xe0\xb8\x84");
   7798 #endif
   7799     CharData storage;
   7800 
   7801     CharData_Init(&storage);
   7802     XML_SetStartElementHandler(parser, start_element_event_handler);
   7803     XML_SetUserData(parser, &storage);
   7804     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   7805                                 XML_TRUE) == XML_STATUS_ERROR)
   7806         xml_failure(parser);
   7807     CharData_CheckXMLChars(&storage, expected);
   7808 }
   7809 END_TEST
   7810 
   7811 START_TEST(test_ns_utf16_doctype)
   7812 {
   7813     const char text[] =
   7814         /* <!DOCTYPE foo:{KHO KHWAI} [ <!ENTITY bar 'baz'> ]>\n
   7815          * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
   7816          */
   7817         "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0f\0o\0o\0:\x0e\x04\0 "
   7818         "\0[\0 \0<\0!\0E\0N\0T\0I\0T\0Y\0 \0b\0a\0r\0 \0'\0b\0a\0z\0'\0>\0 "
   7819         "\0]\0>\0\n"
   7820         /* <foo:{KHO KHWAI} xmlns:foo='URI'>&bar;</foo:{KHO KHWAI}> */
   7821         "\0<\0f\0o\0o\0:\x0e\x04\0 "
   7822         "\0x\0m\0l\0n\0s\0:\0f\0o\0o\0=\0'\0U\0R\0I\0'\0>"
   7823         "\0&\0b\0a\0r\0;"
   7824         "\0<\0/\0f\0o\0o\0:\x0e\x04\0>";
   7825 #ifdef XML_UNICODE
   7826     const XML_Char *expected = XCS("URI \x0e04");
   7827 #else
   7828     const XML_Char *expected = XCS("URI \xe0\xb8\x84");
   7829 #endif
   7830     CharData storage;
   7831 
   7832     CharData_Init(&storage);
   7833     XML_SetUserData(parser, &storage);
   7834     XML_SetStartElementHandler(parser, start_element_event_handler);
   7835     XML_SetUnknownEncodingHandler(parser, MiscEncodingHandler, NULL);
   7836     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   7837                                 XML_TRUE) == XML_STATUS_ERROR)
   7838         xml_failure(parser);
   7839     CharData_CheckXMLChars(&storage, expected);
   7840 }
   7841 END_TEST
   7842 
   7843 START_TEST(test_ns_invalid_doctype)
   7844 {
   7845     const char *text =
   7846         "<!DOCTYPE foo:!bad [ <!ENTITY bar 'baz' ]>\n"
   7847         "<foo:!bad>&bar;</foo:!bad>";
   7848 
   7849     expect_failure(text, XML_ERROR_INVALID_TOKEN,
   7850                    "Invalid character in document local name not faulted");
   7851 }
   7852 END_TEST
   7853 
   7854 START_TEST(test_ns_double_colon_doctype)
   7855 {
   7856     const char *text =
   7857         "<!DOCTYPE foo:a:doc [ <!ENTITY bar 'baz' ]>\n"
   7858         "<foo:a:doc>&bar;</foo:a:doc>";
   7859 
   7860     expect_failure(text, XML_ERROR_SYNTAX,
   7861                    "Double colon in document name not faulted");
   7862 }
   7863 END_TEST
   7864 
   7865 /* Control variable; the number of times duff_allocator() will successfully allocate */
   7866 #define ALLOC_ALWAYS_SUCCEED (-1)
   7867 #define REALLOC_ALWAYS_SUCCEED (-1)
   7868 
   7869 static int allocation_count = ALLOC_ALWAYS_SUCCEED;
   7870 static int reallocation_count = REALLOC_ALWAYS_SUCCEED;
   7871 
   7872 /* Crocked allocator for allocation failure tests */
   7873 static void *duff_allocator(size_t size)
   7874 {
   7875     if (allocation_count == 0)
   7876         return NULL;
   7877     if (allocation_count != ALLOC_ALWAYS_SUCCEED)
   7878         allocation_count--;
   7879     return malloc(size);
   7880 }
   7881 
   7882 /* Crocked reallocator for allocation failure tests */
   7883 static void *duff_reallocator(void *ptr, size_t size)
   7884 {
   7885     if (reallocation_count == 0)
   7886         return NULL;
   7887     if (reallocation_count != REALLOC_ALWAYS_SUCCEED)
   7888         reallocation_count--;
   7889     return realloc(ptr, size);
   7890 }
   7891 
   7892 /* Test that a failure to allocate the parser structure fails gracefully */
   7893 START_TEST(test_misc_alloc_create_parser)
   7894 {
   7895     XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free };
   7896     unsigned int i;
   7897     const unsigned int max_alloc_count = 10;
   7898 
   7899     /* Something this simple shouldn't need more than 10 allocations */
   7900     for (i = 0; i < max_alloc_count; i++)
   7901     {
   7902         allocation_count = i;
   7903         parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
   7904         if (parser != NULL)
   7905             break;
   7906     }
   7907     if (i == 0)
   7908         fail("Parser unexpectedly ignored failing allocator");
   7909     else if (i == max_alloc_count)
   7910         fail("Parser not created with max allocation count");
   7911 }
   7912 END_TEST
   7913 
   7914 /* Test memory allocation failures for a parser with an encoding */
   7915 START_TEST(test_misc_alloc_create_parser_with_encoding)
   7916 {
   7917     XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free };
   7918     unsigned int i;
   7919     const unsigned int max_alloc_count = 10;
   7920 
   7921     /* Try several levels of allocation */
   7922     for (i = 0; i < max_alloc_count; i++) {
   7923         allocation_count = i;
   7924         parser = XML_ParserCreate_MM(XCS("us-ascii"), &memsuite, NULL);
   7925         if (parser != NULL)
   7926             break;
   7927     }
   7928     if (i == 0)
   7929         fail("Parser ignored failing allocator");
   7930     else if (i == max_alloc_count)
   7931         fail("Parser not created with max allocation count");
   7932 }
   7933 END_TEST
   7934 
   7935 /* Test that freeing a NULL parser doesn't cause an explosion.
   7936  * (Not actually tested anywhere else)
   7937  */
   7938 START_TEST(test_misc_null_parser)
   7939 {
   7940     XML_ParserFree(NULL);
   7941 }
   7942 END_TEST
   7943 
   7944 /* Test that XML_ErrorString rejects out-of-range codes */
   7945 START_TEST(test_misc_error_string)
   7946 {
   7947     if (XML_ErrorString((enum XML_Error)-1) != NULL)
   7948         fail("Negative error code not rejected");
   7949     if (XML_ErrorString((enum XML_Error)100) != NULL)
   7950         fail("Large error code not rejected");
   7951 }
   7952 END_TEST
   7953 
   7954 /* Test the version information is consistent */
   7955 
   7956 /* Since we are working in XML_LChars (potentially 16-bits), we
   7957  * can't use the standard C library functions for character
   7958  * manipulation and have to roll our own.
   7959  */
   7960 static int
   7961 parse_version(const XML_LChar *version_text,
   7962               XML_Expat_Version *version_struct)
   7963 {
   7964     while (*version_text != 0x00) {
   7965         if (*version_text >= ASCII_0 && *version_text <= ASCII_9)
   7966             break;
   7967         version_text++;
   7968     }
   7969     if (*version_text == 0x00)
   7970         return XML_FALSE;
   7971 
   7972     /* version_struct->major = strtoul(version_text, 10, &version_text) */
   7973     version_struct->major = 0;
   7974     while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
   7975         version_struct->major =
   7976             10 * version_struct->major + (*version_text++ - ASCII_0);
   7977     }
   7978     if (*version_text++ != ASCII_PERIOD)
   7979         return XML_FALSE;
   7980 
   7981     /* Now for the minor version number */
   7982     version_struct->minor = 0;
   7983     while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
   7984         version_struct->minor =
   7985             10 * version_struct->minor + (*version_text++ - ASCII_0);
   7986     }
   7987     if (*version_text++ != ASCII_PERIOD)
   7988         return XML_FALSE;
   7989 
   7990     /* Finally the micro version number */
   7991     version_struct->micro = 0;
   7992     while (*version_text >= ASCII_0 && *version_text <= ASCII_9) {
   7993         version_struct->micro =
   7994             10 * version_struct->micro + (*version_text++ - ASCII_0);
   7995     }
   7996     if (*version_text != 0x00)
   7997         return XML_FALSE;
   7998     return XML_TRUE;
   7999 }
   8000 
   8001 static int
   8002 versions_equal(const XML_Expat_Version *first,
   8003                const XML_Expat_Version *second)
   8004 {
   8005     return (first->major == second->major &&
   8006             first->minor == second->minor &&
   8007             first->micro == second->micro);
   8008 }
   8009 
   8010 START_TEST(test_misc_version)
   8011 {
   8012     XML_Expat_Version read_version = XML_ExpatVersionInfo();
   8013      /* Silence compiler warning with the following assignment */
   8014     XML_Expat_Version parsed_version = { 0, 0, 0 };
   8015     const XML_LChar *version_text = XML_ExpatVersion();
   8016 
   8017     if (version_text == NULL)
   8018         fail("Could not obtain version text");
   8019     if (!parse_version(version_text, &parsed_version))
   8020         fail("Unable to parse version text");
   8021     if (!versions_equal(&read_version, &parsed_version))
   8022         fail("Version mismatch");
   8023 
   8024 #if ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T)
   8025     if (xcstrcmp(version_text, XCS("expat_2.2.5")))  /* needs bump on releases */
   8026         fail("XML_*_VERSION in expat.h out of sync?\n");
   8027 #else
   8028     /* If we have XML_UNICODE defined but not XML_UNICODE_WCHAR_T
   8029      * then XML_LChar is defined as char, for some reason.
   8030      */
   8031     if (strcmp(version_text, "expat_2.2.5")) /* needs bump on releases */
   8032         fail("XML_*_VERSION in expat.h out of sync?\n");
   8033 #endif  /* ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T) */
   8034 }
   8035 END_TEST
   8036 
   8037 /* Test feature information */
   8038 START_TEST(test_misc_features)
   8039 {
   8040     const XML_Feature *features = XML_GetFeatureList();
   8041 
   8042     /* Prevent problems with double-freeing parsers */
   8043     parser = NULL;
   8044     if (features == NULL)
   8045         fail("Failed to get feature information");
   8046     /* Loop through the features checking what we can */
   8047     while (features->feature != XML_FEATURE_END) {
   8048         switch(features->feature) {
   8049             case XML_FEATURE_SIZEOF_XML_CHAR:
   8050                 if (features->value != sizeof(XML_Char))
   8051                     fail("Incorrect size of XML_Char");
   8052                 break;
   8053             case XML_FEATURE_SIZEOF_XML_LCHAR:
   8054                 if (features->value != sizeof(XML_LChar))
   8055                     fail("Incorrect size of XML_LChar");
   8056                 break;
   8057             default:
   8058                 break;
   8059         }
   8060         features++;
   8061     }
   8062 }
   8063 END_TEST
   8064 
   8065 /* Regression test for GitHub Issue #17: memory leak parsing attribute
   8066  * values with mixed bound and unbound namespaces.
   8067  */
   8068 START_TEST(test_misc_attribute_leak)
   8069 {
   8070     const char *text = "<D xmlns:L=\"D\" l:a='' L:a=''/>";
   8071     XML_Memory_Handling_Suite memsuite = {
   8072         tracking_malloc,
   8073         tracking_realloc,
   8074         tracking_free
   8075     };
   8076 
   8077     parser = XML_ParserCreate_MM(XCS("UTF-8"), &memsuite, XCS("\n"));
   8078     expect_failure(text, XML_ERROR_UNBOUND_PREFIX,
   8079                    "Unbound prefixes not found");
   8080     XML_ParserFree(parser);
   8081     /* Prevent the teardown trying to double free */
   8082     parser = NULL;
   8083 
   8084     if (!tracking_report())
   8085         fail("Memory leak found");
   8086 }
   8087 END_TEST
   8088 
   8089 /* Test parser created for UTF-16LE is successful */
   8090 START_TEST(test_misc_utf16le)
   8091 {
   8092     const char text[] =
   8093         /* <?xml version='1.0'?><q>Hi</q> */
   8094         "<\0?\0x\0m\0l\0 \0"
   8095         "v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0?\0>\0"
   8096         "<\0q\0>\0H\0i\0<\0/\0q\0>\0";
   8097     const XML_Char *expected = XCS("Hi");
   8098     CharData storage;
   8099 
   8100     parser = XML_ParserCreate(XCS("UTF-16LE"));
   8101     if (parser == NULL)
   8102         fail("Parser not created");
   8103 
   8104     CharData_Init(&storage);
   8105     XML_SetUserData(parser, &storage);
   8106     XML_SetCharacterDataHandler(parser, accumulate_characters);
   8107     if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1,
   8108                                 XML_TRUE) == XML_STATUS_ERROR)
   8109         xml_failure(parser);
   8110     CharData_CheckXMLChars(&storage, expected);
   8111 }
   8112 END_TEST
   8113 
   8114 
   8115 static void
   8116 alloc_setup(void)
   8117 {
   8118     XML_Memory_Handling_Suite memsuite = {
   8119         duff_allocator,
   8120         duff_reallocator,
   8121         free
   8122     };
   8123 
   8124     /* Ensure the parser creation will go through */
   8125     allocation_count = ALLOC_ALWAYS_SUCCEED;
   8126     reallocation_count = REALLOC_ALWAYS_SUCCEED;
   8127     parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
   8128     if (parser == NULL)
   8129         fail("Parser not created");
   8130 }
   8131 
   8132 static void
   8133 alloc_teardown(void)
   8134 {
   8135     basic_teardown();
   8136 }
   8137 
   8138 
   8139 /* Test the effects of allocation failures on xml declaration processing */
   8140 START_TEST(test_alloc_parse_xdecl)
   8141 {
   8142     const char *text =
   8143         "<?xml version='1.0' encoding='utf-8'?>\n"
   8144         "<doc>Hello, world</doc>";
   8145     int i;
   8146     const int max_alloc_count = 15;
   8147 
   8148     for (i = 0; i < max_alloc_count; i++) {
   8149         allocation_count = i;
   8150         XML_SetXmlDeclHandler(parser, dummy_xdecl_handler);
   8151         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8152                                     XML_TRUE) != XML_STATUS_ERROR)
   8153             break;
   8154         /* Resetting the parser is insufficient, because some memory
   8155          * allocations are cached within the parser.  Instead we use
   8156          * the teardown and setup routines to ensure that we have the
   8157          * right sort of parser back in our hands.
   8158          */
   8159         alloc_teardown();
   8160         alloc_setup();
   8161     }
   8162     if (i == 0)
   8163         fail("Parse succeeded despite failing allocator");
   8164     if (i == max_alloc_count)
   8165         fail("Parse failed with max allocations");
   8166 }
   8167 END_TEST
   8168 
   8169 /* As above, but with an encoding big enough to cause storing the
   8170  * version information to expand the string pool being used.
   8171  */
   8172 static int XMLCALL
   8173 long_encoding_handler(void *UNUSED_P(userData),
   8174                       const XML_Char *UNUSED_P(encoding),
   8175                       XML_Encoding *info)
   8176 {
   8177     int i;
   8178 
   8179     for (i = 0; i < 256; i++)
   8180         info->map[i] = i;
   8181     info->data = NULL;
   8182     info->convert = NULL;
   8183     info->release = NULL;
   8184     return XML_STATUS_OK;
   8185 }
   8186 
   8187 START_TEST(test_alloc_parse_xdecl_2)
   8188 {
   8189     const char *text =
   8190         "<?xml version='1.0' encoding='"
   8191         /* Each line is 64 characters */
   8192         "ThisIsAStupidlyLongEncodingNameIntendedToTriggerPoolGrowth123456"
   8193         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8194         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8195         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8196         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8197         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8198         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8199         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8200         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8201         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8202         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8203         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8204         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8205         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8206         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8207         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN"
   8208         "'?>"
   8209         "<doc>Hello, world</doc>";
   8210     int i;
   8211     const int max_alloc_count = 20;
   8212 
   8213     for (i = 0; i < max_alloc_count; i++) {
   8214         allocation_count = i;
   8215         XML_SetXmlDeclHandler(parser, dummy_xdecl_handler);
   8216         XML_SetUnknownEncodingHandler(parser, long_encoding_handler, NULL);
   8217         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8218                                     XML_TRUE) != XML_STATUS_ERROR)
   8219             break;
   8220         /* See comment in test_alloc_parse_xdecl() */
   8221         alloc_teardown();
   8222         alloc_setup();
   8223     }
   8224     if (i == 0)
   8225         fail("Parse succeeded despite failing allocator");
   8226     if (i == max_alloc_count)
   8227         fail("Parse failed with max allocations");
   8228 }
   8229 END_TEST
   8230 
   8231 /* Test the effects of allocation failures on a straightforward parse */
   8232 START_TEST(test_alloc_parse_pi)
   8233 {
   8234     const char *text =
   8235         "<?xml version='1.0' encoding='utf-8'?>\n"
   8236         "<?pi unknown?>\n"
   8237         "<doc>"
   8238         "Hello, world"
   8239         "</doc>";
   8240     int i;
   8241     const int max_alloc_count = 15;
   8242 
   8243     for (i = 0; i < max_alloc_count; i++) {
   8244         allocation_count = i;
   8245         XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
   8246         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8247                                     XML_TRUE) != XML_STATUS_ERROR)
   8248             break;
   8249         /* See comment in test_alloc_parse_xdecl() */
   8250         alloc_teardown();
   8251         alloc_setup();
   8252     }
   8253     if (i == 0)
   8254         fail("Parse succeeded despite failing allocator");
   8255     if (i == max_alloc_count)
   8256         fail("Parse failed with max allocations");
   8257 }
   8258 END_TEST
   8259 
   8260 START_TEST(test_alloc_parse_pi_2)
   8261 {
   8262     const char *text =
   8263         "<?xml version='1.0' encoding='utf-8'?>\n"
   8264         "<doc>"
   8265         "Hello, world"
   8266         "<?pi unknown?>\n"
   8267         "</doc>";
   8268     int i;
   8269     const int max_alloc_count = 15;
   8270 
   8271     for (i = 0; i < max_alloc_count; i++) {
   8272         allocation_count = i;
   8273         XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
   8274         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8275                                     XML_TRUE) != XML_STATUS_ERROR)
   8276             break;
   8277         /* See comment in test_alloc_parse_xdecl() */
   8278         alloc_teardown();
   8279         alloc_setup();
   8280     }
   8281     if (i == 0)
   8282         fail("Parse succeeded despite failing allocator");
   8283     if (i == max_alloc_count)
   8284         fail("Parse failed with max allocations");
   8285 }
   8286 END_TEST
   8287 
   8288 START_TEST(test_alloc_parse_pi_3)
   8289 {
   8290     const char *text =
   8291         "<?"
   8292         /* 64 characters per line */
   8293         "This processing instruction should be long enough to ensure that"
   8294         "it triggers the growth of an internal string pool when the      "
   8295         "allocator fails at a cruicial moment FGHIJKLMNOPABCDEFGHIJKLMNOP"
   8296         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8297         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8298         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8299         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8300         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8301         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8302         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8303         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8304         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8305         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8306         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8307         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8308         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8309         "Q?><doc/>";
   8310     int i;
   8311     const int max_alloc_count = 20;
   8312 
   8313     for (i = 0; i < max_alloc_count; i++) {
   8314         allocation_count = i;
   8315         XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
   8316         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8317                                     XML_TRUE) != XML_STATUS_ERROR)
   8318             break;
   8319         /* See comment in test_alloc_parse_xdecl() */
   8320         alloc_teardown();
   8321         alloc_setup();
   8322     }
   8323     if (i == 0)
   8324         fail("Parse succeeded despite failing allocator");
   8325     if (i == max_alloc_count)
   8326         fail("Parse failed with max allocations");
   8327 }
   8328 END_TEST
   8329 
   8330 START_TEST(test_alloc_parse_comment)
   8331 {
   8332     const char *text =
   8333         "<?xml version='1.0' encoding='utf-8'?>\n"
   8334         "<!-- Test parsing this comment -->"
   8335         "<doc>Hi</doc>";
   8336     int i;
   8337     const int max_alloc_count = 15;
   8338 
   8339     for (i = 0; i < max_alloc_count; i++) {
   8340         allocation_count = i;
   8341         XML_SetCommentHandler(parser, dummy_comment_handler);
   8342         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8343                                     XML_TRUE) != XML_STATUS_ERROR)
   8344             break;
   8345         /* See comment in test_alloc_parse_xdecl() */
   8346         alloc_teardown();
   8347         alloc_setup();
   8348     }
   8349     if (i == 0)
   8350         fail("Parse succeeded despite failing allocator");
   8351     if (i == max_alloc_count)
   8352         fail("Parse failed with max allocations");
   8353 }
   8354 END_TEST
   8355 
   8356 START_TEST(test_alloc_parse_comment_2)
   8357 {
   8358     const char *text =
   8359         "<?xml version='1.0' encoding='utf-8'?>\n"
   8360         "<doc>"
   8361         "Hello, world"
   8362         "<!-- Parse this comment too -->"
   8363         "</doc>";
   8364     int i;
   8365     const int max_alloc_count = 15;
   8366 
   8367     for (i = 0; i < max_alloc_count; i++) {
   8368         allocation_count = i;
   8369         XML_SetCommentHandler(parser, dummy_comment_handler);
   8370         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8371                                     XML_TRUE) != XML_STATUS_ERROR)
   8372             break;
   8373         /* See comment in test_alloc_parse_xdecl() */
   8374         alloc_teardown();
   8375         alloc_setup();
   8376     }
   8377     if (i == 0)
   8378         fail("Parse succeeded despite failing allocator");
   8379     if (i == max_alloc_count)
   8380         fail("Parse failed with max allocations");
   8381 }
   8382 END_TEST
   8383 
   8384 static int XMLCALL
   8385 external_entity_duff_loader(XML_Parser parser,
   8386                             const XML_Char *context,
   8387                             const XML_Char *UNUSED_P(base),
   8388                             const XML_Char *UNUSED_P(systemId),
   8389                             const XML_Char *UNUSED_P(publicId))
   8390 {
   8391     XML_Parser new_parser;
   8392     unsigned int i;
   8393     const unsigned int max_alloc_count = 10;
   8394 
   8395     /* Try a few different allocation levels */
   8396     for (i = 0; i < max_alloc_count; i++)
   8397     {
   8398         allocation_count = i;
   8399         new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   8400         if (new_parser != NULL)
   8401         {
   8402             XML_ParserFree(new_parser);
   8403             break;
   8404         }
   8405     }
   8406     if (i == 0)
   8407         fail("External parser creation ignored failing allocator");
   8408     else if (i == max_alloc_count)
   8409         fail("Extern parser not created with max allocation count");
   8410 
   8411     /* Make sure other random allocation doesn't now fail */
   8412     allocation_count = ALLOC_ALWAYS_SUCCEED;
   8413 
   8414     /* Make sure the failure code path is executed too */
   8415     return XML_STATUS_ERROR;
   8416 }
   8417 
   8418 /* Test that external parser creation running out of memory is
   8419  * correctly reported.  Based on the external entity test cases.
   8420  */
   8421 START_TEST(test_alloc_create_external_parser)
   8422 {
   8423     const char *text =
   8424         "<?xml version='1.0' encoding='us-ascii'?>\n"
   8425         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   8426         "<doc>&entity;</doc>";
   8427     char foo_text[] =
   8428         "<!ELEMENT doc (#PCDATA)*>";
   8429 
   8430     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   8431     XML_SetUserData(parser, foo_text);
   8432     XML_SetExternalEntityRefHandler(parser,
   8433                                     external_entity_duff_loader);
   8434     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR) {
   8435         fail("External parser allocator returned success incorrectly");
   8436     }
   8437 }
   8438 END_TEST
   8439 
   8440 /* More external parser memory allocation testing */
   8441 START_TEST(test_alloc_run_external_parser)
   8442 {
   8443     const char *text =
   8444         "<?xml version='1.0' encoding='us-ascii'?>\n"
   8445         "<!DOCTYPE doc SYSTEM 'foo'>\n"
   8446         "<doc>&entity;</doc>";
   8447     char foo_text[] =
   8448         "<!ELEMENT doc (#PCDATA)*>";
   8449     unsigned int i;
   8450     const unsigned int max_alloc_count = 15;
   8451 
   8452     for (i = 0; i < max_alloc_count; i++) {
   8453         XML_SetParamEntityParsing(parser,
   8454                                   XML_PARAM_ENTITY_PARSING_ALWAYS);
   8455         XML_SetUserData(parser, foo_text);
   8456         XML_SetExternalEntityRefHandler(parser,
   8457                                         external_entity_null_loader);
   8458         allocation_count = i;
   8459         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
   8460             break;
   8461         /* See comment in test_alloc_parse_xdecl() */
   8462         alloc_teardown();
   8463         alloc_setup();
   8464     }
   8465     if (i == 0)
   8466         fail("Parsing ignored failing allocator");
   8467     else if (i == max_alloc_count)
   8468         fail("Parsing failed with allocation count 10");
   8469 }
   8470 END_TEST
   8471 
   8472 
   8473 static int XMLCALL
   8474 external_entity_dbl_handler(XML_Parser parser,
   8475                             const XML_Char *context,
   8476                             const XML_Char *UNUSED_P(base),
   8477                             const XML_Char *UNUSED_P(systemId),
   8478                             const XML_Char *UNUSED_P(publicId))
   8479 {
   8480     intptr_t callno = (intptr_t)XML_GetUserData(parser);
   8481     const char *text;
   8482     XML_Parser new_parser;
   8483     int i;
   8484     const int max_alloc_count = 20;
   8485 
   8486     if (callno == 0) {
   8487         /* First time through, check how many calls to malloc occur */
   8488         text = ("<!ELEMENT doc (e+)>\n"
   8489                 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
   8490                 "<!ELEMENT e EMPTY>\n");
   8491         allocation_count = 10000;
   8492         new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   8493         if (new_parser == NULL) {
   8494             fail("Unable to allocate first external parser");
   8495             return XML_STATUS_ERROR;
   8496         }
   8497         /* Stash the number of calls in the user data */
   8498         XML_SetUserData(parser, (void *)(intptr_t)(10000 - allocation_count));
   8499     } else {
   8500         text = ("<?xml version='1.0' encoding='us-ascii'?>"
   8501                 "<e/>");
   8502         /* Try at varying levels to exercise more code paths */
   8503         for (i = 0; i < max_alloc_count; i++) {
   8504             allocation_count = callno + i;
   8505             new_parser = XML_ExternalEntityParserCreate(parser,
   8506                                                         context,
   8507                                                         NULL);
   8508             if (new_parser != NULL)
   8509                 break;
   8510         }
   8511         if (i == 0) {
   8512             fail("Second external parser unexpectedly created");
   8513             XML_ParserFree(new_parser);
   8514             return XML_STATUS_ERROR;
   8515         }
   8516         else if (i == max_alloc_count) {
   8517             fail("Second external parser not created");
   8518             return XML_STATUS_ERROR;
   8519         }
   8520     }
   8521 
   8522     allocation_count = ALLOC_ALWAYS_SUCCEED;
   8523     if (_XML_Parse_SINGLE_BYTES(new_parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
   8524         xml_failure(new_parser);
   8525         return XML_STATUS_ERROR;
   8526     }
   8527     XML_ParserFree(new_parser);
   8528     return XML_STATUS_OK;
   8529 }
   8530 
   8531 /* Test that running out of memory in dtdCopy is correctly reported.
   8532  * Based on test_default_ns_from_ext_subset_and_ext_ge()
   8533  */
   8534 START_TEST(test_alloc_dtd_copy_default_atts)
   8535 {
   8536     const char *text =
   8537         "<?xml version='1.0'?>\n"
   8538         "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
   8539         "  <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
   8540         "]>\n"
   8541         "<doc xmlns='http://example.org/ns1'>\n"
   8542         "&en;\n"
   8543         "</doc>";
   8544 
   8545     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   8546     XML_SetExternalEntityRefHandler(parser,
   8547                                     external_entity_dbl_handler);
   8548     XML_SetUserData(parser, NULL);
   8549     if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
   8550         xml_failure(parser);
   8551 }
   8552 END_TEST
   8553 
   8554 
   8555 static int XMLCALL
   8556 external_entity_dbl_handler_2(XML_Parser parser,
   8557                               const XML_Char *context,
   8558                               const XML_Char *UNUSED_P(base),
   8559                               const XML_Char *UNUSED_P(systemId),
   8560                               const XML_Char *UNUSED_P(publicId))
   8561 {
   8562     intptr_t callno = (intptr_t)XML_GetUserData(parser);
   8563     const char *text;
   8564     XML_Parser new_parser;
   8565     enum XML_Status rv;
   8566 
   8567     if (callno == 0) {
   8568         /* Try different allocation levels for whole exercise */
   8569         text = ("<!ELEMENT doc (e+)>\n"
   8570                 "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
   8571                 "<!ELEMENT e EMPTY>\n");
   8572         XML_SetUserData(parser, (void *)(intptr_t)1);
   8573         new_parser = XML_ExternalEntityParserCreate(parser,
   8574                                                     context,
   8575                                                     NULL);
   8576         if (new_parser == NULL)
   8577             return XML_STATUS_ERROR;
   8578         rv = _XML_Parse_SINGLE_BYTES(new_parser, text, strlen(text),
   8579                                      XML_TRUE);
   8580     } else {
   8581         /* Just run through once */
   8582         text = ("<?xml version='1.0' encoding='us-ascii'?>"
   8583                 "<e/>");
   8584         new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   8585         if (new_parser == NULL)
   8586             return XML_STATUS_ERROR;
   8587         rv =_XML_Parse_SINGLE_BYTES(new_parser, text, strlen(text),
   8588                                     XML_TRUE);
   8589     }
   8590     XML_ParserFree(new_parser);
   8591     if (rv == XML_STATUS_ERROR)
   8592         return XML_STATUS_ERROR;
   8593     return XML_STATUS_OK;
   8594 }
   8595 
   8596 /* Test more external entity allocation failure paths */
   8597 START_TEST(test_alloc_external_entity)
   8598 {
   8599     const char *text =
   8600         "<?xml version='1.0'?>\n"
   8601         "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
   8602         "  <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
   8603         "]>\n"
   8604         "<doc xmlns='http://example.org/ns1'>\n"
   8605         "&en;\n"
   8606         "</doc>";
   8607     int i;
   8608     const int alloc_test_max_repeats = 50;
   8609 
   8610     for (i = 0; i < alloc_test_max_repeats; i++) {
   8611         allocation_count = -1;
   8612         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   8613         XML_SetExternalEntityRefHandler(parser,
   8614                                         external_entity_dbl_handler_2);
   8615         XML_SetUserData(parser, NULL);
   8616         allocation_count = i;
   8617         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8618                                     XML_TRUE) == XML_STATUS_OK)
   8619             break;
   8620         /* See comment in test_alloc_parse_xdecl() */
   8621         alloc_teardown();
   8622         alloc_setup();
   8623     }
   8624     allocation_count = -1;
   8625     if (i == 0)
   8626         fail("External entity parsed despite duff allocator");
   8627     if (i == alloc_test_max_repeats)
   8628         fail("External entity not parsed at max allocation count");
   8629 }
   8630 END_TEST
   8631 
   8632 /* Test more allocation failure paths */
   8633 static int XMLCALL
   8634 external_entity_alloc_set_encoding(XML_Parser parser,
   8635                                    const XML_Char *context,
   8636                                    const XML_Char *UNUSED_P(base),
   8637                                    const XML_Char *UNUSED_P(systemId),
   8638                                    const XML_Char *UNUSED_P(publicId))
   8639 {
   8640     /* As for external_entity_loader() */
   8641     const char *text =
   8642         "<?xml encoding='iso-8859-3'?>"
   8643         "\xC3\xA9";
   8644     XML_Parser ext_parser;
   8645     enum XML_Status status;
   8646 
   8647     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   8648     if (ext_parser == NULL)
   8649         return XML_STATUS_ERROR;
   8650     if (!XML_SetEncoding(ext_parser, XCS("utf-8"))) {
   8651         XML_ParserFree(ext_parser);
   8652         return XML_STATUS_ERROR;
   8653     }
   8654     status = _XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   8655                                      XML_TRUE);
   8656     XML_ParserFree(ext_parser);
   8657     if (status == XML_STATUS_ERROR)
   8658         return XML_STATUS_ERROR;
   8659     return XML_STATUS_OK;
   8660 }
   8661 
   8662 START_TEST(test_alloc_ext_entity_set_encoding)
   8663 {
   8664     const char *text =
   8665         "<!DOCTYPE doc [\n"
   8666         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   8667         "]>\n"
   8668         "<doc>&en;</doc>";
   8669     int i;
   8670     const int max_allocation_count = 30;
   8671 
   8672     for (i = 0; i < max_allocation_count; i++) {
   8673         XML_SetExternalEntityRefHandler(parser,
   8674                                         external_entity_alloc_set_encoding);
   8675         allocation_count = i;
   8676         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8677                                     XML_TRUE) == XML_STATUS_OK)
   8678             break;
   8679         allocation_count = -1;
   8680         /* See comment in test_alloc_parse_xdecl() */
   8681         alloc_teardown();
   8682         alloc_setup();
   8683     }
   8684     if (i == 0)
   8685         fail("Encoding check succeeded despite failing allocator");
   8686     if (i == max_allocation_count)
   8687         fail("Encoding failed at max allocation count");
   8688 }
   8689 END_TEST
   8690 
   8691 static int XMLCALL
   8692 unknown_released_encoding_handler(void *UNUSED_P(data),
   8693                                   const XML_Char *encoding,
   8694                                   XML_Encoding *info)
   8695 {
   8696     if (!xcstrcmp(encoding, XCS("unsupported-encoding"))) {
   8697         int i;
   8698 
   8699         for (i = 0; i < 256; i++)
   8700             info->map[i] = i;
   8701         info->data = NULL;
   8702         info->convert = NULL;
   8703         info->release = dummy_release;
   8704         return XML_STATUS_OK;
   8705     }
   8706     return XML_STATUS_ERROR;
   8707 }
   8708 
   8709 /* Test the effects of allocation failure in internal entities.
   8710  * Based on test_unknown_encoding_internal_entity
   8711  */
   8712 START_TEST(test_alloc_internal_entity)
   8713 {
   8714     const char *text =
   8715         "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
   8716         "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
   8717         "<test a='&foo;'/>";
   8718     unsigned int i;
   8719     const unsigned int max_alloc_count = 20;
   8720 
   8721     for (i = 0; i < max_alloc_count; i++) {
   8722         allocation_count = i;
   8723         XML_SetUnknownEncodingHandler(parser,
   8724                                       unknown_released_encoding_handler,
   8725                                       NULL);
   8726         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
   8727             break;
   8728         /* See comment in test_alloc_parse_xdecl() */
   8729         alloc_teardown();
   8730         alloc_setup();
   8731     }
   8732     if (i == 0)
   8733         fail("Internal entity worked despite failing allocations");
   8734     else if (i == max_alloc_count)
   8735         fail("Internal entity failed at max allocation count");
   8736 }
   8737 END_TEST
   8738 
   8739 
   8740 /* Test the robustness against allocation failure of element handling
   8741  * Based on test_dtd_default_handling().
   8742  */
   8743 START_TEST(test_alloc_dtd_default_handling)
   8744 {
   8745     const char *text =
   8746         "<!DOCTYPE doc [\n"
   8747         "<!ENTITY e SYSTEM 'http://example.org/e'>\n"
   8748         "<!NOTATION n SYSTEM 'http://example.org/n'>\n"
   8749         "<!ENTITY e1 SYSTEM 'http://example.org/e' NDATA n>\n"
   8750         "<!ELEMENT doc (#PCDATA)>\n"
   8751         "<!ATTLIST doc a CDATA #IMPLIED>\n"
   8752         "<?pi in dtd?>\n"
   8753         "<!--comment in dtd-->\n"
   8754         "]>\n"
   8755         "<doc><![CDATA[text in doc]]></doc>";
   8756     const XML_Char *expected = XCS("\n\n\n\n\n\n\n\n\n<doc>text in doc</doc>");
   8757     CharData storage;
   8758     int i;
   8759     const int max_alloc_count = 25;
   8760 
   8761     for (i = 0; i < max_alloc_count; i++) {
   8762         allocation_count = i;
   8763         dummy_handler_flags = 0;
   8764         XML_SetDefaultHandler(parser, accumulate_characters);
   8765         XML_SetDoctypeDeclHandler(parser,
   8766                                   dummy_start_doctype_handler,
   8767                                   dummy_end_doctype_handler);
   8768         XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
   8769         XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
   8770         XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   8771         XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
   8772         XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
   8773         XML_SetCommentHandler(parser, dummy_comment_handler);
   8774         XML_SetCdataSectionHandler(parser,
   8775                                    dummy_start_cdata_handler,
   8776                                    dummy_end_cdata_handler);
   8777         XML_SetUnparsedEntityDeclHandler(
   8778             parser,
   8779             dummy_unparsed_entity_decl_handler);
   8780         CharData_Init(&storage);
   8781         XML_SetUserData(parser, &storage);
   8782         XML_SetCharacterDataHandler(parser, accumulate_characters);
   8783         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8784                                     XML_TRUE) != XML_STATUS_ERROR)
   8785             break;
   8786         /* See comment in test_alloc_parse_xdecl() */
   8787         alloc_teardown();
   8788         alloc_setup();
   8789     }
   8790     if (i == 0)
   8791         fail("Default DTD parsed despite allocation failures");
   8792     if (i == max_alloc_count)
   8793         fail("Default DTD not parsed with maximum alloc count");
   8794     CharData_CheckXMLChars(&storage, expected);
   8795     if (dummy_handler_flags != (DUMMY_START_DOCTYPE_HANDLER_FLAG |
   8796                                 DUMMY_END_DOCTYPE_HANDLER_FLAG |
   8797                                 DUMMY_ENTITY_DECL_HANDLER_FLAG |
   8798                                 DUMMY_NOTATION_DECL_HANDLER_FLAG |
   8799                                 DUMMY_ELEMENT_DECL_HANDLER_FLAG |
   8800                                 DUMMY_ATTLIST_DECL_HANDLER_FLAG |
   8801                                 DUMMY_COMMENT_HANDLER_FLAG |
   8802                                 DUMMY_PI_HANDLER_FLAG |
   8803                                 DUMMY_START_CDATA_HANDLER_FLAG |
   8804                                 DUMMY_END_CDATA_HANDLER_FLAG |
   8805                                 DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG))
   8806         fail("Not all handlers were called");
   8807 }
   8808 END_TEST
   8809 
   8810 /* Test robustness of XML_SetEncoding() with a failing allocator */
   8811 START_TEST(test_alloc_explicit_encoding)
   8812 {
   8813     int i;
   8814     const int max_alloc_count = 5;
   8815 
   8816     for (i = 0; i < max_alloc_count; i++) {
   8817         allocation_count = i;
   8818         if (XML_SetEncoding(parser, XCS("us-ascii")) == XML_STATUS_OK)
   8819             break;
   8820     }
   8821     if (i == 0)
   8822         fail("Encoding set despite failing allocator");
   8823     else if (i == max_alloc_count)
   8824         fail("Encoding not set at max allocation count");
   8825 }
   8826 END_TEST
   8827 
   8828 /* Test robustness of XML_SetBase against a failing allocator */
   8829 START_TEST(test_alloc_set_base)
   8830 {
   8831     const XML_Char *new_base = XCS("/local/file/name.xml");
   8832     int i;
   8833     const int max_alloc_count = 5;
   8834 
   8835     for (i = 0; i < max_alloc_count; i++) {
   8836         allocation_count = i;
   8837         if (XML_SetBase(parser, new_base) == XML_STATUS_OK)
   8838             break;
   8839     }
   8840     if (i == 0)
   8841         fail("Base set despite failing allocator");
   8842     else if (i == max_alloc_count)
   8843         fail("Base not set with max allocation count");
   8844 }
   8845 END_TEST
   8846 
   8847 /* Test buffer extension in the face of a duff reallocator */
   8848 START_TEST(test_alloc_realloc_buffer)
   8849 {
   8850     const char *text = get_buffer_test_text;
   8851     void *buffer;
   8852     int i;
   8853     const int max_realloc_count = 10;
   8854 
   8855     /* Get a smallish buffer */
   8856     for (i = 0; i < max_realloc_count; i++) {
   8857         reallocation_count = i;
   8858         buffer = XML_GetBuffer(parser, 1536);
   8859         if (buffer == NULL)
   8860             fail("1.5K buffer reallocation failed");
   8861         memcpy(buffer, text, strlen(text));
   8862         if (XML_ParseBuffer(parser, strlen(text),
   8863                             XML_FALSE) == XML_STATUS_OK)
   8864             break;
   8865         /* See comment in test_alloc_parse_xdecl() */
   8866         alloc_teardown();
   8867         alloc_setup();
   8868     }
   8869     reallocation_count = -1;
   8870     if (i == 0)
   8871         fail("Parse succeeded with no reallocation");
   8872     else if (i == max_realloc_count)
   8873         fail("Parse failed with max reallocation count");
   8874 }
   8875 END_TEST
   8876 
   8877 /* Same test for external entity parsers */
   8878 static int XMLCALL
   8879 external_entity_reallocator(XML_Parser parser,
   8880                             const XML_Char *context,
   8881                             const XML_Char *UNUSED_P(base),
   8882                             const XML_Char *UNUSED_P(systemId),
   8883                             const XML_Char *UNUSED_P(publicId))
   8884 {
   8885     const char *text = get_buffer_test_text;
   8886     XML_Parser ext_parser;
   8887     void *buffer;
   8888     enum XML_Status status;
   8889 
   8890     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   8891     if (ext_parser == NULL)
   8892         fail("Could not create external entity parser");
   8893 
   8894     reallocation_count = (intptr_t)XML_GetUserData(parser);
   8895     buffer = XML_GetBuffer(ext_parser, 1536);
   8896     if (buffer == NULL)
   8897         fail("Buffer allocation failed");
   8898     memcpy(buffer, text, strlen(text));
   8899     status = XML_ParseBuffer(ext_parser, strlen(text), XML_FALSE);
   8900     reallocation_count = -1;
   8901     XML_ParserFree(ext_parser);
   8902     return (status == XML_STATUS_OK) ? XML_STATUS_OK : XML_STATUS_ERROR;
   8903 }
   8904 
   8905 START_TEST(test_alloc_ext_entity_realloc_buffer)
   8906 {
   8907     const char *text =
   8908         "<!DOCTYPE doc [\n"
   8909         "  <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
   8910         "]>\n"
   8911         "<doc>&en;</doc>";
   8912     int i;
   8913     const int max_realloc_count = 10;
   8914 
   8915     for (i = 0; i < max_realloc_count; i++) {
   8916         XML_SetExternalEntityRefHandler(parser,
   8917                                         external_entity_reallocator);
   8918         XML_SetUserData(parser, (void *)(intptr_t)i);
   8919         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8920                                     XML_TRUE) == XML_STATUS_OK)
   8921             break;
   8922         /* See comment in test_alloc_parse_xdecl() */
   8923         alloc_teardown();
   8924         alloc_setup();
   8925     }
   8926     if (i == 0)
   8927         fail("Succeeded with no reallocations");
   8928     if (i == max_realloc_count)
   8929         fail("Failed with max reallocations");
   8930 }
   8931 END_TEST
   8932 
   8933 /* Test elements with many attributes are handled correctly */
   8934 START_TEST(test_alloc_realloc_many_attributes)
   8935 {
   8936     const char *text =
   8937         "<!DOCTYPE doc [\n"
   8938         "<!ATTLIST doc za CDATA 'default'>\n"
   8939         "<!ATTLIST doc zb CDATA 'def2'>\n"
   8940         "<!ATTLIST doc zc CDATA 'def3'>\n"
   8941         "]>\n"
   8942         "<doc a='1'"
   8943         "     b='2'"
   8944         "     c='3'"
   8945         "     d='4'"
   8946         "     e='5'"
   8947         "     f='6'"
   8948         "     g='7'"
   8949         "     h='8'"
   8950         "     i='9'"
   8951         "     j='10'"
   8952         "     k='11'"
   8953         "     l='12'"
   8954         "     m='13'"
   8955         "     n='14'"
   8956         "     p='15'"
   8957         "     q='16'"
   8958         "     r='17'"
   8959         "     s='18'>"
   8960         "</doc>";
   8961     int i;
   8962     const int max_realloc_count = 10;
   8963 
   8964     for (i = 0; i < max_realloc_count; i++) {
   8965         reallocation_count = i;
   8966         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   8967                                     XML_TRUE) != XML_STATUS_ERROR)
   8968             break;
   8969         /* See comment in test_alloc_parse_xdecl() */
   8970         alloc_teardown();
   8971         alloc_setup();
   8972     }
   8973     if (i == 0)
   8974         fail("Parse succeeded despite no reallocations");
   8975     if (i == max_realloc_count)
   8976         fail("Parse failed at max reallocations");
   8977 }
   8978 END_TEST
   8979 
   8980 /* Test handling of a public entity with failing allocator */
   8981 START_TEST(test_alloc_public_entity_value)
   8982 {
   8983     const char *text =
   8984         "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
   8985         "<doc></doc>\n";
   8986     char dtd_text[] =
   8987         "<!ELEMENT doc EMPTY>\n"
   8988         "<!ENTITY % e1 PUBLIC 'foo' 'bar.ent'>\n"
   8989         "<!ENTITY % "
   8990         /* Each line is 64 characters */
   8991         "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345"
   8992         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8993         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8994         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8995         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8996         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8997         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8998         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   8999         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9000         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9001         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9002         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9003         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9004         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9005         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9006         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9007         " '%e1;'>\n"
   9008         "%e1;\n";
   9009     int i;
   9010     const int max_alloc_count = 50;
   9011 
   9012     for (i = 0; i < max_alloc_count; i++) {
   9013         allocation_count = i;
   9014         dummy_handler_flags = 0;
   9015         XML_SetUserData(parser, dtd_text);
   9016         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   9017         XML_SetExternalEntityRefHandler(parser, external_entity_public);
   9018         /* Provoke a particular code path */
   9019         XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
   9020         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9021                                     XML_TRUE) != XML_STATUS_ERROR)
   9022             break;
   9023         /* See comment in test_alloc_parse_xdecl() */
   9024         alloc_teardown();
   9025         alloc_setup();
   9026     }
   9027     if (i == 0)
   9028         fail("Parsing worked despite failing allocation");
   9029     if (i == max_alloc_count)
   9030         fail("Parsing failed at max allocation count");
   9031     if (dummy_handler_flags != DUMMY_ENTITY_DECL_HANDLER_FLAG)
   9032         fail("Entity declaration handler not called");
   9033 }
   9034 END_TEST
   9035 
   9036 START_TEST(test_alloc_realloc_subst_public_entity_value)
   9037 {
   9038     const char *text =
   9039         "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
   9040         "<doc></doc>\n";
   9041     char dtd_text[] =
   9042         "<!ELEMENT doc EMPTY>\n"
   9043         "<!ENTITY % "
   9044         /* Each line is 64 characters */
   9045         "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345"
   9046         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9047         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9048         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9049         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9050         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9051         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9052         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9053         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9054         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9055         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9056         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9057         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9058         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9059         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9060         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9061         " PUBLIC 'foo' 'bar.ent'>\n"
   9062         "%ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345"
   9063         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9064         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9065         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9066         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9067         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9068         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9069         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9070         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9071         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9072         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9073         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9074         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9075         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9076         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9077         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP;";
   9078     int i;
   9079     const int max_realloc_count = 10;
   9080 
   9081     for (i = 0; i < max_realloc_count; i++) {
   9082         reallocation_count = i;
   9083         XML_SetUserData(parser, dtd_text);
   9084         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   9085         XML_SetExternalEntityRefHandler(parser, external_entity_public);
   9086         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9087                                     XML_TRUE) != XML_STATUS_ERROR)
   9088             break;
   9089         /* See comment in test_alloc_parse_xdecl() */
   9090         alloc_teardown();
   9091         alloc_setup();
   9092     }
   9093     if (i == 0)
   9094         fail("Parsing worked despite failing reallocation");
   9095     if (i == max_realloc_count)
   9096         fail("Parsing failed at max reallocation count");
   9097 }
   9098 END_TEST
   9099 
   9100 START_TEST(test_alloc_parse_public_doctype)
   9101 {
   9102     const char *text =
   9103         "<?xml version='1.0' encoding='utf-8'?>\n"
   9104         "<!DOCTYPE doc PUBLIC '"
   9105         /* 64 characters per line */
   9106         "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/"
   9107         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9108         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9109         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9110         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9111         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9112         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9113         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9114         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9115         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9116         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9117         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9118         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9119         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9120         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9121         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9122         "' 'test'>\n"
   9123         "<doc></doc>";
   9124     int i;
   9125     const int max_alloc_count = 25;
   9126 
   9127     for (i = 0; i < max_alloc_count; i++) {
   9128         allocation_count = i;
   9129         dummy_handler_flags = 0;
   9130         XML_SetDoctypeDeclHandler(parser,
   9131                                   dummy_start_doctype_decl_handler,
   9132                                   dummy_end_doctype_decl_handler);
   9133         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9134                                     XML_TRUE) != XML_STATUS_ERROR)
   9135             break;
   9136         /* See comment in test_alloc_parse_xdecl() */
   9137         alloc_teardown();
   9138         alloc_setup();
   9139     }
   9140     if (i == 0)
   9141         fail("Parse succeeded despite failing allocator");
   9142     if (i == max_alloc_count)
   9143         fail("Parse failed at maximum allocation count");
   9144     if (dummy_handler_flags != (DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG |
   9145                                 DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG))
   9146         fail("Doctype handler functions not called");
   9147 }
   9148 END_TEST
   9149 
   9150 START_TEST(test_alloc_parse_public_doctype_long_name)
   9151 {
   9152     const char *text =
   9153         "<?xml version='1.0' encoding='utf-8'?>\n"
   9154         "<!DOCTYPE doc PUBLIC 'http://example.com/foo' '"
   9155         /* 64 characters per line */
   9156         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9157         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9158         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9159         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9160         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9161         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9162         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9163         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9164         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9165         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9166         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9167         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9168         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9169         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9170         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9171         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   9172         "'>\n"
   9173         "<doc></doc>";
   9174     int i;
   9175     const int max_alloc_count = 25;
   9176 
   9177     for (i = 0; i < max_alloc_count; i++) {
   9178         allocation_count = i;
   9179         XML_SetDoctypeDeclHandler(parser,
   9180                                   dummy_start_doctype_decl_handler,
   9181                                   dummy_end_doctype_decl_handler);
   9182         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9183                                     XML_TRUE) != XML_STATUS_ERROR)
   9184             break;
   9185         /* See comment in test_alloc_parse_xdecl() */
   9186         alloc_teardown();
   9187         alloc_setup();
   9188     }
   9189     if (i == 0)
   9190         fail("Parse succeeded despite failing allocator");
   9191     if (i == max_alloc_count)
   9192         fail("Parse failed at maximum allocation count");
   9193 }
   9194 END_TEST
   9195 
   9196 static int XMLCALL
   9197 external_entity_alloc(XML_Parser parser,
   9198                       const XML_Char *context,
   9199                       const XML_Char *UNUSED_P(base),
   9200                       const XML_Char *UNUSED_P(systemId),
   9201                       const XML_Char *UNUSED_P(publicId))
   9202 {
   9203     const char *text = (const char *)XML_GetUserData(parser);
   9204     XML_Parser ext_parser;
   9205     int parse_res;
   9206 
   9207     ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   9208     if (ext_parser == NULL)
   9209         return XML_STATUS_ERROR;
   9210     parse_res = _XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
   9211                                         XML_TRUE);
   9212     XML_ParserFree(ext_parser);
   9213     return parse_res;
   9214 }
   9215 
   9216 /* Test foreign DTD handling */
   9217 START_TEST(test_alloc_set_foreign_dtd)
   9218 {
   9219     const char *text1 =
   9220         "<?xml version='1.0' encoding='us-ascii'?>\n"
   9221         "<doc>&entity;</doc>";
   9222     char text2[] = "<!ELEMENT doc (#PCDATA)*>";
   9223     int i;
   9224     const int max_alloc_count = 25;
   9225 
   9226     for (i = 0; i < max_alloc_count; i++) {
   9227         allocation_count = i;
   9228         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   9229         XML_SetUserData(parser, &text2);
   9230         XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
   9231         if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE)
   9232             fail("Could not set foreign DTD");
   9233         if (_XML_Parse_SINGLE_BYTES(parser, text1, strlen(text1),
   9234                                     XML_TRUE) != XML_STATUS_ERROR)
   9235             break;
   9236         /* See comment in test_alloc_parse_xdecl() */
   9237         alloc_teardown();
   9238         alloc_setup();
   9239     }
   9240     if (i == 0)
   9241         fail("Parse succeeded despite failing allocator");
   9242     if (i == max_alloc_count)
   9243         fail("Parse failed at maximum allocation count");
   9244 }
   9245 END_TEST
   9246 
   9247 /* Test based on ibm/valid/P32/ibm32v04.xml */
   9248 START_TEST(test_alloc_attribute_enum_value)
   9249 {
   9250     const char *text =
   9251         "<?xml version='1.0' standalone='no'?>\n"
   9252         "<!DOCTYPE animal SYSTEM 'test.dtd'>\n"
   9253         "<animal>This is a \n    <a/>  \n\nyellow tiger</animal>";
   9254     char dtd_text[] =
   9255         "<!ELEMENT animal (#PCDATA|a)*>\n"
   9256         "<!ELEMENT a EMPTY>\n"
   9257         "<!ATTLIST animal xml:space (default|preserve) 'preserve'>";
   9258     int i;
   9259     const int max_alloc_count = 30;
   9260 
   9261     for (i = 0; i < max_alloc_count; i++) {
   9262         allocation_count = i;
   9263         XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
   9264         XML_SetUserData(parser, dtd_text);
   9265         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   9266         /* An attribute list handler provokes a different code path */
   9267         XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
   9268         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9269                                     XML_TRUE) != XML_STATUS_ERROR)
   9270             break;
   9271         /* See comment in test_alloc_parse_xdecl() */
   9272         alloc_teardown();
   9273         alloc_setup();
   9274     }
   9275     if (i == 0)
   9276         fail("Parse succeeded despite failing allocator");
   9277     if (i == max_alloc_count)
   9278         fail("Parse failed at maximum allocation count");
   9279 }
   9280 END_TEST
   9281 
   9282 /* Test attribute enums sufficient to overflow the string pool */
   9283 START_TEST(test_alloc_realloc_attribute_enum_value)
   9284 {
   9285     const char *text =
   9286         "<?xml version='1.0' standalone='no'?>\n"
   9287         "<!DOCTYPE animal SYSTEM 'test.dtd'>\n"
   9288         "<animal>This is a yellow tiger</animal>";
   9289     /* We wish to define a collection of attribute enums that will
   9290      * cause the string pool storing them to have to expand.  This
   9291      * means more than 1024 bytes, including the parentheses and
   9292      * separator bars.
   9293      */
   9294     char dtd_text[] =
   9295         "<!ELEMENT animal (#PCDATA)*>\n"
   9296         "<!ATTLIST animal thing "
   9297         "(default"
   9298         /* Each line is 64 characters */
   9299         "|ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9300         "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9301         "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9302         "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9303         "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9304         "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9305         "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9306         "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9307         "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9308         "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9309         "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9310         "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9311         "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9312         "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9313         "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9314         "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO)"
   9315         " 'default'>";
   9316     int i;
   9317     const int max_realloc_count = 10;
   9318 
   9319     for (i = 0; i < max_realloc_count; i++) {
   9320         reallocation_count = i;
   9321         XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
   9322         XML_SetUserData(parser, dtd_text);
   9323         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   9324         /* An attribute list handler provokes a different code path */
   9325         XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
   9326         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9327                                     XML_TRUE) != XML_STATUS_ERROR)
   9328             break;
   9329         /* See comment in test_alloc_parse_xdecl() */
   9330         alloc_teardown();
   9331         alloc_setup();
   9332     }
   9333     if (i == 0)
   9334         fail("Parse succeeded despite failing reallocator");
   9335     if (i == max_realloc_count)
   9336         fail("Parse failed at maximum reallocation count");
   9337 }
   9338 END_TEST
   9339 
   9340 /* Test attribute enums in a #IMPLIED attribute forcing pool growth */
   9341 START_TEST(test_alloc_realloc_implied_attribute)
   9342 {
   9343     /* Forcing this particular code path is a balancing act.  The
   9344      * addition of the closing parenthesis and terminal NUL must be
   9345      * what pushes the string of enums over the 1024-byte limit,
   9346      * otherwise a different code path will pick up the realloc.
   9347      */
   9348     const char *text =
   9349         "<!DOCTYPE doc [\n"
   9350         "<!ELEMENT doc EMPTY>\n"
   9351         "<!ATTLIST doc a "
   9352         /* Each line is 64 characters */
   9353         "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9354         "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9355         "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9356         "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9357         "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9358         "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9359         "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9360         "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9361         "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9362         "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9363         "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9364         "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9365         "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9366         "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9367         "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9368         "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)"
   9369         " #IMPLIED>\n"
   9370         "]><doc/>";
   9371     int i;
   9372     const int max_realloc_count = 10;
   9373 
   9374     for (i = 0; i < max_realloc_count; i++) {
   9375         reallocation_count = i;
   9376         XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
   9377         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9378                                     XML_TRUE) != XML_STATUS_ERROR)
   9379             break;
   9380         /* See comment in test_alloc_parse_xdecl() */
   9381         alloc_teardown();
   9382         alloc_setup();
   9383     }
   9384     if (i == 0)
   9385         fail("Parse succeeded despite failing reallocator");
   9386     if (i == max_realloc_count)
   9387         fail("Parse failed at maximum reallocation count");
   9388 }
   9389 END_TEST
   9390 
   9391 /* Test attribute enums in a defaulted attribute forcing pool growth */
   9392 START_TEST(test_alloc_realloc_default_attribute)
   9393 {
   9394     /* Forcing this particular code path is a balancing act.  The
   9395      * addition of the closing parenthesis and terminal NUL must be
   9396      * what pushes the string of enums over the 1024-byte limit,
   9397      * otherwise a different code path will pick up the realloc.
   9398      */
   9399     const char *text =
   9400         "<!DOCTYPE doc [\n"
   9401         "<!ELEMENT doc EMPTY>\n"
   9402         "<!ATTLIST doc a "
   9403         /* Each line is 64 characters */
   9404         "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9405         "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9406         "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9407         "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9408         "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9409         "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9410         "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9411         "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9412         "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9413         "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9414         "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9415         "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9416         "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9417         "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9418         "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
   9419         "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)"
   9420         " 'ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO'"
   9421         ">\n]><doc/>";
   9422     int i;
   9423     const int max_realloc_count = 10;
   9424 
   9425     for (i = 0; i < max_realloc_count; i++) {
   9426         reallocation_count = i;
   9427         XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
   9428         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9429                                     XML_TRUE) != XML_STATUS_ERROR)
   9430             break;
   9431         /* See comment in test_alloc_parse_xdecl() */
   9432         alloc_teardown();
   9433         alloc_setup();
   9434     }
   9435     if (i == 0)
   9436         fail("Parse succeeded despite failing reallocator");
   9437     if (i == max_realloc_count)
   9438         fail("Parse failed at maximum reallocation count");
   9439 }
   9440 END_TEST
   9441 
   9442 /* Test long notation name with dodgy allocator */
   9443 START_TEST(test_alloc_notation)
   9444 {
   9445     const char *text =
   9446         "<!DOCTYPE doc [\n"
   9447         "<!NOTATION "
   9448         /* Each line is 64 characters */
   9449         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9450         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9451         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9452         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9453         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9454         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9455         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9456         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9457         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9458         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9459         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9460         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9461         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9462         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9463         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9464         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9465         " SYSTEM 'http://example.org/n'>\n"
   9466         "<!ENTITY e SYSTEM 'http://example.org/e' NDATA "
   9467         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9468         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9469         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9470         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9471         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9472         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9473         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9474         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9475         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9476         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9477         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9478         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9479         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9480         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9481         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9482         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9483         ">\n"
   9484         "<!ELEMENT doc EMPTY>\n"
   9485         "]>\n<doc/>";
   9486     int i;
   9487     const int max_alloc_count = 20;
   9488 
   9489     for (i = 0; i < max_alloc_count; i++) {
   9490         allocation_count = i;
   9491         dummy_handler_flags = 0;
   9492         XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
   9493         XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
   9494         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9495                                     XML_TRUE) != XML_STATUS_ERROR)
   9496             break;
   9497         /* See comment in test_alloc_parse_xdecl() */
   9498         alloc_teardown();
   9499         alloc_setup();
   9500     }
   9501     if (i == 0)
   9502         fail("Parse succeeded despite allocation failures");
   9503     if (i == max_alloc_count)
   9504         fail("Parse failed at maximum allocation count");
   9505     if (dummy_handler_flags != (DUMMY_ENTITY_DECL_HANDLER_FLAG |
   9506                                 DUMMY_NOTATION_DECL_HANDLER_FLAG))
   9507         fail("Entity declaration handler not called");
   9508 }
   9509 END_TEST
   9510 
   9511 /* Test public notation with dodgy allocator */
   9512 START_TEST(test_alloc_public_notation)
   9513 {
   9514     const char *text =
   9515         "<!DOCTYPE doc [\n"
   9516         "<!NOTATION note PUBLIC '"
   9517         /* 64 characters per line */
   9518         "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/"
   9519         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9520         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9521         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9522         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9523         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9524         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9525         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9526         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9527         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9528         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9529         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9530         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9531         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9532         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9533         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9534         "' 'foo'>\n"
   9535         "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n"
   9536         "<!ELEMENT doc EMPTY>\n"
   9537         "]>\n<doc/>";
   9538     int i;
   9539     const int max_alloc_count = 20;
   9540 
   9541     for (i = 0; i < max_alloc_count; i++) {
   9542         allocation_count = i;
   9543         dummy_handler_flags = 0;
   9544         XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
   9545         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9546                                     XML_TRUE) != XML_STATUS_ERROR)
   9547             break;
   9548         /* See comment in test_alloc_parse_xdecl() */
   9549         alloc_teardown();
   9550         alloc_setup();
   9551     }
   9552     if (i == 0)
   9553         fail("Parse succeeded despite allocation failures");
   9554     if (i == max_alloc_count)
   9555         fail("Parse failed at maximum allocation count");
   9556     if (dummy_handler_flags != DUMMY_NOTATION_DECL_HANDLER_FLAG)
   9557         fail("Notation handler not called");
   9558 }
   9559 END_TEST
   9560 
   9561 /* Test public notation with dodgy allocator */
   9562 START_TEST(test_alloc_system_notation)
   9563 {
   9564     const char *text =
   9565         "<!DOCTYPE doc [\n"
   9566         "<!NOTATION note SYSTEM '"
   9567         /* 64 characters per line */
   9568         "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/"
   9569         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9570         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9571         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9572         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9573         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9574         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9575         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9576         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9577         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9578         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9579         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9580         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9581         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9582         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9583         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   9584         "'>\n"
   9585         "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n"
   9586         "<!ELEMENT doc EMPTY>\n"
   9587         "]>\n<doc/>";
   9588     int i;
   9589     const int max_alloc_count = 20;
   9590 
   9591     for (i = 0; i < max_alloc_count; i++) {
   9592         allocation_count = i;
   9593         dummy_handler_flags = 0;
   9594         XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
   9595         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9596                                     XML_TRUE) != XML_STATUS_ERROR)
   9597             break;
   9598         /* See comment in test_alloc_parse_xdecl() */
   9599         alloc_teardown();
   9600         alloc_setup();
   9601     }
   9602     if (i == 0)
   9603         fail("Parse succeeded despite allocation failures");
   9604     if (i == max_alloc_count)
   9605         fail("Parse failed at maximum allocation count");
   9606     if (dummy_handler_flags != DUMMY_NOTATION_DECL_HANDLER_FLAG)
   9607         fail("Notation handler not called");
   9608 }
   9609 END_TEST
   9610 
   9611 START_TEST(test_alloc_nested_groups)
   9612 {
   9613     const char *text =
   9614         "<!DOCTYPE doc [\n"
   9615         "<!ELEMENT doc "
   9616         /* Sixteen elements per line */
   9617         "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,"
   9618         "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?"
   9619         "))))))))))))))))))))))))))))))))>\n"
   9620         "<!ELEMENT e EMPTY>"
   9621         "]>\n"
   9622         "<doc><e/></doc>";
   9623     CharData storage;
   9624     int i;
   9625     const int max_alloc_count = 20;
   9626 
   9627     for (i = 0; i < max_alloc_count; i++) {
   9628         allocation_count = i;
   9629         CharData_Init(&storage);
   9630         XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   9631         XML_SetStartElementHandler(parser, record_element_start_handler);
   9632         XML_SetUserData(parser, &storage);
   9633         dummy_handler_flags = 0;
   9634         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9635                                     XML_TRUE) != XML_STATUS_ERROR)
   9636             break;
   9637         /* See comment in test_alloc_parse_xdecl() */
   9638         alloc_teardown();
   9639         alloc_setup();
   9640     }
   9641 
   9642     if (i == 0)
   9643         fail("Parse succeeded despite failing reallocator");
   9644     if (i == max_alloc_count)
   9645         fail("Parse failed at maximum reallocation count");
   9646     CharData_CheckXMLChars(&storage, XCS("doce"));
   9647     if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
   9648         fail("Element handler not fired");
   9649 }
   9650 END_TEST
   9651 
   9652 START_TEST(test_alloc_realloc_nested_groups)
   9653 {
   9654     const char *text =
   9655         "<!DOCTYPE doc [\n"
   9656         "<!ELEMENT doc "
   9657         /* Sixteen elements per line */
   9658         "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,"
   9659         "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?"
   9660         "))))))))))))))))))))))))))))))))>\n"
   9661         "<!ELEMENT e EMPTY>"
   9662         "]>\n"
   9663         "<doc><e/></doc>";
   9664     CharData storage;
   9665     int i;
   9666     const int max_realloc_count = 10;
   9667 
   9668     for (i = 0; i < max_realloc_count; i++) {
   9669         reallocation_count = i;
   9670         CharData_Init(&storage);
   9671         XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   9672         XML_SetStartElementHandler(parser, record_element_start_handler);
   9673         XML_SetUserData(parser, &storage);
   9674         dummy_handler_flags = 0;
   9675         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9676                                     XML_TRUE) != XML_STATUS_ERROR)
   9677             break;
   9678         /* See comment in test_alloc_parse_xdecl() */
   9679         alloc_teardown();
   9680         alloc_setup();
   9681     }
   9682 
   9683     if (i == 0)
   9684         fail("Parse succeeded despite failing reallocator");
   9685     if (i == max_realloc_count)
   9686         fail("Parse failed at maximum reallocation count");
   9687     CharData_CheckXMLChars(&storage, XCS("doce"));
   9688     if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
   9689         fail("Element handler not fired");
   9690 }
   9691 END_TEST
   9692 
   9693 START_TEST(test_alloc_large_group)
   9694 {
   9695     const char *text =
   9696         "<!DOCTYPE doc [\n"
   9697         "<!ELEMENT doc ("
   9698         "a1|a2|a3|a4|a5|a6|a7|a8|"
   9699         "b1|b2|b3|b4|b5|b6|b7|b8|"
   9700         "c1|c2|c3|c4|c5|c6|c7|c8|"
   9701         "d1|d2|d3|d4|d5|d6|d7|d8|"
   9702         "e1"
   9703         ")+>\n"
   9704         "]>\n"
   9705         "<doc>\n"
   9706         "<a1/>\n"
   9707         "</doc>\n";
   9708     int i;
   9709     const int max_alloc_count = 50;
   9710 
   9711     for (i = 0; i < max_alloc_count; i++) {
   9712         allocation_count = i;
   9713         XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   9714         dummy_handler_flags = 0;
   9715         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9716                                     XML_TRUE) != XML_STATUS_ERROR)
   9717             break;
   9718         /* See comment in test_alloc_parse_xdecl() */
   9719         alloc_teardown();
   9720         alloc_setup();
   9721     }
   9722     if (i == 0)
   9723         fail("Parse succeeded despite failing allocator");
   9724     if (i == max_alloc_count)
   9725         fail("Parse failed at maximum allocation count");
   9726     if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
   9727         fail("Element handler flag not raised");
   9728 }
   9729 END_TEST
   9730 
   9731 START_TEST(test_alloc_realloc_group_choice)
   9732 {
   9733     const char *text =
   9734         "<!DOCTYPE doc [\n"
   9735         "<!ELEMENT doc ("
   9736         "a1|a2|a3|a4|a5|a6|a7|a8|"
   9737         "b1|b2|b3|b4|b5|b6|b7|b8|"
   9738         "c1|c2|c3|c4|c5|c6|c7|c8|"
   9739         "d1|d2|d3|d4|d5|d6|d7|d8|"
   9740         "e1"
   9741         ")+>\n"
   9742         "]>\n"
   9743         "<doc>\n"
   9744         "<a1/>\n"
   9745         "<b2 attr='foo'>This is a foo</b2>\n"
   9746         "<c3></c3>\n"
   9747         "</doc>\n";
   9748     int i;
   9749     const int max_realloc_count = 10;
   9750 
   9751     for (i = 0; i < max_realloc_count; i++) {
   9752         reallocation_count = i;
   9753         XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
   9754         dummy_handler_flags = 0;
   9755         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9756                                     XML_TRUE) != XML_STATUS_ERROR)
   9757             break;
   9758         /* See comment in test_alloc_parse_xdecl() */
   9759         alloc_teardown();
   9760         alloc_setup();
   9761     }
   9762     if (i == 0)
   9763         fail("Parse succeeded despite failing reallocator");
   9764     if (i == max_realloc_count)
   9765         fail("Parse failed at maximum reallocation count");
   9766     if (dummy_handler_flags != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
   9767         fail("Element handler flag not raised");
   9768 }
   9769 END_TEST
   9770 
   9771 START_TEST(test_alloc_pi_in_epilog)
   9772 {
   9773     const char *text =
   9774         "<doc></doc>\n"
   9775         "<?pi in epilog?>";
   9776     int i;
   9777     const int max_alloc_count = 15;
   9778 
   9779     for (i = 0; i < max_alloc_count; i++) {
   9780         allocation_count = i;
   9781         XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
   9782         dummy_handler_flags = 0;
   9783         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9784                                     XML_TRUE) != XML_STATUS_ERROR)
   9785             break;
   9786         /* See comment in test_alloc_parse_xdecl() */
   9787         alloc_teardown();
   9788         alloc_setup();
   9789     }
   9790     if (i == 0)
   9791         fail("Parse completed despite failing allocator");
   9792     if (i == max_alloc_count)
   9793         fail("Parse failed at maximum allocation count");
   9794     if (dummy_handler_flags != DUMMY_PI_HANDLER_FLAG)
   9795         fail("Processing instruction handler not invoked");
   9796 }
   9797 END_TEST
   9798 
   9799 START_TEST(test_alloc_comment_in_epilog)
   9800 {
   9801     const char *text =
   9802         "<doc></doc>\n"
   9803         "<!-- comment in epilog -->";
   9804     int i;
   9805     const int max_alloc_count = 15;
   9806 
   9807     for (i = 0; i < max_alloc_count; i++) {
   9808         allocation_count = i;
   9809         XML_SetCommentHandler(parser, dummy_comment_handler);
   9810         dummy_handler_flags = 0;
   9811         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9812                                     XML_TRUE) != XML_STATUS_ERROR)
   9813             break;
   9814         /* See comment in test_alloc_parse_xdecl() */
   9815         alloc_teardown();
   9816         alloc_setup();
   9817     }
   9818     if (i == 0)
   9819         fail("Parse completed despite failing allocator");
   9820     if (i == max_alloc_count)
   9821         fail("Parse failed at maximum allocation count");
   9822     if (dummy_handler_flags != DUMMY_COMMENT_HANDLER_FLAG)
   9823         fail("Processing instruction handler not invoked");
   9824 }
   9825 END_TEST
   9826 
   9827 START_TEST(test_alloc_realloc_long_attribute_value)
   9828 {
   9829     const char *text =
   9830         "<!DOCTYPE doc [<!ENTITY foo '"
   9831         /* Each line is 64 characters */
   9832         "This entity will be substituted as an attribute value, and is   "
   9833         "calculated to be exactly long enough that the terminating NUL   "
   9834         "that the library adds internally will trigger the string pool to"
   9835         "grow. GHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9836         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9837         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9838         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9839         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9840         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9841         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9842         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9843         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9844         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9845         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9846         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9847         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9848         "'>]>\n"
   9849         "<doc a='&foo;'></doc>";
   9850     int i;
   9851     const int max_realloc_count = 10;
   9852 
   9853     for (i = 0; i < max_realloc_count; i++) {
   9854         reallocation_count = i;
   9855         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9856                                     XML_TRUE) != XML_STATUS_ERROR)
   9857             break;
   9858         /* See comment in test_alloc_parse_xdecl() */
   9859         alloc_teardown();
   9860         alloc_setup();
   9861     }
   9862     if (i == 0)
   9863         fail("Parse succeeded despite failing reallocator");
   9864     if (i == max_realloc_count)
   9865         fail("Parse failed at maximum reallocation count");
   9866 }
   9867 END_TEST
   9868 
   9869 START_TEST(test_alloc_attribute_whitespace)
   9870 {
   9871     const char *text = "<doc a=' '></doc>";
   9872     int i;
   9873     const int max_alloc_count = 15;
   9874 
   9875     for (i = 0; i < max_alloc_count; i++) {
   9876         allocation_count = i;
   9877         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9878                                     XML_TRUE) != XML_STATUS_ERROR)
   9879             break;
   9880         /* See comment in test_alloc_parse_xdecl() */
   9881         alloc_teardown();
   9882         alloc_setup();
   9883     }
   9884     if (i == 0)
   9885         fail("Parse succeeded despite failing allocator");
   9886     if (i == max_alloc_count)
   9887         fail("Parse failed at maximum allocation count");
   9888 }
   9889 END_TEST
   9890 
   9891 START_TEST(test_alloc_attribute_predefined_entity)
   9892 {
   9893     const char *text = "<doc a='&amp;'></doc>";
   9894     int i;
   9895     const int max_alloc_count = 15;
   9896 
   9897     for (i = 0; i < max_alloc_count; i++) {
   9898         allocation_count = i;
   9899         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9900                                     XML_TRUE) != XML_STATUS_ERROR)
   9901             break;
   9902         /* See comment in test_alloc_parse_xdecl() */
   9903         alloc_teardown();
   9904         alloc_setup();
   9905     }
   9906     if (i == 0)
   9907         fail("Parse succeeded despite failing allocator");
   9908     if (i == max_alloc_count)
   9909         fail("Parse failed at maximum allocation count");
   9910 }
   9911 END_TEST
   9912 
   9913 /* Test that a character reference at the end of a suitably long
   9914  * default value for an attribute can trigger pool growth, and recovers
   9915  * if the allocator fails on it.
   9916  */
   9917 START_TEST(test_alloc_long_attr_default_with_char_ref)
   9918 {
   9919     const char *text =
   9920         "<!DOCTYPE doc [<!ATTLIST doc a CDATA '"
   9921         /* 64 characters per line */
   9922         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9923         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9924         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9925         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9926         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9927         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9928         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9929         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9930         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9931         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9932         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9933         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9934         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9935         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9936         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9937         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHI"
   9938         "&#x31;'>]>\n"
   9939         "<doc/>";
   9940     int i;
   9941     const int max_alloc_count = 20;
   9942 
   9943     for (i = 0; i < max_alloc_count; i++) {
   9944         allocation_count = i;
   9945         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9946                                     XML_TRUE) != XML_STATUS_ERROR)
   9947             break;
   9948         /* See comment in test_alloc_parse_xdecl() */
   9949         alloc_teardown();
   9950         alloc_setup();
   9951     }
   9952     if (i == 0)
   9953         fail("Parse succeeded despite failing allocator");
   9954     if (i == max_alloc_count)
   9955         fail("Parse failed at maximum allocation count");
   9956 }
   9957 END_TEST
   9958 
   9959 /* Test that a long character reference substitution triggers a pool
   9960  * expansion correctly for an attribute value.
   9961  */
   9962 START_TEST(test_alloc_long_attr_value)
   9963 {
   9964     const char *text =
   9965         "<!DOCTYPE test [<!ENTITY foo '\n"
   9966         /* 64 characters per line */
   9967         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9968         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9969         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9970         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9971         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9972         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9973         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9974         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9975         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9976         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9977         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9978         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9979         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9980         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9981         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9982         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   9983         "'>]>\n"
   9984         "<test a='&foo;'/>";
   9985     int i;
   9986     const int max_alloc_count = 25;
   9987 
   9988     for (i = 0; i < max_alloc_count; i++) {
   9989         allocation_count = i;
   9990         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   9991                                     XML_TRUE) != XML_STATUS_ERROR)
   9992             break;
   9993         /* See comment in test_alloc_parse_xdecl() */
   9994         alloc_teardown();
   9995         alloc_setup();
   9996     }
   9997     if (i == 0)
   9998         fail("Parse succeeded despite failing allocator");
   9999     if (i == max_alloc_count)
   10000         fail("Parse failed at maximum allocation count");
   10001 }
   10002 END_TEST
   10003 
   10004 /* Test that an error in a nested parameter entity substitution is
   10005  * handled correctly.  It seems unlikely that the code path being
   10006  * exercised can be reached purely by carefully crafted XML, but an
   10007  * allocation error in the right place will definitely do it.
   10008  */
   10009 START_TEST(test_alloc_nested_entities)
   10010 {
   10011     const char *text =
   10012         "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n"
   10013         "<doc />";
   10014     ExtFaults test_data = {
   10015         "<!ENTITY % pe1 '"
   10016         /* 64 characters per line */
   10017         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10018         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10019         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10020         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10021         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10022         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10023         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10024         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10025         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10026         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10027         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10028         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10029         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10030         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10031         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10032         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10033         "'>\n"
   10034         "<!ENTITY % pe2 '%pe1;'>\n"
   10035         "%pe2;",
   10036         "Memory Fail not faulted",
   10037         NULL,
   10038         XML_ERROR_NO_MEMORY
   10039     };
   10040 
   10041     /* Causes an allocation error in a nested storeEntityValue() */
   10042     allocation_count = 12;
   10043     XML_SetUserData(parser, &test_data);
   10044     XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   10045     XML_SetExternalEntityRefHandler(parser, external_entity_faulter);
   10046     expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
   10047                    "Entity allocation failure not noted");
   10048 }
   10049 END_TEST
   10050 
   10051 START_TEST(test_alloc_realloc_param_entity_newline)
   10052 {
   10053     const char *text =
   10054         "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
   10055         "<doc/>";
   10056     char dtd_text[] =
   10057         "<!ENTITY % pe '<!ATTLIST doc att CDATA \""
   10058         /* 64 characters per line */
   10059         "This default value is carefully crafted so that the carriage    "
   10060         "return right at the end of the entity string causes an internal "
   10061         "string pool to have to grow.  This allows us to test the alloc  "
   10062         "failure path from that point. OPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10063         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10064         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10065         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10066         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10067         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10068         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10069         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10070         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10071         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10072         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10073         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10074         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDE"
   10075         "\">\n'>"
   10076         "%pe;\n";
   10077     int i;
   10078     const int max_realloc_count = 5;
   10079 
   10080     for (i = 0; i < max_realloc_count; i++) {
   10081         reallocation_count = i;
   10082         XML_SetUserData(parser, dtd_text);
   10083         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   10084         XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
   10085         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10086                                     XML_TRUE) != XML_STATUS_ERROR)
   10087             break;
   10088         /* See comment in test_alloc_parse_xdecl() */
   10089         alloc_teardown();
   10090         alloc_setup();
   10091     }
   10092     if (i == 0)
   10093         fail("Parse succeeded despite failing reallocator");
   10094     if (i == max_realloc_count)
   10095         fail("Parse failed at maximum reallocation count");
   10096 }
   10097 END_TEST
   10098 
   10099 START_TEST(test_alloc_realloc_ce_extends_pe)
   10100 {
   10101     const char *text =
   10102         "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
   10103         "<doc/>";
   10104     char dtd_text[] =
   10105         "<!ENTITY % pe '<!ATTLIST doc att CDATA \""
   10106         /* 64 characters per line */
   10107         "This default value is carefully crafted so that the character   "
   10108         "entity at the end causes an internal string pool to have to     "
   10109         "grow.  This allows us to test the allocation failure path from  "
   10110         "that point onwards. EFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10111         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10112         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10113         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10114         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10115         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10116         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10117         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10118         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10119         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10120         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10121         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   10122         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFG&#x51;"
   10123         "\">\n'>"
   10124         "%pe;\n";
   10125     int i;
   10126     const int max_realloc_count = 5;
   10127 
   10128     for (i = 0; i < max_realloc_count; i++) {
   10129         reallocation_count = i;
   10130         XML_SetUserData(parser, dtd_text);
   10131         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   10132         XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
   10133         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10134                                     XML_TRUE) != XML_STATUS_ERROR)
   10135             break;
   10136         /* See comment in test_alloc_parse_xdecl() */
   10137         alloc_teardown();
   10138         alloc_setup();
   10139     }
   10140     if (i == 0)
   10141         fail("Parse succeeded despite failing reallocator");
   10142     if (i == max_realloc_count)
   10143         fail("Parse failed at maximum reallocation count");
   10144 }
   10145 END_TEST
   10146 
   10147 START_TEST(test_alloc_realloc_attributes)
   10148 {
   10149     const char *text =
   10150         "<!DOCTYPE doc [\n"
   10151         "  <!ATTLIST doc\n"
   10152         "    a1  (a|b|c)   'a'\n"
   10153         "    a2  (foo|bar) #IMPLIED\n"
   10154         "    a3  NMTOKEN   #IMPLIED\n"
   10155         "    a4  NMTOKENS  #IMPLIED\n"
   10156         "    a5  ID        #IMPLIED\n"
   10157         "    a6  IDREF     #IMPLIED\n"
   10158         "    a7  IDREFS    #IMPLIED\n"
   10159         "    a8  ENTITY    #IMPLIED\n"
   10160         "    a9  ENTITIES  #IMPLIED\n"
   10161         "    a10 CDATA     #IMPLIED\n"
   10162         "  >]>\n"
   10163         "<doc>wombat</doc>\n";
   10164     int i;
   10165     const int max_realloc_count = 5;
   10166 
   10167     for (i = 0; i < max_realloc_count; i++) {
   10168         reallocation_count = i;
   10169         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10170                                     XML_TRUE) != XML_STATUS_ERROR)
   10171             break;
   10172         /* See comment in test_alloc_parse_xdecl() */
   10173         alloc_teardown();
   10174         alloc_setup();
   10175     }
   10176 
   10177     if (i == 0)
   10178         fail("Parse succeeded despite failing reallocator");
   10179     if (i == max_realloc_count)
   10180         fail("Parse failed at maximum reallocation count");
   10181 }
   10182 END_TEST
   10183 
   10184 START_TEST(test_alloc_long_doc_name)
   10185 {
   10186     const char *text =
   10187         /* 64 characters per line */
   10188         "<LongRootElementNameThatWillCauseTheNextAllocationToExpandTheStr"
   10189         "ingPoolForTheDTDQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10190         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10191         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10192         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10193         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10194         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10195         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10196         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10197         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10198         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10199         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10200         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10201         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10202         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10203         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10204         " a='1'/>";
   10205     int i;
   10206     const int max_alloc_count = 20;
   10207 
   10208     for (i = 0; i < max_alloc_count; i++) {
   10209         allocation_count = i;
   10210         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10211                                     XML_TRUE) != XML_STATUS_ERROR)
   10212             break;
   10213         /* See comment in test_alloc_parse_xdecl() */
   10214         alloc_teardown();
   10215         alloc_setup();
   10216     }
   10217     if (i == 0)
   10218         fail("Parsing worked despite failing reallocations");
   10219     else if (i == max_alloc_count)
   10220         fail("Parsing failed even at max reallocation count");
   10221 }
   10222 END_TEST
   10223 
   10224 START_TEST(test_alloc_long_base)
   10225 {
   10226     const char *text =
   10227         "<!DOCTYPE doc [\n"
   10228         "  <!ENTITY e SYSTEM 'foo'>\n"
   10229         "]>\n"
   10230         "<doc>&e;</doc>";
   10231     char entity_text[] = "Hello world";
   10232     const XML_Char *base =
   10233         /* 64 characters per line */
   10234         XCS("LongBaseURI/that/will/overflow/an/internal/buffer/and/cause/it/t")
   10235         XCS("o/have/to/grow/PQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10236         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10237         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10238         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10239         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10240         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10241         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10242         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10243         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10244         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10245         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10246         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10247         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10248         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
   10249         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/");
   10250     int i;
   10251     const int max_alloc_count = 25;
   10252 
   10253     for (i = 0; i < max_alloc_count; i++) {
   10254         allocation_count = i;
   10255         XML_SetUserData(parser, entity_text);
   10256         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   10257         XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
   10258         if (XML_SetBase(parser, base) == XML_STATUS_ERROR) {
   10259             XML_ParserReset(parser, NULL);
   10260             continue;
   10261         }
   10262         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10263                                     XML_TRUE) != XML_STATUS_ERROR)
   10264             break;
   10265         /* See comment in test_alloc_parse_xdecl() */
   10266         alloc_teardown();
   10267         alloc_setup();
   10268     }
   10269     if (i == 0)
   10270         fail("Parsing worked despite failing allocations");
   10271     else if (i == max_alloc_count)
   10272         fail("Parsing failed even at max allocation count");
   10273 }
   10274 END_TEST
   10275 
   10276 START_TEST(test_alloc_long_public_id)
   10277 {
   10278     const char *text =
   10279         "<!DOCTYPE doc [\n"
   10280         "  <!ENTITY e PUBLIC '"
   10281         /* 64 characters per line */
   10282         "LongPublicIDThatShouldResultInAnInternalStringPoolGrowingAtASpec"
   10283         "ificMomentKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10284         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10285         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10286         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10287         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10288         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10289         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10290         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10291         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10292         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10293         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10294         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10295         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10296         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10297         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10298         "' 'bar'>\n"
   10299         "]>\n"
   10300         "<doc>&e;</doc>";
   10301     char entity_text[] = "Hello world";
   10302     int i;
   10303     const int max_alloc_count = 40;
   10304 
   10305     for (i = 0; i < max_alloc_count; i++) {
   10306         allocation_count = i;
   10307         XML_SetUserData(parser, entity_text);
   10308         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   10309         XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
   10310         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10311                                     XML_TRUE) != XML_STATUS_ERROR)
   10312             break;
   10313         /* See comment in test_alloc_parse_xdecl() */
   10314         alloc_teardown();
   10315         alloc_setup();
   10316     }
   10317     if (i == 0)
   10318         fail("Parsing worked despite failing allocations");
   10319     else if (i == max_alloc_count)
   10320         fail("Parsing failed even at max allocation count");
   10321 }
   10322 END_TEST
   10323 
   10324 START_TEST(test_alloc_long_entity_value)
   10325 {
   10326     const char *text =
   10327         "<!DOCTYPE doc [\n"
   10328         "  <!ENTITY e1 '"
   10329         /* 64 characters per line */
   10330         "Long entity value that should provoke a string pool to grow whil"
   10331         "e setting up to parse the external entity below. xyz0123456789AB"
   10332         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10333         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10334         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10335         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10336         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10337         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10338         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10339         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10340         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10341         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10342         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10343         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10344         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10345         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10346         "'>\n"
   10347         "  <!ENTITY e2 SYSTEM 'bar'>\n"
   10348         "]>\n"
   10349         "<doc>&e2;</doc>";
   10350     char entity_text[] = "Hello world";
   10351     int i;
   10352     const int max_alloc_count = 40;
   10353 
   10354     for (i = 0; i < max_alloc_count; i++) {
   10355         allocation_count = i;
   10356         XML_SetUserData(parser, entity_text);
   10357         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   10358         XML_SetExternalEntityRefHandler(parser, external_entity_alloc);
   10359         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10360                                     XML_TRUE) != XML_STATUS_ERROR)
   10361             break;
   10362         /* See comment in test_alloc_parse_xdecl() */
   10363         alloc_teardown();
   10364         alloc_setup();
   10365     }
   10366     if (i == 0)
   10367         fail("Parsing worked despite failing allocations");
   10368     else if (i == max_alloc_count)
   10369         fail("Parsing failed even at max allocation count");
   10370 }
   10371 END_TEST
   10372 
   10373 START_TEST(test_alloc_long_notation)
   10374 {
   10375     const char *text =
   10376         "<!DOCTYPE doc [\n"
   10377         "  <!NOTATION note SYSTEM '"
   10378         /* 64 characters per line */
   10379         "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn"
   10380         "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10381         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10382         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10383         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10384         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10385         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10386         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10387         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10388         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10389         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10390         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10391         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10392         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10393         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10394         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10395         "'>\n"
   10396         "  <!ENTITY e1 SYSTEM 'foo' NDATA "
   10397         /* 64 characters per line */
   10398         "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn"
   10399         "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10400         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10401         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10402         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10403         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10404         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10405         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10406         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10407         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10408         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10409         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10410         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10411         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10412         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10413         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
   10414         ">\n"
   10415         "  <!ENTITY e2 SYSTEM 'bar'>\n"
   10416         "]>\n"
   10417         "<doc>&e2;</doc>";
   10418     ExtOption options[] = {
   10419         { XCS("foo"), "Entity Foo" },
   10420         { XCS("bar"), "Entity Bar" },
   10421         { NULL, NULL }
   10422     };
   10423     int i;
   10424     const int max_alloc_count = 40;
   10425 
   10426     for (i = 0; i < max_alloc_count; i++) {
   10427         allocation_count = i;
   10428         XML_SetUserData(parser, options);
   10429         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   10430         XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
   10431         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10432                                     XML_TRUE) != XML_STATUS_ERROR)
   10433             break;
   10434 
   10435         /* See comment in test_alloc_parse_xdecl() */
   10436         alloc_teardown();
   10437         alloc_setup();
   10438     }
   10439     if (i == 0)
   10440         fail("Parsing worked despite failing allocations");
   10441     else if (i == max_alloc_count)
   10442         fail("Parsing failed even at max allocation count");
   10443 }
   10444 END_TEST
   10445 
   10446 
   10447 static void
   10448 nsalloc_setup(void)
   10449 {
   10450     XML_Memory_Handling_Suite memsuite = {
   10451         duff_allocator,
   10452         duff_reallocator,
   10453         free
   10454     };
   10455     XML_Char ns_sep[2] = { ' ', '\0' };
   10456 
   10457     /* Ensure the parser creation will go through */
   10458     allocation_count = ALLOC_ALWAYS_SUCCEED;
   10459     reallocation_count = REALLOC_ALWAYS_SUCCEED;
   10460     parser = XML_ParserCreate_MM(NULL, &memsuite, ns_sep);
   10461     if (parser == NULL)
   10462         fail("Parser not created");
   10463 }
   10464 
   10465 static void
   10466 nsalloc_teardown(void)
   10467 {
   10468     basic_teardown();
   10469 }
   10470 
   10471 
   10472 /* Test the effects of allocation failure in simple namespace parsing.
   10473  * Based on test_ns_default_with_empty_uri()
   10474  */
   10475 START_TEST(test_nsalloc_xmlns)
   10476 {
   10477     const char *text =
   10478         "<doc xmlns='http://example.org/'>\n"
   10479         "  <e xmlns=''/>\n"
   10480         "</doc>";
   10481     unsigned int i;
   10482     const unsigned int max_alloc_count = 30;
   10483 
   10484     for (i = 0; i < max_alloc_count; i++) {
   10485         allocation_count = i;
   10486         /* Exercise more code paths with a default handler */
   10487         XML_SetDefaultHandler(parser, dummy_default_handler);
   10488         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10489                                     XML_TRUE) != XML_STATUS_ERROR)
   10490             break;
   10491         /* Resetting the parser is insufficient, because some memory
   10492          * allocations are cached within the parser.  Instead we use
   10493          * the teardown and setup routines to ensure that we have the
   10494          * right sort of parser back in our hands.
   10495          */
   10496         nsalloc_teardown();
   10497         nsalloc_setup();
   10498     }
   10499     if (i == 0)
   10500         fail("Parsing worked despite failing allocations");
   10501     else if (i == max_alloc_count)
   10502         fail("Parsing failed even at maximum allocation count");
   10503 }
   10504 END_TEST
   10505 
   10506 /* Test XML_ParseBuffer interface with namespace and a dicky allocator */
   10507 START_TEST(test_nsalloc_parse_buffer)
   10508 {
   10509     const char *text = "<doc>Hello</doc>";
   10510     void *buffer;
   10511 
   10512     /* Try a parse before the start of the world */
   10513     /* (Exercises new code path) */
   10514     allocation_count = 0;
   10515     if (XML_ParseBuffer(parser, 0, XML_FALSE) != XML_STATUS_ERROR)
   10516         fail("Pre-init XML_ParseBuffer not faulted");
   10517     if (XML_GetErrorCode(parser) != XML_ERROR_NO_MEMORY)
   10518         fail("Pre-init XML_ParseBuffer faulted for wrong reason");
   10519 
   10520     /* Now with actual memory allocation */
   10521     allocation_count = ALLOC_ALWAYS_SUCCEED;
   10522     if (XML_ParseBuffer(parser, 0, XML_FALSE) != XML_STATUS_OK)
   10523         xml_failure(parser);
   10524 
   10525     /* Check that resuming an unsuspended parser is faulted */
   10526     if (XML_ResumeParser(parser) != XML_STATUS_ERROR)
   10527         fail("Resuming unsuspended parser not faulted");
   10528     if (XML_GetErrorCode(parser) != XML_ERROR_NOT_SUSPENDED)
   10529         xml_failure(parser);
   10530 
   10531     /* Get the parser into suspended state */
   10532     XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
   10533     resumable = XML_TRUE;
   10534     buffer = XML_GetBuffer(parser, strlen(text));
   10535     if (buffer == NULL)
   10536         fail("Could not acquire parse buffer");
   10537     memcpy(buffer, text, strlen(text));
   10538     if (XML_ParseBuffer(parser, strlen(text),
   10539                         XML_TRUE) != XML_STATUS_SUSPENDED)
   10540         xml_failure(parser);
   10541     if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
   10542         xml_failure(parser);
   10543     if (XML_ParseBuffer(parser, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
   10544         fail("Suspended XML_ParseBuffer not faulted");
   10545     if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
   10546         xml_failure(parser);
   10547     if (XML_GetBuffer(parser, strlen(text)) != NULL)
   10548         fail("Suspended XML_GetBuffer not faulted");
   10549 
   10550     /* Get it going again and complete the world */
   10551     XML_SetCharacterDataHandler(parser, NULL);
   10552     if (XML_ResumeParser(parser) != XML_STATUS_OK)
   10553         xml_failure(parser);
   10554     if (XML_ParseBuffer(parser, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
   10555         fail("Post-finishing XML_ParseBuffer not faulted");
   10556     if (XML_GetErrorCode(parser) != XML_ERROR_FINISHED)
   10557         xml_failure(parser);
   10558     if (XML_GetBuffer(parser, strlen(text)) != NULL)
   10559         fail("Post-finishing XML_GetBuffer not faulted");
   10560 }
   10561 END_TEST
   10562 
   10563 /* Check handling of long prefix names (pool growth) */
   10564 START_TEST(test_nsalloc_long_prefix)
   10565 {
   10566     const char *text =
   10567         "<"
   10568         /* 64 characters per line */
   10569         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10570         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10571         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10572         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10573         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10574         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10575         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10576         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10577         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10578         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10579         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10580         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10581         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10582         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10583         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10584         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10585         ":foo xmlns:"
   10586         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10587         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10588         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10589         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10590         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10591         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10592         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10593         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10594         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10595         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10596         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10597         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10598         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10599         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10600         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10601         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10602         "='http://example.org/'>"
   10603         "</"
   10604         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10605         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10606         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10607         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10608         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10609         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10610         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10611         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10612         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10613         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10614         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10615         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10616         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10617         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10618         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10619         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10620         ":foo>";
   10621     int i;
   10622     const int max_alloc_count = 40;
   10623 
   10624     for (i = 0; i < max_alloc_count; i++) {
   10625         allocation_count = i;
   10626         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10627                                     XML_TRUE) != XML_STATUS_ERROR)
   10628             break;
   10629         /* See comment in test_nsalloc_xmlns() */
   10630         nsalloc_teardown();
   10631         nsalloc_setup();
   10632     }
   10633     if (i == 0)
   10634         fail("Parsing worked despite failing allocations");
   10635     else if (i == max_alloc_count)
   10636         fail("Parsing failed even at max allocation count");
   10637 }
   10638 END_TEST
   10639 
   10640 /* Check handling of long uri names (pool growth) */
   10641 START_TEST(test_nsalloc_long_uri)
   10642 {
   10643     const char *text =
   10644         "<foo:e xmlns:foo='http://example.org/"
   10645         /* 64 characters per line */
   10646         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10647         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10648         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10649         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10650         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10651         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10652         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10653         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10654         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10655         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10656         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10657         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10658         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10659         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10660         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10661         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10662         "' bar:a='12'\n"
   10663         "xmlns:bar='http://example.org/"
   10664         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10665         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10666         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10667         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10668         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10669         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10670         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10671         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10672         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10673         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10674         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10675         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10676         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10677         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10678         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10679         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/"
   10680         "'>"
   10681         "</foo:e>";
   10682     int i;
   10683     const int max_alloc_count = 40;
   10684 
   10685     for (i = 0; i < max_alloc_count; i++) {
   10686         allocation_count = i;
   10687         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10688                                     XML_TRUE) != XML_STATUS_ERROR)
   10689             break;
   10690         /* See comment in test_nsalloc_xmlns() */
   10691         nsalloc_teardown();
   10692         nsalloc_setup();
   10693     }
   10694     if (i == 0)
   10695         fail("Parsing worked despite failing allocations");
   10696     else if (i == max_alloc_count)
   10697         fail("Parsing failed even at max allocation count");
   10698 }
   10699 END_TEST
   10700 
   10701 /* Test handling of long attribute names with prefixes */
   10702 START_TEST(test_nsalloc_long_attr)
   10703 {
   10704     const char *text =
   10705         "<foo:e xmlns:foo='http://example.org/' bar:"
   10706         /* 64 characters per line */
   10707         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10708         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10709         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10710         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10711         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10712         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10713         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10714         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10715         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10716         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10717         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10718         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10719         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10720         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10721         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10722         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10723         "='12'\n"
   10724         "xmlns:bar='http://example.org/'>"
   10725         "</foo:e>";
   10726     int i;
   10727     const int max_alloc_count = 40;
   10728 
   10729     for (i = 0; i < max_alloc_count; i++) {
   10730         allocation_count = i;
   10731         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10732                                     XML_TRUE) != XML_STATUS_ERROR)
   10733             break;
   10734         /* See comment in test_nsalloc_xmlns() */
   10735         nsalloc_teardown();
   10736         nsalloc_setup();
   10737     }
   10738     if (i == 0)
   10739         fail("Parsing worked despite failing allocations");
   10740     else if (i == max_alloc_count)
   10741         fail("Parsing failed even at max allocation count");
   10742 }
   10743 END_TEST
   10744 
   10745 /* Test handling of an attribute name with a long namespace prefix */
   10746 START_TEST(test_nsalloc_long_attr_prefix)
   10747 {
   10748     const char *text =
   10749         "<foo:e xmlns:foo='http://example.org/' "
   10750         /* 64 characters per line */
   10751         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10752         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10753         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10754         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10755         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10756         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10757         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10758         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10759         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10760         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10761         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10762         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10763         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10764         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10765         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10766         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10767         ":a='12'\n"
   10768         "xmlns:"
   10769         /* 64 characters per line */
   10770         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10771         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10772         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10773         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10774         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10775         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10776         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10777         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10778         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10779         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10780         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10781         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10782         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10783         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10784         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10785         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10786         "='http://example.org/'>"
   10787         "</foo:e>";
   10788     const XML_Char *elemstr[] = {
   10789         XCS("http://example.org/ e foo"),
   10790         XCS("http://example.org/ a ")
   10791         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10792         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10793         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10794         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10795         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10796         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10797         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10798         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10799         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10800         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10801         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10802         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10803         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10804         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10805         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10806         XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ")
   10807     };
   10808     int i;
   10809     const int max_alloc_count = 40;
   10810 
   10811     for (i = 0; i < max_alloc_count; i++) {
   10812         allocation_count = i;
   10813         XML_SetReturnNSTriplet(parser, XML_TRUE);
   10814         XML_SetUserData(parser, elemstr);
   10815         XML_SetElementHandler(parser,
   10816                               triplet_start_checker,
   10817                               triplet_end_checker);
   10818         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10819                                     XML_TRUE) != XML_STATUS_ERROR)
   10820             break;
   10821         /* See comment in test_nsalloc_xmlns() */
   10822         nsalloc_teardown();
   10823         nsalloc_setup();
   10824     }
   10825     if (i == 0)
   10826         fail("Parsing worked despite failing allocations");
   10827     else if (i == max_alloc_count)
   10828         fail("Parsing failed even at max allocation count");
   10829 }
   10830 END_TEST
   10831 
   10832 /* Test attribute handling in the face of a dodgy reallocator */
   10833 START_TEST(test_nsalloc_realloc_attributes)
   10834 {
   10835     const char *text =
   10836         "<foo:e xmlns:foo='http://example.org/' bar:a='12'\n"
   10837         "       xmlns:bar='http://example.org/'>"
   10838         "</foo:e>";
   10839     int i;
   10840     const int max_realloc_count = 10;
   10841 
   10842     for (i = 0; i < max_realloc_count; i++) {
   10843         reallocation_count = i;
   10844         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10845                                     XML_TRUE) != XML_STATUS_ERROR)
   10846             break;
   10847         /* See comment in test_nsalloc_xmlns() */
   10848         nsalloc_teardown();
   10849         nsalloc_setup();
   10850     }
   10851     if (i == 0)
   10852         fail("Parsing worked despite failing reallocations");
   10853     else if (i == max_realloc_count)
   10854         fail("Parsing failed at max reallocation count");
   10855 }
   10856 END_TEST
   10857 
   10858 /* Test long element names with namespaces under a failing allocator */
   10859 START_TEST(test_nsalloc_long_element)
   10860 {
   10861     const char *text =
   10862         "<foo:thisisalongenoughelementnametotriggerareallocation\n"
   10863         " xmlns:foo='http://example.org/' bar:a='12'\n"
   10864         " xmlns:bar='http://example.org/'>"
   10865         "</foo:thisisalongenoughelementnametotriggerareallocation>";
   10866     const XML_Char *elemstr[] = {
   10867         XCS("http://example.org/")
   10868         XCS(" thisisalongenoughelementnametotriggerareallocation foo"),
   10869         XCS("http://example.org/ a bar")
   10870     };
   10871     int i;
   10872     const int max_alloc_count = 30;
   10873 
   10874     for (i = 0; i < max_alloc_count; i++) {
   10875         allocation_count = i;
   10876         XML_SetReturnNSTriplet(parser, XML_TRUE);
   10877         XML_SetUserData(parser, elemstr);
   10878         XML_SetElementHandler(parser,
   10879                               triplet_start_checker,
   10880                               triplet_end_checker);
   10881         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   10882                                     XML_TRUE) != XML_STATUS_ERROR)
   10883             break;
   10884         /* See comment in test_nsalloc_xmlns() */
   10885         nsalloc_teardown();
   10886         nsalloc_setup();
   10887     }
   10888     if (i == 0)
   10889         fail("Parsing worked despite failing reallocations");
   10890     else if (i == max_alloc_count)
   10891         fail("Parsing failed at max reallocation count");
   10892 }
   10893 END_TEST
   10894 
   10895 /* Test the effects of reallocation failure when reassigning a
   10896  * binding.
   10897  *
   10898  * XML_ParserReset does not free the BINDING structures used by a
   10899  * parser, but instead adds them to an internal free list to be reused
   10900  * as necessary.  Likewise the URI buffers allocated for the binding
   10901  * aren't freed, but kept attached to their existing binding.  If the
   10902  * new binding has a longer URI, it will need reallocation.  This test
   10903  * provokes that reallocation, and tests the control path if it fails.
   10904  */
   10905 START_TEST(test_nsalloc_realloc_binding_uri)
   10906 {
   10907     const char *first =
   10908         "<doc xmlns='http://example.org/'>\n"
   10909         "  <e xmlns='' />\n"
   10910         "</doc>";
   10911     const char *second =
   10912         "<doc xmlns='http://example.org/long/enough/URI/to/reallocate/'>\n"
   10913         "  <e xmlns='' />\n"
   10914         "</doc>";
   10915     unsigned i;
   10916     const unsigned max_realloc_count = 10;
   10917 
   10918     /* First, do a full parse that will leave bindings around */
   10919     if (_XML_Parse_SINGLE_BYTES(parser, first, strlen(first),
   10920                                 XML_TRUE) == XML_STATUS_ERROR)
   10921         xml_failure(parser);
   10922 
   10923     /* Now repeat with a longer URI and a duff reallocator */
   10924     for (i = 0; i < max_realloc_count; i++) {
   10925         XML_ParserReset(parser, NULL);
   10926         reallocation_count = i;
   10927         if (_XML_Parse_SINGLE_BYTES(parser, second, strlen(second),
   10928                                     XML_TRUE) != XML_STATUS_ERROR)
   10929             break;
   10930     }
   10931     if (i == 0)
   10932         fail("Parsing worked despite failing reallocation");
   10933     else if (i == max_realloc_count)
   10934         fail("Parsing failed at max reallocation count");
   10935 }
   10936 END_TEST
   10937 
   10938 /* Check handling of long prefix names (pool growth) */
   10939 START_TEST(test_nsalloc_realloc_long_prefix)
   10940 {
   10941     const char *text =
   10942         "<"
   10943         /* 64 characters per line */
   10944         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10945         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10946         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10947         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10948         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10949         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10950         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10951         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10952         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10953         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10954         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10955         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10956         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10957         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10958         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10959         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10960         ":foo xmlns:"
   10961         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10962         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10963         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10964         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10965         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10966         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10967         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10968         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10969         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10970         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10971         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10972         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10973         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10974         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10975         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10976         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10977         "='http://example.org/'>"
   10978         "</"
   10979         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10980         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10981         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10982         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10983         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10984         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10985         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10986         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10987         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10988         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10989         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10990         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10991         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10992         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10993         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10994         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   10995         ":foo>";
   10996     int i;
   10997     const int max_realloc_count = 12;
   10998 
   10999     for (i = 0; i < max_realloc_count; i++) {
   11000         reallocation_count = i;
   11001         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   11002                                     XML_TRUE) != XML_STATUS_ERROR)
   11003             break;
   11004         /* See comment in test_nsalloc_xmlns() */
   11005         nsalloc_teardown();
   11006         nsalloc_setup();
   11007     }
   11008     if (i == 0)
   11009         fail("Parsing worked despite failing reallocations");
   11010     else if (i == max_realloc_count)
   11011         fail("Parsing failed even at max reallocation count");
   11012 }
   11013 END_TEST
   11014 
   11015 /* Check handling of even long prefix names (different code path) */
   11016 START_TEST(test_nsalloc_realloc_longer_prefix)
   11017 {
   11018     const char *text =
   11019         "<"
   11020         /* 64 characters per line */
   11021         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11022         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11023         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11024         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11025         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11026         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11027         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11028         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11029         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11030         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11031         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11032         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11033         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11034         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11035         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11036         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11037         "Q:foo xmlns:"
   11038         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11039         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11040         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11041         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11042         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11043         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11044         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11045         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11046         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11047         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11048         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11049         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11050         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11051         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11052         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11053         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11054         "Q='http://example.org/'>"
   11055         "</"
   11056         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11057         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11058         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11059         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11060         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11061         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11062         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11063         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11064         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11065         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11066         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11067         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11068         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11069         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11070         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11071         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11072         "Q:foo>";
   11073     int i;
   11074     const int max_realloc_count = 12;
   11075 
   11076     for (i = 0; i < max_realloc_count; i++) {
   11077         reallocation_count = i;
   11078         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   11079                                     XML_TRUE) != XML_STATUS_ERROR)
   11080             break;
   11081         /* See comment in test_nsalloc_xmlns() */
   11082         nsalloc_teardown();
   11083         nsalloc_setup();
   11084     }
   11085     if (i == 0)
   11086         fail("Parsing worked despite failing reallocations");
   11087     else if (i == max_realloc_count)
   11088         fail("Parsing failed even at max reallocation count");
   11089 }
   11090 END_TEST
   11091 
   11092 START_TEST(test_nsalloc_long_namespace)
   11093 {
   11094     const char *text1 =
   11095         "<"
   11096         /* 64 characters per line */
   11097         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11098         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11099         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11100         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11101         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11102         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11103         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11104         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11105         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11106         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11107         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11108         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11109         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11110         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11111         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11112         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11113         ":e xmlns:"
   11114         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11115         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11116         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11117         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11118         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11119         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11120         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11121         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11122         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11123         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11124         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11125         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11126         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11127         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11128         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11129         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11130         "='http://example.org/'>\n";
   11131     const char *text2 =
   11132         "<"
   11133         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11134         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11135         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11136         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11137         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11138         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11139         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11140         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11141         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11142         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11143         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11144         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11145         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11146         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11147         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11148         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11149         ":f "
   11150         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11151         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11152         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11153         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11154         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11155         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11156         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11157         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11158         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11159         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11160         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11161         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11162         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11163         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11164         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11165         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11166         ":attr='foo'/>\n"
   11167         "</"
   11168         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11169         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11170         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11171         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11172         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11173         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11174         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11175         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11176         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11177         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11178         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11179         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11180         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11181         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11182         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11183         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11184         ":e>";
   11185     int i;
   11186     const int max_alloc_count = 40;
   11187 
   11188     for (i = 0; i < max_alloc_count; i++) {
   11189         allocation_count = i;
   11190         if (_XML_Parse_SINGLE_BYTES(parser, text1, strlen(text1),
   11191                                     XML_FALSE) != XML_STATUS_ERROR &&
   11192             _XML_Parse_SINGLE_BYTES(parser, text2, strlen(text2),
   11193                                     XML_TRUE) != XML_STATUS_ERROR)
   11194             break;
   11195         /* See comment in test_nsalloc_xmlns() */
   11196         nsalloc_teardown();
   11197         nsalloc_setup();
   11198     }
   11199     if (i == 0)
   11200         fail("Parsing worked despite failing allocations");
   11201     else if (i == max_alloc_count)
   11202         fail("Parsing failed even at max allocation count");
   11203 }
   11204 END_TEST
   11205 
   11206 /* Using a slightly shorter namespace name provokes allocations in
   11207  * slightly different places in the code.
   11208  */
   11209 START_TEST(test_nsalloc_less_long_namespace)
   11210 {
   11211     const char *text =
   11212         "<"
   11213         /* 64 characters per line */
   11214         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11215         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11216         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11217         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11218         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11219         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11220         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11221         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
   11222         ":e xmlns:"
   11223         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11224         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11225         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11226         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11227         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11228         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11229         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11230         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
   11231         "='http://example.org/'>\n"
   11232         "<"
   11233         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11234         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11235         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11236         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11237         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11238         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11239         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11240         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
   11241         ":f "
   11242         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11243         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11244         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11245         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11246         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11247         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11248         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11249         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
   11250         ":att='foo'/>\n"
   11251         "</"
   11252         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11253         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11254         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11255         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11256         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11257         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11258         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
   11259         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
   11260         ":e>";
   11261     int i;
   11262     const int max_alloc_count = 40;
   11263 
   11264     for (i = 0; i < max_alloc_count; i++) {
   11265         allocation_count = i;
   11266         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   11267                                     XML_TRUE) != XML_STATUS_ERROR)
   11268             break;
   11269         /* See comment in test_nsalloc_xmlns() */
   11270         nsalloc_teardown();
   11271         nsalloc_setup();
   11272     }
   11273     if (i == 0)
   11274         fail("Parsing worked despite failing allocations");
   11275     else if (i == max_alloc_count)
   11276         fail("Parsing failed even at max allocation count");
   11277 }
   11278 END_TEST
   11279 
   11280 START_TEST(test_nsalloc_long_context)
   11281 {
   11282     const char *text =
   11283         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11284         "  <!ATTLIST doc baz ID #REQUIRED>\n"
   11285         "  <!ENTITY en SYSTEM 'bar'>\n"
   11286         "]>\n"
   11287         "<doc xmlns='http://example.org/"
   11288         /* 64 characters per line */
   11289         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11290         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11291         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11292         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11293         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11294         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11295         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11296         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11297         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11298         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11299         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11300         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11301         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11302         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11303         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11304         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKL"
   11305         "' baz='2'>\n"
   11306         "&en;"
   11307         "</doc>";
   11308     ExtOption options[] = {
   11309         { XCS("foo"), "<!ELEMENT e EMPTY>"},
   11310         { XCS("bar"), "<e/>" },
   11311         { NULL, NULL }
   11312     };
   11313     int i;
   11314     const int max_alloc_count = 70;
   11315 
   11316     for (i = 0; i < max_alloc_count; i++) {
   11317         allocation_count = i;
   11318         XML_SetUserData(parser, options);
   11319         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   11320         XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
   11321         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   11322                                     XML_TRUE) != XML_STATUS_ERROR)
   11323             break;
   11324 
   11325         /* See comment in test_nsalloc_xmlns() */
   11326         nsalloc_teardown();
   11327         nsalloc_setup();
   11328     }
   11329     if (i == 0)
   11330         fail("Parsing worked despite failing allocations");
   11331     else if (i == max_alloc_count)
   11332         fail("Parsing failed even at max allocation count");
   11333 }
   11334 END_TEST
   11335 
   11336 /* This function is void; it will throw a fail() on error, so if it
   11337  * returns normally it must have succeeded.
   11338  */
   11339 static void
   11340 context_realloc_test(const char *text)
   11341 {
   11342     ExtOption options[] = {
   11343         { XCS("foo"), "<!ELEMENT e EMPTY>"},
   11344         { XCS("bar"), "<e/>" },
   11345         { NULL, NULL }
   11346     };
   11347     int i;
   11348     const int max_realloc_count = 6;
   11349 
   11350     for (i = 0; i < max_realloc_count; i++) {
   11351         reallocation_count = i;
   11352         XML_SetUserData(parser, options);
   11353         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   11354         XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
   11355         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   11356                                     XML_TRUE) != XML_STATUS_ERROR)
   11357             break;
   11358         /* See comment in test_nsalloc_xmlns() */
   11359         nsalloc_teardown();
   11360         nsalloc_setup();
   11361     }
   11362     if (i == 0)
   11363         fail("Parsing worked despite failing reallocations");
   11364     else if (i == max_realloc_count)
   11365         fail("Parsing failed even at max reallocation count");
   11366 }
   11367 
   11368 START_TEST(test_nsalloc_realloc_long_context)
   11369 {
   11370     const char *text =
   11371         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11372         "  <!ENTITY en SYSTEM 'bar'>\n"
   11373         "]>\n"
   11374         "<doc xmlns='http://example.org/"
   11375         /* 64 characters per line */
   11376         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11377         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11378         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11379         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11380         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11381         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11382         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11383         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11384         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11385         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11386         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11387         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11388         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11389         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11390         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11391         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKL"
   11392         "'>\n"
   11393         "&en;"
   11394         "</doc>";
   11395 
   11396     context_realloc_test(text);
   11397 }
   11398 END_TEST
   11399 
   11400 START_TEST(test_nsalloc_realloc_long_context_2)
   11401 {
   11402     const char *text =
   11403         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11404         "  <!ENTITY en SYSTEM 'bar'>\n"
   11405         "]>\n"
   11406         "<doc xmlns='http://example.org/"
   11407         /* 64 characters per line */
   11408         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11409         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11410         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11411         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11412         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11413         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11414         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11415         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11416         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11417         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11418         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11419         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11420         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11421         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11422         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11423         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJK"
   11424         "'>\n"
   11425         "&en;"
   11426         "</doc>";
   11427 
   11428     context_realloc_test(text);
   11429 }
   11430 END_TEST
   11431 
   11432 START_TEST(test_nsalloc_realloc_long_context_3)
   11433 {
   11434     const char *text =
   11435         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11436         "  <!ENTITY en SYSTEM 'bar'>\n"
   11437         "]>\n"
   11438         "<doc xmlns='http://example.org/"
   11439         /* 64 characters per line */
   11440         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11441         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11442         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11443         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11444         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11445         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11446         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11447         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11448         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11449         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11450         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11451         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11452         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11453         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11454         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11455         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGH"
   11456         "'>\n"
   11457         "&en;"
   11458         "</doc>";
   11459 
   11460     context_realloc_test(text);
   11461 }
   11462 END_TEST
   11463 
   11464 START_TEST(test_nsalloc_realloc_long_context_4)
   11465 {
   11466     const char *text =
   11467         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11468         "  <!ENTITY en SYSTEM 'bar'>\n"
   11469         "]>\n"
   11470         "<doc xmlns='http://example.org/"
   11471         /* 64 characters per line */
   11472         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11473         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11474         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11475         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11476         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11477         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11478         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11479         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11480         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11481         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11482         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11483         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11484         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11485         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11486         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11487         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO"
   11488         "'>\n"
   11489         "&en;"
   11490         "</doc>";
   11491 
   11492     context_realloc_test(text);
   11493 }
   11494 END_TEST
   11495 
   11496 START_TEST(test_nsalloc_realloc_long_context_5)
   11497 {
   11498     const char *text =
   11499         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11500         "  <!ENTITY en SYSTEM 'bar'>\n"
   11501         "]>\n"
   11502         "<doc xmlns='http://example.org/"
   11503         /* 64 characters per line */
   11504         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11505         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11506         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11507         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11508         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11509         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11510         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11511         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11512         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11513         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11514         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11515         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11516         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11517         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11518         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11519         "ABC"
   11520         "'>\n"
   11521         "&en;"
   11522         "</doc>";
   11523 
   11524     context_realloc_test(text);
   11525 }
   11526 END_TEST
   11527 
   11528 START_TEST(test_nsalloc_realloc_long_context_6)
   11529 {
   11530     const char *text =
   11531         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11532         "  <!ENTITY en SYSTEM 'bar'>\n"
   11533         "]>\n"
   11534         "<doc xmlns='http://example.org/"
   11535         /* 64 characters per line */
   11536         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11537         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11538         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11539         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11540         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11541         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11542         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11543         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11544         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11545         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11546         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11547         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11548         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11549         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11550         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
   11551         "'>\n"
   11552         "&en;"
   11553         "</doc>";
   11554 
   11555     context_realloc_test(text);
   11556 }
   11557 END_TEST
   11558 
   11559 START_TEST(test_nsalloc_realloc_long_context_7)
   11560 {
   11561     const char *text =
   11562         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11563         "  <!ENTITY en SYSTEM 'bar'>\n"
   11564         "]>\n"
   11565         "<doc xmlns='http://example.org/"
   11566         /* 64 characters per line */
   11567         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11568         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11569         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11570         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11571         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11572         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11573         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11574         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11575         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11576         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11577         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11578         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11579         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11580         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11581         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11582         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLM"
   11583         "'>\n"
   11584         "&en;"
   11585         "</doc>";
   11586 
   11587     context_realloc_test(text);
   11588 }
   11589 END_TEST
   11590 
   11591 START_TEST(test_nsalloc_realloc_long_ge_name)
   11592 {
   11593     const char *text =
   11594         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11595         "  <!ENTITY "
   11596         /* 64 characters per line */
   11597         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11598         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11599         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11600         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11601         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11602         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11603         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11604         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11605         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11606         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11607         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11608         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11609         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11610         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11611         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11612         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11613         " SYSTEM 'bar'>\n"
   11614         "]>\n"
   11615         "<doc xmlns='http://example.org/baz'>\n"
   11616         "&"
   11617         /* 64 characters per line */
   11618         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11619         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11620         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11621         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11622         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11623         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11624         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11625         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11626         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11627         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11628         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11629         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11630         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11631         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11632         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11633         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11634         ";"
   11635         "</doc>";
   11636     ExtOption options[] = {
   11637         { XCS("foo"), "<!ELEMENT el EMPTY>" },
   11638         { XCS("bar"), "<el/>" },
   11639         { NULL, NULL }
   11640     };
   11641     int i;
   11642     const int max_realloc_count = 10;
   11643 
   11644     for (i = 0; i < max_realloc_count; i++) {
   11645         reallocation_count = i;
   11646         XML_SetUserData(parser, options);
   11647         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   11648         XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
   11649         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   11650                                     XML_TRUE) != XML_STATUS_ERROR)
   11651             break;
   11652         /* See comment in test_nsalloc_xmlns() */
   11653         nsalloc_teardown();
   11654         nsalloc_setup();
   11655     }
   11656     if (i == 0)
   11657         fail("Parsing worked despite failing reallocations");
   11658     else if (i == max_realloc_count)
   11659         fail("Parsing failed even at max reallocation count");
   11660 }
   11661 END_TEST
   11662 
   11663 /* Test that when a namespace is passed through the context mechanism
   11664  * to an external entity parser, the parsers handle reallocation
   11665  * failures correctly.  The prefix is exactly the right length to
   11666  * provoke particular uncommon code paths.
   11667  */
   11668 START_TEST(test_nsalloc_realloc_long_context_in_dtd)
   11669 {
   11670     const char *text1 =
   11671         "<!DOCTYPE "
   11672         /* 64 characters per line */
   11673         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11674         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11675         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11676         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11677         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11678         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11679         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11680         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11681         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11682         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11683         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11684         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11685         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11686         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11687         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11688         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11689         ":doc [\n"
   11690         "  <!ENTITY First SYSTEM 'foo/First'>\n"
   11691         "]>\n"
   11692         "<"
   11693         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11694         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11695         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11696         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11697         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11698         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11699         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11700         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11701         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11702         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11703         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11704         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11705         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11706         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11707         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11708         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11709         ":doc xmlns:"
   11710         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11711         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11712         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11713         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11714         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11715         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11716         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11717         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11718         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11719         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11720         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11721         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11722         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11723         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11724         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11725         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11726         "='foo/Second'>&First;";
   11727     const char *text2 = "</"
   11728         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11729         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11730         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11731         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11732         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11733         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11734         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11735         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11736         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11737         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11738         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11739         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11740         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11741         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11742         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11743         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11744         ":doc>";
   11745     ExtOption options[] = {
   11746         { XCS("foo/First"), "Hello world" },
   11747         { NULL, NULL }
   11748     };
   11749     int i;
   11750     const int max_realloc_count = 20;
   11751 
   11752     for (i = 0; i < max_realloc_count; i++) {
   11753         reallocation_count = i;
   11754         XML_SetUserData(parser, options);
   11755         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   11756         XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
   11757         if (_XML_Parse_SINGLE_BYTES(parser, text1, strlen(text1),
   11758                                     XML_FALSE) != XML_STATUS_ERROR &&
   11759             _XML_Parse_SINGLE_BYTES(parser, text2, strlen(text2),
   11760                                     XML_TRUE) != XML_STATUS_ERROR)
   11761             break;
   11762         /* See comment in test_nsalloc_xmlns() */
   11763         nsalloc_teardown();
   11764         nsalloc_setup();
   11765     }
   11766     if (i == 0)
   11767         fail("Parsing worked despite failing reallocations");
   11768     else if (i == max_realloc_count)
   11769         fail("Parsing failed even at max reallocation count");
   11770 }
   11771 END_TEST
   11772 
   11773 START_TEST(test_nsalloc_long_default_in_ext)
   11774 {
   11775     const char *text =
   11776         "<!DOCTYPE doc [\n"
   11777         "  <!ATTLIST e a1 CDATA '"
   11778         /* 64 characters per line */
   11779         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11780         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11781         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11782         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11783         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11784         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11785         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11786         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11787         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11788         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11789         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11790         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11791         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11792         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11793         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11794         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
   11795         "'>\n"
   11796         "  <!ENTITY x SYSTEM 'foo'>\n"
   11797         "]>\n"
   11798         "<doc>&x;</doc>";
   11799     ExtOption options[] = {
   11800         { XCS("foo"), "<e/>"},
   11801         { NULL, NULL }
   11802     };
   11803     int i;
   11804     const int max_alloc_count = 50;
   11805 
   11806     for (i = 0; i < max_alloc_count; i++) {
   11807         allocation_count = i;
   11808         XML_SetUserData(parser, options);
   11809         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   11810         XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
   11811         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   11812                                     XML_TRUE) != XML_STATUS_ERROR)
   11813             break;
   11814 
   11815         /* See comment in test_nsalloc_xmlns() */
   11816         nsalloc_teardown();
   11817         nsalloc_setup();
   11818     }
   11819     if (i == 0)
   11820         fail("Parsing worked despite failing allocations");
   11821     else if (i == max_alloc_count)
   11822         fail("Parsing failed even at max allocation count");
   11823 }
   11824 END_TEST
   11825 
   11826 START_TEST(test_nsalloc_long_systemid_in_ext)
   11827 {
   11828     const char *text =
   11829         "<!DOCTYPE doc SYSTEM 'foo' [\n"
   11830         "  <!ENTITY en SYSTEM '"
   11831         /* 64 characters per line */
   11832         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11833         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11834         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11835         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11836         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11837         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11838         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11839         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11840         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11841         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11842         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11843         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11844         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11845         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11846         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11847         "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
   11848         "'>\n"
   11849         "]>\n"
   11850         "<doc>&en;</doc>";
   11851     ExtOption options[] = {
   11852         { XCS("foo"), "<!ELEMENT e EMPTY>" },
   11853         {
   11854             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11855             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11856             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11857             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11858             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11859             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11860             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11861             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11862             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11863             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11864             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11865             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11866             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11867             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11868             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/")
   11869             XCS("ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"),
   11870             "<e/>"
   11871         },
   11872         { NULL, NULL }
   11873     };
   11874     int i;
   11875     const int max_alloc_count = 55;
   11876 
   11877     for (i = 0; i < max_alloc_count; i++) {
   11878         allocation_count = i;
   11879         XML_SetUserData(parser, options);
   11880         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   11881         XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
   11882         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   11883                                     XML_TRUE) != XML_STATUS_ERROR)
   11884             break;
   11885 
   11886         /* See comment in test_nsalloc_xmlns() */
   11887         nsalloc_teardown();
   11888         nsalloc_setup();
   11889     }
   11890     if (i == 0)
   11891         fail("Parsing worked despite failing allocations");
   11892     else if (i == max_alloc_count)
   11893         fail("Parsing failed even at max allocation count");
   11894 }
   11895 END_TEST
   11896 
   11897 /* Test the effects of allocation failure on parsing an element in a
   11898  * namespace.  Based on test_nsalloc_long_context.
   11899  */
   11900 START_TEST(test_nsalloc_prefixed_element)
   11901 {
   11902     const char *text =
   11903         "<!DOCTYPE pfx:element SYSTEM 'foo' [\n"
   11904         "  <!ATTLIST pfx:element baz ID #REQUIRED>\n"
   11905         "  <!ENTITY en SYSTEM 'bar'>\n"
   11906         "]>\n"
   11907         "<pfx:element xmlns:pfx='http://example.org/' baz='2'>\n"
   11908         "&en;"
   11909         "</pfx:element>";
   11910     ExtOption options[] = {
   11911         { XCS("foo"), "<!ELEMENT e EMPTY>" },
   11912         { XCS("bar"), "<e/>" },
   11913         { NULL, NULL }
   11914     };
   11915     int i;
   11916     const int max_alloc_count = 70;
   11917 
   11918     for (i = 0; i < max_alloc_count; i++) {
   11919         allocation_count = i;
   11920         XML_SetUserData(parser, options);
   11921         XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
   11922         XML_SetExternalEntityRefHandler(parser, external_entity_optioner);
   11923         if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
   11924                                     XML_TRUE) != XML_STATUS_ERROR)
   11925             break;
   11926 
   11927         /* See comment in test_nsalloc_xmlns() */
   11928         nsalloc_teardown();
   11929         nsalloc_setup();
   11930     }
   11931     if (i == 0)
   11932         fail("Success despite failing allocator");
   11933     else if (i == max_alloc_count)
   11934         fail("Failed even at full allocation count");
   11935 }
   11936 END_TEST
   11937 
   11938 static Suite *
   11939 make_suite(void)
   11940 {
   11941     Suite *s = suite_create("basic");
   11942     TCase *tc_basic = tcase_create("basic tests");
   11943     TCase *tc_namespace = tcase_create("XML namespaces");
   11944     TCase *tc_misc = tcase_create("miscellaneous tests");
   11945     TCase *tc_alloc = tcase_create("allocation tests");
   11946     TCase *tc_nsalloc = tcase_create("namespace allocation tests");
   11947 
   11948     suite_add_tcase(s, tc_basic);
   11949     tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
   11950     tcase_add_test(tc_basic, test_nul_byte);
   11951     tcase_add_test(tc_basic, test_u0000_char);
   11952     tcase_add_test(tc_basic, test_siphash_self);
   11953     tcase_add_test(tc_basic, test_siphash_spec);
   11954     tcase_add_test(tc_basic, test_bom_utf8);
   11955     tcase_add_test(tc_basic, test_bom_utf16_be);
   11956     tcase_add_test(tc_basic, test_bom_utf16_le);
   11957     tcase_add_test(tc_basic, test_nobom_utf16_le);
   11958     tcase_add_test(tc_basic, test_illegal_utf8);
   11959     tcase_add_test(tc_basic, test_utf8_auto_align);
   11960     tcase_add_test(tc_basic, test_utf16);
   11961     tcase_add_test(tc_basic, test_utf16_le_epilog_newline);
   11962     tcase_add_test(tc_basic, test_not_utf16);
   11963     tcase_add_test(tc_basic, test_bad_encoding);
   11964     tcase_add_test(tc_basic, test_latin1_umlauts);
   11965     tcase_add_test(tc_basic, test_long_utf8_character);
   11966     tcase_add_test(tc_basic, test_long_latin1_attribute);
   11967     tcase_add_test(tc_basic, test_long_ascii_attribute);
   11968     /* Regression test for SF bug #491986. */
   11969     tcase_add_test(tc_basic, test_danish_latin1);
   11970     /* Regression test for SF bug #514281. */
   11971     tcase_add_test(tc_basic, test_french_charref_hexidecimal);
   11972     tcase_add_test(tc_basic, test_french_charref_decimal);
   11973     tcase_add_test(tc_basic, test_french_latin1);
   11974     tcase_add_test(tc_basic, test_french_utf8);
   11975     tcase_add_test(tc_basic, test_utf8_false_rejection);
   11976     tcase_add_test(tc_basic, test_line_number_after_parse);
   11977     tcase_add_test(tc_basic, test_column_number_after_parse);
   11978     tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers);
   11979     tcase_add_test(tc_basic, test_line_number_after_error);
   11980     tcase_add_test(tc_basic, test_column_number_after_error);
   11981     tcase_add_test(tc_basic, test_really_long_lines);
   11982     tcase_add_test(tc_basic, test_really_long_encoded_lines);
   11983     tcase_add_test(tc_basic, test_end_element_events);
   11984     tcase_add_test(tc_basic, test_attr_whitespace_normalization);
   11985     tcase_add_test(tc_basic, test_xmldecl_misplaced);
   11986     tcase_add_test(tc_basic, test_xmldecl_invalid);
   11987     tcase_add_test(tc_basic, test_xmldecl_missing_attr);
   11988     tcase_add_test(tc_basic, test_xmldecl_missing_value);
   11989     tcase_add_test(tc_basic, test_unknown_encoding_internal_entity);
   11990     tcase_add_test(tc_basic, test_unrecognised_encoding_internal_entity);
   11991     tcase_add_test(tc_basic,
   11992                    test_wfc_undeclared_entity_unread_external_subset);
   11993     tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset);
   11994     tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone);
   11995     tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
   11996     tcase_add_test(tc_basic, test_not_standalone_handler_reject);
   11997     tcase_add_test(tc_basic, test_not_standalone_handler_accept);
   11998     tcase_add_test(tc_basic,
   11999                    test_wfc_undeclared_entity_with_external_subset_standalone);
   12000     tcase_add_test(tc_basic,
   12001                    test_entity_with_external_subset_unless_standalone);
   12002     tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs);
   12003     tcase_add_test(tc_basic, test_ext_entity_set_encoding);
   12004     tcase_add_test(tc_basic, test_ext_entity_no_handler);
   12005     tcase_add_test(tc_basic, test_ext_entity_set_bom);
   12006     tcase_add_test(tc_basic, test_ext_entity_bad_encoding);
   12007     tcase_add_test(tc_basic, test_ext_entity_bad_encoding_2);
   12008     tcase_add_test(tc_basic, test_ext_entity_invalid_parse);
   12009     tcase_add_test(tc_basic, test_ext_entity_invalid_suspended_parse);
   12010     tcase_add_test(tc_basic, test_dtd_default_handling);
   12011     tcase_add_test(tc_basic, test_dtd_attr_handling);
   12012     tcase_add_test(tc_basic, test_empty_ns_without_namespaces);
   12013     tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces);
   12014     tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls);
   12015     tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls);
   12016     tcase_add_test(tc_basic, test_repeated_stop_parser_between_char_data_calls);
   12017     tcase_add_test(tc_basic, test_good_cdata_ascii);
   12018     tcase_add_test(tc_basic, test_good_cdata_utf16);
   12019     tcase_add_test(tc_basic, test_good_cdata_utf16_le);
   12020     tcase_add_test(tc_basic, test_long_cdata_utf16);
   12021     tcase_add_test(tc_basic, test_multichar_cdata_utf16);
   12022     tcase_add_test(tc_basic, test_utf16_bad_surrogate_pair);
   12023     tcase_add_test(tc_basic, test_bad_cdata);
   12024     tcase_add_test(tc_basic, test_bad_cdata_utf16);
   12025     tcase_add_test(tc_basic, test_stop_parser_between_cdata_calls);
   12026     tcase_add_test(tc_basic, test_suspend_parser_between_cdata_calls);
   12027     tcase_add_test(tc_basic, test_memory_allocation);
   12028     tcase_add_test(tc_basic, test_default_current);
   12029     tcase_add_test(tc_basic, test_dtd_elements);
   12030     tcase_add_test(tc_basic, test_set_foreign_dtd);
   12031     tcase_add_test(tc_basic, test_foreign_dtd_not_standalone);
   12032     tcase_add_test(tc_basic, test_invalid_foreign_dtd);
   12033     tcase_add_test(tc_basic, test_foreign_dtd_with_doctype);
   12034     tcase_add_test(tc_basic, test_foreign_dtd_without_external_subset);
   12035     tcase_add_test(tc_basic, test_empty_foreign_dtd);
   12036     tcase_add_test(tc_basic, test_set_base);
   12037     tcase_add_test(tc_basic, test_attributes);
   12038     tcase_add_test(tc_basic, test_reset_in_entity);
   12039     tcase_add_test(tc_basic, test_resume_invalid_parse);
   12040     tcase_add_test(tc_basic, test_resume_resuspended);
   12041     tcase_add_test(tc_basic, test_cdata_default);
   12042     tcase_add_test(tc_basic, test_subordinate_reset);
   12043     tcase_add_test(tc_basic, test_subordinate_suspend);
   12044     tcase_add_test(tc_basic, test_subordinate_xdecl_suspend);
   12045     tcase_add_test(tc_basic, test_subordinate_xdecl_abort);
   12046     tcase_add_test(tc_basic, test_explicit_encoding);
   12047     tcase_add_test(tc_basic, test_trailing_cr);
   12048     tcase_add_test(tc_basic, test_ext_entity_trailing_cr);
   12049     tcase_add_test(tc_basic, test_trailing_rsqb);
   12050     tcase_add_test(tc_basic, test_ext_entity_trailing_rsqb);
   12051     tcase_add_test(tc_basic, test_ext_entity_good_cdata);
   12052     tcase_add_test(tc_basic, test_user_parameters);
   12053     tcase_add_test(tc_basic, test_ext_entity_ref_parameter);
   12054     tcase_add_test(tc_basic, test_empty_parse);
   12055     tcase_add_test(tc_basic, test_get_buffer_1);
   12056     tcase_add_test(tc_basic, test_get_buffer_2);
   12057     tcase_add_test(tc_basic, test_byte_info_at_end);
   12058     tcase_add_test(tc_basic, test_byte_info_at_error);
   12059     tcase_add_test(tc_basic, test_byte_info_at_cdata);
   12060     tcase_add_test(tc_basic, test_predefined_entities);
   12061     tcase_add_test(tc_basic, test_invalid_tag_in_dtd);
   12062     tcase_add_test(tc_basic, test_not_predefined_entities);
   12063     tcase_add_test(tc_basic, test_ignore_section);
   12064     tcase_add_test(tc_basic, test_ignore_section_utf16);
   12065     tcase_add_test(tc_basic, test_ignore_section_utf16_be);
   12066     tcase_add_test(tc_basic, test_bad_ignore_section);
   12067     tcase_add_test(tc_basic, test_external_entity_values);
   12068     tcase_add_test(tc_basic, test_ext_entity_not_standalone);
   12069     tcase_add_test(tc_basic, test_ext_entity_value_abort);
   12070     tcase_add_test(tc_basic, test_bad_public_doctype);
   12071     tcase_add_test(tc_basic, test_attribute_enum_value);
   12072     tcase_add_test(tc_basic, test_predefined_entity_redefinition);
   12073     tcase_add_test(tc_basic, test_dtd_stop_processing);
   12074     tcase_add_test(tc_basic, test_public_notation_no_sysid);
   12075     tcase_add_test(tc_basic, test_nested_groups);
   12076     tcase_add_test(tc_basic, test_group_choice);
   12077     tcase_add_test(tc_basic, test_standalone_parameter_entity);
   12078     tcase_add_test(tc_basic, test_skipped_parameter_entity);
   12079     tcase_add_test(tc_basic, test_recursive_external_parameter_entity);
   12080     tcase_add_test(tc_basic, test_undefined_ext_entity_in_external_dtd);
   12081     tcase_add_test(tc_basic, test_suspend_xdecl);
   12082     tcase_add_test(tc_basic, test_abort_epilog);
   12083     tcase_add_test(tc_basic, test_abort_epilog_2);
   12084     tcase_add_test(tc_basic, test_suspend_epilog);
   12085     tcase_add_test(tc_basic, test_unfinished_epilog);
   12086     tcase_add_test(tc_basic, test_partial_char_in_epilog);
   12087     tcase_add_test(tc_basic, test_hash_collision);
   12088     tcase_add_test(tc_basic, test_suspend_resume_internal_entity);
   12089     tcase_add_test(tc_basic, test_resume_entity_with_syntax_error);
   12090     tcase_add_test(tc_basic, test_suspend_resume_parameter_entity);
   12091     tcase_add_test(tc_basic, test_restart_on_error);
   12092     tcase_add_test(tc_basic, test_reject_lt_in_attribute_value);
   12093     tcase_add_test(tc_basic, test_reject_unfinished_param_in_att_value);
   12094     tcase_add_test(tc_basic, test_trailing_cr_in_att_value);
   12095     tcase_add_test(tc_basic, test_standalone_internal_entity);
   12096     tcase_add_test(tc_basic, test_skipped_external_entity);
   12097     tcase_add_test(tc_basic, test_skipped_null_loaded_ext_entity);
   12098     tcase_add_test(tc_basic, test_skipped_unloaded_ext_entity);
   12099     tcase_add_test(tc_basic, test_param_entity_with_trailing_cr);
   12100     tcase_add_test(tc_basic, test_invalid_character_entity);
   12101     tcase_add_test(tc_basic, test_invalid_character_entity_2);
   12102     tcase_add_test(tc_basic, test_invalid_character_entity_3);
   12103     tcase_add_test(tc_basic, test_invalid_character_entity_4);
   12104     tcase_add_test(tc_basic, test_pi_handled_in_default);
   12105     tcase_add_test(tc_basic, test_comment_handled_in_default);
   12106     tcase_add_test(tc_basic, test_pi_yml);
   12107     tcase_add_test(tc_basic, test_pi_xnl);
   12108     tcase_add_test(tc_basic, test_pi_xmm);
   12109     tcase_add_test(tc_basic, test_utf16_pi);
   12110     tcase_add_test(tc_basic, test_utf16_be_pi);
   12111     tcase_add_test(tc_basic, test_utf16_be_comment);
   12112     tcase_add_test(tc_basic, test_utf16_le_comment);
   12113     tcase_add_test(tc_basic, test_missing_encoding_conversion_fn);
   12114     tcase_add_test(tc_basic, test_failing_encoding_conversion_fn);
   12115     tcase_add_test(tc_basic, test_unknown_encoding_success);
   12116     tcase_add_test(tc_basic, test_unknown_encoding_bad_name);
   12117     tcase_add_test(tc_basic, test_unknown_encoding_bad_name_2);
   12118     tcase_add_test(tc_basic, test_unknown_encoding_long_name_1);
   12119     tcase_add_test(tc_basic, test_unknown_encoding_long_name_2);
   12120     tcase_add_test(tc_basic, test_invalid_unknown_encoding);
   12121     tcase_add_test(tc_basic, test_unknown_ascii_encoding_ok);
   12122     tcase_add_test(tc_basic, test_unknown_ascii_encoding_fail);
   12123     tcase_add_test(tc_basic, test_unknown_encoding_invalid_length);
   12124     tcase_add_test(tc_basic, test_unknown_encoding_invalid_topbit);
   12125     tcase_add_test(tc_basic, test_unknown_encoding_invalid_surrogate);
   12126     tcase_add_test(tc_basic, test_unknown_encoding_invalid_high);
   12127     tcase_add_test(tc_basic, test_unknown_encoding_invalid_attr_value);
   12128     tcase_add_test(tc_basic, test_ext_entity_latin1_utf16le_bom);
   12129     tcase_add_test(tc_basic, test_ext_entity_latin1_utf16be_bom);
   12130     tcase_add_test(tc_basic, test_ext_entity_latin1_utf16le_bom2);
   12131     tcase_add_test(tc_basic, test_ext_entity_latin1_utf16be_bom2);
   12132     tcase_add_test(tc_basic, test_ext_entity_utf16_be);
   12133     tcase_add_test(tc_basic, test_ext_entity_utf16_le);
   12134     tcase_add_test(tc_basic, test_ext_entity_utf16_unknown);
   12135     tcase_add_test(tc_basic, test_ext_entity_utf8_non_bom);
   12136     tcase_add_test(tc_basic, test_utf8_in_cdata_section);
   12137     tcase_add_test(tc_basic, test_utf8_in_cdata_section_2);
   12138     tcase_add_test(tc_basic, test_trailing_spaces_in_elements);
   12139     tcase_add_test(tc_basic, test_utf16_attribute);
   12140     tcase_add_test(tc_basic, test_utf16_second_attr);
   12141     tcase_add_test(tc_basic, test_attr_after_solidus);
   12142     tcase_add_test(tc_basic, test_utf16_pe);
   12143     tcase_add_test(tc_basic, test_bad_attr_desc_keyword);
   12144     tcase_add_test(tc_basic, test_bad_attr_desc_keyword_utf16);
   12145     tcase_add_test(tc_basic, test_bad_doctype);
   12146     tcase_add_test(tc_basic, test_bad_doctype_utf16);
   12147     tcase_add_test(tc_basic, test_bad_doctype_plus);
   12148     tcase_add_test(tc_basic, test_bad_doctype_star);
   12149     tcase_add_test(tc_basic, test_bad_doctype_query);
   12150     tcase_add_test(tc_basic, test_unknown_encoding_bad_ignore);
   12151     tcase_add_test(tc_basic, test_entity_in_utf16_be_attr);
   12152     tcase_add_test(tc_basic, test_entity_in_utf16_le_attr);
   12153     tcase_add_test(tc_basic, test_entity_public_utf16_be);
   12154     tcase_add_test(tc_basic, test_entity_public_utf16_le);
   12155     tcase_add_test(tc_basic, test_short_doctype);
   12156     tcase_add_test(tc_basic, test_short_doctype_2);
   12157     tcase_add_test(tc_basic, test_short_doctype_3);
   12158     tcase_add_test(tc_basic, test_long_doctype);
   12159     tcase_add_test(tc_basic, test_bad_entity);
   12160     tcase_add_test(tc_basic, test_bad_entity_2);
   12161     tcase_add_test(tc_basic, test_bad_entity_3);
   12162     tcase_add_test(tc_basic, test_bad_entity_4);
   12163     tcase_add_test(tc_basic, test_bad_notation);
   12164     tcase_add_test(tc_basic, test_default_doctype_handler);
   12165     tcase_add_test(tc_basic, test_empty_element_abort);
   12166 
   12167     suite_add_tcase(s, tc_namespace);
   12168     tcase_add_checked_fixture(tc_namespace,
   12169                               namespace_setup, namespace_teardown);
   12170     tcase_add_test(tc_namespace, test_return_ns_triplet);
   12171     tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
   12172     tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
   12173     tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
   12174     tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge);
   12175     tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
   12176     tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
   12177     tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
   12178     tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
   12179     tcase_add_test(tc_namespace, test_ns_unbound_prefix);
   12180     tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
   12181     tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
   12182     tcase_add_test(tc_namespace, test_ns_duplicate_hashes);
   12183     tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
   12184     tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
   12185     tcase_add_test(tc_namespace, test_ns_parser_reset);
   12186     tcase_add_test(tc_namespace, test_ns_long_element);
   12187     tcase_add_test(tc_namespace, test_ns_mixed_prefix_atts);
   12188     tcase_add_test(tc_namespace, test_ns_extend_uri_buffer);
   12189     tcase_add_test(tc_namespace, test_ns_reserved_attributes);
   12190     tcase_add_test(tc_namespace, test_ns_reserved_attributes_2);
   12191     tcase_add_test(tc_namespace, test_ns_extremely_long_prefix);
   12192     tcase_add_test(tc_namespace, test_ns_unknown_encoding_success);
   12193     tcase_add_test(tc_namespace, test_ns_double_colon);
   12194     tcase_add_test(tc_namespace, test_ns_double_colon_element);
   12195     tcase_add_test(tc_namespace, test_ns_bad_attr_leafname);
   12196     tcase_add_test(tc_namespace, test_ns_bad_element_leafname);
   12197     tcase_add_test(tc_namespace, test_ns_utf16_leafname);
   12198     tcase_add_test(tc_namespace, test_ns_utf16_element_leafname);
   12199     tcase_add_test(tc_namespace, test_ns_utf16_doctype);
   12200     tcase_add_test(tc_namespace, test_ns_invalid_doctype);
   12201     tcase_add_test(tc_namespace, test_ns_double_colon_doctype);
   12202 
   12203     suite_add_tcase(s, tc_misc);
   12204     tcase_add_checked_fixture(tc_misc, NULL, basic_teardown);
   12205     tcase_add_test(tc_misc, test_misc_alloc_create_parser);
   12206     tcase_add_test(tc_misc, test_misc_alloc_create_parser_with_encoding);
   12207     tcase_add_test(tc_misc, test_misc_null_parser);
   12208     tcase_add_test(tc_misc, test_misc_error_string);
   12209     tcase_add_test(tc_misc, test_misc_version);
   12210     tcase_add_test(tc_misc, test_misc_features);
   12211     tcase_add_test(tc_misc, test_misc_attribute_leak);
   12212     tcase_add_test(tc_misc, test_misc_utf16le);
   12213 
   12214     suite_add_tcase(s, tc_alloc);
   12215     tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
   12216     tcase_add_test(tc_alloc, test_alloc_parse_xdecl);
   12217     tcase_add_test(tc_alloc, test_alloc_parse_xdecl_2);
   12218     tcase_add_test(tc_alloc, test_alloc_parse_pi);
   12219     tcase_add_test(tc_alloc, test_alloc_parse_pi_2);
   12220     tcase_add_test(tc_alloc, test_alloc_parse_pi_3);
   12221     tcase_add_test(tc_alloc, test_alloc_parse_comment);
   12222     tcase_add_test(tc_alloc, test_alloc_parse_comment_2);
   12223     tcase_add_test(tc_alloc, test_alloc_create_external_parser);
   12224     tcase_add_test(tc_alloc, test_alloc_run_external_parser);
   12225     tcase_add_test(tc_alloc, test_alloc_dtd_copy_default_atts);
   12226     tcase_add_test(tc_alloc, test_alloc_external_entity);
   12227     tcase_add_test(tc_alloc, test_alloc_ext_entity_set_encoding);
   12228     tcase_add_test(tc_alloc, test_alloc_internal_entity);
   12229     tcase_add_test(tc_alloc, test_alloc_dtd_default_handling);
   12230     tcase_add_test(tc_alloc, test_alloc_explicit_encoding);
   12231     tcase_add_test(tc_alloc, test_alloc_set_base);
   12232     tcase_add_test(tc_alloc, test_alloc_realloc_buffer);
   12233     tcase_add_test(tc_alloc, test_alloc_ext_entity_realloc_buffer);
   12234     tcase_add_test(tc_alloc, test_alloc_realloc_many_attributes);
   12235     tcase_add_test(tc_alloc, test_alloc_public_entity_value);
   12236     tcase_add_test(tc_alloc, test_alloc_realloc_subst_public_entity_value);
   12237     tcase_add_test(tc_alloc, test_alloc_parse_public_doctype);
   12238     tcase_add_test(tc_alloc, test_alloc_parse_public_doctype_long_name);
   12239     tcase_add_test(tc_alloc, test_alloc_set_foreign_dtd);
   12240     tcase_add_test(tc_alloc, test_alloc_attribute_enum_value);
   12241     tcase_add_test(tc_alloc, test_alloc_realloc_attribute_enum_value);
   12242     tcase_add_test(tc_alloc, test_alloc_realloc_implied_attribute);
   12243     tcase_add_test(tc_alloc, test_alloc_realloc_default_attribute);
   12244     tcase_add_test(tc_alloc, test_alloc_notation);
   12245     tcase_add_test(tc_alloc, test_alloc_public_notation);
   12246     tcase_add_test(tc_alloc, test_alloc_system_notation);
   12247     tcase_add_test(tc_alloc, test_alloc_nested_groups);
   12248     tcase_add_test(tc_alloc, test_alloc_realloc_nested_groups);
   12249     tcase_add_test(tc_alloc, test_alloc_large_group);
   12250     tcase_add_test(tc_alloc, test_alloc_realloc_group_choice);
   12251     tcase_add_test(tc_alloc, test_alloc_pi_in_epilog);
   12252     tcase_add_test(tc_alloc, test_alloc_comment_in_epilog);
   12253     tcase_add_test(tc_alloc, test_alloc_realloc_long_attribute_value);
   12254     tcase_add_test(tc_alloc, test_alloc_attribute_whitespace);
   12255     tcase_add_test(tc_alloc, test_alloc_attribute_predefined_entity);
   12256     tcase_add_test(tc_alloc, test_alloc_long_attr_default_with_char_ref);
   12257     tcase_add_test(tc_alloc, test_alloc_long_attr_value);
   12258     tcase_add_test(tc_alloc, test_alloc_nested_entities);
   12259     tcase_add_test(tc_alloc, test_alloc_realloc_param_entity_newline);
   12260     tcase_add_test(tc_alloc, test_alloc_realloc_ce_extends_pe);
   12261     tcase_add_test(tc_alloc, test_alloc_realloc_attributes);
   12262     tcase_add_test(tc_alloc, test_alloc_long_doc_name);
   12263     tcase_add_test(tc_alloc, test_alloc_long_base);
   12264     tcase_add_test(tc_alloc, test_alloc_long_public_id);
   12265     tcase_add_test(tc_alloc, test_alloc_long_entity_value);
   12266     tcase_add_test(tc_alloc, test_alloc_long_notation);
   12267 
   12268     suite_add_tcase(s, tc_nsalloc);
   12269     tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown);
   12270     tcase_add_test(tc_nsalloc, test_nsalloc_xmlns);
   12271     tcase_add_test(tc_nsalloc, test_nsalloc_parse_buffer);
   12272     tcase_add_test(tc_nsalloc, test_nsalloc_long_prefix);
   12273     tcase_add_test(tc_nsalloc, test_nsalloc_long_uri);
   12274     tcase_add_test(tc_nsalloc, test_nsalloc_long_attr);
   12275     tcase_add_test(tc_nsalloc, test_nsalloc_long_attr_prefix);
   12276     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_attributes);
   12277     tcase_add_test(tc_nsalloc, test_nsalloc_long_element);
   12278     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_binding_uri);
   12279     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_prefix);
   12280     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_longer_prefix);
   12281     tcase_add_test(tc_nsalloc, test_nsalloc_long_namespace);
   12282     tcase_add_test(tc_nsalloc, test_nsalloc_less_long_namespace);
   12283     tcase_add_test(tc_nsalloc, test_nsalloc_long_context);
   12284     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context);
   12285     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_2);
   12286     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_3);
   12287     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_4);
   12288     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_5);
   12289     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_6);
   12290     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_7);
   12291     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_ge_name);
   12292     tcase_add_test(tc_nsalloc, test_nsalloc_realloc_long_context_in_dtd);
   12293     tcase_add_test(tc_nsalloc, test_nsalloc_long_default_in_ext);
   12294     tcase_add_test(tc_nsalloc, test_nsalloc_long_systemid_in_ext);
   12295     tcase_add_test(tc_nsalloc, test_nsalloc_prefixed_element);
   12296 
   12297     return s;
   12298 }
   12299 
   12300 
   12301 int
   12302 main(int argc, char *argv[])
   12303 {
   12304     int i, nf;
   12305     int verbosity = CK_NORMAL;
   12306     Suite *s = make_suite();
   12307     SRunner *sr = srunner_create(s);
   12308 
   12309     /* run the tests for internal helper functions */
   12310     testhelper_is_whitespace_normalized();
   12311 
   12312     for (i = 1; i < argc; ++i) {
   12313         char *opt = argv[i];
   12314         if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0)
   12315             verbosity = CK_VERBOSE;
   12316         else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0)
   12317             verbosity = CK_SILENT;
   12318         else {
   12319             fprintf(stderr, "runtests: unknown option '%s'\n", opt);
   12320             return 2;
   12321         }
   12322     }
   12323     if (verbosity != CK_SILENT)
   12324         printf("Expat version: %" XML_FMT_STR "\n", XML_ExpatVersion());
   12325     srunner_run_all(sr, verbosity);
   12326     nf = srunner_ntests_failed(sr);
   12327     srunner_free(sr);
   12328 
   12329     return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
   12330 }
   12331