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