Return to compat.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / xml |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 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: ! 23: typedef 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: ! 36: static 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: ! 49: static 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: ! 89: static 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: ! 200: static 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: ! 209: static 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: ! 233: static 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: ! 262: static 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: ! 277: static 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: ! 295: static 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: ! 311: static 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: ! 323: static 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: ! 336: static 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: ! 351: static 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: ! 362: static 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: ! 374: static 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: ! 413: static xmlSAXHandler ! 414: php_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: ! 449: PHPAPI XML_Parser ! 450: XML_ParserCreate(const XML_Char *encoding) ! 451: { ! 452: return XML_ParserCreate_MM(encoding, NULL, NULL); ! 453: } ! 454: ! 455: PHPAPI XML_Parser ! 456: XML_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: ! 464: PHPAPI XML_Parser ! 465: XML_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: ! 503: PHPAPI void ! 504: XML_SetUserData(XML_Parser parser, void *user) ! 505: { ! 506: parser->user = user; ! 507: } ! 508: ! 509: PHPAPI void * ! 510: XML_GetUserData(XML_Parser parser) ! 511: { ! 512: return parser->user; ! 513: } ! 514: ! 515: PHPAPI void ! 516: XML_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: ! 522: PHPAPI void ! 523: XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler cdata) ! 524: { ! 525: parser->h_cdata = cdata; ! 526: } ! 527: ! 528: PHPAPI void ! 529: XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler pi) ! 530: { ! 531: parser->h_pi = pi; ! 532: } ! 533: ! 534: PHPAPI void ! 535: XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler comment) ! 536: { ! 537: parser->h_comment = comment; ! 538: } ! 539: ! 540: PHPAPI void ! 541: XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler d) ! 542: { ! 543: parser->h_default = d; ! 544: } ! 545: ! 546: PHPAPI void ! 547: XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler unparsed_decl) ! 548: { ! 549: parser->h_unparsed_entity_decl = unparsed_decl; ! 550: } ! 551: ! 552: PHPAPI void ! 553: XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler notation_decl) ! 554: { ! 555: parser->h_notation_decl = notation_decl; ! 556: } ! 557: ! 558: PHPAPI void ! 559: XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler ext_entity) ! 560: { ! 561: parser->h_external_entity_ref = ext_entity; ! 562: } ! 563: ! 564: PHPAPI void ! 565: XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start_ns) ! 566: { ! 567: parser->h_start_ns = start_ns; ! 568: } ! 569: ! 570: PHPAPI void ! 571: XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end_ns) ! 572: { ! 573: parser->h_end_ns = end_ns; ! 574: } ! 575: ! 576: PHPAPI int ! 577: XML_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 ! 582: the inifite loop in libxml <= 2.6.17 which occurs when no encoding ! 583: has 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: ! 615: PHPAPI int ! 616: XML_GetErrorCode(XML_Parser parser) ! 617: { ! 618: return parser->parser->errNo; ! 619: } ! 620: ! 621: static 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: ! 727: PHPAPI const XML_Char * ! 728: XML_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: ! 736: PHPAPI int ! 737: XML_GetCurrentLineNumber(XML_Parser parser) ! 738: { ! 739: return parser->parser->input->line; ! 740: } ! 741: ! 742: PHPAPI int ! 743: XML_GetCurrentColumnNumber(XML_Parser parser) ! 744: { ! 745: return parser->parser->input->col; ! 746: } ! 747: ! 748: PHPAPI int ! 749: XML_GetCurrentByteIndex(XML_Parser parser) ! 750: { ! 751: return parser->parser->input->consumed + ! 752: (parser->parser->input->cur - parser->parser->input->base); ! 753: } ! 754: ! 755: PHPAPI int ! 756: XML_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: ! 764: PHPAPI const XML_Char *XML_ExpatVersion(void) ! 765: { ! 766: return "1.0"; ! 767: } ! 768: ! 769: PHPAPI void ! 770: XML_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: */