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