root/ext/xml/compat.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _qualify_namespace
  2. _start_element_handler
  3. _start_element_handler_ns
  4. _namespace_handler
  5. _end_element_handler
  6. _end_element_handler_ns
  7. _cdata_handler
  8. _pi_handler
  9. _unparsed_entity_decl_handler
  10. _notation_decl_handler
  11. _build_comment
  12. _comment_handler
  13. _build_entity
  14. _external_entity_ref_handler
  15. _get_entity
  16. XML_ParserCreate
  17. XML_ParserCreateNS
  18. XML_ParserCreate_MM
  19. XML_SetUserData
  20. XML_GetUserData
  21. XML_SetElementHandler
  22. XML_SetCharacterDataHandler
  23. XML_SetProcessingInstructionHandler
  24. XML_SetCommentHandler
  25. XML_SetDefaultHandler
  26. XML_SetUnparsedEntityDeclHandler
  27. XML_SetNotationDeclHandler
  28. XML_SetExternalEntityRefHandler
  29. XML_SetStartNamespaceDeclHandler
  30. XML_SetEndNamespaceDeclHandler
  31. XML_Parse
  32. XML_GetErrorCode
  33. XML_ErrorString
  34. XML_GetCurrentLineNumber
  35. XML_GetCurrentColumnNumber
  36. XML_GetCurrentByteIndex
  37. XML_GetCurrentByteCount
  38. XML_ExpatVersion
  39. XML_ParserFree

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 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_separator, 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_separator = 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_separator = 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         (const XML_Char *)"No error",
 623         (const XML_Char *)"No memory",
 624         (const XML_Char *)"Invalid document start",
 625         (const XML_Char *)"Empty document",
 626         (const XML_Char *)"Not well-formed (invalid token)",
 627         (const XML_Char *)"Invalid document end",
 628         (const XML_Char *)"Invalid hexadecimal character reference",
 629         (const XML_Char *)"Invalid decimal character reference",
 630         (const XML_Char *)"Invalid character reference",
 631         (const XML_Char *)"Invalid character",
 632         (const XML_Char *)"XML_ERR_CHARREF_AT_EOF",
 633         (const XML_Char *)"XML_ERR_CHARREF_IN_PROLOG",
 634         (const XML_Char *)"XML_ERR_CHARREF_IN_EPILOG",
 635         (const XML_Char *)"XML_ERR_CHARREF_IN_DTD",
 636         (const XML_Char *)"XML_ERR_ENTITYREF_AT_EOF",
 637         (const XML_Char *)"XML_ERR_ENTITYREF_IN_PROLOG",
 638         (const XML_Char *)"XML_ERR_ENTITYREF_IN_EPILOG",
 639         (const XML_Char *)"XML_ERR_ENTITYREF_IN_DTD",
 640         (const XML_Char *)"PEReference at end of document",
 641         (const XML_Char *)"PEReference in prolog",
 642         (const XML_Char *)"PEReference in epilog",
 643         (const XML_Char *)"PEReference: forbidden within markup decl in internal subset",
 644         (const XML_Char *)"XML_ERR_ENTITYREF_NO_NAME",
 645         (const XML_Char *)"EntityRef: expecting ';'",
 646         (const XML_Char *)"PEReference: no name",
 647         (const XML_Char *)"PEReference: expecting ';'",
 648         (const XML_Char *)"Undeclared entity error",
 649         (const XML_Char *)"Undeclared entity warning",
 650         (const XML_Char *)"Unparsed Entity",
 651         (const XML_Char *)"XML_ERR_ENTITY_IS_EXTERNAL",
 652         (const XML_Char *)"XML_ERR_ENTITY_IS_PARAMETER",
 653         (const XML_Char *)"Unknown encoding",
 654         (const XML_Char *)"Unsupported encoding",
 655         (const XML_Char *)"String not started expecting ' or \"",
 656         (const XML_Char *)"String not closed expecting \" or '",
 657         (const XML_Char *)"Namespace declaration error",
 658         (const XML_Char *)"EntityValue: \" or ' expected",
 659         (const XML_Char *)"EntityValue: \" or ' expected",
 660         (const XML_Char *)"< in attribute",
 661         (const XML_Char *)"Attribute not started",
 662         (const XML_Char *)"Attribute not finished",
 663         (const XML_Char *)"Attribute without value",
 664         (const XML_Char *)"Attribute redefined",
 665         (const XML_Char *)"SystemLiteral \" or ' expected",
 666         (const XML_Char *)"SystemLiteral \" or ' expected",
 667         /* (const XML_Char *)"XML_ERR_COMMENT_NOT_STARTED", <= eliminated on purpose */
 668         (const XML_Char *)"Comment not finished",
 669         (const XML_Char *)"Processing Instruction not started",
 670         (const XML_Char *)"Processing Instruction not finished",
 671         (const XML_Char *)"NOTATION: Name expected here",
 672         (const XML_Char *)"'>' required to close NOTATION declaration",
 673         (const XML_Char *)"'(' required to start ATTLIST enumeration",
 674         (const XML_Char *)"'(' required to start ATTLIST enumeration",
 675         (const XML_Char *)"MixedContentDecl : '|' or ')*' expected",
 676         (const XML_Char *)"XML_ERR_MIXED_NOT_FINISHED",
 677         (const XML_Char *)"ELEMENT in DTD not started",
 678         (const XML_Char *)"ELEMENT in DTD not finished",
 679         (const XML_Char *)"XML declaration not started",
 680         (const XML_Char *)"XML declaration not finished",
 681         (const XML_Char *)"XML_ERR_CONDSEC_NOT_STARTED",
 682         (const XML_Char *)"XML conditional section not closed",
 683         (const XML_Char *)"Content error in the external subset",
 684         (const XML_Char *)"DOCTYPE not finished",
 685         (const XML_Char *)"Sequence ']]>' not allowed in content",
 686         (const XML_Char *)"CDATA not finished",
 687         (const XML_Char *)"Reserved XML Name",
 688         (const XML_Char *)"Space required",
 689         (const XML_Char *)"XML_ERR_SEPARATOR_REQUIRED",
 690         (const XML_Char *)"NmToken expected in ATTLIST enumeration",
 691         (const XML_Char *)"XML_ERR_NAME_REQUIRED",
 692         (const XML_Char *)"MixedContentDecl : '#PCDATA' expected",
 693         (const XML_Char *)"SYSTEM or PUBLIC, the URI is missing",
 694         (const XML_Char *)"PUBLIC, the Public Identifier is missing",
 695         (const XML_Char *)"< required",
 696         (const XML_Char *)"> required",
 697         (const XML_Char *)"</ required",
 698         (const XML_Char *)"= required",
 699         (const XML_Char *)"Mismatched tag",
 700         (const XML_Char *)"Tag not finished",
 701         (const XML_Char *)"standalone accepts only 'yes' or 'no'",
 702         (const XML_Char *)"Invalid XML encoding name",
 703         (const XML_Char *)"Comment must not contain '--' (double-hyphen)",
 704         (const XML_Char *)"Invalid encoding",
 705         (const XML_Char *)"external parsed entities cannot be standalone",
 706         (const XML_Char *)"XML conditional section '[' expected",
 707         (const XML_Char *)"Entity value required",
 708         (const XML_Char *)"chunk is not well balanced",
 709         (const XML_Char *)"extra content at the end of well balanced chunk",
 710         (const XML_Char *)"XML_ERR_ENTITY_CHAR_ERROR",
 711         (const XML_Char *)"PEReferences forbidden in internal subset",
 712         (const XML_Char *)"Detected an entity reference loop",
 713         (const XML_Char *)"XML_ERR_ENTITY_BOUNDARY",
 714         (const XML_Char *)"Invalid URI",
 715         (const XML_Char *)"Fragment not allowed",
 716         (const XML_Char *)"XML_WAR_CATALOG_PI",
 717         (const XML_Char *)"XML_ERR_NO_DTD",
 718         (const XML_Char *)"conditional section INCLUDE or IGNORE keyword expected", /* 95 */
 719         (const XML_Char *)"Version in XML Declaration missing", /* 96 */
 720         (const XML_Char *)"XML_WAR_UNKNOWN_VERSION", /* 97 */
 721         (const XML_Char *)"XML_WAR_LANG_VALUE", /* 98 */
 722         (const XML_Char *)"XML_WAR_NS_URI", /* 99 */
 723         (const XML_Char *)"XML_WAR_NS_URI_RELATIVE", /* 100 */
 724         (const XML_Char *)"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_separator) {
 774                         xmlFree(parser->_ns_separator);
 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  */

/* [<][>][^][v][top][bottom][index][help] */