Home | History | Annotate | Line # | Download | only in tests
      1      1.1  wiz /* XML handler functions for the Expat test suite
      2      1.1  wiz                             __  __            _
      3      1.1  wiz                          ___\ \/ /_ __   __ _| |_
      4      1.1  wiz                         / _ \\  /| '_ \ / _` | __|
      5      1.1  wiz                        |  __//  \| |_) | (_| | |_
      6      1.1  wiz                         \___/_/\_\ .__/ \__,_|\__|
      7      1.1  wiz                                  |_| XML parser
      8      1.1  wiz 
      9      1.1  wiz    Copyright (c) 2001-2006 Fred L. Drake, Jr. <fdrake (at) users.sourceforge.net>
     10      1.1  wiz    Copyright (c) 2003      Greg Stein <gstein (at) users.sourceforge.net>
     11      1.1  wiz    Copyright (c) 2005-2007 Steven Solie <steven (at) solie.ca>
     12      1.1  wiz    Copyright (c) 2005-2012 Karl Waclawek <karl (at) waclawek.net>
     13  1.1.1.2  jdc    Copyright (c) 2016-2026 Sebastian Pipping <sebastian (at) pipping.org>
     14      1.1  wiz    Copyright (c) 2017-2022 Rhodri James <rhodri (at) wildebeest.org.uk>
     15      1.1  wiz    Copyright (c) 2017      Joe Orton <jorton (at) redhat.com>
     16      1.1  wiz    Copyright (c) 2017      Jos Gutirrez de la Concha <jose (at) zeroc.com>
     17      1.1  wiz    Copyright (c) 2018      Marco Maggi <marco.maggi-ipsu (at) poste.it>
     18      1.1  wiz    Copyright (c) 2019      David Loffredo <loffredo (at) steptools.com>
     19      1.1  wiz    Copyright (c) 2020      Tim Gates <tim.gates (at) iress.com>
     20      1.1  wiz    Copyright (c) 2021      Donghee Na <donghee.na (at) python.org>
     21      1.1  wiz    Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild (at) sony.com>
     22  1.1.1.2  jdc    Copyright (c) 2026      Matthew Fernandez <matthew.fernandez (at) gmail.com>
     23  1.1.1.2  jdc    Copyright (c) 2026      Berkay Eren rn <berkay.ueruen (at) siemens.com>
     24  1.1.1.3  jdc    Copyright (c) 2026      Kartik Kenchi <netliomax25 (at) gmail.com>
     25      1.1  wiz    Licensed under the MIT license:
     26      1.1  wiz 
     27      1.1  wiz    Permission is  hereby granted,  free of charge,  to any  person obtaining
     28      1.1  wiz    a  copy  of  this  software   and  associated  documentation  files  (the
     29      1.1  wiz    "Software"),  to  deal in  the  Software  without restriction,  including
     30      1.1  wiz    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
     31      1.1  wiz    distribute, sublicense, and/or sell copies of the Software, and to permit
     32      1.1  wiz    persons  to whom  the Software  is  furnished to  do so,  subject to  the
     33      1.1  wiz    following conditions:
     34      1.1  wiz 
     35      1.1  wiz    The above copyright  notice and this permission notice  shall be included
     36      1.1  wiz    in all copies or substantial portions of the Software.
     37      1.1  wiz 
     38      1.1  wiz    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
     39      1.1  wiz    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
     40      1.1  wiz    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
     41      1.1  wiz    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
     42      1.1  wiz    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
     43      1.1  wiz    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     44      1.1  wiz    USE OR OTHER DEALINGS IN THE SOFTWARE.
     45      1.1  wiz */
     46      1.1  wiz 
     47      1.1  wiz #if defined(NDEBUG)
     48      1.1  wiz #  undef NDEBUG /* because test suite relies on assert(...) at the moment */
     49      1.1  wiz #endif
     50      1.1  wiz 
     51  1.1.1.3  jdc #include "expat_config.h"
     52  1.1.1.3  jdc 
     53  1.1.1.2  jdc #include <stdint.h>
     54      1.1  wiz #include <stdio.h>
     55      1.1  wiz #include <string.h>
     56      1.1  wiz #include <assert.h>
     57      1.1  wiz 
     58      1.1  wiz #include "expat.h"
     59      1.1  wiz #include "internal.h"
     60      1.1  wiz #include "chardata.h"
     61      1.1  wiz #include "structdata.h"
     62      1.1  wiz #include "common.h"
     63      1.1  wiz #include "handlers.h"
     64      1.1  wiz 
     65      1.1  wiz /* Global variables for user parameter settings tests */
     66      1.1  wiz /* Variable holding the expected handler userData */
     67      1.1  wiz const void *g_handler_data = NULL;
     68      1.1  wiz /* Count of the number of times the comment handler has been invoked */
     69      1.1  wiz int g_comment_count = 0;
     70      1.1  wiz /* Count of the number of skipped entities */
     71      1.1  wiz int g_skip_count = 0;
     72      1.1  wiz /* Count of the number of times the XML declaration handler is invoked */
     73      1.1  wiz int g_xdecl_count = 0;
     74      1.1  wiz 
     75      1.1  wiz /* Start/End Element Handlers */
     76      1.1  wiz 
     77      1.1  wiz void XMLCALL
     78      1.1  wiz start_element_event_handler(void *userData, const XML_Char *name,
     79      1.1  wiz                             const XML_Char **atts) {
     80      1.1  wiz   UNUSED_P(atts);
     81      1.1  wiz   CharData_AppendXMLChars((CharData *)userData, name, -1);
     82      1.1  wiz }
     83      1.1  wiz 
     84      1.1  wiz void XMLCALL
     85      1.1  wiz end_element_event_handler(void *userData, const XML_Char *name) {
     86      1.1  wiz   CharData *storage = (CharData *)userData;
     87      1.1  wiz   CharData_AppendXMLChars(storage, XCS("/"), 1);
     88      1.1  wiz   CharData_AppendXMLChars(storage, name, -1);
     89      1.1  wiz }
     90      1.1  wiz 
     91      1.1  wiz void XMLCALL
     92      1.1  wiz start_element_event_handler2(void *userData, const XML_Char *name,
     93      1.1  wiz                              const XML_Char **attr) {
     94      1.1  wiz   StructData *storage = (StructData *)userData;
     95      1.1  wiz   UNUSED_P(attr);
     96  1.1.1.2  jdc   StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
     97  1.1.1.2  jdc                      (int)XML_GetCurrentLineNumber(g_parser), STRUCT_START_TAG);
     98      1.1  wiz }
     99      1.1  wiz 
    100      1.1  wiz void XMLCALL
    101      1.1  wiz end_element_event_handler2(void *userData, const XML_Char *name) {
    102      1.1  wiz   StructData *storage = (StructData *)userData;
    103  1.1.1.2  jdc   StructData_AddItem(storage, name, (int)XML_GetCurrentColumnNumber(g_parser),
    104  1.1.1.2  jdc                      (int)XML_GetCurrentLineNumber(g_parser), STRUCT_END_TAG);
    105      1.1  wiz }
    106      1.1  wiz 
    107      1.1  wiz void XMLCALL
    108      1.1  wiz counting_start_element_handler(void *userData, const XML_Char *name,
    109      1.1  wiz                                const XML_Char **atts) {
    110      1.1  wiz   ParserAndElementInfo *const parserAndElementInfos
    111      1.1  wiz       = (ParserAndElementInfo *)userData;
    112      1.1  wiz   ElementInfo *info = parserAndElementInfos->info;
    113      1.1  wiz   AttrInfo *attr;
    114      1.1  wiz   int count, id, i;
    115      1.1  wiz 
    116      1.1  wiz   while (info->name != NULL) {
    117      1.1  wiz     if (! xcstrcmp(name, info->name))
    118      1.1  wiz       break;
    119      1.1  wiz     info++;
    120      1.1  wiz   }
    121      1.1  wiz   if (info->name == NULL)
    122      1.1  wiz     fail("Element not recognised");
    123      1.1  wiz   /* The attribute count is twice what you might expect.  It is a
    124      1.1  wiz    * count of items in atts, an array which contains alternating
    125      1.1  wiz    * attribute names and attribute values.  For the naive user this
    126      1.1  wiz    * is possibly a little unexpected, but it is what the
    127      1.1  wiz    * documentation in expat.h tells us to expect.
    128      1.1  wiz    */
    129      1.1  wiz   count = XML_GetSpecifiedAttributeCount(parserAndElementInfos->parser);
    130      1.1  wiz   if (info->attr_count * 2 != count) {
    131      1.1  wiz     fail("Not got expected attribute count");
    132      1.1  wiz     return;
    133      1.1  wiz   }
    134      1.1  wiz   id = XML_GetIdAttributeIndex(parserAndElementInfos->parser);
    135      1.1  wiz   if (id == -1 && info->id_name != NULL) {
    136      1.1  wiz     fail("ID not present");
    137      1.1  wiz     return;
    138      1.1  wiz   }
    139  1.1.1.2  jdc   if (id != -1 && xcstrcmp(atts[id], info->id_name) != 0) {
    140      1.1  wiz     fail("ID does not have the correct name");
    141      1.1  wiz     return;
    142      1.1  wiz   }
    143  1.1.1.2  jdc   for (i = 0; i < info->attr_count + info->default_attr_count; i++) {
    144      1.1  wiz     attr = info->attributes;
    145      1.1  wiz     while (attr->name != NULL) {
    146      1.1  wiz       if (! xcstrcmp(atts[0], attr->name))
    147      1.1  wiz         break;
    148      1.1  wiz       attr++;
    149      1.1  wiz     }
    150      1.1  wiz     if (attr->name == NULL) {
    151      1.1  wiz       fail("Attribute not recognised");
    152      1.1  wiz       return;
    153      1.1  wiz     }
    154  1.1.1.2  jdc     if (xcstrcmp(atts[1], attr->value) != 0) {
    155      1.1  wiz       fail("Attribute has wrong value");
    156      1.1  wiz       return;
    157      1.1  wiz     }
    158      1.1  wiz     /* Remember, two entries in atts per attribute (see above) */
    159      1.1  wiz     atts += 2;
    160      1.1  wiz   }
    161  1.1.1.2  jdc 
    162  1.1.1.2  jdc   // Self-test that the test case's list of expected attributes is complete
    163  1.1.1.2  jdc   assert_true(atts[0] == NULL);
    164      1.1  wiz }
    165      1.1  wiz 
    166      1.1  wiz void XMLCALL
    167      1.1  wiz suspending_end_handler(void *userData, const XML_Char *s) {
    168      1.1  wiz   UNUSED_P(s);
    169      1.1  wiz   XML_StopParser((XML_Parser)userData, 1);
    170      1.1  wiz }
    171      1.1  wiz 
    172      1.1  wiz void XMLCALL
    173      1.1  wiz start_element_suspender(void *userData, const XML_Char *name,
    174      1.1  wiz                         const XML_Char **atts) {
    175      1.1  wiz   UNUSED_P(userData);
    176      1.1  wiz   UNUSED_P(atts);
    177      1.1  wiz   if (! xcstrcmp(name, XCS("suspend")))
    178      1.1  wiz     XML_StopParser(g_parser, XML_TRUE);
    179      1.1  wiz   if (! xcstrcmp(name, XCS("abort")))
    180      1.1  wiz     XML_StopParser(g_parser, XML_FALSE);
    181      1.1  wiz }
    182      1.1  wiz 
    183      1.1  wiz /* Check that an element name and attribute name match the expected values.
    184      1.1  wiz    The expected values are passed as an array reference of string pointers
    185      1.1  wiz    provided as the userData argument; the first is the expected
    186      1.1  wiz    element name, and the second is the expected attribute name.
    187      1.1  wiz */
    188      1.1  wiz int g_triplet_start_flag = XML_FALSE;
    189      1.1  wiz int g_triplet_end_flag = XML_FALSE;
    190      1.1  wiz 
    191      1.1  wiz void XMLCALL
    192      1.1  wiz triplet_start_checker(void *userData, const XML_Char *name,
    193      1.1  wiz                       const XML_Char **atts) {
    194      1.1  wiz   XML_Char **elemstr = (XML_Char **)userData;
    195      1.1  wiz   char buffer[1024];
    196      1.1  wiz   if (xcstrcmp(elemstr[0], name) != 0) {
    197      1.1  wiz     snprintf(buffer, sizeof(buffer),
    198      1.1  wiz              "unexpected start string: '%" XML_FMT_STR "'", name);
    199      1.1  wiz     fail(buffer);
    200      1.1  wiz   }
    201      1.1  wiz   if (xcstrcmp(elemstr[1], atts[0]) != 0) {
    202      1.1  wiz     snprintf(buffer, sizeof(buffer),
    203      1.1  wiz              "unexpected attribute string: '%" XML_FMT_STR "'", atts[0]);
    204      1.1  wiz     fail(buffer);
    205      1.1  wiz   }
    206      1.1  wiz   g_triplet_start_flag = XML_TRUE;
    207      1.1  wiz }
    208      1.1  wiz 
    209      1.1  wiz /* Check that the element name passed to the end-element handler matches
    210      1.1  wiz    the expected value.  The expected value is passed as the first element
    211      1.1  wiz    in an array of strings passed as the userData argument.
    212      1.1  wiz */
    213      1.1  wiz void XMLCALL
    214      1.1  wiz triplet_end_checker(void *userData, const XML_Char *name) {
    215      1.1  wiz   XML_Char **elemstr = (XML_Char **)userData;
    216      1.1  wiz   if (xcstrcmp(elemstr[0], name) != 0) {
    217      1.1  wiz     char buffer[1024];
    218      1.1  wiz     snprintf(buffer, sizeof(buffer),
    219      1.1  wiz              "unexpected end string: '%" XML_FMT_STR "'", name);
    220      1.1  wiz     fail(buffer);
    221      1.1  wiz   }
    222      1.1  wiz   g_triplet_end_flag = XML_TRUE;
    223      1.1  wiz }
    224      1.1  wiz 
    225      1.1  wiz void XMLCALL
    226      1.1  wiz overwrite_start_checker(void *userData, const XML_Char *name,
    227      1.1  wiz                         const XML_Char **atts) {
    228      1.1  wiz   CharData *storage = (CharData *)userData;
    229      1.1  wiz   CharData_AppendXMLChars(storage, XCS("start "), 6);
    230      1.1  wiz   CharData_AppendXMLChars(storage, name, -1);
    231      1.1  wiz   while (*atts != NULL) {
    232      1.1  wiz     CharData_AppendXMLChars(storage, XCS("\nattribute "), 11);
    233      1.1  wiz     CharData_AppendXMLChars(storage, *atts, -1);
    234      1.1  wiz     atts += 2;
    235      1.1  wiz   }
    236      1.1  wiz   CharData_AppendXMLChars(storage, XCS("\n"), 1);
    237      1.1  wiz }
    238      1.1  wiz 
    239      1.1  wiz void XMLCALL
    240      1.1  wiz overwrite_end_checker(void *userData, const XML_Char *name) {
    241      1.1  wiz   CharData *storage = (CharData *)userData;
    242      1.1  wiz   CharData_AppendXMLChars(storage, XCS("end "), 4);
    243      1.1  wiz   CharData_AppendXMLChars(storage, name, -1);
    244      1.1  wiz   CharData_AppendXMLChars(storage, XCS("\n"), 1);
    245      1.1  wiz }
    246      1.1  wiz 
    247      1.1  wiz void XMLCALL
    248      1.1  wiz start_element_fail(void *userData, const XML_Char *name,
    249      1.1  wiz                    const XML_Char **atts) {
    250      1.1  wiz   UNUSED_P(userData);
    251      1.1  wiz   UNUSED_P(name);
    252      1.1  wiz   UNUSED_P(atts);
    253      1.1  wiz 
    254      1.1  wiz   /* We should never get here. */
    255      1.1  wiz   fail("should never reach start_element_fail()");
    256      1.1  wiz }
    257      1.1  wiz 
    258      1.1  wiz void XMLCALL
    259      1.1  wiz start_ns_clearing_start_element(void *userData, const XML_Char *prefix,
    260      1.1  wiz                                 const XML_Char *uri) {
    261      1.1  wiz   UNUSED_P(prefix);
    262      1.1  wiz   UNUSED_P(uri);
    263      1.1  wiz   XML_SetStartElementHandler((XML_Parser)userData, NULL);
    264      1.1  wiz }
    265      1.1  wiz 
    266      1.1  wiz void XMLCALL
    267      1.1  wiz start_element_issue_240(void *userData, const XML_Char *name,
    268      1.1  wiz                         const XML_Char **atts) {
    269      1.1  wiz   DataIssue240 *mydata = (DataIssue240 *)userData;
    270      1.1  wiz   UNUSED_P(name);
    271      1.1  wiz   UNUSED_P(atts);
    272      1.1  wiz   mydata->deep++;
    273      1.1  wiz }
    274      1.1  wiz 
    275      1.1  wiz void XMLCALL
    276      1.1  wiz end_element_issue_240(void *userData, const XML_Char *name) {
    277      1.1  wiz   DataIssue240 *mydata = (DataIssue240 *)userData;
    278      1.1  wiz 
    279      1.1  wiz   UNUSED_P(name);
    280      1.1  wiz   mydata->deep--;
    281      1.1  wiz   if (mydata->deep == 0) {
    282      1.1  wiz     XML_StopParser(mydata->parser, 0);
    283      1.1  wiz   }
    284      1.1  wiz }
    285      1.1  wiz 
    286      1.1  wiz /* Text encoding handlers */
    287      1.1  wiz 
    288      1.1  wiz int XMLCALL
    289      1.1  wiz UnknownEncodingHandler(void *data, const XML_Char *encoding,
    290      1.1  wiz                        XML_Encoding *info) {
    291      1.1  wiz   UNUSED_P(data);
    292      1.1  wiz   if (xcstrcmp(encoding, XCS("unsupported-encoding")) == 0) {
    293      1.1  wiz     int i;
    294      1.1  wiz     for (i = 0; i < 256; ++i)
    295      1.1  wiz       info->map[i] = i;
    296      1.1  wiz     info->data = NULL;
    297      1.1  wiz     info->convert = NULL;
    298      1.1  wiz     info->release = NULL;
    299      1.1  wiz     return XML_STATUS_OK;
    300      1.1  wiz   }
    301      1.1  wiz   return XML_STATUS_ERROR;
    302      1.1  wiz }
    303      1.1  wiz 
    304      1.1  wiz static void
    305      1.1  wiz dummy_release(void *data) {
    306      1.1  wiz   UNUSED_P(data);
    307      1.1  wiz }
    308      1.1  wiz 
    309      1.1  wiz int XMLCALL
    310      1.1  wiz UnrecognisedEncodingHandler(void *data, const XML_Char *encoding,
    311      1.1  wiz                             XML_Encoding *info) {
    312      1.1  wiz   UNUSED_P(data);
    313      1.1  wiz   UNUSED_P(encoding);
    314      1.1  wiz   info->data = NULL;
    315      1.1  wiz   info->convert = NULL;
    316      1.1  wiz   info->release = dummy_release;
    317      1.1  wiz   return XML_STATUS_ERROR;
    318      1.1  wiz }
    319      1.1  wiz 
    320      1.1  wiz int XMLCALL
    321      1.1  wiz unknown_released_encoding_handler(void *data, const XML_Char *encoding,
    322      1.1  wiz                                   XML_Encoding *info) {
    323      1.1  wiz   UNUSED_P(data);
    324      1.1  wiz   if (! xcstrcmp(encoding, XCS("unsupported-encoding"))) {
    325      1.1  wiz     int i;
    326      1.1  wiz 
    327      1.1  wiz     for (i = 0; i < 256; i++)
    328      1.1  wiz       info->map[i] = i;
    329      1.1  wiz     info->data = NULL;
    330      1.1  wiz     info->convert = NULL;
    331      1.1  wiz     info->release = dummy_release;
    332      1.1  wiz     return XML_STATUS_OK;
    333      1.1  wiz   }
    334      1.1  wiz   return XML_STATUS_ERROR;
    335      1.1  wiz }
    336      1.1  wiz 
    337      1.1  wiz static int XMLCALL
    338      1.1  wiz failing_converter(void *data, const char *s) {
    339      1.1  wiz   UNUSED_P(data);
    340      1.1  wiz   UNUSED_P(s);
    341      1.1  wiz   /* Always claim to have failed */
    342      1.1  wiz   return -1;
    343      1.1  wiz }
    344      1.1  wiz 
    345      1.1  wiz static int XMLCALL
    346      1.1  wiz prefix_converter(void *data, const char *s) {
    347      1.1  wiz   UNUSED_P(data);
    348      1.1  wiz   /* If the first byte is 0xff, raise an error */
    349      1.1  wiz   if (s[0] == (char)-1)
    350      1.1  wiz     return -1;
    351      1.1  wiz   /* Just add the low bits of the first byte to the second */
    352      1.1  wiz   return (s[1] + (s[0] & 0x7f)) & 0x01ff;
    353      1.1  wiz }
    354      1.1  wiz 
    355      1.1  wiz int XMLCALL
    356      1.1  wiz MiscEncodingHandler(void *data, const XML_Char *encoding, XML_Encoding *info) {
    357      1.1  wiz   int i;
    358      1.1  wiz   int high_map = -2; /* Assume a 2-byte sequence */
    359      1.1  wiz 
    360      1.1  wiz   if (! xcstrcmp(encoding, XCS("invalid-9"))
    361      1.1  wiz       || ! xcstrcmp(encoding, XCS("ascii-like"))
    362      1.1  wiz       || ! xcstrcmp(encoding, XCS("invalid-len"))
    363      1.1  wiz       || ! xcstrcmp(encoding, XCS("invalid-a"))
    364      1.1  wiz       || ! xcstrcmp(encoding, XCS("invalid-surrogate"))
    365      1.1  wiz       || ! xcstrcmp(encoding, XCS("invalid-high")))
    366      1.1  wiz     high_map = -1;
    367      1.1  wiz 
    368      1.1  wiz   for (i = 0; i < 128; ++i)
    369      1.1  wiz     info->map[i] = i;
    370      1.1  wiz   for (; i < 256; ++i)
    371      1.1  wiz     info->map[i] = high_map;
    372      1.1  wiz 
    373      1.1  wiz   /* If required, put an invalid value in the ASCII entries */
    374      1.1  wiz   if (! xcstrcmp(encoding, XCS("invalid-9")))
    375      1.1  wiz     info->map[9] = 5;
    376      1.1  wiz   /* If required, have a top-bit set character starts a 5-byte sequence */
    377      1.1  wiz   if (! xcstrcmp(encoding, XCS("invalid-len")))
    378      1.1  wiz     info->map[0x81] = -5;
    379      1.1  wiz   /* If required, make a top-bit set character a valid ASCII character */
    380      1.1  wiz   if (! xcstrcmp(encoding, XCS("invalid-a")))
    381      1.1  wiz     info->map[0x82] = 'a';
    382      1.1  wiz   /* If required, give a top-bit set character a forbidden value,
    383      1.1  wiz    * what would otherwise be the first of a surrogate pair.
    384      1.1  wiz    */
    385      1.1  wiz   if (! xcstrcmp(encoding, XCS("invalid-surrogate")))
    386      1.1  wiz     info->map[0x83] = 0xd801;
    387      1.1  wiz   /* If required, give a top-bit set character too high a value */
    388      1.1  wiz   if (! xcstrcmp(encoding, XCS("invalid-high")))
    389      1.1  wiz     info->map[0x84] = 0x010101;
    390      1.1  wiz 
    391      1.1  wiz   info->data = data;
    392      1.1  wiz   info->release = NULL;
    393      1.1  wiz   if (! xcstrcmp(encoding, XCS("failing-conv")))
    394      1.1  wiz     info->convert = failing_converter;
    395      1.1  wiz   else if (! xcstrcmp(encoding, XCS("prefix-conv")))
    396      1.1  wiz     info->convert = prefix_converter;
    397      1.1  wiz   else
    398      1.1  wiz     info->convert = NULL;
    399      1.1  wiz   return XML_STATUS_OK;
    400      1.1  wiz }
    401      1.1  wiz 
    402      1.1  wiz int XMLCALL
    403      1.1  wiz long_encoding_handler(void *userData, const XML_Char *encoding,
    404      1.1  wiz                       XML_Encoding *info) {
    405      1.1  wiz   int i;
    406      1.1  wiz 
    407      1.1  wiz   UNUSED_P(userData);
    408      1.1  wiz   UNUSED_P(encoding);
    409      1.1  wiz   for (i = 0; i < 256; i++)
    410      1.1  wiz     info->map[i] = i;
    411      1.1  wiz   info->data = NULL;
    412      1.1  wiz   info->convert = NULL;
    413      1.1  wiz   info->release = NULL;
    414      1.1  wiz   return XML_STATUS_OK;
    415      1.1  wiz }
    416      1.1  wiz 
    417  1.1.1.2  jdc int XMLCALL
    418  1.1.1.2  jdc user_data_checking_unknown_encoding_handler(void *userData,
    419  1.1.1.2  jdc                                             const XML_Char *encoding,
    420  1.1.1.2  jdc                                             XML_Encoding *info) {
    421  1.1.1.2  jdc   const intptr_t number = (intptr_t)userData;
    422  1.1.1.2  jdc   assert_true(number == 0xC0FFEE);
    423  1.1.1.2  jdc   return long_encoding_handler(userData, encoding, info);
    424  1.1.1.2  jdc }
    425  1.1.1.2  jdc 
    426      1.1  wiz /* External Entity Handlers */
    427      1.1  wiz 
    428      1.1  wiz int XMLCALL
    429      1.1  wiz external_entity_optioner(XML_Parser parser, const XML_Char *context,
    430      1.1  wiz                          const XML_Char *base, const XML_Char *systemId,
    431      1.1  wiz                          const XML_Char *publicId) {
    432  1.1.1.2  jdc   ExtOption *options = XML_GetUserData(parser);
    433      1.1  wiz   XML_Parser ext_parser;
    434      1.1  wiz 
    435      1.1  wiz   UNUSED_P(base);
    436      1.1  wiz   UNUSED_P(publicId);
    437      1.1  wiz   while (options->parse_text != NULL) {
    438      1.1  wiz     if (! xcstrcmp(systemId, options->system_id)) {
    439      1.1  wiz       enum XML_Status rc;
    440      1.1  wiz       ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    441      1.1  wiz       if (ext_parser == NULL)
    442      1.1  wiz         return XML_STATUS_ERROR;
    443      1.1  wiz       rc = _XML_Parse_SINGLE_BYTES(ext_parser, options->parse_text,
    444      1.1  wiz                                    (int)strlen(options->parse_text), XML_TRUE);
    445      1.1  wiz       XML_ParserFree(ext_parser);
    446      1.1  wiz       return rc;
    447      1.1  wiz     }
    448      1.1  wiz     options++;
    449      1.1  wiz   }
    450      1.1  wiz   fail("No suitable option found");
    451      1.1  wiz   return XML_STATUS_ERROR;
    452      1.1  wiz }
    453      1.1  wiz 
    454      1.1  wiz int XMLCALL
    455      1.1  wiz external_entity_loader(XML_Parser parser, const XML_Char *context,
    456      1.1  wiz                        const XML_Char *base, const XML_Char *systemId,
    457      1.1  wiz                        const XML_Char *publicId) {
    458  1.1.1.2  jdc   ExtTest *test_data = XML_GetUserData(parser);
    459      1.1  wiz   XML_Parser extparser;
    460      1.1  wiz 
    461      1.1  wiz   UNUSED_P(base);
    462      1.1  wiz   UNUSED_P(systemId);
    463      1.1  wiz   UNUSED_P(publicId);
    464      1.1  wiz   extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
    465      1.1  wiz   if (extparser == NULL)
    466      1.1  wiz     fail("Could not create external entity parser.");
    467      1.1  wiz   if (test_data->encoding != NULL) {
    468      1.1  wiz     if (! XML_SetEncoding(extparser, test_data->encoding))
    469      1.1  wiz       fail("XML_SetEncoding() ignored for external entity");
    470      1.1  wiz   }
    471      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(extparser, test_data->parse_text,
    472      1.1  wiz                               (int)strlen(test_data->parse_text), XML_TRUE)
    473      1.1  wiz       == XML_STATUS_ERROR) {
    474      1.1  wiz     xml_failure(extparser);
    475      1.1  wiz     return XML_STATUS_ERROR;
    476      1.1  wiz   }
    477      1.1  wiz   XML_ParserFree(extparser);
    478      1.1  wiz   return XML_STATUS_OK;
    479      1.1  wiz }
    480      1.1  wiz 
    481      1.1  wiz int XMLCALL
    482      1.1  wiz external_entity_faulter(XML_Parser parser, const XML_Char *context,
    483      1.1  wiz                         const XML_Char *base, const XML_Char *systemId,
    484      1.1  wiz                         const XML_Char *publicId) {
    485      1.1  wiz   XML_Parser ext_parser;
    486  1.1.1.2  jdc   ExtFaults *fault = XML_GetUserData(parser);
    487      1.1  wiz 
    488      1.1  wiz   UNUSED_P(base);
    489      1.1  wiz   UNUSED_P(systemId);
    490      1.1  wiz   UNUSED_P(publicId);
    491      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    492      1.1  wiz   if (ext_parser == NULL)
    493      1.1  wiz     fail("Could not create external entity parser");
    494      1.1  wiz   if (fault->encoding != NULL) {
    495      1.1  wiz     if (! XML_SetEncoding(ext_parser, fault->encoding))
    496      1.1  wiz       fail("XML_SetEncoding failed");
    497      1.1  wiz   }
    498      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, fault->parse_text,
    499      1.1  wiz                               (int)strlen(fault->parse_text), XML_TRUE)
    500      1.1  wiz       != XML_STATUS_ERROR)
    501      1.1  wiz     fail(fault->fail_text);
    502      1.1  wiz   if (XML_GetErrorCode(ext_parser) != fault->error)
    503      1.1  wiz     xml_failure(ext_parser);
    504      1.1  wiz 
    505      1.1  wiz   XML_ParserFree(ext_parser);
    506      1.1  wiz   return XML_STATUS_ERROR;
    507      1.1  wiz }
    508      1.1  wiz 
    509      1.1  wiz int XMLCALL
    510      1.1  wiz external_entity_null_loader(XML_Parser parser, const XML_Char *context,
    511      1.1  wiz                             const XML_Char *base, const XML_Char *systemId,
    512      1.1  wiz                             const XML_Char *publicId) {
    513      1.1  wiz   UNUSED_P(parser);
    514      1.1  wiz   UNUSED_P(context);
    515      1.1  wiz   UNUSED_P(base);
    516      1.1  wiz   UNUSED_P(systemId);
    517      1.1  wiz   UNUSED_P(publicId);
    518      1.1  wiz   return XML_STATUS_OK;
    519      1.1  wiz }
    520      1.1  wiz 
    521      1.1  wiz int XMLCALL
    522      1.1  wiz external_entity_resetter(XML_Parser parser, const XML_Char *context,
    523      1.1  wiz                          const XML_Char *base, const XML_Char *systemId,
    524      1.1  wiz                          const XML_Char *publicId) {
    525      1.1  wiz   const char *text = "<!ELEMENT doc (#PCDATA)*>";
    526      1.1  wiz   XML_Parser ext_parser;
    527      1.1  wiz   XML_ParsingStatus status;
    528      1.1  wiz 
    529      1.1  wiz   UNUSED_P(base);
    530      1.1  wiz   UNUSED_P(systemId);
    531      1.1  wiz   UNUSED_P(publicId);
    532      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    533      1.1  wiz   if (ext_parser == NULL)
    534      1.1  wiz     fail("Could not create external entity parser");
    535      1.1  wiz   XML_GetParsingStatus(ext_parser, &status);
    536      1.1  wiz   if (status.parsing != XML_INITIALIZED) {
    537      1.1  wiz     fail("Parsing status is not INITIALIZED");
    538      1.1  wiz     return XML_STATUS_ERROR;
    539      1.1  wiz   }
    540      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    541      1.1  wiz       == XML_STATUS_ERROR) {
    542      1.1  wiz     xml_failure(parser);
    543      1.1  wiz     return XML_STATUS_ERROR;
    544      1.1  wiz   }
    545      1.1  wiz   XML_GetParsingStatus(ext_parser, &status);
    546      1.1  wiz   if (status.parsing != XML_FINISHED) {
    547      1.1  wiz     fail("Parsing status is not FINISHED");
    548      1.1  wiz     return XML_STATUS_ERROR;
    549      1.1  wiz   }
    550      1.1  wiz   /* Check we can't parse here */
    551      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    552      1.1  wiz       != XML_STATUS_ERROR)
    553      1.1  wiz     fail("Parsing when finished not faulted");
    554      1.1  wiz   if (XML_GetErrorCode(ext_parser) != XML_ERROR_FINISHED)
    555      1.1  wiz     fail("Parsing when finished faulted with wrong code");
    556      1.1  wiz   XML_ParserReset(ext_parser, NULL);
    557      1.1  wiz   XML_GetParsingStatus(ext_parser, &status);
    558      1.1  wiz   if (status.parsing != XML_FINISHED) {
    559      1.1  wiz     fail("Parsing status not still FINISHED");
    560      1.1  wiz     return XML_STATUS_ERROR;
    561      1.1  wiz   }
    562      1.1  wiz   XML_ParserFree(ext_parser);
    563      1.1  wiz   return XML_STATUS_OK;
    564      1.1  wiz }
    565      1.1  wiz 
    566      1.1  wiz void XMLCALL
    567      1.1  wiz entity_suspending_decl_handler(void *userData, const XML_Char *name,
    568      1.1  wiz                                XML_Content *model) {
    569      1.1  wiz   XML_Parser ext_parser = (XML_Parser)userData;
    570      1.1  wiz 
    571      1.1  wiz   UNUSED_P(name);
    572      1.1  wiz   if (XML_StopParser(ext_parser, XML_TRUE) != XML_STATUS_ERROR)
    573      1.1  wiz     fail("Attempting to suspend a subordinate parser not faulted");
    574      1.1  wiz   if (XML_GetErrorCode(ext_parser) != XML_ERROR_SUSPEND_PE)
    575      1.1  wiz     fail("Suspending subordinate parser get wrong code");
    576      1.1  wiz   XML_SetElementDeclHandler(ext_parser, NULL);
    577      1.1  wiz   XML_FreeContentModel(g_parser, model);
    578      1.1  wiz }
    579      1.1  wiz 
    580      1.1  wiz int XMLCALL
    581      1.1  wiz external_entity_suspender(XML_Parser parser, const XML_Char *context,
    582      1.1  wiz                           const XML_Char *base, const XML_Char *systemId,
    583      1.1  wiz                           const XML_Char *publicId) {
    584      1.1  wiz   const char *text = "<!ELEMENT doc (#PCDATA)*>";
    585      1.1  wiz   XML_Parser ext_parser;
    586      1.1  wiz 
    587      1.1  wiz   UNUSED_P(base);
    588      1.1  wiz   UNUSED_P(systemId);
    589      1.1  wiz   UNUSED_P(publicId);
    590      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    591      1.1  wiz   if (ext_parser == NULL)
    592      1.1  wiz     fail("Could not create external entity parser");
    593      1.1  wiz   XML_SetElementDeclHandler(ext_parser, entity_suspending_decl_handler);
    594      1.1  wiz   XML_SetUserData(ext_parser, ext_parser);
    595      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    596      1.1  wiz       == XML_STATUS_ERROR) {
    597      1.1  wiz     xml_failure(ext_parser);
    598      1.1  wiz     return XML_STATUS_ERROR;
    599      1.1  wiz   }
    600      1.1  wiz   XML_ParserFree(ext_parser);
    601      1.1  wiz   return XML_STATUS_OK;
    602      1.1  wiz }
    603      1.1  wiz 
    604      1.1  wiz void XMLCALL
    605      1.1  wiz entity_suspending_xdecl_handler(void *userData, const XML_Char *version,
    606      1.1  wiz                                 const XML_Char *encoding, int standalone) {
    607      1.1  wiz   XML_Parser ext_parser = (XML_Parser)userData;
    608      1.1  wiz 
    609      1.1  wiz   UNUSED_P(version);
    610      1.1  wiz   UNUSED_P(encoding);
    611      1.1  wiz   UNUSED_P(standalone);
    612      1.1  wiz   XML_StopParser(ext_parser, g_resumable);
    613      1.1  wiz   XML_SetXmlDeclHandler(ext_parser, NULL);
    614      1.1  wiz }
    615      1.1  wiz 
    616      1.1  wiz int XMLCALL
    617      1.1  wiz external_entity_suspend_xmldecl(XML_Parser parser, const XML_Char *context,
    618      1.1  wiz                                 const XML_Char *base, const XML_Char *systemId,
    619      1.1  wiz                                 const XML_Char *publicId) {
    620      1.1  wiz   const char *text = "<?xml version='1.0' encoding='us-ascii'?>";
    621      1.1  wiz   XML_Parser ext_parser;
    622      1.1  wiz   XML_ParsingStatus status;
    623      1.1  wiz   enum XML_Status rc;
    624      1.1  wiz 
    625      1.1  wiz   UNUSED_P(base);
    626      1.1  wiz   UNUSED_P(systemId);
    627      1.1  wiz   UNUSED_P(publicId);
    628      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    629      1.1  wiz   if (ext_parser == NULL)
    630      1.1  wiz     fail("Could not create external entity parser");
    631      1.1  wiz   XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
    632      1.1  wiz   XML_SetUserData(ext_parser, ext_parser);
    633      1.1  wiz   rc = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE);
    634      1.1  wiz   XML_GetParsingStatus(ext_parser, &status);
    635      1.1  wiz   if (g_resumable) {
    636      1.1  wiz     if (rc == XML_STATUS_ERROR)
    637      1.1  wiz       xml_failure(ext_parser);
    638      1.1  wiz     if (status.parsing != XML_SUSPENDED)
    639      1.1  wiz       fail("Ext Parsing status not SUSPENDED");
    640      1.1  wiz   } else {
    641      1.1  wiz     if (rc != XML_STATUS_ERROR)
    642      1.1  wiz       fail("Ext parsing not aborted");
    643      1.1  wiz     if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED)
    644      1.1  wiz       xml_failure(ext_parser);
    645      1.1  wiz     if (status.parsing != XML_FINISHED)
    646      1.1  wiz       fail("Ext Parsing status not FINISHED");
    647      1.1  wiz   }
    648      1.1  wiz 
    649      1.1  wiz   XML_ParserFree(ext_parser);
    650      1.1  wiz   return XML_STATUS_OK;
    651      1.1  wiz }
    652      1.1  wiz 
    653      1.1  wiz int XMLCALL
    654      1.1  wiz external_entity_suspending_faulter(XML_Parser parser, const XML_Char *context,
    655      1.1  wiz                                    const XML_Char *base,
    656      1.1  wiz                                    const XML_Char *systemId,
    657      1.1  wiz                                    const XML_Char *publicId) {
    658      1.1  wiz   XML_Parser ext_parser;
    659  1.1.1.2  jdc   ExtFaults *fault = XML_GetUserData(parser);
    660      1.1  wiz   void *buffer;
    661      1.1  wiz   int parse_len = (int)strlen(fault->parse_text);
    662      1.1  wiz 
    663      1.1  wiz   UNUSED_P(base);
    664      1.1  wiz   UNUSED_P(systemId);
    665      1.1  wiz   UNUSED_P(publicId);
    666      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    667      1.1  wiz   if (ext_parser == NULL)
    668      1.1  wiz     fail("Could not create external entity parser");
    669      1.1  wiz   XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
    670      1.1  wiz   XML_SetUserData(ext_parser, ext_parser);
    671      1.1  wiz   g_resumable = XML_TRUE;
    672      1.1  wiz   buffer = XML_GetBuffer(ext_parser, parse_len);
    673      1.1  wiz   if (buffer == NULL)
    674      1.1  wiz     fail("Could not allocate parse buffer");
    675      1.1  wiz   assert(buffer != NULL);
    676      1.1  wiz   memcpy(buffer, fault->parse_text, parse_len);
    677      1.1  wiz   if (XML_ParseBuffer(ext_parser, parse_len, XML_FALSE) != XML_STATUS_SUSPENDED)
    678      1.1  wiz     fail("XML declaration did not suspend");
    679      1.1  wiz   if (XML_ResumeParser(ext_parser) != XML_STATUS_OK)
    680      1.1  wiz     xml_failure(ext_parser);
    681      1.1  wiz   if (XML_ParseBuffer(ext_parser, 0, XML_TRUE) != XML_STATUS_ERROR)
    682      1.1  wiz     fail(fault->fail_text);
    683      1.1  wiz   if (XML_GetErrorCode(ext_parser) != fault->error)
    684      1.1  wiz     xml_failure(ext_parser);
    685      1.1  wiz 
    686      1.1  wiz   XML_ParserFree(ext_parser);
    687      1.1  wiz   return XML_STATUS_ERROR;
    688      1.1  wiz }
    689      1.1  wiz 
    690      1.1  wiz int XMLCALL
    691      1.1  wiz external_entity_failer__if_not_xml_ge(XML_Parser parser,
    692      1.1  wiz                                       const XML_Char *context,
    693      1.1  wiz                                       const XML_Char *base,
    694      1.1  wiz                                       const XML_Char *systemId,
    695      1.1  wiz                                       const XML_Char *publicId) {
    696      1.1  wiz   UNUSED_P(parser);
    697      1.1  wiz   UNUSED_P(context);
    698      1.1  wiz   UNUSED_P(base);
    699      1.1  wiz   UNUSED_P(systemId);
    700      1.1  wiz   UNUSED_P(publicId);
    701      1.1  wiz #if XML_GE == 0
    702      1.1  wiz   fail(
    703      1.1  wiz       "Function external_entity_suspending_failer was called despite XML_GE==0.");
    704      1.1  wiz #endif
    705      1.1  wiz   return XML_STATUS_OK;
    706      1.1  wiz }
    707      1.1  wiz 
    708      1.1  wiz int XMLCALL
    709      1.1  wiz external_entity_cr_catcher(XML_Parser parser, const XML_Char *context,
    710      1.1  wiz                            const XML_Char *base, const XML_Char *systemId,
    711      1.1  wiz                            const XML_Char *publicId) {
    712      1.1  wiz   const char *text = "\r";
    713      1.1  wiz   XML_Parser ext_parser;
    714      1.1  wiz 
    715      1.1  wiz   UNUSED_P(base);
    716      1.1  wiz   UNUSED_P(systemId);
    717      1.1  wiz   UNUSED_P(publicId);
    718      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    719      1.1  wiz   if (ext_parser == NULL)
    720      1.1  wiz     fail("Could not create external entity parser");
    721      1.1  wiz   XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler);
    722      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    723      1.1  wiz       == XML_STATUS_ERROR)
    724      1.1  wiz     xml_failure(ext_parser);
    725      1.1  wiz   XML_ParserFree(ext_parser);
    726      1.1  wiz   return XML_STATUS_OK;
    727      1.1  wiz }
    728      1.1  wiz 
    729      1.1  wiz int XMLCALL
    730      1.1  wiz external_entity_bad_cr_catcher(XML_Parser parser, const XML_Char *context,
    731      1.1  wiz                                const XML_Char *base, const XML_Char *systemId,
    732      1.1  wiz                                const XML_Char *publicId) {
    733      1.1  wiz   const char *text = "<tag>\r";
    734      1.1  wiz   XML_Parser ext_parser;
    735      1.1  wiz 
    736      1.1  wiz   UNUSED_P(base);
    737      1.1  wiz   UNUSED_P(systemId);
    738      1.1  wiz   UNUSED_P(publicId);
    739      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    740      1.1  wiz   if (ext_parser == NULL)
    741      1.1  wiz     fail("Could not create external entity parser");
    742      1.1  wiz   XML_SetCharacterDataHandler(ext_parser, cr_cdata_handler);
    743      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    744      1.1  wiz       == XML_STATUS_OK)
    745      1.1  wiz     fail("Async entity error not caught");
    746      1.1  wiz   if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY)
    747      1.1  wiz     xml_failure(ext_parser);
    748      1.1  wiz   XML_ParserFree(ext_parser);
    749      1.1  wiz   return XML_STATUS_OK;
    750      1.1  wiz }
    751      1.1  wiz 
    752      1.1  wiz int XMLCALL
    753      1.1  wiz external_entity_rsqb_catcher(XML_Parser parser, const XML_Char *context,
    754      1.1  wiz                              const XML_Char *base, const XML_Char *systemId,
    755      1.1  wiz                              const XML_Char *publicId) {
    756      1.1  wiz   const char *text = "<tag>]";
    757      1.1  wiz   XML_Parser ext_parser;
    758      1.1  wiz 
    759      1.1  wiz   UNUSED_P(base);
    760      1.1  wiz   UNUSED_P(systemId);
    761      1.1  wiz   UNUSED_P(publicId);
    762      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    763      1.1  wiz   if (ext_parser == NULL)
    764      1.1  wiz     fail("Could not create external entity parser");
    765      1.1  wiz   XML_SetCharacterDataHandler(ext_parser, rsqb_handler);
    766      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    767      1.1  wiz       != XML_STATUS_ERROR)
    768      1.1  wiz     fail("Async entity error not caught");
    769      1.1  wiz   if (XML_GetErrorCode(ext_parser) != XML_ERROR_ASYNC_ENTITY)
    770      1.1  wiz     xml_failure(ext_parser);
    771      1.1  wiz   XML_ParserFree(ext_parser);
    772      1.1  wiz   return XML_STATUS_OK;
    773      1.1  wiz }
    774      1.1  wiz 
    775      1.1  wiz int XMLCALL
    776      1.1  wiz external_entity_good_cdata_ascii(XML_Parser parser, const XML_Char *context,
    777      1.1  wiz                                  const XML_Char *base, const XML_Char *systemId,
    778      1.1  wiz                                  const XML_Char *publicId) {
    779      1.1  wiz   const char *text = "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>";
    780      1.1  wiz   const XML_Char *expected = XCS("<greeting>Hello, world!</greeting>");
    781      1.1  wiz   CharData storage;
    782      1.1  wiz   XML_Parser ext_parser;
    783      1.1  wiz 
    784      1.1  wiz   UNUSED_P(base);
    785      1.1  wiz   UNUSED_P(systemId);
    786      1.1  wiz   UNUSED_P(publicId);
    787      1.1  wiz   CharData_Init(&storage);
    788      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    789      1.1  wiz   if (ext_parser == NULL)
    790      1.1  wiz     fail("Could not create external entity parser");
    791      1.1  wiz   XML_SetUserData(ext_parser, &storage);
    792      1.1  wiz   XML_SetCharacterDataHandler(ext_parser, accumulate_characters);
    793      1.1  wiz 
    794      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    795      1.1  wiz       == XML_STATUS_ERROR)
    796      1.1  wiz     xml_failure(ext_parser);
    797      1.1  wiz   CharData_CheckXMLChars(&storage, expected);
    798      1.1  wiz 
    799      1.1  wiz   XML_ParserFree(ext_parser);
    800      1.1  wiz   return XML_STATUS_OK;
    801      1.1  wiz }
    802      1.1  wiz 
    803      1.1  wiz int XMLCALL
    804      1.1  wiz external_entity_param_checker(XML_Parser parser, const XML_Char *context,
    805      1.1  wiz                               const XML_Char *base, const XML_Char *systemId,
    806      1.1  wiz                               const XML_Char *publicId) {
    807      1.1  wiz   const char *text = "<!-- Subordinate parser -->\n"
    808      1.1  wiz                      "<!ELEMENT doc (#PCDATA)*>";
    809      1.1  wiz   XML_Parser ext_parser;
    810      1.1  wiz 
    811      1.1  wiz   UNUSED_P(base);
    812      1.1  wiz   UNUSED_P(systemId);
    813      1.1  wiz   UNUSED_P(publicId);
    814      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    815      1.1  wiz   if (ext_parser == NULL)
    816      1.1  wiz     fail("Could not create external entity parser");
    817      1.1  wiz   g_handler_data = ext_parser;
    818      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    819      1.1  wiz       == XML_STATUS_ERROR) {
    820      1.1  wiz     xml_failure(parser);
    821      1.1  wiz     return XML_STATUS_ERROR;
    822      1.1  wiz   }
    823      1.1  wiz   g_handler_data = parser;
    824      1.1  wiz   XML_ParserFree(ext_parser);
    825      1.1  wiz   return XML_STATUS_OK;
    826      1.1  wiz }
    827      1.1  wiz 
    828      1.1  wiz int XMLCALL
    829      1.1  wiz external_entity_ref_param_checker(XML_Parser parameter, const XML_Char *context,
    830      1.1  wiz                                   const XML_Char *base,
    831      1.1  wiz                                   const XML_Char *systemId,
    832      1.1  wiz                                   const XML_Char *publicId) {
    833      1.1  wiz   const char *text = "<!ELEMENT doc (#PCDATA)*>";
    834      1.1  wiz   XML_Parser ext_parser;
    835      1.1  wiz 
    836      1.1  wiz   UNUSED_P(base);
    837      1.1  wiz   UNUSED_P(systemId);
    838      1.1  wiz   UNUSED_P(publicId);
    839      1.1  wiz   if ((void *)parameter != g_handler_data)
    840      1.1  wiz     fail("External entity ref handler parameter not correct");
    841      1.1  wiz 
    842      1.1  wiz   /* Here we use the global 'parser' variable */
    843      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(g_parser, context, NULL);
    844      1.1  wiz   if (ext_parser == NULL)
    845      1.1  wiz     fail("Could not create external entity parser");
    846      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    847      1.1  wiz       == XML_STATUS_ERROR)
    848      1.1  wiz     xml_failure(ext_parser);
    849      1.1  wiz 
    850      1.1  wiz   XML_ParserFree(ext_parser);
    851      1.1  wiz   return XML_STATUS_OK;
    852      1.1  wiz }
    853      1.1  wiz 
    854      1.1  wiz int XMLCALL
    855      1.1  wiz external_entity_param(XML_Parser parser, const XML_Char *context,
    856      1.1  wiz                       const XML_Char *base, const XML_Char *systemId,
    857      1.1  wiz                       const XML_Char *publicId) {
    858      1.1  wiz   const char *text1 = "<!ELEMENT doc EMPTY>\n"
    859      1.1  wiz                       "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
    860      1.1  wiz                       "<!ENTITY % e2 '%e1;'>\n"
    861      1.1  wiz                       "%e1;\n";
    862      1.1  wiz   const char *text2 = "<!ELEMENT el EMPTY>\n"
    863      1.1  wiz                       "<el/>\n";
    864      1.1  wiz   XML_Parser ext_parser;
    865      1.1  wiz 
    866      1.1  wiz   UNUSED_P(base);
    867      1.1  wiz   UNUSED_P(publicId);
    868      1.1  wiz   if (systemId == NULL)
    869      1.1  wiz     return XML_STATUS_OK;
    870      1.1  wiz 
    871      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    872      1.1  wiz   if (ext_parser == NULL)
    873      1.1  wiz     fail("Could not create external entity parser");
    874      1.1  wiz 
    875      1.1  wiz   if (! xcstrcmp(systemId, XCS("004-1.ent"))) {
    876      1.1  wiz     if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE)
    877      1.1  wiz         != XML_STATUS_ERROR)
    878      1.1  wiz       fail("Inner DTD with invalid tag not rejected");
    879      1.1  wiz     if (XML_GetErrorCode(ext_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
    880      1.1  wiz       xml_failure(ext_parser);
    881      1.1  wiz   } else if (! xcstrcmp(systemId, XCS("004-2.ent"))) {
    882      1.1  wiz     if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE)
    883      1.1  wiz         != XML_STATUS_ERROR)
    884      1.1  wiz       fail("Invalid tag in external param not rejected");
    885      1.1  wiz     if (XML_GetErrorCode(ext_parser) != XML_ERROR_SYNTAX)
    886      1.1  wiz       xml_failure(ext_parser);
    887      1.1  wiz   } else {
    888      1.1  wiz     fail("Unknown system ID");
    889      1.1  wiz   }
    890      1.1  wiz 
    891      1.1  wiz   XML_ParserFree(ext_parser);
    892      1.1  wiz   return XML_STATUS_ERROR;
    893      1.1  wiz }
    894      1.1  wiz 
    895      1.1  wiz int XMLCALL
    896      1.1  wiz external_entity_load_ignore(XML_Parser parser, const XML_Char *context,
    897      1.1  wiz                             const XML_Char *base, const XML_Char *systemId,
    898      1.1  wiz                             const XML_Char *publicId) {
    899      1.1  wiz   const char *text = "<![IGNORE[<!ELEMENT e (#PCDATA)*>]]>";
    900      1.1  wiz   XML_Parser ext_parser;
    901      1.1  wiz 
    902      1.1  wiz   UNUSED_P(base);
    903      1.1  wiz   UNUSED_P(systemId);
    904      1.1  wiz   UNUSED_P(publicId);
    905      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    906      1.1  wiz   if (ext_parser == NULL)
    907      1.1  wiz     fail("Could not create external entity parser");
    908      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
    909      1.1  wiz       == XML_STATUS_ERROR)
    910      1.1  wiz     xml_failure(parser);
    911      1.1  wiz 
    912      1.1  wiz   XML_ParserFree(ext_parser);
    913      1.1  wiz   return XML_STATUS_OK;
    914      1.1  wiz }
    915      1.1  wiz 
    916      1.1  wiz int XMLCALL
    917      1.1  wiz external_entity_load_ignore_utf16(XML_Parser parser, const XML_Char *context,
    918      1.1  wiz                                   const XML_Char *base,
    919      1.1  wiz                                   const XML_Char *systemId,
    920      1.1  wiz                                   const XML_Char *publicId) {
    921      1.1  wiz   const char text[] =
    922      1.1  wiz       /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */
    923      1.1  wiz       "<\0!\0[\0I\0G\0N\0O\0R\0E\0[\0"
    924      1.1  wiz       "<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 \0"
    925      1.1  wiz       "(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>\0";
    926      1.1  wiz   XML_Parser ext_parser;
    927      1.1  wiz 
    928      1.1  wiz   UNUSED_P(base);
    929      1.1  wiz   UNUSED_P(systemId);
    930      1.1  wiz   UNUSED_P(publicId);
    931      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    932      1.1  wiz   if (ext_parser == NULL)
    933      1.1  wiz     fail("Could not create external entity parser");
    934      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text) - 1, XML_TRUE)
    935      1.1  wiz       == XML_STATUS_ERROR)
    936      1.1  wiz     xml_failure(parser);
    937      1.1  wiz 
    938      1.1  wiz   XML_ParserFree(ext_parser);
    939      1.1  wiz   return XML_STATUS_OK;
    940      1.1  wiz }
    941      1.1  wiz 
    942      1.1  wiz int XMLCALL
    943      1.1  wiz external_entity_load_ignore_utf16_be(XML_Parser parser, const XML_Char *context,
    944      1.1  wiz                                      const XML_Char *base,
    945      1.1  wiz                                      const XML_Char *systemId,
    946      1.1  wiz                                      const XML_Char *publicId) {
    947      1.1  wiz   const char text[] =
    948      1.1  wiz       /* <![IGNORE[<!ELEMENT e (#PCDATA)*>]]> */
    949      1.1  wiz       "\0<\0!\0[\0I\0G\0N\0O\0R\0E\0["
    950      1.1  wiz       "\0<\0!\0E\0L\0E\0M\0E\0N\0T\0 \0e\0 "
    951      1.1  wiz       "\0(\0#\0P\0C\0D\0A\0T\0A\0)\0*\0>\0]\0]\0>";
    952      1.1  wiz   XML_Parser ext_parser;
    953      1.1  wiz 
    954      1.1  wiz   UNUSED_P(base);
    955      1.1  wiz   UNUSED_P(systemId);
    956      1.1  wiz   UNUSED_P(publicId);
    957      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    958      1.1  wiz   if (ext_parser == NULL)
    959      1.1  wiz     fail("Could not create external entity parser");
    960      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)sizeof(text) - 1, XML_TRUE)
    961      1.1  wiz       == XML_STATUS_ERROR)
    962      1.1  wiz     xml_failure(parser);
    963      1.1  wiz 
    964      1.1  wiz   XML_ParserFree(ext_parser);
    965      1.1  wiz   return XML_STATUS_OK;
    966      1.1  wiz }
    967      1.1  wiz 
    968      1.1  wiz int XMLCALL
    969      1.1  wiz external_entity_valuer(XML_Parser parser, const XML_Char *context,
    970      1.1  wiz                        const XML_Char *base, const XML_Char *systemId,
    971      1.1  wiz                        const XML_Char *publicId) {
    972      1.1  wiz   const char *text1 = "<!ELEMENT doc EMPTY>\n"
    973      1.1  wiz                       "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
    974      1.1  wiz                       "<!ENTITY % e2 '%e1;'>\n"
    975      1.1  wiz                       "%e1;\n";
    976      1.1  wiz   XML_Parser ext_parser;
    977      1.1  wiz 
    978      1.1  wiz   UNUSED_P(base);
    979      1.1  wiz   UNUSED_P(publicId);
    980      1.1  wiz   if (systemId == NULL)
    981      1.1  wiz     return XML_STATUS_OK;
    982      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
    983      1.1  wiz   if (ext_parser == NULL)
    984      1.1  wiz     fail("Could not create external entity parser");
    985      1.1  wiz   if (! xcstrcmp(systemId, XCS("004-1.ent"))) {
    986      1.1  wiz     if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE)
    987      1.1  wiz         == XML_STATUS_ERROR)
    988      1.1  wiz       xml_failure(ext_parser);
    989      1.1  wiz   } else if (! xcstrcmp(systemId, XCS("004-2.ent"))) {
    990  1.1.1.2  jdc     ExtFaults *fault = XML_GetUserData(parser);
    991      1.1  wiz     enum XML_Status status;
    992      1.1  wiz     enum XML_Error error;
    993      1.1  wiz 
    994      1.1  wiz     status = _XML_Parse_SINGLE_BYTES(ext_parser, fault->parse_text,
    995      1.1  wiz                                      (int)strlen(fault->parse_text), XML_TRUE);
    996      1.1  wiz     if (fault->error == XML_ERROR_NONE) {
    997      1.1  wiz       if (status == XML_STATUS_ERROR)
    998      1.1  wiz         xml_failure(ext_parser);
    999      1.1  wiz     } else {
   1000      1.1  wiz       if (status != XML_STATUS_ERROR)
   1001      1.1  wiz         fail(fault->fail_text);
   1002      1.1  wiz       error = XML_GetErrorCode(ext_parser);
   1003      1.1  wiz       if (error != fault->error
   1004      1.1  wiz           && (fault->error != XML_ERROR_XML_DECL
   1005      1.1  wiz               || error != XML_ERROR_TEXT_DECL))
   1006      1.1  wiz         xml_failure(ext_parser);
   1007      1.1  wiz     }
   1008      1.1  wiz   }
   1009      1.1  wiz 
   1010      1.1  wiz   XML_ParserFree(ext_parser);
   1011      1.1  wiz   return XML_STATUS_OK;
   1012      1.1  wiz }
   1013      1.1  wiz 
   1014      1.1  wiz int XMLCALL
   1015      1.1  wiz external_entity_not_standalone(XML_Parser parser, const XML_Char *context,
   1016      1.1  wiz                                const XML_Char *base, const XML_Char *systemId,
   1017      1.1  wiz                                const XML_Char *publicId) {
   1018      1.1  wiz   const char *text1 = "<!ELEMENT doc EMPTY>\n"
   1019      1.1  wiz                       "<!ENTITY % e1 SYSTEM 'bar'>\n"
   1020      1.1  wiz                       "%e1;\n";
   1021      1.1  wiz   const char *text2 = "<!ATTLIST doc a1 CDATA 'value'>";
   1022      1.1  wiz   XML_Parser ext_parser;
   1023      1.1  wiz 
   1024      1.1  wiz   UNUSED_P(base);
   1025      1.1  wiz   UNUSED_P(publicId);
   1026      1.1  wiz   if (systemId == NULL)
   1027      1.1  wiz     return XML_STATUS_OK;
   1028      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1029      1.1  wiz   if (ext_parser == NULL)
   1030      1.1  wiz     fail("Could not create external entity parser");
   1031      1.1  wiz   if (! xcstrcmp(systemId, XCS("foo"))) {
   1032      1.1  wiz     XML_SetNotStandaloneHandler(ext_parser, reject_not_standalone_handler);
   1033      1.1  wiz     if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE)
   1034      1.1  wiz         != XML_STATUS_ERROR)
   1035      1.1  wiz       fail("Expected not standalone rejection");
   1036      1.1  wiz     if (XML_GetErrorCode(ext_parser) != XML_ERROR_NOT_STANDALONE)
   1037      1.1  wiz       xml_failure(ext_parser);
   1038      1.1  wiz     XML_SetNotStandaloneHandler(ext_parser, NULL);
   1039      1.1  wiz     XML_ParserFree(ext_parser);
   1040      1.1  wiz     return XML_STATUS_ERROR;
   1041      1.1  wiz   } else if (! xcstrcmp(systemId, XCS("bar"))) {
   1042      1.1  wiz     if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE)
   1043      1.1  wiz         == XML_STATUS_ERROR)
   1044      1.1  wiz       xml_failure(ext_parser);
   1045      1.1  wiz   }
   1046      1.1  wiz 
   1047      1.1  wiz   XML_ParserFree(ext_parser);
   1048      1.1  wiz   return XML_STATUS_OK;
   1049      1.1  wiz }
   1050      1.1  wiz 
   1051      1.1  wiz int XMLCALL
   1052      1.1  wiz external_entity_value_aborter(XML_Parser parser, const XML_Char *context,
   1053      1.1  wiz                               const XML_Char *base, const XML_Char *systemId,
   1054      1.1  wiz                               const XML_Char *publicId) {
   1055      1.1  wiz   const char *text1 = "<!ELEMENT doc EMPTY>\n"
   1056      1.1  wiz                       "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
   1057      1.1  wiz                       "<!ENTITY % e2 '%e1;'>\n"
   1058      1.1  wiz                       "%e1;\n";
   1059      1.1  wiz   const char *text2 = "<?xml version='1.0' encoding='utf-8'?>";
   1060      1.1  wiz   XML_Parser ext_parser;
   1061      1.1  wiz 
   1062      1.1  wiz   UNUSED_P(base);
   1063      1.1  wiz   UNUSED_P(publicId);
   1064      1.1  wiz   if (systemId == NULL)
   1065      1.1  wiz     return XML_STATUS_OK;
   1066      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1067      1.1  wiz   if (ext_parser == NULL)
   1068      1.1  wiz     fail("Could not create external entity parser");
   1069      1.1  wiz   if (! xcstrcmp(systemId, XCS("004-1.ent"))) {
   1070      1.1  wiz     if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, (int)strlen(text1), XML_TRUE)
   1071      1.1  wiz         == XML_STATUS_ERROR)
   1072      1.1  wiz       xml_failure(ext_parser);
   1073      1.1  wiz   }
   1074      1.1  wiz   if (! xcstrcmp(systemId, XCS("004-2.ent"))) {
   1075      1.1  wiz     XML_SetXmlDeclHandler(ext_parser, entity_suspending_xdecl_handler);
   1076      1.1  wiz     XML_SetUserData(ext_parser, ext_parser);
   1077      1.1  wiz     if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, (int)strlen(text2), XML_TRUE)
   1078      1.1  wiz         != XML_STATUS_ERROR)
   1079      1.1  wiz       fail("Aborted parse not faulted");
   1080      1.1  wiz     if (XML_GetErrorCode(ext_parser) != XML_ERROR_ABORTED)
   1081      1.1  wiz       xml_failure(ext_parser);
   1082      1.1  wiz   }
   1083      1.1  wiz 
   1084      1.1  wiz   XML_ParserFree(ext_parser);
   1085      1.1  wiz   return XML_STATUS_OK;
   1086      1.1  wiz }
   1087      1.1  wiz 
   1088      1.1  wiz int XMLCALL
   1089      1.1  wiz external_entity_public(XML_Parser parser, const XML_Char *context,
   1090      1.1  wiz                        const XML_Char *base, const XML_Char *systemId,
   1091      1.1  wiz                        const XML_Char *publicId) {
   1092  1.1.1.2  jdc   const char *text1 = XML_GetUserData(parser);
   1093      1.1  wiz   const char *text2 = "<!ATTLIST doc a CDATA 'value'>";
   1094      1.1  wiz   const char *text = NULL;
   1095      1.1  wiz   XML_Parser ext_parser;
   1096      1.1  wiz   int parse_res;
   1097      1.1  wiz 
   1098      1.1  wiz   UNUSED_P(base);
   1099      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1100      1.1  wiz   if (ext_parser == NULL)
   1101      1.1  wiz     return XML_STATUS_ERROR;
   1102      1.1  wiz   if (systemId != NULL && ! xcstrcmp(systemId, XCS("http://example.org/"))) {
   1103      1.1  wiz     text = text1;
   1104      1.1  wiz   } else if (publicId != NULL && ! xcstrcmp(publicId, XCS("foo"))) {
   1105      1.1  wiz     text = text2;
   1106      1.1  wiz   } else
   1107      1.1  wiz     fail("Unexpected parameters to external entity parser");
   1108      1.1  wiz   assert(text != NULL);
   1109      1.1  wiz   parse_res
   1110      1.1  wiz       = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE);
   1111      1.1  wiz   XML_ParserFree(ext_parser);
   1112      1.1  wiz   return parse_res;
   1113      1.1  wiz }
   1114      1.1  wiz 
   1115      1.1  wiz int XMLCALL
   1116      1.1  wiz external_entity_devaluer(XML_Parser parser, const XML_Char *context,
   1117      1.1  wiz                          const XML_Char *base, const XML_Char *systemId,
   1118      1.1  wiz                          const XML_Char *publicId) {
   1119      1.1  wiz   const char *text = "<!ELEMENT doc EMPTY>\n"
   1120      1.1  wiz                      "<!ENTITY % e1 SYSTEM 'bar'>\n"
   1121      1.1  wiz                      "%e1;\n";
   1122      1.1  wiz   XML_Parser ext_parser;
   1123      1.1  wiz   int clear_handler_flag = (XML_GetUserData(parser) != NULL);
   1124      1.1  wiz 
   1125      1.1  wiz   UNUSED_P(base);
   1126      1.1  wiz   UNUSED_P(publicId);
   1127      1.1  wiz   if (systemId == NULL || ! xcstrcmp(systemId, XCS("bar")))
   1128      1.1  wiz     return XML_STATUS_OK;
   1129  1.1.1.2  jdc   if (xcstrcmp(systemId, XCS("foo")) != 0)
   1130      1.1  wiz     fail("Unexpected system ID");
   1131      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1132      1.1  wiz   if (ext_parser == NULL)
   1133      1.1  wiz     fail("Could note create external entity parser");
   1134      1.1  wiz   if (clear_handler_flag)
   1135      1.1  wiz     XML_SetExternalEntityRefHandler(ext_parser, NULL);
   1136      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
   1137      1.1  wiz       == XML_STATUS_ERROR)
   1138      1.1  wiz     xml_failure(ext_parser);
   1139      1.1  wiz 
   1140      1.1  wiz   XML_ParserFree(ext_parser);
   1141      1.1  wiz   return XML_STATUS_OK;
   1142      1.1  wiz }
   1143      1.1  wiz 
   1144      1.1  wiz int XMLCALL
   1145      1.1  wiz external_entity_oneshot_loader(XML_Parser parser, const XML_Char *context,
   1146      1.1  wiz                                const XML_Char *base, const XML_Char *systemId,
   1147      1.1  wiz                                const XML_Char *publicId) {
   1148  1.1.1.2  jdc   ExtHdlrData *test_data = XML_GetUserData(parser);
   1149      1.1  wiz   XML_Parser ext_parser;
   1150      1.1  wiz 
   1151      1.1  wiz   UNUSED_P(base);
   1152      1.1  wiz   UNUSED_P(systemId);
   1153      1.1  wiz   UNUSED_P(publicId);
   1154      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1155      1.1  wiz   if (ext_parser == NULL)
   1156      1.1  wiz     fail("Could not create external entity parser.");
   1157      1.1  wiz   /* Use the requested entity parser for further externals */
   1158      1.1  wiz   XML_SetExternalEntityRefHandler(ext_parser, test_data->handler);
   1159      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, test_data->parse_text,
   1160      1.1  wiz                               (int)strlen(test_data->parse_text), XML_TRUE)
   1161      1.1  wiz       == XML_STATUS_ERROR) {
   1162      1.1  wiz     xml_failure(ext_parser);
   1163      1.1  wiz   }
   1164      1.1  wiz 
   1165      1.1  wiz   XML_ParserFree(ext_parser);
   1166      1.1  wiz   return XML_STATUS_OK;
   1167      1.1  wiz }
   1168      1.1  wiz 
   1169      1.1  wiz int XMLCALL
   1170      1.1  wiz external_entity_loader2(XML_Parser parser, const XML_Char *context,
   1171      1.1  wiz                         const XML_Char *base, const XML_Char *systemId,
   1172      1.1  wiz                         const XML_Char *publicId) {
   1173  1.1.1.2  jdc   ExtTest2 *test_data = XML_GetUserData(parser);
   1174      1.1  wiz   XML_Parser extparser;
   1175      1.1  wiz 
   1176      1.1  wiz   UNUSED_P(base);
   1177      1.1  wiz   UNUSED_P(systemId);
   1178      1.1  wiz   UNUSED_P(publicId);
   1179      1.1  wiz   extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1180      1.1  wiz   if (extparser == NULL)
   1181      1.1  wiz     fail("Coulr not create external entity parser");
   1182      1.1  wiz   if (test_data->encoding != NULL) {
   1183      1.1  wiz     if (! XML_SetEncoding(extparser, test_data->encoding))
   1184      1.1  wiz       fail("XML_SetEncoding() ignored for external entity");
   1185      1.1  wiz   }
   1186      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(extparser, test_data->parse_text,
   1187      1.1  wiz                               test_data->parse_len, XML_TRUE)
   1188      1.1  wiz       == XML_STATUS_ERROR) {
   1189      1.1  wiz     xml_failure(extparser);
   1190      1.1  wiz   }
   1191      1.1  wiz 
   1192      1.1  wiz   XML_ParserFree(extparser);
   1193      1.1  wiz   return XML_STATUS_OK;
   1194      1.1  wiz }
   1195      1.1  wiz 
   1196      1.1  wiz int XMLCALL
   1197      1.1  wiz external_entity_faulter2(XML_Parser parser, const XML_Char *context,
   1198      1.1  wiz                          const XML_Char *base, const XML_Char *systemId,
   1199      1.1  wiz                          const XML_Char *publicId) {
   1200  1.1.1.2  jdc   ExtFaults2 *test_data = XML_GetUserData(parser);
   1201      1.1  wiz   XML_Parser extparser;
   1202      1.1  wiz 
   1203      1.1  wiz   UNUSED_P(base);
   1204      1.1  wiz   UNUSED_P(systemId);
   1205      1.1  wiz   UNUSED_P(publicId);
   1206      1.1  wiz   extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1207      1.1  wiz   if (extparser == NULL)
   1208      1.1  wiz     fail("Could not create external entity parser");
   1209      1.1  wiz   if (test_data->encoding != NULL) {
   1210      1.1  wiz     if (! XML_SetEncoding(extparser, test_data->encoding))
   1211      1.1  wiz       fail("XML_SetEncoding() ignored for external entity");
   1212      1.1  wiz   }
   1213      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(extparser, test_data->parse_text,
   1214      1.1  wiz                               test_data->parse_len, XML_TRUE)
   1215      1.1  wiz       != XML_STATUS_ERROR)
   1216      1.1  wiz     fail(test_data->fail_text);
   1217      1.1  wiz   if (XML_GetErrorCode(extparser) != test_data->error)
   1218      1.1  wiz     xml_failure(extparser);
   1219      1.1  wiz 
   1220      1.1  wiz   XML_ParserFree(extparser);
   1221      1.1  wiz   return XML_STATUS_ERROR;
   1222      1.1  wiz }
   1223      1.1  wiz 
   1224      1.1  wiz int XMLCALL
   1225      1.1  wiz external_entity_unfinished_attlist(XML_Parser parser, const XML_Char *context,
   1226      1.1  wiz                                    const XML_Char *base,
   1227      1.1  wiz                                    const XML_Char *systemId,
   1228      1.1  wiz                                    const XML_Char *publicId) {
   1229      1.1  wiz   const char *text = "<!ELEMENT barf ANY>\n"
   1230      1.1  wiz                      "<!ATTLIST barf my_attr (blah|%blah;a|foo) #REQUIRED>\n"
   1231      1.1  wiz                      "<!--COMMENT-->\n";
   1232      1.1  wiz   XML_Parser ext_parser;
   1233      1.1  wiz 
   1234      1.1  wiz   UNUSED_P(base);
   1235      1.1  wiz   UNUSED_P(publicId);
   1236      1.1  wiz   if (systemId == NULL)
   1237      1.1  wiz     return XML_STATUS_OK;
   1238      1.1  wiz 
   1239      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1240      1.1  wiz   if (ext_parser == NULL)
   1241      1.1  wiz     fail("Could not create external entity parser");
   1242      1.1  wiz 
   1243      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
   1244      1.1  wiz       == XML_STATUS_ERROR)
   1245      1.1  wiz     xml_failure(ext_parser);
   1246      1.1  wiz 
   1247      1.1  wiz   XML_ParserFree(ext_parser);
   1248      1.1  wiz   return XML_STATUS_OK;
   1249      1.1  wiz }
   1250      1.1  wiz 
   1251      1.1  wiz int XMLCALL
   1252      1.1  wiz external_entity_handler(XML_Parser parser, const XML_Char *context,
   1253      1.1  wiz                         const XML_Char *base, const XML_Char *systemId,
   1254      1.1  wiz                         const XML_Char *publicId) {
   1255      1.1  wiz   void *user_data = XML_GetUserData(parser);
   1256      1.1  wiz   const char *text;
   1257      1.1  wiz   XML_Parser p2;
   1258      1.1  wiz 
   1259      1.1  wiz   UNUSED_P(base);
   1260      1.1  wiz   UNUSED_P(systemId);
   1261      1.1  wiz   UNUSED_P(publicId);
   1262      1.1  wiz   if (user_data == NULL)
   1263      1.1  wiz     text = ("<!ELEMENT doc (e+)>\n"
   1264      1.1  wiz             "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
   1265      1.1  wiz             "<!ELEMENT e EMPTY>\n");
   1266      1.1  wiz   else
   1267      1.1  wiz     text = ("<?xml version='1.0' encoding='us-ascii'?>"
   1268      1.1  wiz             "<e/>");
   1269      1.1  wiz 
   1270      1.1  wiz   /* Set user data to any non-NULL value */
   1271      1.1  wiz   XML_SetUserData(parser, parser);
   1272      1.1  wiz   p2 = XML_ExternalEntityParserCreate(parser, context, NULL);
   1273      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(p2, text, (int)strlen(text), XML_TRUE)
   1274      1.1  wiz       == XML_STATUS_ERROR) {
   1275      1.1  wiz     xml_failure(p2);
   1276      1.1  wiz     return XML_STATUS_ERROR;
   1277      1.1  wiz   }
   1278      1.1  wiz   XML_ParserFree(p2);
   1279      1.1  wiz   return XML_STATUS_OK;
   1280      1.1  wiz }
   1281      1.1  wiz 
   1282      1.1  wiz int XMLCALL
   1283      1.1  wiz external_entity_duff_loader(XML_Parser parser, const XML_Char *context,
   1284      1.1  wiz                             const XML_Char *base, const XML_Char *systemId,
   1285      1.1  wiz                             const XML_Char *publicId) {
   1286      1.1  wiz   XML_Parser new_parser;
   1287      1.1  wiz   unsigned int i;
   1288      1.1  wiz   const unsigned int max_alloc_count = 10;
   1289      1.1  wiz 
   1290      1.1  wiz   UNUSED_P(base);
   1291      1.1  wiz   UNUSED_P(systemId);
   1292      1.1  wiz   UNUSED_P(publicId);
   1293      1.1  wiz   /* Try a few different allocation levels */
   1294      1.1  wiz   for (i = 0; i < max_alloc_count; i++) {
   1295  1.1.1.2  jdc     g_allocation_count = (int)i;
   1296      1.1  wiz     new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1297      1.1  wiz     if (new_parser != NULL) {
   1298      1.1  wiz       XML_ParserFree(new_parser);
   1299      1.1  wiz       break;
   1300      1.1  wiz     }
   1301      1.1  wiz   }
   1302      1.1  wiz   if (i == 0)
   1303      1.1  wiz     fail("External parser creation ignored failing allocator");
   1304      1.1  wiz   else if (i == max_alloc_count)
   1305      1.1  wiz     fail("Extern parser not created with max allocation count");
   1306      1.1  wiz 
   1307      1.1  wiz   /* Make sure other random allocation doesn't now fail */
   1308      1.1  wiz   g_allocation_count = ALLOC_ALWAYS_SUCCEED;
   1309      1.1  wiz 
   1310      1.1  wiz   /* Make sure the failure code path is executed too */
   1311      1.1  wiz   return XML_STATUS_ERROR;
   1312      1.1  wiz }
   1313      1.1  wiz 
   1314      1.1  wiz int XMLCALL
   1315      1.1  wiz external_entity_dbl_handler(XML_Parser parser, const XML_Char *context,
   1316      1.1  wiz                             const XML_Char *base, const XML_Char *systemId,
   1317      1.1  wiz                             const XML_Char *publicId) {
   1318  1.1.1.2  jdc   int *pcallno = XML_GetUserData(parser);
   1319      1.1  wiz   int callno = *pcallno;
   1320      1.1  wiz   const char *text;
   1321      1.1  wiz   XML_Parser new_parser = NULL;
   1322      1.1  wiz   int i;
   1323      1.1  wiz   const int max_alloc_count = 20;
   1324      1.1  wiz 
   1325      1.1  wiz   UNUSED_P(base);
   1326      1.1  wiz   UNUSED_P(systemId);
   1327      1.1  wiz   UNUSED_P(publicId);
   1328      1.1  wiz   if (callno == 0) {
   1329      1.1  wiz     /* First time through, check how many calls to malloc occur */
   1330      1.1  wiz     text = ("<!ELEMENT doc (e+)>\n"
   1331      1.1  wiz             "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
   1332      1.1  wiz             "<!ELEMENT e EMPTY>\n");
   1333      1.1  wiz     g_allocation_count = 10000;
   1334      1.1  wiz     new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1335      1.1  wiz     if (new_parser == NULL) {
   1336      1.1  wiz       fail("Unable to allocate first external parser");
   1337      1.1  wiz       return XML_STATUS_ERROR;
   1338      1.1  wiz     }
   1339      1.1  wiz     /* Stash the number of calls in the user data */
   1340      1.1  wiz     *pcallno = 10000 - g_allocation_count;
   1341      1.1  wiz   } else {
   1342      1.1  wiz     text = ("<?xml version='1.0' encoding='us-ascii'?>"
   1343      1.1  wiz             "<e/>");
   1344      1.1  wiz     /* Try at varying levels to exercise more code paths */
   1345      1.1  wiz     for (i = 0; i < max_alloc_count; i++) {
   1346      1.1  wiz       g_allocation_count = callno + i;
   1347      1.1  wiz       new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1348      1.1  wiz       if (new_parser != NULL)
   1349      1.1  wiz         break;
   1350      1.1  wiz     }
   1351      1.1  wiz     if (i == 0) {
   1352      1.1  wiz       fail("Second external parser unexpectedly created");
   1353      1.1  wiz       XML_ParserFree(new_parser);
   1354      1.1  wiz       return XML_STATUS_ERROR;
   1355      1.1  wiz     } else if (i == max_alloc_count) {
   1356      1.1  wiz       fail("Second external parser not created");
   1357      1.1  wiz       return XML_STATUS_ERROR;
   1358      1.1  wiz     }
   1359      1.1  wiz   }
   1360      1.1  wiz 
   1361      1.1  wiz   g_allocation_count = ALLOC_ALWAYS_SUCCEED;
   1362      1.1  wiz   if (_XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE)
   1363      1.1  wiz       == XML_STATUS_ERROR) {
   1364      1.1  wiz     xml_failure(new_parser);
   1365      1.1  wiz     return XML_STATUS_ERROR;
   1366      1.1  wiz   }
   1367      1.1  wiz   XML_ParserFree(new_parser);
   1368      1.1  wiz   return XML_STATUS_OK;
   1369      1.1  wiz }
   1370      1.1  wiz 
   1371      1.1  wiz int XMLCALL
   1372      1.1  wiz external_entity_dbl_handler_2(XML_Parser parser, const XML_Char *context,
   1373      1.1  wiz                               const XML_Char *base, const XML_Char *systemId,
   1374      1.1  wiz                               const XML_Char *publicId) {
   1375  1.1.1.2  jdc   int *pcallno = XML_GetUserData(parser);
   1376      1.1  wiz   int callno = *pcallno;
   1377      1.1  wiz   const char *text;
   1378      1.1  wiz   XML_Parser new_parser;
   1379      1.1  wiz   enum XML_Status rv;
   1380      1.1  wiz 
   1381      1.1  wiz   UNUSED_P(base);
   1382      1.1  wiz   UNUSED_P(systemId);
   1383      1.1  wiz   UNUSED_P(publicId);
   1384      1.1  wiz   if (callno == 0) {
   1385      1.1  wiz     /* Try different allocation levels for whole exercise */
   1386      1.1  wiz     text = ("<!ELEMENT doc (e+)>\n"
   1387      1.1  wiz             "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
   1388      1.1  wiz             "<!ELEMENT e EMPTY>\n");
   1389      1.1  wiz     *pcallno = 1;
   1390      1.1  wiz     new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1391      1.1  wiz     if (new_parser == NULL)
   1392      1.1  wiz       return XML_STATUS_ERROR;
   1393      1.1  wiz     rv = _XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE);
   1394      1.1  wiz   } else {
   1395      1.1  wiz     /* Just run through once */
   1396      1.1  wiz     text = ("<?xml version='1.0' encoding='us-ascii'?>"
   1397      1.1  wiz             "<e/>");
   1398      1.1  wiz     new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1399      1.1  wiz     if (new_parser == NULL)
   1400      1.1  wiz       return XML_STATUS_ERROR;
   1401      1.1  wiz     rv = _XML_Parse_SINGLE_BYTES(new_parser, text, (int)strlen(text), XML_TRUE);
   1402      1.1  wiz   }
   1403      1.1  wiz   XML_ParserFree(new_parser);
   1404      1.1  wiz   if (rv == XML_STATUS_ERROR)
   1405      1.1  wiz     return XML_STATUS_ERROR;
   1406      1.1  wiz   return XML_STATUS_OK;
   1407      1.1  wiz }
   1408      1.1  wiz 
   1409      1.1  wiz int XMLCALL
   1410      1.1  wiz external_entity_alloc_set_encoding(XML_Parser parser, const XML_Char *context,
   1411      1.1  wiz                                    const XML_Char *base,
   1412      1.1  wiz                                    const XML_Char *systemId,
   1413      1.1  wiz                                    const XML_Char *publicId) {
   1414      1.1  wiz   /* As for external_entity_loader() */
   1415      1.1  wiz   const char *text = "<?xml encoding='iso-8859-3'?>"
   1416      1.1  wiz                      "\xC3\xA9";
   1417      1.1  wiz   XML_Parser ext_parser;
   1418      1.1  wiz   enum XML_Status status;
   1419      1.1  wiz 
   1420      1.1  wiz   UNUSED_P(base);
   1421      1.1  wiz   UNUSED_P(systemId);
   1422      1.1  wiz   UNUSED_P(publicId);
   1423      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1424      1.1  wiz   if (ext_parser == NULL)
   1425      1.1  wiz     return XML_STATUS_ERROR;
   1426      1.1  wiz   if (! XML_SetEncoding(ext_parser, XCS("utf-8"))) {
   1427      1.1  wiz     XML_ParserFree(ext_parser);
   1428      1.1  wiz     return XML_STATUS_ERROR;
   1429      1.1  wiz   }
   1430      1.1  wiz   status
   1431      1.1  wiz       = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE);
   1432      1.1  wiz   XML_ParserFree(ext_parser);
   1433      1.1  wiz   if (status == XML_STATUS_ERROR)
   1434      1.1  wiz     return XML_STATUS_ERROR;
   1435      1.1  wiz   return XML_STATUS_OK;
   1436      1.1  wiz }
   1437      1.1  wiz 
   1438      1.1  wiz int XMLCALL
   1439      1.1  wiz external_entity_reallocator(XML_Parser parser, const XML_Char *context,
   1440      1.1  wiz                             const XML_Char *base, const XML_Char *systemId,
   1441      1.1  wiz                             const XML_Char *publicId) {
   1442      1.1  wiz   const char *text = get_buffer_test_text;
   1443      1.1  wiz   XML_Parser ext_parser;
   1444      1.1  wiz   void *buffer;
   1445      1.1  wiz   enum XML_Status status;
   1446      1.1  wiz 
   1447      1.1  wiz   UNUSED_P(base);
   1448      1.1  wiz   UNUSED_P(systemId);
   1449      1.1  wiz   UNUSED_P(publicId);
   1450      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1451      1.1  wiz   if (ext_parser == NULL)
   1452      1.1  wiz     fail("Could not create external entity parser");
   1453      1.1  wiz 
   1454      1.1  wiz   g_reallocation_count = *(int *)XML_GetUserData(parser);
   1455      1.1  wiz   buffer = XML_GetBuffer(ext_parser, 1536);
   1456      1.1  wiz   if (buffer == NULL)
   1457      1.1  wiz     fail("Buffer allocation failed");
   1458      1.1  wiz   assert(buffer != NULL);
   1459      1.1  wiz   memcpy(buffer, text, strlen(text));
   1460      1.1  wiz   status = XML_ParseBuffer(ext_parser, (int)strlen(text), XML_FALSE);
   1461      1.1  wiz   g_reallocation_count = -1;
   1462      1.1  wiz   XML_ParserFree(ext_parser);
   1463      1.1  wiz   return (status == XML_STATUS_OK) ? XML_STATUS_OK : XML_STATUS_ERROR;
   1464      1.1  wiz }
   1465      1.1  wiz 
   1466      1.1  wiz int XMLCALL
   1467      1.1  wiz external_entity_alloc(XML_Parser parser, const XML_Char *context,
   1468      1.1  wiz                       const XML_Char *base, const XML_Char *systemId,
   1469      1.1  wiz                       const XML_Char *publicId) {
   1470  1.1.1.2  jdc   const char *text = XML_GetUserData(parser);
   1471      1.1  wiz   XML_Parser ext_parser;
   1472      1.1  wiz   int parse_res;
   1473      1.1  wiz 
   1474      1.1  wiz   UNUSED_P(base);
   1475      1.1  wiz   UNUSED_P(systemId);
   1476      1.1  wiz   UNUSED_P(publicId);
   1477      1.1  wiz   ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
   1478      1.1  wiz   if (ext_parser == NULL)
   1479      1.1  wiz     return XML_STATUS_ERROR;
   1480      1.1  wiz   parse_res
   1481      1.1  wiz       = _XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE);
   1482      1.1  wiz   XML_ParserFree(ext_parser);
   1483      1.1  wiz   return parse_res;
   1484      1.1  wiz }
   1485      1.1  wiz 
   1486      1.1  wiz int XMLCALL
   1487      1.1  wiz external_entity_parser_create_alloc_fail_handler(XML_Parser parser,
   1488      1.1  wiz                                                  const XML_Char *context,
   1489      1.1  wiz                                                  const XML_Char *base,
   1490      1.1  wiz                                                  const XML_Char *systemId,
   1491      1.1  wiz                                                  const XML_Char *publicId) {
   1492      1.1  wiz   UNUSED_P(base);
   1493      1.1  wiz   UNUSED_P(systemId);
   1494      1.1  wiz   UNUSED_P(publicId);
   1495      1.1  wiz 
   1496      1.1  wiz   if (context != NULL)
   1497      1.1  wiz     fail("Unexpected non-NULL context");
   1498      1.1  wiz 
   1499      1.1  wiz   // The following number intends to fail the upcoming allocation in line
   1500      1.1  wiz   // "parser->m_protocolEncodingName = copyString(encodingName,
   1501      1.1  wiz   // &(parser->m_mem));" in function parserInit.
   1502      1.1  wiz   g_allocation_count = 3;
   1503      1.1  wiz 
   1504      1.1  wiz   const XML_Char *const encodingName = XCS("UTF-8"); // needs something non-NULL
   1505      1.1  wiz   const XML_Parser ext_parser
   1506      1.1  wiz       = XML_ExternalEntityParserCreate(parser, context, encodingName);
   1507      1.1  wiz   if (ext_parser != NULL)
   1508      1.1  wiz     fail(
   1509      1.1  wiz         "Call to XML_ExternalEntityParserCreate was expected to fail out-of-memory");
   1510      1.1  wiz 
   1511      1.1  wiz   g_allocation_count = ALLOC_ALWAYS_SUCCEED;
   1512      1.1  wiz   return XML_STATUS_ERROR;
   1513      1.1  wiz }
   1514      1.1  wiz 
   1515      1.1  wiz #if XML_GE == 1
   1516      1.1  wiz int
   1517      1.1  wiz accounting_external_entity_ref_handler(XML_Parser parser,
   1518      1.1  wiz                                        const XML_Char *context,
   1519      1.1  wiz                                        const XML_Char *base,
   1520      1.1  wiz                                        const XML_Char *systemId,
   1521      1.1  wiz                                        const XML_Char *publicId) {
   1522      1.1  wiz   UNUSED_P(base);
   1523      1.1  wiz   UNUSED_P(publicId);
   1524      1.1  wiz 
   1525  1.1.1.2  jdc   const struct AccountingTestCase *const testCase = XML_GetUserData(parser);
   1526      1.1  wiz 
   1527      1.1  wiz   const char *externalText = NULL;
   1528      1.1  wiz   if (xcstrcmp(systemId, XCS("first.ent")) == 0) {
   1529      1.1  wiz     externalText = testCase->firstExternalText;
   1530      1.1  wiz   } else if (xcstrcmp(systemId, XCS("second.ent")) == 0) {
   1531      1.1  wiz     externalText = testCase->secondExternalText;
   1532      1.1  wiz   } else {
   1533      1.1  wiz     assert(! "systemId is neither \"first.ent\" nor \"second.ent\"");
   1534      1.1  wiz   }
   1535      1.1  wiz   assert(externalText);
   1536      1.1  wiz 
   1537      1.1  wiz   XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
   1538      1.1  wiz   assert(entParser);
   1539      1.1  wiz 
   1540      1.1  wiz   const enum XML_Status status = _XML_Parse_SINGLE_BYTES(
   1541      1.1  wiz       entParser, externalText, (int)strlen(externalText), XML_TRUE);
   1542      1.1  wiz 
   1543      1.1  wiz   XML_ParserFree(entParser);
   1544      1.1  wiz   return status;
   1545      1.1  wiz }
   1546      1.1  wiz #endif /* XML_GE == 1 */
   1547      1.1  wiz 
   1548      1.1  wiz /* NotStandalone handlers */
   1549      1.1  wiz 
   1550      1.1  wiz int XMLCALL
   1551      1.1  wiz reject_not_standalone_handler(void *userData) {
   1552      1.1  wiz   UNUSED_P(userData);
   1553      1.1  wiz   return XML_STATUS_ERROR;
   1554      1.1  wiz }
   1555      1.1  wiz 
   1556      1.1  wiz int XMLCALL
   1557      1.1  wiz accept_not_standalone_handler(void *userData) {
   1558      1.1  wiz   UNUSED_P(userData);
   1559      1.1  wiz   return XML_STATUS_OK;
   1560      1.1  wiz }
   1561      1.1  wiz 
   1562      1.1  wiz /* Attribute List handlers */
   1563      1.1  wiz void XMLCALL
   1564      1.1  wiz verify_attlist_decl_handler(void *userData, const XML_Char *element_name,
   1565      1.1  wiz                             const XML_Char *attr_name,
   1566      1.1  wiz                             const XML_Char *attr_type,
   1567      1.1  wiz                             const XML_Char *default_value, int is_required) {
   1568      1.1  wiz   AttTest *at = (AttTest *)userData;
   1569      1.1  wiz 
   1570  1.1.1.2  jdc   if (xcstrcmp(element_name, at->element_name) != 0)
   1571      1.1  wiz     fail("Unexpected element name in attribute declaration");
   1572  1.1.1.2  jdc   if (xcstrcmp(attr_name, at->attr_name) != 0)
   1573      1.1  wiz     fail("Unexpected attribute name in attribute declaration");
   1574  1.1.1.2  jdc   if (xcstrcmp(attr_type, at->attr_type) != 0)
   1575      1.1  wiz     fail("Unexpected attribute type in attribute declaration");
   1576      1.1  wiz   if ((default_value == NULL && at->default_value != NULL)
   1577      1.1  wiz       || (default_value != NULL && at->default_value == NULL)
   1578  1.1.1.2  jdc       || (default_value != NULL
   1579  1.1.1.2  jdc           && xcstrcmp(default_value, at->default_value) != 0))
   1580      1.1  wiz     fail("Unexpected default value in attribute declaration");
   1581      1.1  wiz   if (is_required != at->is_required)
   1582      1.1  wiz     fail("Requirement mismatch in attribute declaration");
   1583      1.1  wiz }
   1584      1.1  wiz 
   1585      1.1  wiz /* Character Data handlers */
   1586      1.1  wiz 
   1587      1.1  wiz void XMLCALL
   1588      1.1  wiz clearing_aborting_character_handler(void *userData, const XML_Char *s,
   1589      1.1  wiz                                     int len) {
   1590      1.1  wiz   UNUSED_P(userData);
   1591      1.1  wiz   UNUSED_P(s);
   1592      1.1  wiz   UNUSED_P(len);
   1593      1.1  wiz   XML_StopParser(g_parser, g_resumable);
   1594      1.1  wiz   XML_SetCharacterDataHandler(g_parser, NULL);
   1595      1.1  wiz }
   1596      1.1  wiz 
   1597      1.1  wiz void XMLCALL
   1598      1.1  wiz parser_stop_character_handler(void *userData, const XML_Char *s, int len) {
   1599      1.1  wiz   UNUSED_P(userData);
   1600      1.1  wiz   UNUSED_P(s);
   1601      1.1  wiz   UNUSED_P(len);
   1602      1.1  wiz   XML_ParsingStatus status;
   1603      1.1  wiz   XML_GetParsingStatus(g_parser, &status);
   1604      1.1  wiz   if (status.parsing == XML_FINISHED) {
   1605      1.1  wiz     return; // the parser was stopped by a previous call to this handler.
   1606      1.1  wiz   }
   1607      1.1  wiz   XML_StopParser(g_parser, g_resumable);
   1608      1.1  wiz   XML_SetCharacterDataHandler(g_parser, NULL);
   1609      1.1  wiz   if (! g_resumable) {
   1610      1.1  wiz     /* Check that aborting an aborted parser is faulted */
   1611      1.1  wiz     if (XML_StopParser(g_parser, XML_FALSE) != XML_STATUS_ERROR)
   1612      1.1  wiz       fail("Aborting aborted parser not faulted");
   1613      1.1  wiz     if (XML_GetErrorCode(g_parser) != XML_ERROR_FINISHED)
   1614      1.1  wiz       xml_failure(g_parser);
   1615      1.1  wiz   } else if (g_abortable) {
   1616      1.1  wiz     /* Check that aborting a suspended parser works */
   1617      1.1  wiz     if (XML_StopParser(g_parser, XML_FALSE) == XML_STATUS_ERROR)
   1618      1.1  wiz       xml_failure(g_parser);
   1619      1.1  wiz   } else {
   1620      1.1  wiz     /* Check that suspending a suspended parser works */
   1621      1.1  wiz     if (XML_StopParser(g_parser, XML_TRUE) != XML_STATUS_ERROR)
   1622      1.1  wiz       fail("Suspending suspended parser not faulted");
   1623      1.1  wiz     if (XML_GetErrorCode(g_parser) != XML_ERROR_SUSPENDED)
   1624      1.1  wiz       xml_failure(g_parser);
   1625      1.1  wiz   }
   1626      1.1  wiz }
   1627      1.1  wiz 
   1628      1.1  wiz void XMLCALL
   1629      1.1  wiz cr_cdata_handler(void *userData, const XML_Char *s, int len) {
   1630      1.1  wiz   int *pfound = (int *)userData;
   1631      1.1  wiz 
   1632      1.1  wiz   /* Internal processing turns the CR into a newline for the
   1633      1.1  wiz    * character data handler, but not for the default handler
   1634      1.1  wiz    */
   1635      1.1  wiz   if (len == 1 && (*s == XCS('\n') || *s == XCS('\r')))
   1636      1.1  wiz     *pfound = 1;
   1637      1.1  wiz }
   1638      1.1  wiz 
   1639      1.1  wiz void XMLCALL
   1640      1.1  wiz rsqb_handler(void *userData, const XML_Char *s, int len) {
   1641      1.1  wiz   int *pfound = (int *)userData;
   1642      1.1  wiz 
   1643      1.1  wiz   if (len == 1 && *s == XCS(']'))
   1644      1.1  wiz     *pfound = 1;
   1645      1.1  wiz }
   1646      1.1  wiz 
   1647      1.1  wiz void XMLCALL
   1648      1.1  wiz byte_character_handler(void *userData, const XML_Char *s, int len) {
   1649      1.1  wiz #if XML_CONTEXT_BYTES > 0
   1650      1.1  wiz   int offset, size;
   1651      1.1  wiz   const char *buffer;
   1652      1.1  wiz   ByteTestData *data = (ByteTestData *)userData;
   1653      1.1  wiz 
   1654      1.1  wiz   UNUSED_P(s);
   1655      1.1  wiz   buffer = XML_GetInputContext(g_parser, &offset, &size);
   1656      1.1  wiz   if (buffer == NULL)
   1657      1.1  wiz     fail("Failed to get context buffer");
   1658      1.1  wiz   if (offset != data->start_element_len)
   1659      1.1  wiz     fail("Context offset in unexpected position");
   1660      1.1  wiz   if (len != data->cdata_len)
   1661      1.1  wiz     fail("CDATA length reported incorrectly");
   1662      1.1  wiz   if (size != data->total_string_len)
   1663      1.1  wiz     fail("Context size is not full buffer");
   1664      1.1  wiz   if (XML_GetCurrentByteIndex(g_parser) != offset)
   1665      1.1  wiz     fail("Character byte index incorrect");
   1666      1.1  wiz   if (XML_GetCurrentByteCount(g_parser) != len)
   1667      1.1  wiz     fail("Character byte count incorrect");
   1668      1.1  wiz #else
   1669      1.1  wiz   UNUSED_P(s);
   1670      1.1  wiz   UNUSED_P(userData);
   1671      1.1  wiz   UNUSED_P(len);
   1672      1.1  wiz #endif
   1673      1.1  wiz }
   1674      1.1  wiz 
   1675      1.1  wiz void XMLCALL
   1676      1.1  wiz ext2_accumulate_characters(void *userData, const XML_Char *s, int len) {
   1677      1.1  wiz   ExtTest2 *test_data = (ExtTest2 *)userData;
   1678      1.1  wiz   accumulate_characters(test_data->storage, s, len);
   1679      1.1  wiz }
   1680      1.1  wiz 
   1681      1.1  wiz /* Handlers that record their function name and int arg. */
   1682      1.1  wiz 
   1683      1.1  wiz static void
   1684      1.1  wiz record_call(struct handler_record_list *const rec, const char *funcname,
   1685      1.1  wiz             const int arg) {
   1686      1.1  wiz   const int max_entries = sizeof(rec->entries) / sizeof(rec->entries[0]);
   1687      1.1  wiz   assert_true(rec->count < max_entries);
   1688      1.1  wiz   struct handler_record_entry *const e = &rec->entries[rec->count++];
   1689      1.1  wiz   e->name = funcname;
   1690      1.1  wiz   e->arg = arg;
   1691      1.1  wiz }
   1692      1.1  wiz 
   1693      1.1  wiz void XMLCALL
   1694      1.1  wiz record_default_handler(void *userData, const XML_Char *s, int len) {
   1695      1.1  wiz   UNUSED_P(s);
   1696      1.1  wiz   record_call((struct handler_record_list *)userData, __func__, len);
   1697      1.1  wiz }
   1698      1.1  wiz 
   1699      1.1  wiz void XMLCALL
   1700      1.1  wiz record_cdata_handler(void *userData, const XML_Char *s, int len) {
   1701      1.1  wiz   UNUSED_P(s);
   1702      1.1  wiz   record_call((struct handler_record_list *)userData, __func__, len);
   1703      1.1  wiz   XML_DefaultCurrent(g_parser);
   1704      1.1  wiz }
   1705      1.1  wiz 
   1706      1.1  wiz void XMLCALL
   1707      1.1  wiz record_cdata_nodefault_handler(void *userData, const XML_Char *s, int len) {
   1708      1.1  wiz   UNUSED_P(s);
   1709      1.1  wiz   record_call((struct handler_record_list *)userData, __func__, len);
   1710      1.1  wiz }
   1711      1.1  wiz 
   1712      1.1  wiz void XMLCALL
   1713      1.1  wiz record_skip_handler(void *userData, const XML_Char *entityName,
   1714      1.1  wiz                     int is_parameter_entity) {
   1715      1.1  wiz   UNUSED_P(entityName);
   1716      1.1  wiz   record_call((struct handler_record_list *)userData, __func__,
   1717      1.1  wiz               is_parameter_entity);
   1718      1.1  wiz }
   1719      1.1  wiz 
   1720      1.1  wiz void XMLCALL
   1721      1.1  wiz record_element_start_handler(void *userData, const XML_Char *name,
   1722      1.1  wiz                              const XML_Char **atts) {
   1723      1.1  wiz   UNUSED_P(atts);
   1724      1.1  wiz   CharData_AppendXMLChars((CharData *)userData, name, (int)xcstrlen(name));
   1725      1.1  wiz }
   1726      1.1  wiz 
   1727      1.1  wiz void XMLCALL
   1728      1.1  wiz record_element_end_handler(void *userData, const XML_Char *name) {
   1729      1.1  wiz   CharData *storage = (CharData *)userData;
   1730      1.1  wiz 
   1731      1.1  wiz   CharData_AppendXMLChars(storage, XCS("/"), 1);
   1732      1.1  wiz   CharData_AppendXMLChars(storage, name, -1);
   1733      1.1  wiz }
   1734      1.1  wiz 
   1735      1.1  wiz const struct handler_record_entry *
   1736      1.1  wiz _handler_record_get(const struct handler_record_list *storage, int index,
   1737      1.1  wiz                     const char *file, int line) {
   1738      1.1  wiz   if (storage->count <= index) {
   1739      1.1  wiz     _fail(file, line, "too few handler calls");
   1740      1.1  wiz   }
   1741      1.1  wiz   return &storage->entries[index];
   1742      1.1  wiz }
   1743      1.1  wiz 
   1744      1.1  wiz /* Entity Declaration Handlers */
   1745      1.1  wiz static const XML_Char *entity_name_to_match = NULL;
   1746      1.1  wiz static const XML_Char *entity_value_to_match = NULL;
   1747      1.1  wiz static int entity_match_flag = ENTITY_MATCH_NOT_FOUND;
   1748      1.1  wiz 
   1749      1.1  wiz void XMLCALL
   1750      1.1  wiz param_entity_match_handler(void *userData, const XML_Char *entityName,
   1751      1.1  wiz                            int is_parameter_entity, const XML_Char *value,
   1752      1.1  wiz                            int value_length, const XML_Char *base,
   1753      1.1  wiz                            const XML_Char *systemId, const XML_Char *publicId,
   1754      1.1  wiz                            const XML_Char *notationName) {
   1755      1.1  wiz   UNUSED_P(userData);
   1756      1.1  wiz   UNUSED_P(base);
   1757      1.1  wiz   UNUSED_P(systemId);
   1758      1.1  wiz   UNUSED_P(publicId);
   1759      1.1  wiz   UNUSED_P(notationName);
   1760      1.1  wiz   if (! is_parameter_entity || entity_name_to_match == NULL
   1761      1.1  wiz       || entity_value_to_match == NULL) {
   1762      1.1  wiz     return;
   1763      1.1  wiz   }
   1764      1.1  wiz   if (! xcstrcmp(entityName, entity_name_to_match)) {
   1765      1.1  wiz     /* The cast here is safe because we control the horizontal and
   1766      1.1  wiz      * the vertical, and we therefore know our strings are never
   1767      1.1  wiz      * going to overflow an int.
   1768      1.1  wiz      */
   1769      1.1  wiz     if (value_length != (int)xcstrlen(entity_value_to_match)
   1770  1.1.1.2  jdc         || xcstrncmp(value, entity_value_to_match, value_length) != 0) {
   1771      1.1  wiz       entity_match_flag = ENTITY_MATCH_FAIL;
   1772      1.1  wiz     } else {
   1773      1.1  wiz       entity_match_flag = ENTITY_MATCH_SUCCESS;
   1774      1.1  wiz     }
   1775      1.1  wiz   }
   1776      1.1  wiz   /* Else leave the match flag alone */
   1777      1.1  wiz }
   1778      1.1  wiz 
   1779      1.1  wiz void
   1780      1.1  wiz param_entity_match_init(const XML_Char *name, const XML_Char *value) {
   1781      1.1  wiz   entity_name_to_match = name;
   1782      1.1  wiz   entity_value_to_match = value;
   1783      1.1  wiz   entity_match_flag = ENTITY_MATCH_NOT_FOUND;
   1784      1.1  wiz }
   1785      1.1  wiz 
   1786      1.1  wiz int
   1787      1.1  wiz get_param_entity_match_flag(void) {
   1788      1.1  wiz   return entity_match_flag;
   1789      1.1  wiz }
   1790      1.1  wiz 
   1791      1.1  wiz /* Misc handlers */
   1792      1.1  wiz 
   1793      1.1  wiz void XMLCALL
   1794      1.1  wiz xml_decl_handler(void *userData, const XML_Char *version,
   1795      1.1  wiz                  const XML_Char *encoding, int standalone) {
   1796      1.1  wiz   UNUSED_P(version);
   1797      1.1  wiz   UNUSED_P(encoding);
   1798      1.1  wiz   if (userData != g_handler_data)
   1799      1.1  wiz     fail("User data (xml decl) not correctly set");
   1800      1.1  wiz   if (standalone != -1)
   1801      1.1  wiz     fail("Standalone not flagged as not present in XML decl");
   1802      1.1  wiz   g_xdecl_count++;
   1803      1.1  wiz }
   1804      1.1  wiz 
   1805      1.1  wiz void XMLCALL
   1806      1.1  wiz param_check_skip_handler(void *userData, const XML_Char *entityName,
   1807      1.1  wiz                          int is_parameter_entity) {
   1808      1.1  wiz   UNUSED_P(entityName);
   1809      1.1  wiz   UNUSED_P(is_parameter_entity);
   1810      1.1  wiz   if (userData != g_handler_data)
   1811      1.1  wiz     fail("User data (skip) not correctly set");
   1812      1.1  wiz   g_skip_count++;
   1813      1.1  wiz }
   1814      1.1  wiz 
   1815      1.1  wiz void XMLCALL
   1816      1.1  wiz data_check_comment_handler(void *userData, const XML_Char *data) {
   1817      1.1  wiz   UNUSED_P(data);
   1818      1.1  wiz   /* Check that the userData passed through is what we expect */
   1819      1.1  wiz   if (userData != g_handler_data)
   1820      1.1  wiz     fail("User data (parser) not correctly set");
   1821      1.1  wiz   /* Check that the user data in the parser is appropriate */
   1822      1.1  wiz   if (XML_GetUserData(userData) != (void *)1)
   1823      1.1  wiz     fail("User data in parser not correctly set");
   1824      1.1  wiz   g_comment_count++;
   1825      1.1  wiz }
   1826      1.1  wiz 
   1827      1.1  wiz void XMLCALL
   1828      1.1  wiz selective_aborting_default_handler(void *userData, const XML_Char *s, int len) {
   1829      1.1  wiz   const XML_Char trigger_char = *(const XML_Char *)userData;
   1830      1.1  wiz 
   1831      1.1  wiz   int found = 0;
   1832      1.1  wiz   for (int i = 0; i < len; ++i) {
   1833      1.1  wiz     if (s[i] == trigger_char) {
   1834      1.1  wiz       found = 1;
   1835      1.1  wiz       break;
   1836      1.1  wiz     }
   1837      1.1  wiz   }
   1838      1.1  wiz 
   1839      1.1  wiz   if (found) {
   1840      1.1  wiz     XML_StopParser(g_parser, g_resumable);
   1841      1.1  wiz     XML_SetDefaultHandler(g_parser, NULL);
   1842      1.1  wiz   }
   1843      1.1  wiz }
   1844      1.1  wiz 
   1845      1.1  wiz void XMLCALL
   1846      1.1  wiz suspending_comment_handler(void *userData, const XML_Char *data) {
   1847      1.1  wiz   UNUSED_P(data);
   1848      1.1  wiz   XML_Parser parser = (XML_Parser)userData;
   1849      1.1  wiz   XML_StopParser(parser, XML_TRUE);
   1850      1.1  wiz }
   1851      1.1  wiz 
   1852      1.1  wiz void XMLCALL
   1853      1.1  wiz element_decl_suspender(void *userData, const XML_Char *name,
   1854      1.1  wiz                        XML_Content *model) {
   1855      1.1  wiz   UNUSED_P(userData);
   1856      1.1  wiz   UNUSED_P(name);
   1857      1.1  wiz   XML_StopParser(g_parser, XML_TRUE);
   1858      1.1  wiz   XML_FreeContentModel(g_parser, model);
   1859      1.1  wiz }
   1860      1.1  wiz 
   1861      1.1  wiz void XMLCALL
   1862      1.1  wiz suspend_after_element_declaration(void *userData, const XML_Char *name,
   1863      1.1  wiz                                   XML_Content *model) {
   1864      1.1  wiz   UNUSED_P(name);
   1865      1.1  wiz   XML_Parser parser = (XML_Parser)userData;
   1866      1.1  wiz   assert_true(XML_StopParser(parser, /*resumable*/ XML_TRUE) == XML_STATUS_OK);
   1867      1.1  wiz   XML_FreeContentModel(parser, model);
   1868      1.1  wiz }
   1869      1.1  wiz 
   1870      1.1  wiz void XMLCALL
   1871      1.1  wiz accumulate_pi_characters(void *userData, const XML_Char *target,
   1872      1.1  wiz                          const XML_Char *data) {
   1873      1.1  wiz   CharData *storage = (CharData *)userData;
   1874      1.1  wiz 
   1875      1.1  wiz   CharData_AppendXMLChars(storage, target, -1);
   1876      1.1  wiz   CharData_AppendXMLChars(storage, XCS(": "), 2);
   1877      1.1  wiz   CharData_AppendXMLChars(storage, data, -1);
   1878      1.1  wiz   CharData_AppendXMLChars(storage, XCS("\n"), 1);
   1879      1.1  wiz }
   1880      1.1  wiz 
   1881      1.1  wiz void XMLCALL
   1882      1.1  wiz accumulate_comment(void *userData, const XML_Char *data) {
   1883      1.1  wiz   CharData *storage = (CharData *)userData;
   1884      1.1  wiz 
   1885      1.1  wiz   CharData_AppendXMLChars(storage, data, -1);
   1886      1.1  wiz }
   1887      1.1  wiz 
   1888      1.1  wiz void XMLCALL
   1889      1.1  wiz accumulate_entity_decl(void *userData, const XML_Char *entityName,
   1890      1.1  wiz                        int is_parameter_entity, const XML_Char *value,
   1891      1.1  wiz                        int value_length, const XML_Char *base,
   1892      1.1  wiz                        const XML_Char *systemId, const XML_Char *publicId,
   1893      1.1  wiz                        const XML_Char *notationName) {
   1894      1.1  wiz   CharData *storage = (CharData *)userData;
   1895      1.1  wiz 
   1896      1.1  wiz   UNUSED_P(is_parameter_entity);
   1897      1.1  wiz   UNUSED_P(base);
   1898      1.1  wiz   UNUSED_P(systemId);
   1899      1.1  wiz   UNUSED_P(publicId);
   1900      1.1  wiz   UNUSED_P(notationName);
   1901      1.1  wiz   CharData_AppendXMLChars(storage, entityName, -1);
   1902      1.1  wiz   CharData_AppendXMLChars(storage, XCS("="), 1);
   1903      1.1  wiz   if (value == NULL)
   1904      1.1  wiz     CharData_AppendXMLChars(storage, XCS("(null)"), -1);
   1905      1.1  wiz   else
   1906      1.1  wiz     CharData_AppendXMLChars(storage, value, value_length);
   1907      1.1  wiz   CharData_AppendXMLChars(storage, XCS("\n"), 1);
   1908      1.1  wiz }
   1909      1.1  wiz 
   1910      1.1  wiz void XMLCALL
   1911      1.1  wiz accumulate_char_data_and_suspend(void *userData, const XML_Char *s, int len) {
   1912      1.1  wiz   ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData;
   1913      1.1  wiz 
   1914      1.1  wiz   CharData_AppendXMLChars(parserPlusStorage->storage, s, len);
   1915      1.1  wiz 
   1916      1.1  wiz   for (int i = 0; i < len; i++) {
   1917      1.1  wiz     if (s[i] == 'Z') {
   1918      1.1  wiz       XML_StopParser(parserPlusStorage->parser, /*resumable=*/XML_TRUE);
   1919      1.1  wiz       break;
   1920      1.1  wiz     }
   1921      1.1  wiz   }
   1922      1.1  wiz }
   1923      1.1  wiz 
   1924      1.1  wiz void XMLCALL
   1925      1.1  wiz accumulate_start_element(void *userData, const XML_Char *name,
   1926      1.1  wiz                          const XML_Char **atts) {
   1927      1.1  wiz   CharData *const storage = (CharData *)userData;
   1928      1.1  wiz   CharData_AppendXMLChars(storage, XCS("("), 1);
   1929      1.1  wiz   CharData_AppendXMLChars(storage, name, -1);
   1930      1.1  wiz 
   1931      1.1  wiz   if ((atts != NULL) && (atts[0] != NULL)) {
   1932      1.1  wiz     CharData_AppendXMLChars(storage, XCS("("), 1);
   1933      1.1  wiz     while (atts[0] != NULL) {
   1934      1.1  wiz       CharData_AppendXMLChars(storage, atts[0], -1);
   1935      1.1  wiz       CharData_AppendXMLChars(storage, XCS("="), 1);
   1936      1.1  wiz       CharData_AppendXMLChars(storage, atts[1], -1);
   1937      1.1  wiz       atts += 2;
   1938      1.1  wiz       if (atts[0] != NULL) {
   1939      1.1  wiz         CharData_AppendXMLChars(storage, XCS(","), 1);
   1940      1.1  wiz       }
   1941      1.1  wiz     }
   1942      1.1  wiz     CharData_AppendXMLChars(storage, XCS(")"), 1);
   1943      1.1  wiz   }
   1944      1.1  wiz 
   1945      1.1  wiz   CharData_AppendXMLChars(storage, XCS(")\n"), 2);
   1946      1.1  wiz }
   1947      1.1  wiz 
   1948      1.1  wiz void XMLCALL
   1949      1.1  wiz accumulate_characters(void *userData, const XML_Char *s, int len) {
   1950      1.1  wiz   CharData *const storage = (CharData *)userData;
   1951      1.1  wiz   CharData_AppendXMLChars(storage, s, len);
   1952      1.1  wiz }
   1953      1.1  wiz 
   1954      1.1  wiz void XMLCALL
   1955      1.1  wiz accumulate_attribute(void *userData, const XML_Char *name,
   1956      1.1  wiz                      const XML_Char **atts) {
   1957      1.1  wiz   CharData *const storage = (CharData *)userData;
   1958      1.1  wiz   UNUSED_P(name);
   1959      1.1  wiz   /* Check there are attributes to deal with */
   1960      1.1  wiz   if (atts == NULL)
   1961      1.1  wiz     return;
   1962      1.1  wiz 
   1963      1.1  wiz   while (storage->count < 0 && atts[0] != NULL) {
   1964      1.1  wiz     /* "accumulate" the value of the first attribute we see */
   1965      1.1  wiz     CharData_AppendXMLChars(storage, atts[1], -1);
   1966      1.1  wiz     atts += 2;
   1967      1.1  wiz   }
   1968      1.1  wiz }
   1969      1.1  wiz 
   1970      1.1  wiz void XMLCALL
   1971      1.1  wiz ext_accumulate_characters(void *userData, const XML_Char *s, int len) {
   1972      1.1  wiz   ExtTest *const test_data = (ExtTest *)userData;
   1973      1.1  wiz   accumulate_characters(test_data->storage, s, len);
   1974      1.1  wiz }
   1975      1.1  wiz 
   1976      1.1  wiz void XMLCALL
   1977      1.1  wiz checking_default_handler(void *userData, const XML_Char *s, int len) {
   1978      1.1  wiz   DefaultCheck *data = (DefaultCheck *)userData;
   1979      1.1  wiz   int i;
   1980      1.1  wiz 
   1981      1.1  wiz   for (i = 0; data[i].expected != NULL; i++) {
   1982      1.1  wiz     if (data[i].expectedLen == len
   1983      1.1  wiz         && ! memcmp(data[i].expected, s, len * sizeof(XML_Char))) {
   1984      1.1  wiz       data[i].seen = XML_TRUE;
   1985      1.1  wiz       break;
   1986      1.1  wiz     }
   1987      1.1  wiz   }
   1988      1.1  wiz }
   1989      1.1  wiz 
   1990      1.1  wiz void XMLCALL
   1991      1.1  wiz accumulate_and_suspend_comment_handler(void *userData, const XML_Char *data) {
   1992      1.1  wiz   ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData;
   1993      1.1  wiz   accumulate_comment(parserPlusStorage->storage, data);
   1994      1.1  wiz   XML_StopParser(parserPlusStorage->parser, XML_TRUE);
   1995      1.1  wiz }
   1996  1.1.1.3  jdc 
   1997  1.1.1.3  jdc void XMLCALL
   1998  1.1.1.3  jdc forbidden_calls_character_handler(void *userData, const XML_Char *s, int len) {
   1999  1.1.1.3  jdc   UNUSED_P(s);
   2000  1.1.1.3  jdc   UNUSED_P(len);
   2001  1.1.1.3  jdc   XML_Parser parser = userData;
   2002  1.1.1.3  jdc 
   2003  1.1.1.3  jdc   assert_true(parser != NULL); // self-test
   2004  1.1.1.3  jdc 
   2005  1.1.1.3  jdc   assert_true(XML_GetBuffer(parser, 123) == NULL); // i.e. rejected
   2006  1.1.1.3  jdc 
   2007  1.1.1.3  jdc   assert_true(XML_Parse(parser, "", 0, /*isFinal=*/XML_FALSE)
   2008  1.1.1.3  jdc               == XML_STATUS_ERROR); // i.e. rejected
   2009  1.1.1.3  jdc 
   2010  1.1.1.3  jdc   assert_true(XML_ParseBuffer(parser, 0, /*isFinal=*/XML_FALSE)
   2011  1.1.1.3  jdc               == XML_STATUS_ERROR); // i.e. rejected
   2012  1.1.1.3  jdc 
   2013  1.1.1.3  jdc   XML_ParserFree(parser); // rejected
   2014  1.1.1.3  jdc 
   2015  1.1.1.3  jdc   assert_true(XML_ParserReset(parser, /*encodingName=*/NULL)
   2016  1.1.1.3  jdc               == XML_FALSE); // i.e. rejected
   2017  1.1.1.3  jdc 
   2018  1.1.1.3  jdc   assert_true(XML_GetErrorCode(parser) == XML_ERROR_NONE);
   2019  1.1.1.3  jdc }
   2020  1.1.1.3  jdc 
   2021  1.1.1.3  jdc void XMLCALL
   2022  1.1.1.3  jdc suspend_then_resume_character_handler(void *userData, const XML_Char *s,
   2023  1.1.1.3  jdc                                       int len) {
   2024  1.1.1.3  jdc   UNUSED_P(s);
   2025  1.1.1.3  jdc   UNUSED_P(len);
   2026  1.1.1.3  jdc   ResumeFromHandlerData *const data = (ResumeFromHandlerData *)userData;
   2027  1.1.1.3  jdc 
   2028  1.1.1.3  jdc   data->callCount++;
   2029  1.1.1.3  jdc   if (data->callCount > 1) {
   2030  1.1.1.3  jdc     // Reached only if the guard under test is missing: XML_ResumeParser would
   2031  1.1.1.3  jdc     // then have driven the parser re-entrantly and called us again.  Bail out
   2032  1.1.1.3  jdc     // so the test fails by assertion below rather than recursing without bound.
   2033  1.1.1.3  jdc     return;
   2034  1.1.1.3  jdc   }
   2035  1.1.1.3  jdc 
   2036  1.1.1.3  jdc   // Put the parser into XML_SUSPENDED so that, without the guard,
   2037  1.1.1.3  jdc   // XML_ResumeParser would proceed into a re-entrant parse.
   2038  1.1.1.3  jdc   assert_true(XML_StopParser(data->parser, /*resumable=*/XML_TRUE)
   2039  1.1.1.3  jdc               == XML_STATUS_OK);
   2040  1.1.1.3  jdc 
   2041  1.1.1.3  jdc   // Resuming the parser from inside a handler must be rejected.
   2042  1.1.1.3  jdc   assert_true(XML_ResumeParser(data->parser) == XML_STATUS_ERROR);
   2043  1.1.1.3  jdc }
   2044