1/* 2 +----------------------------------------------------------------------+ 3 | PHP Version 5 | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1997-2013 The PHP Group | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 3.01 of the PHP license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | http://www.php.net/license/3_01.txt | 11 | If you did not receive a copy of the PHP license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@php.net so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 | Authors: Sterling Hughes <sterling@php.net> | 16 +----------------------------------------------------------------------+ 17 */ 18 19#include "php.h" 20#if defined(HAVE_LIBXML) && (defined(HAVE_XML) || defined(HAVE_XMLRPC)) && !defined(HAVE_LIBEXPAT) 21#include "expat_compat.h" 22 23typedef struct _php_xml_ns { 24 xmlNsPtr nsptr; 25 int ref_count; 26 void *next; 27 void *prev; 28} php_xml_ns; 29 30#ifdef LIBXML_EXPAT_COMPAT 31 32#define IS_NS_DECL(__ns) \ 33 ((__ns) != NULL && strlen(__ns) == 5 && *(__ns) == 'x' && *((__ns)+1) == 'm' && \ 34 *((__ns)+2) == 'l' && *((__ns)+3) == 'n' && *((__ns)+4) == 's') 35 36static void 37_qualify_namespace(XML_Parser parser, const xmlChar *name, const xmlChar *URI, xmlChar **qualified) 38{ 39 if (URI) { 40 /* Use libxml functions otherwise its memory deallocation is screwed up */ 41 *qualified = xmlStrdup(URI); 42 *qualified = xmlStrncat(*qualified, parser->_ns_seperator, 1); 43 *qualified = xmlStrncat(*qualified, name, xmlStrlen(name)); 44 } else { 45 *qualified = xmlStrdup(name); 46 } 47} 48 49static void 50_start_element_handler(void *user, const xmlChar *name, const xmlChar **attributes) 51{ 52 XML_Parser parser = (XML_Parser) user; 53 xmlChar *qualified_name = NULL; 54 55 if (parser->h_start_element == NULL) { 56 if (parser->h_default) { 57 int attno = 0; 58 59 qualified_name = xmlStrncatNew((xmlChar *)"<", name, xmlStrlen(name)); 60 if (attributes) { 61 while (attributes[attno] != NULL) { 62 int att_len; 63 char *att_string, *att_name, *att_value; 64 65 att_name = (char *)attributes[attno++]; 66 att_value = (char *)attributes[attno++]; 67 68 att_len = spprintf(&att_string, 0, " %s=\"%s\"", att_name, att_value); 69 70 qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len); 71 efree(att_string); 72 } 73 74 } 75 qualified_name = xmlStrncat(qualified_name, (xmlChar *)">", 1); 76 parser->h_default(parser->user, (const XML_Char *) qualified_name, xmlStrlen(qualified_name)); 77 xmlFree(qualified_name); 78 } 79 return; 80 } 81 82 qualified_name = xmlStrdup(name); 83 84 parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attributes); 85 86 xmlFree(qualified_name); 87} 88 89static void 90_start_element_handler_ns(void *user, const xmlChar *name, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, const xmlChar ** attributes) 91{ 92 XML_Parser parser = (XML_Parser) user; 93 xmlChar *qualified_name = NULL; 94 xmlChar **attrs = NULL; 95 int i; 96 int z = 0; 97 int y = 0; 98 99 if (nb_namespaces > 0 && parser->h_start_ns != NULL) { 100 for (i = 0; i < nb_namespaces; i += 1) { 101 parser->h_start_ns(parser->user, (const XML_Char *) namespaces[y], (const XML_Char *) namespaces[y+1]); 102 y += 2; 103 } 104 y = 0; 105 } 106 107 if (parser->h_start_element == NULL) { 108 if (parser->h_default) { 109 110 if (prefix) { 111 qualified_name = xmlStrncatNew((xmlChar *)"<", prefix, xmlStrlen(prefix)); 112 qualified_name = xmlStrncat(qualified_name, (xmlChar *)":", 1); 113 qualified_name = xmlStrncat(qualified_name, name, xmlStrlen(name)); 114 } else { 115 qualified_name = xmlStrncatNew((xmlChar *)"<", name, xmlStrlen(name)); 116 } 117 118 if (namespaces) { 119 int i, j; 120 for (i = 0,j = 0;j < nb_namespaces;j++) { 121 int ns_len; 122 char *ns_string, *ns_prefix, *ns_url; 123 124 ns_prefix = (char *) namespaces[i++]; 125 ns_url = (char *) namespaces[i++]; 126 127 if (ns_prefix) { 128 ns_len = spprintf(&ns_string, 0, " xmlns:%s=\"%s\"", ns_prefix, ns_url); 129 } else { 130 ns_len = spprintf(&ns_string, 0, " xmlns=\"%s\"", ns_url); 131 } 132 qualified_name = xmlStrncat(qualified_name, (xmlChar *)ns_string, ns_len); 133 134 efree(ns_string); 135 } 136 } 137 138 if (attributes) { 139 for (i = 0; i < nb_attributes; i += 1) { 140 int att_len; 141 char *att_string, *att_name, *att_value, *att_prefix, *att_valueend; 142 143 att_name = (char *) attributes[y++]; 144 att_prefix = (char *)attributes[y++]; 145 y++; 146 att_value = (char *)attributes[y++]; 147 att_valueend = (char *)attributes[y++]; 148 149 if (att_prefix) { 150 att_len = spprintf(&att_string, 0, " %s:%s=\"", att_prefix, att_name); 151 } else { 152 att_len = spprintf(&att_string, 0, " %s=\"", att_name); 153 } 154 155 qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len); 156 qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_value, att_valueend - att_value); 157 qualified_name = xmlStrncat(qualified_name, (xmlChar *)"\"", 1); 158 159 efree(att_string); 160 } 161 162 } 163 qualified_name = xmlStrncat(qualified_name, (xmlChar *)">", 1); 164 parser->h_default(parser->user, (const XML_Char *) qualified_name, xmlStrlen(qualified_name)); 165 xmlFree(qualified_name); 166 } 167 return; 168 } 169 _qualify_namespace(parser, name, URI, &qualified_name); 170 171 if (attributes != NULL) { 172 xmlChar *qualified_name_attr = NULL; 173 attrs = safe_emalloc((nb_attributes * 2) + 1, sizeof(int *), 0); 174 175 for (i = 0; i < nb_attributes; i += 1) { 176 177 if (attributes[y+1] != NULL) { 178 _qualify_namespace(parser, attributes[y] , attributes[y + 2], &qualified_name_attr); 179 } else { 180 qualified_name_attr = xmlStrdup(attributes[y]); 181 } 182 attrs[z] = qualified_name_attr; 183 attrs[z + 1] = xmlStrndup(attributes[y + 3] , (int) (attributes[y + 4] - attributes[y + 3])); 184 z += 2; 185 y += 5; 186 } 187 188 attrs[z] = NULL; 189 } 190 parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attrs); 191 if (attrs) { 192 for (i = 0; i < z; i++) { 193 xmlFree(attrs[i]); 194 } 195 efree(attrs); 196 } 197 xmlFree(qualified_name); 198} 199 200static void 201_namespace_handler(XML_Parser parser, xmlNsPtr nsptr) 202{ 203 if (nsptr != NULL) { 204 _namespace_handler(parser, nsptr->next); 205 parser->h_end_ns(parser->user, nsptr->prefix); 206 } 207} 208 209static void 210_end_element_handler(void *user, const xmlChar *name) 211{ 212 xmlChar *qualified_name; 213 XML_Parser parser = (XML_Parser) user; 214 215 if (parser->h_end_element == NULL) { 216 if (parser->h_default) { 217 char *end_element; 218 219 spprintf(&end_element, 0, "</%s>", (char *)name); 220 parser->h_default(parser->user, (const XML_Char *) end_element, strlen(end_element)); 221 efree(end_element); 222 } 223 return; 224 } 225 226 qualified_name = xmlStrdup(name); 227 228 parser->h_end_element(parser->user, (const XML_Char *) qualified_name); 229 230 xmlFree(qualified_name); 231} 232 233static void 234_end_element_handler_ns(void *user, const xmlChar *name, const xmlChar * prefix, const xmlChar *URI) 235{ 236 xmlChar *qualified_name; 237 XML_Parser parser = (XML_Parser) user; 238 239 if (parser->h_end_element == NULL) { 240 if (parser->h_default) { 241 char *end_element; 242 int end_element_len; 243 244 if (prefix) { 245 end_element_len = spprintf(&end_element, 0, "</%s:%s>", (char *) prefix, (char *)name); 246 } else { 247 end_element_len = spprintf(&end_element, 0, "</%s>", (char *)name); 248 } 249 parser->h_default(parser->user, (const XML_Char *) end_element, end_element_len); 250 efree(end_element); 251 } 252 return; 253 } 254 255 _qualify_namespace(parser, name, URI, &qualified_name); 256 257 parser->h_end_element(parser->user, (const XML_Char *) qualified_name); 258 259 xmlFree(qualified_name); 260} 261 262static void 263_cdata_handler(void *user, const xmlChar *cdata, int cdata_len) 264{ 265 XML_Parser parser = (XML_Parser) user; 266 267 if (parser->h_cdata == NULL) { 268 if (parser->h_default) { 269 parser->h_default(parser->user, (const XML_Char *) cdata, cdata_len); 270 } 271 return; 272 } 273 274 parser->h_cdata(parser->user, (const XML_Char *) cdata, cdata_len); 275} 276 277static void 278_pi_handler(void *user, const xmlChar *target, const xmlChar *data) 279{ 280 XML_Parser parser = (XML_Parser) user; 281 282 if (parser->h_pi == NULL) { 283 if (parser->h_default) { 284 char *full_pi; 285 spprintf(&full_pi, 0, "<?%s %s?>", (char *)target, (char *)data); 286 parser->h_default(parser->user, (const XML_Char *) full_pi, strlen(full_pi)); 287 efree(full_pi); 288 } 289 return; 290 } 291 292 parser->h_pi(parser->user, (const XML_Char *) target, (const XML_Char *) data); 293} 294 295static void 296_unparsed_entity_decl_handler(void *user, 297 const xmlChar *name, 298 const xmlChar *pub_id, 299 const xmlChar *sys_id, 300 const xmlChar *notation) 301{ 302 XML_Parser parser = (XML_Parser) user; 303 304 if (parser->h_unparsed_entity_decl == NULL) { 305 return; 306 } 307 308 parser->h_unparsed_entity_decl(parser->user, name, NULL, sys_id, pub_id, notation); 309} 310 311static void 312_notation_decl_handler(void *user, const xmlChar *notation, const xmlChar *pub_id, const xmlChar *sys_id) 313{ 314 XML_Parser parser = (XML_Parser) user; 315 316 if (parser->h_notation_decl == NULL) { 317 return; 318 } 319 320 parser->h_notation_decl(parser->user, notation, NULL, sys_id, pub_id); 321} 322 323static void 324_build_comment(const xmlChar *data, int data_len, xmlChar **comment, int *comment_len) 325{ 326 *comment_len = data_len + 7; 327 328 *comment = xmlMalloc(*comment_len + 1); 329 memcpy(*comment, "<!--", 4); 330 memcpy(*comment + 4, data, data_len); 331 memcpy(*comment + 4 + data_len, "-->", 3); 332 333 (*comment)[*comment_len] = '\0'; 334} 335 336static void 337_comment_handler(void *user, const xmlChar *comment) 338{ 339 XML_Parser parser = (XML_Parser) user; 340 341 if (parser->h_default) { 342 xmlChar *d_comment; 343 int d_comment_len; 344 345 _build_comment(comment, xmlStrlen(comment), &d_comment, &d_comment_len); 346 parser->h_default(parser->user, d_comment, d_comment_len); 347 xmlFree(d_comment); 348 } 349} 350 351static void 352_build_entity(const xmlChar *name, int len, xmlChar **entity, int *entity_len) 353{ 354 *entity_len = len + 2; 355 *entity = xmlMalloc(*entity_len + 1); 356 (*entity)[0] = '&'; 357 memcpy(*entity+1, name, len); 358 (*entity)[len+1] = ';'; 359 (*entity)[*entity_len] = '\0'; 360} 361 362static void 363_external_entity_ref_handler(void *user, const xmlChar *names, int type, const xmlChar *sys_id, const xmlChar *pub_id, xmlChar *content) 364{ 365 XML_Parser parser = (XML_Parser) user; 366 367 if (parser->h_external_entity_ref == NULL) { 368 return; 369 } 370 371 parser->h_external_entity_ref(parser, names, "", sys_id, pub_id); 372} 373 374static xmlEntityPtr 375_get_entity(void *user, const xmlChar *name) 376{ 377 XML_Parser parser = (XML_Parser) user; 378 xmlEntityPtr ret = NULL; 379 380 if (parser->parser->inSubset == 0) { 381 ret = xmlGetPredefinedEntity(name); 382 if (ret == NULL) 383 ret = xmlGetDocEntity(parser->parser->myDoc, name); 384 385 if (ret == NULL || (parser->parser->instate != XML_PARSER_ENTITY_VALUE && parser->parser->instate != XML_PARSER_ATTRIBUTE_VALUE)) { 386 if (ret == NULL || ret->etype == XML_INTERNAL_GENERAL_ENTITY || ret->etype == XML_INTERNAL_PARAMETER_ENTITY || ret->etype == XML_INTERNAL_PREDEFINED_ENTITY) { 387 /* Predefined entities will expand unless no cdata handler is present */ 388 if (parser->h_default && ! (ret && ret->etype == XML_INTERNAL_PREDEFINED_ENTITY && parser->h_cdata)) { 389 xmlChar *entity; 390 int len; 391 392 _build_entity(name, xmlStrlen(name), &entity, &len); 393 parser->h_default(parser->user, (const xmlChar *) entity, len); 394 xmlFree(entity); 395 } else { 396 /* expat will not expand internal entities if default handler is present otherwise 397 it will expand and pass them to cdata handler */ 398 if (parser->h_cdata && ret) { 399 parser->h_cdata(parser->user, ret->content, xmlStrlen(ret->content)); 400 } 401 } 402 } else { 403 if (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) { 404 _external_entity_ref_handler(user, ret->name, ret->etype, ret->SystemID, ret->ExternalID, NULL); 405 } 406 } 407 } 408 } 409 410 return ret; 411} 412 413static xmlSAXHandler 414php_xml_compat_handlers = { 415 NULL, /* internalSubset */ 416 NULL, /* isStandalone */ 417 NULL, /* hasInternalSubset */ 418 NULL, /* hasExternalSubset */ 419 NULL, /* resolveEntity */ 420 _get_entity, /* getEntity */ 421 NULL, /* entityDecl */ 422 _notation_decl_handler, 423 NULL, /* attributeDecl */ 424 NULL, /* elementDecl */ 425 _unparsed_entity_decl_handler, /* unparsedEntity */ 426 NULL, /* setDocumentLocator */ 427 NULL, /* startDocument */ 428 NULL, /* endDocument */ 429 _start_element_handler, /* startElement */ 430 _end_element_handler, /* endElement */ 431 NULL, /* reference */ 432 _cdata_handler, 433 NULL, /* ignorableWhitespace */ 434 _pi_handler, 435 _comment_handler, /* comment */ 436 NULL, /* warning */ 437 NULL, /* error */ 438 NULL, /* fatalError */ 439 NULL, /* getParameterEntity */ 440 _cdata_handler, /* cdataBlock */ 441 NULL, /* externalSubset */ 442 XML_SAX2_MAGIC, 443 NULL, 444 _start_element_handler_ns, 445 _end_element_handler_ns, 446 NULL 447}; 448 449PHPAPI XML_Parser 450XML_ParserCreate(const XML_Char *encoding) 451{ 452 return XML_ParserCreate_MM(encoding, NULL, NULL); 453} 454 455PHPAPI XML_Parser 456XML_ParserCreateNS(const XML_Char *encoding, const XML_Char sep) 457{ 458 XML_Char tmp[2]; 459 tmp[0] = sep; 460 tmp[1] = '\0'; 461 return XML_ParserCreate_MM(encoding, NULL, tmp); 462} 463 464PHPAPI XML_Parser 465XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, const XML_Char *sep) 466{ 467 XML_Parser parser; 468 469 parser = (XML_Parser) emalloc(sizeof(struct _XML_Parser)); 470 memset(parser, 0, sizeof(struct _XML_Parser)); 471 parser->use_namespace = 0; 472 parser->_ns_seperator = NULL; 473 474 parser->parser = xmlCreatePushParserCtxt((xmlSAXHandlerPtr) &php_xml_compat_handlers, (void *) parser, NULL, 0, NULL); 475 if (parser->parser == NULL) { 476 efree(parser); 477 return NULL; 478 } 479#if LIBXML_VERSION <= 20617 480 /* for older versions of libxml2, allow correct detection of 481 * charset in documents with a BOM: */ 482 parser->parser->charset = XML_CHAR_ENCODING_NONE; 483#endif 484 485#if LIBXML_VERSION >= 20703 486 xmlCtxtUseOptions(parser->parser, XML_PARSE_OLDSAX); 487#endif 488 489 parser->parser->replaceEntities = 1; 490 parser->parser->wellFormed = 0; 491 if (sep != NULL) { 492 parser->use_namespace = 1; 493 parser->parser->sax2 = 1; 494 parser->_ns_seperator = xmlStrdup(sep); 495 } else { 496 /* Reset flag as XML_SAX2_MAGIC is needed for xmlCreatePushParserCtxt 497 so must be set in the handlers */ 498 parser->parser->sax->initialized = 1; 499 } 500 return parser; 501} 502 503PHPAPI void 504XML_SetUserData(XML_Parser parser, void *user) 505{ 506 parser->user = user; 507} 508 509PHPAPI void * 510XML_GetUserData(XML_Parser parser) 511{ 512 return parser->user; 513} 514 515PHPAPI void 516XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end) 517{ 518 parser->h_start_element = start; 519 parser->h_end_element = end; 520} 521 522PHPAPI void 523XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler cdata) 524{ 525 parser->h_cdata = cdata; 526} 527 528PHPAPI void 529XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler pi) 530{ 531 parser->h_pi = pi; 532} 533 534PHPAPI void 535XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler comment) 536{ 537 parser->h_comment = comment; 538} 539 540PHPAPI void 541XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler d) 542{ 543 parser->h_default = d; 544} 545 546PHPAPI void 547XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler unparsed_decl) 548{ 549 parser->h_unparsed_entity_decl = unparsed_decl; 550} 551 552PHPAPI void 553XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler notation_decl) 554{ 555 parser->h_notation_decl = notation_decl; 556} 557 558PHPAPI void 559XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler ext_entity) 560{ 561 parser->h_external_entity_ref = ext_entity; 562} 563 564PHPAPI void 565XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start_ns) 566{ 567 parser->h_start_ns = start_ns; 568} 569 570PHPAPI void 571XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end_ns) 572{ 573 parser->h_end_ns = end_ns; 574} 575 576PHPAPI int 577XML_Parse(XML_Parser parser, const XML_Char *data, int data_len, int is_final) 578{ 579 int error; 580 581/* The following is a hack to keep BC with PHP 4 while avoiding 582the inifite loop in libxml <= 2.6.17 which occurs when no encoding 583has been defined and none can be detected */ 584#if LIBXML_VERSION <= 20617 585 if (parser->parser->charset == XML_CHAR_ENCODING_NONE) { 586 if (data_len >= 4 || (parser->parser->input->buf->buffer->use + data_len >= 4)) { 587 xmlChar start[4]; 588 int char_count; 589 590 char_count = parser->parser->input->buf->buffer->use; 591 if (char_count > 4) { 592 char_count = 4; 593 } 594 595 memcpy(start, parser->parser->input->buf->buffer->content, (size_t)char_count); 596 memcpy(start + char_count, data, (size_t)(4 - char_count)); 597 598 if (xmlDetectCharEncoding(&start[0], 4) == XML_CHAR_ENCODING_NONE) { 599 parser->parser->charset = XML_CHAR_ENCODING_UTF8; 600 } 601 } 602 } 603#endif 604 605 error = xmlParseChunk(parser->parser, data, data_len, is_final); 606 if (!error) { 607 return 1; 608 } else if (parser->parser->lastError.level > XML_ERR_WARNING ){ 609 return 0; 610 } else { 611 return 1; 612 } 613} 614 615PHPAPI int 616XML_GetErrorCode(XML_Parser parser) 617{ 618 return parser->parser->errNo; 619} 620 621static const XML_Char *const error_mapping[] = { 622 "No error", 623 "No memory", 624 "Invalid document start", 625 "Empty document", 626 "Not well-formed (invalid token)", 627 "Invalid document end", 628 "Invalid hexadecimal character reference", 629 "Invalid decimal character reference", 630 "Invalid character reference", 631 "Invalid character", 632 "XML_ERR_CHARREF_AT_EOF", 633 "XML_ERR_CHARREF_IN_PROLOG", 634 "XML_ERR_CHARREF_IN_EPILOG", 635 "XML_ERR_CHARREF_IN_DTD", 636 "XML_ERR_ENTITYREF_AT_EOF", 637 "XML_ERR_ENTITYREF_IN_PROLOG", 638 "XML_ERR_ENTITYREF_IN_EPILOG", 639 "XML_ERR_ENTITYREF_IN_DTD", 640 "PEReference at end of document", 641 "PEReference in prolog", 642 "PEReference in epilog", 643 "PEReference: forbidden within markup decl in internal subset", 644 "XML_ERR_ENTITYREF_NO_NAME", 645 "EntityRef: expecting ';'", 646 "PEReference: no name", 647 "PEReference: expecting ';'", 648 "Undeclared entity error", 649 "Undeclared entity warning", 650 "Unparsed Entity", 651 "XML_ERR_ENTITY_IS_EXTERNAL", 652 "XML_ERR_ENTITY_IS_PARAMETER", 653 "Unknown encoding", 654 "Unsupported encoding", 655 "String not started expecting ' or \"", 656 "String not closed expecting \" or '", 657 "Namespace declaration error", 658 "EntityValue: \" or ' expected", 659 "EntityValue: \" or ' expected", 660 "< in attribute", 661 "Attribute not started", 662 "Attribute not finished", 663 "Attribute without value", 664 "Attribute redefined", 665 "SystemLiteral \" or ' expected", 666 "SystemLiteral \" or ' expected", 667 /* "XML_ERR_COMMENT_NOT_STARTED", <= eliminated on purpose */ 668 "Comment not finished", 669 "Processing Instruction not started", 670 "Processing Instruction not finished", 671 "NOTATION: Name expected here", 672 "'>' required to close NOTATION declaration", 673 "'(' required to start ATTLIST enumeration", 674 "'(' required to start ATTLIST enumeration", 675 "MixedContentDecl : '|' or ')*' expected", 676 "XML_ERR_MIXED_NOT_FINISHED", 677 "ELEMENT in DTD not started", 678 "ELEMENT in DTD not finished", 679 "XML declaration not started", 680 "XML declaration not finished", 681 "XML_ERR_CONDSEC_NOT_STARTED", 682 "XML conditional section not closed", 683 "Content error in the external subset", 684 "DOCTYPE not finished", 685 "Sequence ']]>' not allowed in content", 686 "CDATA not finished", 687 "Reserved XML Name", 688 "Space required", 689 "XML_ERR_SEPARATOR_REQUIRED", 690 "NmToken expected in ATTLIST enumeration", 691 "XML_ERR_NAME_REQUIRED", 692 "MixedContentDecl : '#PCDATA' expected", 693 "SYSTEM or PUBLIC, the URI is missing", 694 "PUBLIC, the Public Identifier is missing", 695 "< required", 696 "> required", 697 "</ required", 698 "= required", 699 "Mismatched tag", 700 "Tag not finished", 701 "standalone accepts only 'yes' or 'no'", 702 "Invalid XML encoding name", 703 "Comment must not contain '--' (double-hyphen)", 704 "Invalid encoding", 705 "external parsed entities cannot be standalone", 706 "XML conditional section '[' expected", 707 "Entity value required", 708 "chunk is not well balanced", 709 "extra content at the end of well balanced chunk", 710 "XML_ERR_ENTITY_CHAR_ERROR", 711 "PEReferences forbidden in internal subset", 712 "Detected an entity reference loop", 713 "XML_ERR_ENTITY_BOUNDARY", 714 "Invalid URI", 715 "Fragment not allowed", 716 "XML_WAR_CATALOG_PI", 717 "XML_ERR_NO_DTD", 718 "conditional section INCLUDE or IGNORE keyword expected", /* 95 */ 719 "Version in XML Declaration missing", /* 96 */ 720 "XML_WAR_UNKNOWN_VERSION", /* 97 */ 721 "XML_WAR_LANG_VALUE", /* 98 */ 722 "XML_WAR_NS_URI", /* 99 */ 723 "XML_WAR_NS_URI_RELATIVE", /* 100 */ 724 "Missing encoding in text declaration" /* 101 */ 725}; 726 727PHPAPI const XML_Char * 728XML_ErrorString(int code) 729{ 730 if (code < 0 || code >= (int)(sizeof(error_mapping) / sizeof(error_mapping[0]))) { 731 return "Unknown"; 732 } 733 return error_mapping[code]; 734} 735 736PHPAPI int 737XML_GetCurrentLineNumber(XML_Parser parser) 738{ 739 return parser->parser->input->line; 740} 741 742PHPAPI int 743XML_GetCurrentColumnNumber(XML_Parser parser) 744{ 745 return parser->parser->input->col; 746} 747 748PHPAPI int 749XML_GetCurrentByteIndex(XML_Parser parser) 750{ 751 return parser->parser->input->consumed + 752 (parser->parser->input->cur - parser->parser->input->base); 753} 754 755PHPAPI int 756XML_GetCurrentByteCount(XML_Parser parser) 757{ 758 /* WARNING: this is identical to ByteIndex; it should probably 759 * be different */ 760 return parser->parser->input->consumed + 761 (parser->parser->input->cur - parser->parser->input->base); 762} 763 764PHPAPI const XML_Char *XML_ExpatVersion(void) 765{ 766 return "1.0"; 767} 768 769PHPAPI void 770XML_ParserFree(XML_Parser parser) 771{ 772 if (parser->use_namespace) { 773 if (parser->_ns_seperator) { 774 xmlFree(parser->_ns_seperator); 775 } 776 } 777 if (parser->parser->myDoc) { 778 xmlFreeDoc(parser->parser->myDoc); 779 parser->parser->myDoc = NULL; 780 } 781 xmlFreeParserCtxt(parser->parser); 782 efree(parser); 783} 784 785#endif /* LIBXML_EXPAT_COMPAT */ 786#endif 787 788/** 789 * Local Variables: 790 * tab-width: 4 791 * c-basic-offset: 4 792 * indent-tabs-mode: t 793 * End: 794 * vim600: fdm=marker 795 * vim: ts=4 noet sw=4 796 */ 797