Home | History | Annotate | Line # | Download | only in tests
      1  1.1  wiz /* Tests in the "namespace" test case 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  wiz    Copyright (c) 2016-2023 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      Sony Corporation / Snild Dolkow <snild (at) sony.com>
     22  1.1  wiz    Licensed under the MIT license:
     23  1.1  wiz 
     24  1.1  wiz    Permission is  hereby granted,  free of charge,  to any  person obtaining
     25  1.1  wiz    a  copy  of  this  software   and  associated  documentation  files  (the
     26  1.1  wiz    "Software"),  to  deal in  the  Software  without restriction,  including
     27  1.1  wiz    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
     28  1.1  wiz    distribute, sublicense, and/or sell copies of the Software, and to permit
     29  1.1  wiz    persons  to whom  the Software  is  furnished to  do so,  subject to  the
     30  1.1  wiz    following conditions:
     31  1.1  wiz 
     32  1.1  wiz    The above copyright  notice and this permission notice  shall be included
     33  1.1  wiz    in all copies or substantial portions of the Software.
     34  1.1  wiz 
     35  1.1  wiz    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
     36  1.1  wiz    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
     37  1.1  wiz    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
     38  1.1  wiz    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
     39  1.1  wiz    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
     40  1.1  wiz    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     41  1.1  wiz    USE OR OTHER DEALINGS IN THE SOFTWARE.
     42  1.1  wiz */
     43  1.1  wiz 
     44  1.1  wiz #include "expat_config.h"
     45  1.1  wiz 
     46  1.1  wiz #include <string.h>
     47  1.1  wiz 
     48  1.1  wiz #include "expat.h"
     49  1.1  wiz #include "internal.h"
     50  1.1  wiz #include "minicheck.h"
     51  1.1  wiz #include "common.h"
     52  1.1  wiz #include "dummy.h"
     53  1.1  wiz #include "handlers.h"
     54  1.1  wiz #include "ns_tests.h"
     55  1.1  wiz 
     56  1.1  wiz static void
     57  1.1  wiz namespace_setup(void) {
     58  1.1  wiz   g_parser = XML_ParserCreateNS(NULL, XCS(' '));
     59  1.1  wiz   if (g_parser == NULL)
     60  1.1  wiz     fail("Parser not created.");
     61  1.1  wiz }
     62  1.1  wiz 
     63  1.1  wiz static void
     64  1.1  wiz namespace_teardown(void) {
     65  1.1  wiz   basic_teardown();
     66  1.1  wiz }
     67  1.1  wiz 
     68  1.1  wiz START_TEST(test_return_ns_triplet) {
     69  1.1  wiz   const char *text = "<foo:e xmlns:foo='http://example.org/' bar:a='12'\n"
     70  1.1  wiz                      "       xmlns:bar='http://example.org/'>";
     71  1.1  wiz   const char *epilog = "</foo:e>";
     72  1.1  wiz   const XML_Char *elemstr[]
     73  1.1  wiz       = {XCS("http://example.org/ e foo"), XCS("http://example.org/ a bar")};
     74  1.1  wiz   XML_SetReturnNSTriplet(g_parser, XML_TRUE);
     75  1.1  wiz   XML_SetUserData(g_parser, (void *)elemstr);
     76  1.1  wiz   XML_SetElementHandler(g_parser, triplet_start_checker, triplet_end_checker);
     77  1.1  wiz   XML_SetNamespaceDeclHandler(g_parser, dummy_start_namespace_decl_handler,
     78  1.1  wiz                               dummy_end_namespace_decl_handler);
     79  1.1  wiz   g_triplet_start_flag = XML_FALSE;
     80  1.1  wiz   g_triplet_end_flag = XML_FALSE;
     81  1.1  wiz   init_dummy_handlers();
     82  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_FALSE)
     83  1.1  wiz       == XML_STATUS_ERROR)
     84  1.1  wiz     xml_failure(g_parser);
     85  1.1  wiz   /* Check that unsetting "return triplets" fails while still parsing */
     86  1.1  wiz   XML_SetReturnNSTriplet(g_parser, XML_FALSE);
     87  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, epilog, (int)strlen(epilog), XML_TRUE)
     88  1.1  wiz       == XML_STATUS_ERROR)
     89  1.1  wiz     xml_failure(g_parser);
     90  1.1  wiz   if (! g_triplet_start_flag)
     91  1.1  wiz     fail("triplet_start_checker not invoked");
     92  1.1  wiz   if (! g_triplet_end_flag)
     93  1.1  wiz     fail("triplet_end_checker not invoked");
     94  1.1  wiz   if (get_dummy_handler_flags()
     95  1.1  wiz       != (DUMMY_START_NS_DECL_HANDLER_FLAG | DUMMY_END_NS_DECL_HANDLER_FLAG))
     96  1.1  wiz     fail("Namespace handlers not called");
     97  1.1  wiz }
     98  1.1  wiz END_TEST
     99  1.1  wiz 
    100  1.1  wiz /* Test that the parsing status is correctly reset by XML_ParserReset().
    101  1.1  wiz  * We use test_return_ns_triplet() for our example parse to improve
    102  1.1  wiz  * coverage of tidying up code executed.
    103  1.1  wiz  */
    104  1.1  wiz START_TEST(test_ns_parser_reset) {
    105  1.1  wiz   XML_ParsingStatus status;
    106  1.1  wiz 
    107  1.1  wiz   XML_GetParsingStatus(g_parser, &status);
    108  1.1  wiz   if (status.parsing != XML_INITIALIZED)
    109  1.1  wiz     fail("parsing status doesn't start INITIALIZED");
    110  1.1  wiz   test_return_ns_triplet();
    111  1.1  wiz   XML_GetParsingStatus(g_parser, &status);
    112  1.1  wiz   if (status.parsing != XML_FINISHED)
    113  1.1  wiz     fail("parsing status doesn't end FINISHED");
    114  1.1  wiz   XML_ParserReset(g_parser, NULL);
    115  1.1  wiz   XML_GetParsingStatus(g_parser, &status);
    116  1.1  wiz   if (status.parsing != XML_INITIALIZED)
    117  1.1  wiz     fail("parsing status doesn't reset to INITIALIZED");
    118  1.1  wiz }
    119  1.1  wiz END_TEST
    120  1.1  wiz 
    121  1.1  wiz static void
    122  1.1  wiz run_ns_tagname_overwrite_test(const char *text, const XML_Char *result) {
    123  1.1  wiz   CharData storage;
    124  1.1  wiz   CharData_Init(&storage);
    125  1.1  wiz   XML_SetUserData(g_parser, &storage);
    126  1.1  wiz   XML_SetElementHandler(g_parser, overwrite_start_checker,
    127  1.1  wiz                         overwrite_end_checker);
    128  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    129  1.1  wiz       == XML_STATUS_ERROR)
    130  1.1  wiz     xml_failure(g_parser);
    131  1.1  wiz   CharData_CheckXMLChars(&storage, result);
    132  1.1  wiz }
    133  1.1  wiz 
    134  1.1  wiz /* Regression test for SF bug #566334. */
    135  1.1  wiz START_TEST(test_ns_tagname_overwrite) {
    136  1.1  wiz   const char *text = "<n:e xmlns:n='http://example.org/'>\n"
    137  1.1  wiz                      "  <n:f n:attr='foo'/>\n"
    138  1.1  wiz                      "  <n:g n:attr2='bar'/>\n"
    139  1.1  wiz                      "</n:e>";
    140  1.1  wiz   const XML_Char *result = XCS("start http://example.org/ e\n")
    141  1.1  wiz       XCS("start http://example.org/ f\n")
    142  1.1  wiz           XCS("attribute http://example.org/ attr\n")
    143  1.1  wiz               XCS("end http://example.org/ f\n")
    144  1.1  wiz                   XCS("start http://example.org/ g\n")
    145  1.1  wiz                       XCS("attribute http://example.org/ attr2\n")
    146  1.1  wiz                           XCS("end http://example.org/ g\n")
    147  1.1  wiz                               XCS("end http://example.org/ e\n");
    148  1.1  wiz   run_ns_tagname_overwrite_test(text, result);
    149  1.1  wiz }
    150  1.1  wiz END_TEST
    151  1.1  wiz 
    152  1.1  wiz /* Regression test for SF bug #566334. */
    153  1.1  wiz START_TEST(test_ns_tagname_overwrite_triplet) {
    154  1.1  wiz   const char *text = "<n:e xmlns:n='http://example.org/'>\n"
    155  1.1  wiz                      "  <n:f n:attr='foo'/>\n"
    156  1.1  wiz                      "  <n:g n:attr2='bar'/>\n"
    157  1.1  wiz                      "</n:e>";
    158  1.1  wiz   const XML_Char *result = XCS("start http://example.org/ e n\n")
    159  1.1  wiz       XCS("start http://example.org/ f n\n")
    160  1.1  wiz           XCS("attribute http://example.org/ attr n\n")
    161  1.1  wiz               XCS("end http://example.org/ f n\n")
    162  1.1  wiz                   XCS("start http://example.org/ g n\n")
    163  1.1  wiz                       XCS("attribute http://example.org/ attr2 n\n")
    164  1.1  wiz                           XCS("end http://example.org/ g n\n")
    165  1.1  wiz                               XCS("end http://example.org/ e n\n");
    166  1.1  wiz   XML_SetReturnNSTriplet(g_parser, XML_TRUE);
    167  1.1  wiz   run_ns_tagname_overwrite_test(text, result);
    168  1.1  wiz }
    169  1.1  wiz END_TEST
    170  1.1  wiz 
    171  1.1  wiz /* Regression test for SF bug #620343. */
    172  1.1  wiz START_TEST(test_start_ns_clears_start_element) {
    173  1.1  wiz   /* This needs to use separate start/end tags; using the empty tag
    174  1.1  wiz      syntax doesn't cause the problematic path through Expat to be
    175  1.1  wiz      taken.
    176  1.1  wiz   */
    177  1.1  wiz   const char *text = "<e xmlns='http://example.org/'></e>";
    178  1.1  wiz 
    179  1.1  wiz   XML_SetStartElementHandler(g_parser, start_element_fail);
    180  1.1  wiz   XML_SetStartNamespaceDeclHandler(g_parser, start_ns_clearing_start_element);
    181  1.1  wiz   XML_SetEndNamespaceDeclHandler(g_parser, dummy_end_namespace_decl_handler);
    182  1.1  wiz   XML_UseParserAsHandlerArg(g_parser);
    183  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    184  1.1  wiz       == XML_STATUS_ERROR)
    185  1.1  wiz     xml_failure(g_parser);
    186  1.1  wiz }
    187  1.1  wiz END_TEST
    188  1.1  wiz 
    189  1.1  wiz /* Regression test for SF bug #616863. */
    190  1.1  wiz START_TEST(test_default_ns_from_ext_subset_and_ext_ge) {
    191  1.1  wiz   const char *text = "<?xml version='1.0'?>\n"
    192  1.1  wiz                      "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
    193  1.1  wiz                      "  <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
    194  1.1  wiz                      "]>\n"
    195  1.1  wiz                      "<doc xmlns='http://example.org/ns1'>\n"
    196  1.1  wiz                      "&en;\n"
    197  1.1  wiz                      "</doc>";
    198  1.1  wiz 
    199  1.1  wiz   XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
    200  1.1  wiz   XML_SetExternalEntityRefHandler(g_parser, external_entity_handler);
    201  1.1  wiz   /* We actually need to set this handler to tickle this bug. */
    202  1.1  wiz   XML_SetStartElementHandler(g_parser, dummy_start_element);
    203  1.1  wiz   XML_SetUserData(g_parser, NULL);
    204  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    205  1.1  wiz       == XML_STATUS_ERROR)
    206  1.1  wiz     xml_failure(g_parser);
    207  1.1  wiz }
    208  1.1  wiz END_TEST
    209  1.1  wiz 
    210  1.1  wiz /* Regression test #1 for SF bug #673791. */
    211  1.1  wiz START_TEST(test_ns_prefix_with_empty_uri_1) {
    212  1.1  wiz   const char *text = "<doc xmlns:prefix='http://example.org/'>\n"
    213  1.1  wiz                      "  <e xmlns:prefix=''/>\n"
    214  1.1  wiz                      "</doc>";
    215  1.1  wiz 
    216  1.1  wiz   expect_failure(text, XML_ERROR_UNDECLARING_PREFIX,
    217  1.1  wiz                  "Did not report re-setting namespace"
    218  1.1  wiz                  " URI with prefix to ''.");
    219  1.1  wiz }
    220  1.1  wiz END_TEST
    221  1.1  wiz 
    222  1.1  wiz /* Regression test #2 for SF bug #673791. */
    223  1.1  wiz START_TEST(test_ns_prefix_with_empty_uri_2) {
    224  1.1  wiz   const char *text = "<?xml version='1.0'?>\n"
    225  1.1  wiz                      "<docelem xmlns:pre=''/>";
    226  1.1  wiz 
    227  1.1  wiz   expect_failure(text, XML_ERROR_UNDECLARING_PREFIX,
    228  1.1  wiz                  "Did not report setting namespace URI with prefix to ''.");
    229  1.1  wiz }
    230  1.1  wiz END_TEST
    231  1.1  wiz 
    232  1.1  wiz /* Regression test #3 for SF bug #673791. */
    233  1.1  wiz START_TEST(test_ns_prefix_with_empty_uri_3) {
    234  1.1  wiz   const char *text = "<!DOCTYPE doc [\n"
    235  1.1  wiz                      "  <!ELEMENT doc EMPTY>\n"
    236  1.1  wiz                      "  <!ATTLIST doc\n"
    237  1.1  wiz                      "    xmlns:prefix CDATA ''>\n"
    238  1.1  wiz                      "]>\n"
    239  1.1  wiz                      "<doc/>";
    240  1.1  wiz 
    241  1.1  wiz   expect_failure(text, XML_ERROR_UNDECLARING_PREFIX,
    242  1.1  wiz                  "Didn't report attr default setting NS w/ prefix to ''.");
    243  1.1  wiz }
    244  1.1  wiz END_TEST
    245  1.1  wiz 
    246  1.1  wiz /* Regression test #4 for SF bug #673791. */
    247  1.1  wiz START_TEST(test_ns_prefix_with_empty_uri_4) {
    248  1.1  wiz   const char *text = "<!DOCTYPE doc [\n"
    249  1.1  wiz                      "  <!ELEMENT prefix:doc EMPTY>\n"
    250  1.1  wiz                      "  <!ATTLIST prefix:doc\n"
    251  1.1  wiz                      "    xmlns:prefix CDATA 'http://example.org/'>\n"
    252  1.1  wiz                      "]>\n"
    253  1.1  wiz                      "<prefix:doc/>";
    254  1.1  wiz   /* Packaged info expected by the end element handler;
    255  1.1  wiz      the weird structuring lets us reuse the triplet_end_checker()
    256  1.1  wiz      function also used for another test. */
    257  1.1  wiz   const XML_Char *elemstr[] = {XCS("http://example.org/ doc prefix")};
    258  1.1  wiz   XML_SetReturnNSTriplet(g_parser, XML_TRUE);
    259  1.1  wiz   XML_SetUserData(g_parser, (void *)elemstr);
    260  1.1  wiz   XML_SetEndElementHandler(g_parser, triplet_end_checker);
    261  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    262  1.1  wiz       == XML_STATUS_ERROR)
    263  1.1  wiz     xml_failure(g_parser);
    264  1.1  wiz }
    265  1.1  wiz END_TEST
    266  1.1  wiz 
    267  1.1  wiz /* Test with non-xmlns prefix */
    268  1.1  wiz START_TEST(test_ns_unbound_prefix) {
    269  1.1  wiz   const char *text = "<!DOCTYPE doc [\n"
    270  1.1  wiz                      "  <!ELEMENT prefix:doc EMPTY>\n"
    271  1.1  wiz                      "  <!ATTLIST prefix:doc\n"
    272  1.1  wiz                      "    notxmlns:prefix CDATA 'http://example.org/'>\n"
    273  1.1  wiz                      "]>\n"
    274  1.1  wiz                      "<prefix:doc/>";
    275  1.1  wiz 
    276  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    277  1.1  wiz       != XML_STATUS_ERROR)
    278  1.1  wiz     fail("Unbound prefix incorrectly passed");
    279  1.1  wiz   if (XML_GetErrorCode(g_parser) != XML_ERROR_UNBOUND_PREFIX)
    280  1.1  wiz     xml_failure(g_parser);
    281  1.1  wiz }
    282  1.1  wiz END_TEST
    283  1.1  wiz 
    284  1.1  wiz START_TEST(test_ns_default_with_empty_uri) {
    285  1.1  wiz   const char *text = "<doc xmlns='http://example.org/'>\n"
    286  1.1  wiz                      "  <e xmlns=''/>\n"
    287  1.1  wiz                      "</doc>";
    288  1.1  wiz   /* Add some handlers to exercise extra code paths */
    289  1.1  wiz   XML_SetStartNamespaceDeclHandler(g_parser,
    290  1.1  wiz                                    dummy_start_namespace_decl_handler);
    291  1.1  wiz   XML_SetEndNamespaceDeclHandler(g_parser, dummy_end_namespace_decl_handler);
    292  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    293  1.1  wiz       == XML_STATUS_ERROR)
    294  1.1  wiz     xml_failure(g_parser);
    295  1.1  wiz }
    296  1.1  wiz END_TEST
    297  1.1  wiz 
    298  1.1  wiz /* Regression test for SF bug #692964: two prefixes for one namespace. */
    299  1.1  wiz START_TEST(test_ns_duplicate_attrs_diff_prefixes) {
    300  1.1  wiz   const char *text = "<doc xmlns:a='http://example.org/a'\n"
    301  1.1  wiz                      "     xmlns:b='http://example.org/a'\n"
    302  1.1  wiz                      "     a:a='v' b:a='v' />";
    303  1.1  wiz   expect_failure(text, XML_ERROR_DUPLICATE_ATTRIBUTE,
    304  1.1  wiz                  "did not report multiple attributes with same URI+name");
    305  1.1  wiz }
    306  1.1  wiz END_TEST
    307  1.1  wiz 
    308  1.1  wiz START_TEST(test_ns_duplicate_hashes) {
    309  1.1  wiz   /* The hash of an attribute is calculated as the hash of its URI
    310  1.1  wiz    * concatenated with a space followed by its name (after the
    311  1.1  wiz    * colon).  We wish to generate attributes with the same hash
    312  1.1  wiz    * value modulo the attribute table size so that we can check that
    313  1.1  wiz    * the attribute hash table works correctly.  The attribute hash
    314  1.1  wiz    * table size will be the smallest power of two greater than the
    315  1.1  wiz    * number of attributes, but at least eight.  There is
    316  1.1  wiz    * unfortunately no programmatic way of getting the hash or the
    317  1.1  wiz    * table size at user level, but the test code coverage percentage
    318  1.1  wiz    * will drop if the hashes cease to point to the same row.
    319  1.1  wiz    *
    320  1.1  wiz    * The cunning plan is to have few enough attributes to have a
    321  1.1  wiz    * reliable table size of 8, and have the single letter attribute
    322  1.1  wiz    * names be 8 characters apart, producing a hash which will be the
    323  1.1  wiz    * same modulo 8.
    324  1.1  wiz    */
    325  1.1  wiz   const char *text = "<doc xmlns:a='http://example.org/a'\n"
    326  1.1  wiz                      "     a:a='v' a:i='w' />";
    327  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    328  1.1  wiz       == XML_STATUS_ERROR)
    329  1.1  wiz     xml_failure(g_parser);
    330  1.1  wiz }
    331  1.1  wiz END_TEST
    332  1.1  wiz 
    333  1.1  wiz /* Regression test for SF bug #695401: unbound prefix. */
    334  1.1  wiz START_TEST(test_ns_unbound_prefix_on_attribute) {
    335  1.1  wiz   const char *text = "<doc a:attr=''/>";
    336  1.1  wiz   expect_failure(text, XML_ERROR_UNBOUND_PREFIX,
    337  1.1  wiz                  "did not report unbound prefix on attribute");
    338  1.1  wiz }
    339  1.1  wiz END_TEST
    340  1.1  wiz 
    341  1.1  wiz /* Regression test for SF bug #695401: unbound prefix. */
    342  1.1  wiz START_TEST(test_ns_unbound_prefix_on_element) {
    343  1.1  wiz   const char *text = "<a:doc/>";
    344  1.1  wiz   expect_failure(text, XML_ERROR_UNBOUND_PREFIX,
    345  1.1  wiz                  "did not report unbound prefix on element");
    346  1.1  wiz }
    347  1.1  wiz END_TEST
    348  1.1  wiz 
    349  1.1  wiz /* Test that long element names with namespaces are handled correctly */
    350  1.1  wiz START_TEST(test_ns_long_element) {
    351  1.1  wiz   const char *text
    352  1.1  wiz       = "<foo:thisisalongenoughelementnametotriggerareallocation\n"
    353  1.1  wiz         " xmlns:foo='http://example.org/' bar:a='12'\n"
    354  1.1  wiz         " xmlns:bar='http://example.org/'>"
    355  1.1  wiz         "</foo:thisisalongenoughelementnametotriggerareallocation>";
    356  1.1  wiz   const XML_Char *elemstr[]
    357  1.1  wiz       = {XCS("http://example.org/")
    358  1.1  wiz              XCS(" thisisalongenoughelementnametotriggerareallocation foo"),
    359  1.1  wiz          XCS("http://example.org/ a bar")};
    360  1.1  wiz 
    361  1.1  wiz   XML_SetReturnNSTriplet(g_parser, XML_TRUE);
    362  1.1  wiz   XML_SetUserData(g_parser, (void *)elemstr);
    363  1.1  wiz   XML_SetElementHandler(g_parser, triplet_start_checker, triplet_end_checker);
    364  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    365  1.1  wiz       == XML_STATUS_ERROR)
    366  1.1  wiz     xml_failure(g_parser);
    367  1.1  wiz }
    368  1.1  wiz END_TEST
    369  1.1  wiz 
    370  1.1  wiz /* Test mixed population of prefixed and unprefixed attributes */
    371  1.1  wiz START_TEST(test_ns_mixed_prefix_atts) {
    372  1.1  wiz   const char *text = "<e a='12' bar:b='13'\n"
    373  1.1  wiz                      " xmlns:bar='http://example.org/'>"
    374  1.1  wiz                      "</e>";
    375  1.1  wiz 
    376  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    377  1.1  wiz       == XML_STATUS_ERROR)
    378  1.1  wiz     xml_failure(g_parser);
    379  1.1  wiz }
    380  1.1  wiz END_TEST
    381  1.1  wiz 
    382  1.1  wiz /* Test having a long namespaced element name inside a short one.
    383  1.1  wiz  * This exercises some internal buffer reallocation that is shared
    384  1.1  wiz  * across elements with the same namespace URI.
    385  1.1  wiz  */
    386  1.1  wiz START_TEST(test_ns_extend_uri_buffer) {
    387  1.1  wiz   const char *text = "<foo:e xmlns:foo='http://example.org/'>"
    388  1.1  wiz                      " <foo:thisisalongenoughnametotriggerallocationaction"
    389  1.1  wiz                      "   foo:a='12' />"
    390  1.1  wiz                      "</foo:e>";
    391  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
    392  1.1  wiz       == XML_STATUS_ERROR)
    393  1.1  wiz     xml_failure(g_parser);
    394  1.1  wiz }
    395  1.1  wiz END_TEST
    396  1.1  wiz 
    397  1.1  wiz /* Test that xmlns is correctly rejected as an attribute in the xmlns
    398  1.1  wiz  * namespace, but not in other namespaces
    399  1.1  wiz  */
    400  1.1  wiz START_TEST(test_ns_reserved_attributes) {
    401  1.1  wiz   const char *text1
    402  1.1  wiz       = "<foo:e xmlns:foo='http://example.org/' xmlns:xmlns='12' />";
    403  1.1  wiz   const char *text2
    404  1.1  wiz       = "<foo:e xmlns:foo='http://example.org/' foo:xmlns='12' />";
    405  1.1  wiz   expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XMLNS,
    406  1.1  wiz                  "xmlns not rejected as an attribute");
    407  1.1  wiz   XML_ParserReset(g_parser, NULL);
    408  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text2, (int)strlen(text2), XML_TRUE)
    409  1.1  wiz       == XML_STATUS_ERROR)
    410  1.1  wiz     xml_failure(g_parser);
    411  1.1  wiz }
    412  1.1  wiz END_TEST
    413  1.1  wiz 
    414  1.1  wiz /* Test more reserved attributes */
    415  1.1  wiz START_TEST(test_ns_reserved_attributes_2) {
    416  1.1  wiz   const char *text1 = "<foo:e xmlns:foo='http://example.org/'"
    417  1.1  wiz                       "  xmlns:xml='http://example.org/' />";
    418  1.1  wiz   const char *text2
    419  1.1  wiz       = "<foo:e xmlns:foo='http://www.w3.org/XML/1998/namespace' />";
    420  1.1  wiz   const char *text3 = "<foo:e xmlns:foo='http://www.w3.org/2000/xmlns/' />";
    421  1.1  wiz 
    422  1.1  wiz   expect_failure(text1, XML_ERROR_RESERVED_PREFIX_XML,
    423  1.1  wiz                  "xml not rejected as an attribute");
    424  1.1  wiz   XML_ParserReset(g_parser, NULL);
    425  1.1  wiz   expect_failure(text2, XML_ERROR_RESERVED_NAMESPACE_URI,
    426  1.1  wiz                  "Use of w3.org URL not faulted");
    427  1.1  wiz   XML_ParserReset(g_parser, NULL);
    428  1.1  wiz   expect_failure(text3, XML_ERROR_RESERVED_NAMESPACE_URI,
    429  1.1  wiz                  "Use of w3.org xmlns URL not faulted");
    430  1.1  wiz }
    431  1.1  wiz END_TEST
    432  1.1  wiz 
    433  1.1  wiz /* Test string pool handling of namespace names of 2048 characters */
    434  1.1  wiz /* Exercises a particular string pool growth path */
    435  1.1  wiz START_TEST(test_ns_extremely_long_prefix) {
    436  1.1  wiz   /* C99 compilers are only required to support 4095-character
    437  1.1  wiz    * strings, so the following needs to be split in two to be safe
    438  1.1  wiz    * for all compilers.
    439  1.1  wiz    */
    440  1.1  wiz   const char *text1
    441  1.1  wiz       = "<doc "
    442  1.1  wiz         /* 64 character on each line */
    443  1.1  wiz         /* ...gives a total length of 2048 */
    444  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    445  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    446  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    447  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    448  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    449  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    450  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    451  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    452  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    453  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    454  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    455  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    456  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    457  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    458  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    459  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    460  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    461  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    462  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    463  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    464  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    465  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    466  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    467  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    468  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    469  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    470  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    471  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    472  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    473  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    474  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    475  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    476  1.1  wiz         ":a='12'";
    477  1.1  wiz   const char *text2
    478  1.1  wiz       = " xmlns:"
    479  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    480  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    481  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    482  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    483  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    484  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    485  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    486  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    487  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    488  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    489  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    490  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    491  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    492  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    493  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    494  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    495  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    496  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    497  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    498  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    499  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    500  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    501  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    502  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    503  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    504  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    505  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    506  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    507  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    508  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    509  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    510  1.1  wiz         "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
    511  1.1  wiz         "='foo'\n>"
    512  1.1  wiz         "</doc>";
    513  1.1  wiz 
    514  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text1, (int)strlen(text1), XML_FALSE)
    515  1.1  wiz       == XML_STATUS_ERROR)
    516  1.1  wiz     xml_failure(g_parser);
    517  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text2, (int)strlen(text2), XML_TRUE)
    518  1.1  wiz       == XML_STATUS_ERROR)
    519  1.1  wiz     xml_failure(g_parser);
    520  1.1  wiz }
    521  1.1  wiz END_TEST
    522  1.1  wiz 
    523  1.1  wiz /* Test unknown encoding handlers in namespace setup */
    524  1.1  wiz START_TEST(test_ns_unknown_encoding_success) {
    525  1.1  wiz   const char *text = "<?xml version='1.0' encoding='prefix-conv'?>\n"
    526  1.1  wiz                      "<foo:e xmlns:foo='http://example.org/'>Hi</foo:e>";
    527  1.1  wiz 
    528  1.1  wiz   XML_SetUnknownEncodingHandler(g_parser, MiscEncodingHandler, NULL);
    529  1.1  wiz   run_character_check(text, XCS("Hi"));
    530  1.1  wiz }
    531  1.1  wiz END_TEST
    532  1.1  wiz 
    533  1.1  wiz /* Test that too many colons are rejected */
    534  1.1  wiz START_TEST(test_ns_double_colon) {
    535  1.1  wiz   const char *text = "<foo:e xmlns:foo='http://example.org/' foo:a:b='bar' />";
    536  1.1  wiz   const enum XML_Status status
    537  1.1  wiz       = _XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE);
    538  1.1  wiz #ifdef XML_NS
    539  1.1  wiz   if ((status == XML_STATUS_OK)
    540  1.1  wiz       || (XML_GetErrorCode(g_parser) != XML_ERROR_INVALID_TOKEN)) {
    541  1.1  wiz     fail("Double colon in attribute name not faulted"
    542  1.1  wiz          " (despite active namespace support)");
    543  1.1  wiz   }
    544  1.1  wiz #else
    545  1.1  wiz   if (status != XML_STATUS_OK) {
    546  1.1  wiz     fail("Double colon in attribute name faulted"
    547  1.1  wiz          " (despite inactive namespace support");
    548  1.1  wiz   }
    549  1.1  wiz #endif
    550  1.1  wiz }
    551  1.1  wiz END_TEST
    552  1.1  wiz 
    553  1.1  wiz START_TEST(test_ns_double_colon_element) {
    554  1.1  wiz   const char *text = "<foo:bar:e xmlns:foo='http://example.org/' />";
    555  1.1  wiz   const enum XML_Status status
    556  1.1  wiz       = _XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE);
    557  1.1  wiz #ifdef XML_NS
    558  1.1  wiz   if ((status == XML_STATUS_OK)
    559  1.1  wiz       || (XML_GetErrorCode(g_parser) != XML_ERROR_INVALID_TOKEN)) {
    560  1.1  wiz     fail("Double colon in element name not faulted"
    561  1.1  wiz          " (despite active namespace support)");
    562  1.1  wiz   }
    563  1.1  wiz #else
    564  1.1  wiz   if (status != XML_STATUS_OK) {
    565  1.1  wiz     fail("Double colon in element name faulted"
    566  1.1  wiz          " (despite inactive namespace support");
    567  1.1  wiz   }
    568  1.1  wiz #endif
    569  1.1  wiz }
    570  1.1  wiz END_TEST
    571  1.1  wiz 
    572  1.1  wiz /* Test that non-name characters after a colon are rejected */
    573  1.1  wiz START_TEST(test_ns_bad_attr_leafname) {
    574  1.1  wiz   const char *text = "<foo:e xmlns:foo='http://example.org/' foo:?ar='baz' />";
    575  1.1  wiz 
    576  1.1  wiz   expect_failure(text, XML_ERROR_INVALID_TOKEN,
    577  1.1  wiz                  "Invalid character in leafname not faulted");
    578  1.1  wiz }
    579  1.1  wiz END_TEST
    580  1.1  wiz 
    581  1.1  wiz START_TEST(test_ns_bad_element_leafname) {
    582  1.1  wiz   const char *text = "<foo:?oc xmlns:foo='http://example.org/' />";
    583  1.1  wiz 
    584  1.1  wiz   expect_failure(text, XML_ERROR_INVALID_TOKEN,
    585  1.1  wiz                  "Invalid character in element leafname not faulted");
    586  1.1  wiz }
    587  1.1  wiz END_TEST
    588  1.1  wiz 
    589  1.1  wiz /* Test high-byte-set UTF-16 characters are valid in a leafname */
    590  1.1  wiz START_TEST(test_ns_utf16_leafname) {
    591  1.1  wiz   const char text[] =
    592  1.1  wiz       /* <n:e xmlns:n='URI' n:{KHO KHWAI}='a' />
    593  1.1  wiz        * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
    594  1.1  wiz        */
    595  1.1  wiz       "<\0n\0:\0e\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0 \0"
    596  1.1  wiz       "n\0:\0\x04\x0e=\0'\0a\0'\0 \0/\0>\0";
    597  1.1  wiz   const XML_Char *expected = XCS("a");
    598  1.1  wiz   CharData storage;
    599  1.1  wiz 
    600  1.1  wiz   CharData_Init(&storage);
    601  1.1  wiz   XML_SetStartElementHandler(g_parser, accumulate_attribute);
    602  1.1  wiz   XML_SetUserData(g_parser, &storage);
    603  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)sizeof(text) - 1, XML_TRUE)
    604  1.1  wiz       == XML_STATUS_ERROR)
    605  1.1  wiz     xml_failure(g_parser);
    606  1.1  wiz   CharData_CheckXMLChars(&storage, expected);
    607  1.1  wiz }
    608  1.1  wiz END_TEST
    609  1.1  wiz 
    610  1.1  wiz START_TEST(test_ns_utf16_element_leafname) {
    611  1.1  wiz   const char text[] =
    612  1.1  wiz       /* <n:{KHO KHWAI} xmlns:n='URI'/>
    613  1.1  wiz        * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
    614  1.1  wiz        */
    615  1.1  wiz       "\0<\0n\0:\x0e\x04\0 \0x\0m\0l\0n\0s\0:\0n\0=\0'\0U\0R\0I\0'\0/\0>";
    616  1.1  wiz #ifdef XML_UNICODE
    617  1.1  wiz   const XML_Char *expected = XCS("URI \x0e04");
    618  1.1  wiz #else
    619  1.1  wiz   const XML_Char *expected = XCS("URI \xe0\xb8\x84");
    620  1.1  wiz #endif
    621  1.1  wiz   CharData storage;
    622  1.1  wiz 
    623  1.1  wiz   CharData_Init(&storage);
    624  1.1  wiz   XML_SetStartElementHandler(g_parser, start_element_event_handler);
    625  1.1  wiz   XML_SetUserData(g_parser, &storage);
    626  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)sizeof(text) - 1, XML_TRUE)
    627  1.1  wiz       == XML_STATUS_ERROR)
    628  1.1  wiz     xml_failure(g_parser);
    629  1.1  wiz   CharData_CheckXMLChars(&storage, expected);
    630  1.1  wiz }
    631  1.1  wiz END_TEST
    632  1.1  wiz 
    633  1.1  wiz START_TEST(test_ns_utf16_doctype) {
    634  1.1  wiz   const char text[] =
    635  1.1  wiz       /* <!DOCTYPE foo:{KHO KHWAI} [ <!ENTITY bar 'baz'> ]>\n
    636  1.1  wiz        * where {KHO KHWAI} = U+0E04 = 0xe0 0xb8 0x84 in UTF-8
    637  1.1  wiz        */
    638  1.1  wiz       "\0<\0!\0D\0O\0C\0T\0Y\0P\0E\0 \0f\0o\0o\0:\x0e\x04\0 "
    639  1.1  wiz       "\0[\0 \0<\0!\0E\0N\0T\0I\0T\0Y\0 \0b\0a\0r\0 \0'\0b\0a\0z\0'\0>\0 "
    640  1.1  wiz       "\0]\0>\0\n"
    641  1.1  wiz       /* <foo:{KHO KHWAI} xmlns:foo='URI'>&bar;</foo:{KHO KHWAI}> */
    642  1.1  wiz       "\0<\0f\0o\0o\0:\x0e\x04\0 "
    643  1.1  wiz       "\0x\0m\0l\0n\0s\0:\0f\0o\0o\0=\0'\0U\0R\0I\0'\0>"
    644  1.1  wiz       "\0&\0b\0a\0r\0;"
    645  1.1  wiz       "\0<\0/\0f\0o\0o\0:\x0e\x04\0>";
    646  1.1  wiz #ifdef XML_UNICODE
    647  1.1  wiz   const XML_Char *expected = XCS("URI \x0e04");
    648  1.1  wiz #else
    649  1.1  wiz   const XML_Char *expected = XCS("URI \xe0\xb8\x84");
    650  1.1  wiz #endif
    651  1.1  wiz   CharData storage;
    652  1.1  wiz 
    653  1.1  wiz   CharData_Init(&storage);
    654  1.1  wiz   XML_SetUserData(g_parser, &storage);
    655  1.1  wiz   XML_SetStartElementHandler(g_parser, start_element_event_handler);
    656  1.1  wiz   XML_SetUnknownEncodingHandler(g_parser, MiscEncodingHandler, NULL);
    657  1.1  wiz   if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)sizeof(text) - 1, XML_TRUE)
    658  1.1  wiz       == XML_STATUS_ERROR)
    659  1.1  wiz     xml_failure(g_parser);
    660  1.1  wiz   CharData_CheckXMLChars(&storage, expected);
    661  1.1  wiz }
    662  1.1  wiz END_TEST
    663  1.1  wiz 
    664  1.1  wiz START_TEST(test_ns_invalid_doctype) {
    665  1.1  wiz   const char *text = "<!DOCTYPE foo:!bad [ <!ENTITY bar 'baz' ]>\n"
    666  1.1  wiz                      "<foo:!bad>&bar;</foo:!bad>";
    667  1.1  wiz 
    668  1.1  wiz   expect_failure(text, XML_ERROR_INVALID_TOKEN,
    669  1.1  wiz                  "Invalid character in document local name not faulted");
    670  1.1  wiz }
    671  1.1  wiz END_TEST
    672  1.1  wiz 
    673  1.1  wiz START_TEST(test_ns_double_colon_doctype) {
    674  1.1  wiz   const char *text = "<!DOCTYPE foo:a:doc [ <!ENTITY bar 'baz' ]>\n"
    675  1.1  wiz                      "<foo:a:doc>&bar;</foo:a:doc>";
    676  1.1  wiz 
    677  1.1  wiz   expect_failure(text, XML_ERROR_SYNTAX,
    678  1.1  wiz                  "Double colon in document name not faulted");
    679  1.1  wiz }
    680  1.1  wiz END_TEST
    681  1.1  wiz 
    682  1.1  wiz START_TEST(test_ns_separator_in_uri) {
    683  1.1  wiz   struct test_case {
    684  1.1  wiz     enum XML_Status expectedStatus;
    685  1.1  wiz     const char *doc;
    686  1.1  wiz     XML_Char namesep;
    687  1.1  wiz   };
    688  1.1  wiz   struct test_case cases[] = {
    689  1.1  wiz       {XML_STATUS_OK, "<doc xmlns='one_two' />", XCS('\n')},
    690  1.1  wiz       {XML_STATUS_ERROR, "<doc xmlns='one&#x0A;two' />", XCS('\n')},
    691  1.1  wiz       {XML_STATUS_OK, "<doc xmlns='one:two' />", XCS(':')},
    692  1.1  wiz   };
    693  1.1  wiz 
    694  1.1  wiz   size_t i = 0;
    695  1.1  wiz   size_t failCount = 0;
    696  1.1  wiz   for (; i < sizeof(cases) / sizeof(cases[0]); i++) {
    697  1.1  wiz     set_subtest("%s", cases[i].doc);
    698  1.1  wiz     XML_Parser parser = XML_ParserCreateNS(NULL, cases[i].namesep);
    699  1.1  wiz     XML_SetElementHandler(parser, dummy_start_element, dummy_end_element);
    700  1.1  wiz     if (_XML_Parse_SINGLE_BYTES(parser, cases[i].doc, (int)strlen(cases[i].doc),
    701  1.1  wiz                                 /*isFinal*/ XML_TRUE)
    702  1.1  wiz         != cases[i].expectedStatus) {
    703  1.1  wiz       failCount++;
    704  1.1  wiz     }
    705  1.1  wiz     XML_ParserFree(parser);
    706  1.1  wiz   }
    707  1.1  wiz 
    708  1.1  wiz   if (failCount) {
    709  1.1  wiz     fail("Namespace separator handling is broken");
    710  1.1  wiz   }
    711  1.1  wiz }
    712  1.1  wiz END_TEST
    713  1.1  wiz 
    714  1.1  wiz void
    715  1.1  wiz make_namespace_test_case(Suite *s) {
    716  1.1  wiz   TCase *tc_namespace = tcase_create("XML namespaces");
    717  1.1  wiz 
    718  1.1  wiz   suite_add_tcase(s, tc_namespace);
    719  1.1  wiz   tcase_add_checked_fixture(tc_namespace, namespace_setup, namespace_teardown);
    720  1.1  wiz   tcase_add_test(tc_namespace, test_return_ns_triplet);
    721  1.1  wiz   tcase_add_test(tc_namespace, test_ns_parser_reset);
    722  1.1  wiz   tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
    723  1.1  wiz   tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
    724  1.1  wiz   tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
    725  1.1  wiz   tcase_add_test__ifdef_xml_dtd(tc_namespace,
    726  1.1  wiz                                 test_default_ns_from_ext_subset_and_ext_ge);
    727  1.1  wiz   tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
    728  1.1  wiz   tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
    729  1.1  wiz   tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
    730  1.1  wiz   tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
    731  1.1  wiz   tcase_add_test(tc_namespace, test_ns_unbound_prefix);
    732  1.1  wiz   tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
    733  1.1  wiz   tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
    734  1.1  wiz   tcase_add_test(tc_namespace, test_ns_duplicate_hashes);
    735  1.1  wiz   tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
    736  1.1  wiz   tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
    737  1.1  wiz   tcase_add_test(tc_namespace, test_ns_long_element);
    738  1.1  wiz   tcase_add_test(tc_namespace, test_ns_mixed_prefix_atts);
    739  1.1  wiz   tcase_add_test(tc_namespace, test_ns_extend_uri_buffer);
    740  1.1  wiz   tcase_add_test(tc_namespace, test_ns_reserved_attributes);
    741  1.1  wiz   tcase_add_test(tc_namespace, test_ns_reserved_attributes_2);
    742  1.1  wiz   tcase_add_test(tc_namespace, test_ns_extremely_long_prefix);
    743  1.1  wiz   tcase_add_test(tc_namespace, test_ns_unknown_encoding_success);
    744  1.1  wiz   tcase_add_test(tc_namespace, test_ns_double_colon);
    745  1.1  wiz   tcase_add_test(tc_namespace, test_ns_double_colon_element);
    746  1.1  wiz   tcase_add_test(tc_namespace, test_ns_bad_attr_leafname);
    747  1.1  wiz   tcase_add_test(tc_namespace, test_ns_bad_element_leafname);
    748  1.1  wiz   tcase_add_test(tc_namespace, test_ns_utf16_leafname);
    749  1.1  wiz   tcase_add_test(tc_namespace, test_ns_utf16_element_leafname);
    750  1.1  wiz   tcase_add_test__if_xml_ge(tc_namespace, test_ns_utf16_doctype);
    751  1.1  wiz   tcase_add_test(tc_namespace, test_ns_invalid_doctype);
    752  1.1  wiz   tcase_add_test(tc_namespace, test_ns_double_colon_doctype);
    753  1.1  wiz   tcase_add_test(tc_namespace, test_ns_separator_in_uri);
    754  1.1  wiz }
    755