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. _end_element_handler
  5. _end_element_handler_ns
  6. _cdata_handler
  7. _pi_handler
  8. _unparsed_entity_decl_handler
  9. _notation_decl_handler
  10. _build_comment
  11. _comment_handler
  12. _build_entity
  13. _external_entity_ref_handler
  14. _get_entity
  15. XML_ParserCreate
  16. XML_ParserCreateNS
  17. XML_ParserCreate_MM
  18. XML_SetUserData
  19. XML_GetUserData
  20. XML_SetElementHandler
  21. XML_SetCharacterDataHandler
  22. XML_SetProcessingInstructionHandler
  23. XML_SetCommentHandler
  24. XML_SetDefaultHandler
  25. XML_SetUnparsedEntityDeclHandler
  26. XML_SetNotationDeclHandler
  27. XML_SetExternalEntityRefHandler
  28. XML_SetStartNamespaceDeclHandler
  29. XML_SetEndNamespaceDeclHandler
  30. XML_Parse
  31. XML_GetErrorCode
  32. XML_ErrorString
  33. XML_GetCurrentLineNumber
  34. XML_GetCurrentColumnNumber
  35. XML_GetCurrentByteIndex
  36. XML_GetCurrentByteCount
  37. XML_ExpatVersion
  38. XML_ParserFree

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   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 _end_element_handler(void *user, const xmlChar *name)
 202 {
 203         xmlChar    *qualified_name;
 204         XML_Parser  parser = (XML_Parser) user;
 205 
 206         if (parser->h_end_element == NULL) {
 207                 if (parser->h_default) {
 208                         char *end_element;
 209 
 210                         spprintf(&end_element, 0, "</%s>", (char *)name);
 211                         parser->h_default(parser->user, (const XML_Char *) end_element, strlen(end_element));
 212                         efree(end_element);
 213                 }
 214                 return;
 215         }
 216 
 217         qualified_name = xmlStrdup(name);
 218 
 219         parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
 220 
 221         xmlFree(qualified_name);
 222 }
 223 
 224 static void
 225 _end_element_handler_ns(void *user, const xmlChar *name, const xmlChar * prefix, const xmlChar *URI)
 226 {
 227         xmlChar    *qualified_name;
 228         XML_Parser  parser = (XML_Parser) user;
 229 
 230         if (parser->h_end_element == NULL) {
 231                 if (parser->h_default) {
 232                         char *end_element;
 233                         int end_element_len;
 234 
 235                         if (prefix) {
 236                                 end_element_len = spprintf(&end_element, 0, "</%s:%s>", (char *) prefix, (char *)name);
 237                         } else {
 238                                 end_element_len = spprintf(&end_element, 0, "</%s>", (char *)name);
 239                         }
 240                         parser->h_default(parser->user, (const XML_Char *) end_element, end_element_len);
 241                         efree(end_element);
 242                 }
 243                 return;
 244         }
 245 
 246         _qualify_namespace(parser, name, URI,  &qualified_name);
 247 
 248         parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
 249 
 250         xmlFree(qualified_name);
 251 }
 252 
 253 static void
 254 _cdata_handler(void *user, const xmlChar *cdata, int cdata_len)
 255 {
 256         XML_Parser parser = (XML_Parser) user;
 257 
 258         if (parser->h_cdata == NULL) {
 259                 if (parser->h_default) {
 260                         parser->h_default(parser->user, (const XML_Char *) cdata, cdata_len);
 261                 }
 262                 return;
 263         }
 264 
 265         parser->h_cdata(parser->user, (const XML_Char *) cdata, cdata_len);
 266 }
 267 
 268 static void
 269 _pi_handler(void *user, const xmlChar *target, const xmlChar *data)
 270 {
 271         XML_Parser parser = (XML_Parser) user;
 272 
 273         if (parser->h_pi == NULL) {
 274                 if (parser->h_default) {
 275                         char    *full_pi;
 276                         spprintf(&full_pi, 0, "<?%s %s?>", (char *)target, (char *)data);
 277                         parser->h_default(parser->user, (const XML_Char *) full_pi, strlen(full_pi));
 278                         efree(full_pi);
 279                 }
 280                 return;
 281         }
 282 
 283         parser->h_pi(parser->user, (const XML_Char *) target, (const XML_Char *) data);
 284 }
 285 
 286 static void
 287 _unparsed_entity_decl_handler(void *user,
 288                               const xmlChar *name,
 289                                                           const xmlChar *pub_id,
 290                                                           const xmlChar *sys_id,
 291                                                           const xmlChar *notation)
 292 {
 293         XML_Parser parser = (XML_Parser) user;
 294 
 295         if (parser->h_unparsed_entity_decl == NULL) {
 296                 return;
 297         }
 298 
 299         parser->h_unparsed_entity_decl(parser->user, name, NULL, sys_id, pub_id, notation);
 300 }
 301 
 302 static void
 303 _notation_decl_handler(void *user, const xmlChar *notation, const xmlChar *pub_id, const xmlChar *sys_id)
 304 {
 305         XML_Parser parser = (XML_Parser) user;
 306 
 307         if (parser->h_notation_decl == NULL) {
 308                 return;
 309         }
 310 
 311         parser->h_notation_decl(parser->user, notation, NULL, sys_id, pub_id);
 312 }
 313 
 314 static void
 315 _build_comment(const xmlChar *data, int data_len, xmlChar **comment, int *comment_len)
 316 {
 317         *comment_len = data_len + 7;
 318 
 319         *comment = xmlMalloc(*comment_len + 1);
 320         memcpy(*comment, "<!--", 4);
 321         memcpy(*comment + 4, data, data_len);
 322         memcpy(*comment + 4 + data_len, "-->", 3);
 323 
 324         (*comment)[*comment_len] = '\0';
 325 }
 326 
 327 static void
 328 _comment_handler(void *user, const xmlChar *comment)
 329 {
 330         XML_Parser parser = (XML_Parser) user;
 331 
 332         if (parser->h_default) {
 333                 xmlChar *d_comment;
 334                 int      d_comment_len;
 335 
 336                 _build_comment(comment, xmlStrlen(comment), &d_comment, &d_comment_len);
 337                 parser->h_default(parser->user, d_comment, d_comment_len);
 338                 xmlFree(d_comment);
 339         }
 340 }
 341 
 342 static void
 343 _build_entity(const xmlChar *name, int len, xmlChar **entity, int *entity_len)
 344 {
 345         *entity_len = len + 2;
 346         *entity = xmlMalloc(*entity_len + 1);
 347         (*entity)[0] = '&';
 348         memcpy(*entity+1, name, len);
 349         (*entity)[len+1] = ';';
 350         (*entity)[*entity_len] = '\0';
 351 }
 352 
 353 static void
 354 _external_entity_ref_handler(void *user, const xmlChar *names, int type, const xmlChar *sys_id, const xmlChar *pub_id, xmlChar *content)
 355 {
 356         XML_Parser parser = (XML_Parser) user;
 357 
 358         if (parser->h_external_entity_ref == NULL) {
 359                 return;
 360         }
 361 
 362         parser->h_external_entity_ref(parser, names, (XML_Char *) "", sys_id, pub_id);
 363 }
 364 
 365 static xmlEntityPtr
 366 _get_entity(void *user, const xmlChar *name)
 367 {
 368         XML_Parser parser = (XML_Parser) user;
 369         xmlEntityPtr ret = NULL;
 370 
 371         if (parser->parser->inSubset == 0) {
 372                 ret = xmlGetPredefinedEntity(name);
 373                 if (ret == NULL)
 374                         ret = xmlGetDocEntity(parser->parser->myDoc, name);
 375 
 376                 if (ret == NULL || (parser->parser->instate != XML_PARSER_ENTITY_VALUE && parser->parser->instate != XML_PARSER_ATTRIBUTE_VALUE)) {
 377                         if (ret == NULL || ret->etype == XML_INTERNAL_GENERAL_ENTITY || ret->etype == XML_INTERNAL_PARAMETER_ENTITY || ret->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
 378                                 /* Predefined entities will expand unless no cdata handler is present */
 379                                 if (parser->h_default && ! (ret && ret->etype == XML_INTERNAL_PREDEFINED_ENTITY && parser->h_cdata)) {
 380                                         xmlChar *entity;
 381                                         int      len;
 382 
 383                                         _build_entity(name, xmlStrlen(name), &entity, &len);
 384                                         parser->h_default(parser->user, (const xmlChar *) entity, len);
 385                                         xmlFree(entity);
 386                                 } else {
 387                                         /* expat will not expand internal entities if default handler is present otherwise
 388                                         it will expand and pass them to cdata handler */
 389                                         if (parser->h_cdata && ret) {
 390                                                 parser->h_cdata(parser->user, ret->content, xmlStrlen(ret->content));
 391                                         }
 392                                 }
 393                         } else {
 394                                 if (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
 395                                         _external_entity_ref_handler(user, ret->name, ret->etype, ret->SystemID, ret->ExternalID, NULL);
 396                                 }
 397                         }
 398                 }
 399         }
 400 
 401         return ret;
 402 }
 403 
 404 static xmlSAXHandler
 405 php_xml_compat_handlers = {
 406         NULL, /* internalSubset */
 407         NULL, /* isStandalone */
 408         NULL, /* hasInternalSubset */
 409         NULL, /* hasExternalSubset */
 410         NULL, /* resolveEntity */
 411         _get_entity, /* getEntity */
 412         NULL, /* entityDecl */
 413         _notation_decl_handler,
 414         NULL, /* attributeDecl */
 415         NULL, /* elementDecl */
 416         _unparsed_entity_decl_handler, /* unparsedEntity */
 417         NULL, /* setDocumentLocator */
 418         NULL, /* startDocument */
 419         NULL, /* endDocument */
 420         _start_element_handler, /* startElement */
 421         _end_element_handler, /* endElement */
 422         NULL, /* reference */
 423         _cdata_handler,
 424         NULL, /* ignorableWhitespace */
 425         _pi_handler,
 426         _comment_handler, /* comment */
 427         NULL, /* warning */
 428         NULL, /* error */
 429         NULL,  /* fatalError */
 430         NULL,  /* getParameterEntity */
 431         _cdata_handler, /* cdataBlock */
 432         NULL, /* externalSubset */
 433         XML_SAX2_MAGIC,
 434         NULL,
 435         _start_element_handler_ns,
 436         _end_element_handler_ns,
 437         NULL
 438 };
 439 
 440 PHP_XML_API XML_Parser
 441 XML_ParserCreate(const XML_Char *encoding)
 442 {
 443         return XML_ParserCreate_MM(encoding, NULL, NULL);
 444 }
 445 
 446 PHP_XML_API XML_Parser
 447 XML_ParserCreateNS(const XML_Char *encoding, const XML_Char sep)
 448 {
 449         XML_Char tmp[2];
 450         tmp[0] = sep;
 451         tmp[1] = '\0';
 452         return XML_ParserCreate_MM(encoding, NULL, tmp);
 453 }
 454 
 455 PHP_XML_API XML_Parser
 456 XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, const XML_Char *sep)
 457 {
 458         XML_Parser parser;
 459 
 460         parser = (XML_Parser) emalloc(sizeof(struct _XML_Parser));
 461         memset(parser, 0, sizeof(struct _XML_Parser));
 462         parser->use_namespace = 0;
 463         parser->_ns_separator = NULL;
 464 
 465         parser->parser = xmlCreatePushParserCtxt((xmlSAXHandlerPtr) &php_xml_compat_handlers, (void *) parser, NULL, 0, NULL);
 466         if (parser->parser == NULL) {
 467                 efree(parser);
 468                 return NULL;
 469         }
 470 #if LIBXML_VERSION <= 20617
 471         /* for older versions of libxml2, allow correct detection of
 472          * charset in documents with a BOM: */
 473         parser->parser->charset = XML_CHAR_ENCODING_NONE;
 474 #endif
 475 
 476 #if LIBXML_VERSION >= 20703
 477         xmlCtxtUseOptions(parser->parser, XML_PARSE_OLDSAX);
 478 #endif
 479 
 480         parser->parser->replaceEntities = 1;
 481         parser->parser->wellFormed = 0;
 482         if (sep != NULL) {
 483                 parser->use_namespace = 1;
 484                 parser->parser->sax2 = 1;
 485                 parser->_ns_separator = xmlStrdup(sep);
 486         } else {
 487                 /* Reset flag as XML_SAX2_MAGIC is needed for xmlCreatePushParserCtxt
 488                 so must be set in the handlers */
 489                 parser->parser->sax->initialized = 1;
 490         }
 491         return parser;
 492 }
 493 
 494 PHP_XML_API void
 495 XML_SetUserData(XML_Parser parser, void *user)
 496 {
 497         parser->user = user;
 498 }
 499 
 500 PHP_XML_API void *
 501 XML_GetUserData(XML_Parser parser)
 502 {
 503         return parser->user;
 504 }
 505 
 506 PHP_XML_API void
 507 XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end)
 508 {
 509         parser->h_start_element = start;
 510         parser->h_end_element = end;
 511 }
 512 
 513 PHP_XML_API void
 514 XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler cdata)
 515 {
 516         parser->h_cdata = cdata;
 517 }
 518 
 519 PHP_XML_API void
 520 XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler pi)
 521 {
 522         parser->h_pi = pi;
 523 }
 524 
 525 PHP_XML_API void
 526 XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler comment)
 527 {
 528         parser->h_comment = comment;
 529 }
 530 
 531 PHP_XML_API void
 532 XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler d)
 533 {
 534         parser->h_default = d;
 535 }
 536 
 537 PHP_XML_API void
 538 XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler unparsed_decl)
 539 {
 540         parser->h_unparsed_entity_decl = unparsed_decl;
 541 }
 542 
 543 PHP_XML_API void
 544 XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler notation_decl)
 545 {
 546         parser->h_notation_decl = notation_decl;
 547 }
 548 
 549 PHP_XML_API void
 550 XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler ext_entity)
 551 {
 552         parser->h_external_entity_ref = ext_entity;
 553 }
 554 
 555 PHP_XML_API void
 556 XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start_ns)
 557 {
 558         parser->h_start_ns = start_ns;
 559 }
 560 
 561 PHP_XML_API void
 562 XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end_ns)
 563 {
 564         parser->h_end_ns = end_ns;
 565 }
 566 
 567 PHP_XML_API int
 568 XML_Parse(XML_Parser parser, const XML_Char *data, int data_len, int is_final)
 569 {
 570         int error;
 571 
 572 /* The following is a hack to keep BC with PHP 4 while avoiding
 573 the inifite loop in libxml <= 2.6.17 which occurs when no encoding
 574 has been defined and none can be detected */
 575 #if LIBXML_VERSION <= 20617
 576         if (parser->parser->charset == XML_CHAR_ENCODING_NONE) {
 577                 if (data_len >= 4 || (parser->parser->input->buf->buffer->use + data_len >= 4)) {
 578                         xmlChar start[4];
 579                         int char_count;
 580 
 581                         char_count = parser->parser->input->buf->buffer->use;
 582                         if (char_count > 4) {
 583                                 char_count = 4;
 584                         }
 585 
 586                         memcpy(start, parser->parser->input->buf->buffer->content, (size_t)char_count);
 587                         memcpy(start + char_count, data, (size_t)(4 - char_count));
 588 
 589                         if (xmlDetectCharEncoding(&start[0], 4) == XML_CHAR_ENCODING_NONE) {
 590                                 parser->parser->charset = XML_CHAR_ENCODING_UTF8;
 591                         }
 592                 }
 593         }
 594 #endif
 595 
 596         error = xmlParseChunk(parser->parser, (char *) data, data_len, is_final);
 597         if (!error) {
 598                 return 1;
 599         } else if (parser->parser->lastError.level > XML_ERR_WARNING ){
 600                 return 0;
 601         } else {
 602                 return 1;
 603         }
 604 }
 605 
 606 PHP_XML_API int
 607 XML_GetErrorCode(XML_Parser parser)
 608 {
 609         return parser->parser->errNo;
 610 }
 611 
 612 static const XML_Char *const error_mapping[] = {
 613         (const XML_Char *)"No error",
 614         (const XML_Char *)"No memory",
 615         (const XML_Char *)"Invalid document start",
 616         (const XML_Char *)"Empty document",
 617         (const XML_Char *)"Not well-formed (invalid token)",
 618         (const XML_Char *)"Invalid document end",
 619         (const XML_Char *)"Invalid hexadecimal character reference",
 620         (const XML_Char *)"Invalid decimal character reference",
 621         (const XML_Char *)"Invalid character reference",
 622         (const XML_Char *)"Invalid character",
 623         (const XML_Char *)"XML_ERR_CHARREF_AT_EOF",
 624         (const XML_Char *)"XML_ERR_CHARREF_IN_PROLOG",
 625         (const XML_Char *)"XML_ERR_CHARREF_IN_EPILOG",
 626         (const XML_Char *)"XML_ERR_CHARREF_IN_DTD",
 627         (const XML_Char *)"XML_ERR_ENTITYREF_AT_EOF",
 628         (const XML_Char *)"XML_ERR_ENTITYREF_IN_PROLOG",
 629         (const XML_Char *)"XML_ERR_ENTITYREF_IN_EPILOG",
 630         (const XML_Char *)"XML_ERR_ENTITYREF_IN_DTD",
 631         (const XML_Char *)"PEReference at end of document",
 632         (const XML_Char *)"PEReference in prolog",
 633         (const XML_Char *)"PEReference in epilog",
 634         (const XML_Char *)"PEReference: forbidden within markup decl in internal subset",
 635         (const XML_Char *)"XML_ERR_ENTITYREF_NO_NAME",
 636         (const XML_Char *)"EntityRef: expecting ';'",
 637         (const XML_Char *)"PEReference: no name",
 638         (const XML_Char *)"PEReference: expecting ';'",
 639         (const XML_Char *)"Undeclared entity error",
 640         (const XML_Char *)"Undeclared entity warning",
 641         (const XML_Char *)"Unparsed Entity",
 642         (const XML_Char *)"XML_ERR_ENTITY_IS_EXTERNAL",
 643         (const XML_Char *)"XML_ERR_ENTITY_IS_PARAMETER",
 644         (const XML_Char *)"Unknown encoding",
 645         (const XML_Char *)"Unsupported encoding",
 646         (const XML_Char *)"String not started expecting ' or \"",
 647         (const XML_Char *)"String not closed expecting \" or '",
 648         (const XML_Char *)"Namespace declaration error",
 649         (const XML_Char *)"EntityValue: \" or ' expected",
 650         (const XML_Char *)"EntityValue: \" or ' expected",
 651         (const XML_Char *)"< in attribute",
 652         (const XML_Char *)"Attribute not started",
 653         (const XML_Char *)"Attribute not finished",
 654         (const XML_Char *)"Attribute without value",
 655         (const XML_Char *)"Attribute redefined",
 656         (const XML_Char *)"SystemLiteral \" or ' expected",
 657         (const XML_Char *)"SystemLiteral \" or ' expected",
 658         /* (const XML_Char *)"XML_ERR_COMMENT_NOT_STARTED", <= eliminated on purpose */
 659         (const XML_Char *)"Comment not finished",
 660         (const XML_Char *)"Processing Instruction not started",
 661         (const XML_Char *)"Processing Instruction not finished",
 662         (const XML_Char *)"NOTATION: Name expected here",
 663         (const XML_Char *)"'>' required to close NOTATION declaration",
 664         (const XML_Char *)"'(' required to start ATTLIST enumeration",
 665         (const XML_Char *)"'(' required to start ATTLIST enumeration",
 666         (const XML_Char *)"MixedContentDecl : '|' or ')*' expected",
 667         (const XML_Char *)"XML_ERR_MIXED_NOT_FINISHED",
 668         (const XML_Char *)"ELEMENT in DTD not started",
 669         (const XML_Char *)"ELEMENT in DTD not finished",
 670         (const XML_Char *)"XML declaration not started",
 671         (const XML_Char *)"XML declaration not finished",
 672         (const XML_Char *)"XML_ERR_CONDSEC_NOT_STARTED",
 673         (const XML_Char *)"XML conditional section not closed",
 674         (const XML_Char *)"Content error in the external subset",
 675         (const XML_Char *)"DOCTYPE not finished",
 676         (const XML_Char *)"Sequence ']]>' not allowed in content",
 677         (const XML_Char *)"CDATA not finished",
 678         (const XML_Char *)"Reserved XML Name",
 679         (const XML_Char *)"Space required",
 680         (const XML_Char *)"XML_ERR_SEPARATOR_REQUIRED",
 681         (const XML_Char *)"NmToken expected in ATTLIST enumeration",
 682         (const XML_Char *)"XML_ERR_NAME_REQUIRED",
 683         (const XML_Char *)"MixedContentDecl : '#PCDATA' expected",
 684         (const XML_Char *)"SYSTEM or PUBLIC, the URI is missing",
 685         (const XML_Char *)"PUBLIC, the Public Identifier is missing",
 686         (const XML_Char *)"< required",
 687         (const XML_Char *)"> required",
 688         (const XML_Char *)"</ required",
 689         (const XML_Char *)"= required",
 690         (const XML_Char *)"Mismatched tag",
 691         (const XML_Char *)"Tag not finished",
 692         (const XML_Char *)"standalone accepts only 'yes' or 'no'",
 693         (const XML_Char *)"Invalid XML encoding name",
 694         (const XML_Char *)"Comment must not contain '--' (double-hyphen)",
 695         (const XML_Char *)"Invalid encoding",
 696         (const XML_Char *)"external parsed entities cannot be standalone",
 697         (const XML_Char *)"XML conditional section '[' expected",
 698         (const XML_Char *)"Entity value required",
 699         (const XML_Char *)"chunk is not well balanced",
 700         (const XML_Char *)"extra content at the end of well balanced chunk",
 701         (const XML_Char *)"XML_ERR_ENTITY_CHAR_ERROR",
 702         (const XML_Char *)"PEReferences forbidden in internal subset",
 703         (const XML_Char *)"Detected an entity reference loop",
 704         (const XML_Char *)"XML_ERR_ENTITY_BOUNDARY",
 705         (const XML_Char *)"Invalid URI",
 706         (const XML_Char *)"Fragment not allowed",
 707         (const XML_Char *)"XML_WAR_CATALOG_PI",
 708         (const XML_Char *)"XML_ERR_NO_DTD",
 709         (const XML_Char *)"conditional section INCLUDE or IGNORE keyword expected", /* 95 */
 710         (const XML_Char *)"Version in XML Declaration missing", /* 96 */
 711         (const XML_Char *)"XML_WAR_UNKNOWN_VERSION", /* 97 */
 712         (const XML_Char *)"XML_WAR_LANG_VALUE", /* 98 */
 713         (const XML_Char *)"XML_WAR_NS_URI", /* 99 */
 714         (const XML_Char *)"XML_WAR_NS_URI_RELATIVE", /* 100 */
 715         (const XML_Char *)"Missing encoding in text declaration" /* 101 */
 716 };
 717 
 718 PHP_XML_API const XML_Char *
 719 XML_ErrorString(int code)
 720 {
 721         if (code < 0 || code >= (int)(sizeof(error_mapping) / sizeof(error_mapping[0]))) {
 722                 return (const XML_Char *) "Unknown";
 723         }
 724         return error_mapping[code];
 725 }
 726 
 727 PHP_XML_API int
 728 XML_GetCurrentLineNumber(XML_Parser parser)
 729 {
 730         return parser->parser->input->line;
 731 }
 732 
 733 PHP_XML_API int
 734 XML_GetCurrentColumnNumber(XML_Parser parser)
 735 {
 736         return parser->parser->input->col;
 737 }
 738 
 739 PHP_XML_API int
 740 XML_GetCurrentByteIndex(XML_Parser parser)
 741 {
 742         return parser->parser->input->consumed +
 743                         (parser->parser->input->cur - parser->parser->input->base);
 744 }
 745 
 746 PHP_XML_API int
 747 XML_GetCurrentByteCount(XML_Parser parser)
 748 {
 749         /* WARNING: this is identical to ByteIndex; it should probably
 750          * be different */
 751         return parser->parser->input->consumed +
 752                         (parser->parser->input->cur - parser->parser->input->base);
 753 }
 754 
 755 PHP_XML_API const XML_Char *XML_ExpatVersion(void)
 756 {
 757         return (const XML_Char *) "1.0";
 758 }
 759 
 760 PHP_XML_API void
 761 XML_ParserFree(XML_Parser parser)
 762 {
 763         if (parser->use_namespace) {
 764                 if (parser->_ns_separator) {
 765                         xmlFree(parser->_ns_separator);
 766                 }
 767         }
 768         if (parser->parser->myDoc) {
 769                 xmlFreeDoc(parser->parser->myDoc);
 770                 parser->parser->myDoc = NULL;
 771         }
 772         xmlFreeParserCtxt(parser->parser);
 773         efree(parser);
 774 }
 775 
 776 #endif /* LIBXML_EXPAT_COMPAT */
 777 #endif
 778 
 779 /**
 780  * Local Variables:
 781  * tab-width: 4
 782  * c-basic-offset: 4
 783  * indent-tabs-mode: t
 784  * End:
 785  * vim600: fdm=marker
 786  * vim: ts=4 noet sw=4
 787  */

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