PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/xml - xml.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 564 645 87.4 %
Date: 2016-07-19 Functions: 48 56 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       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: Stig Sæther Bakken <ssb@php.net>                            |
      16             :    |          Thies C. Arntzen <thies@thieso.net>                         |
      17             :    |          Sterling Hughes <sterling@php.net>                          |
      18             :    +----------------------------------------------------------------------+
      19             :  */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #define IS_EXT_MODULE
      24             : 
      25             : #ifdef HAVE_CONFIG_H
      26             : #include "config.h"
      27             : #endif
      28             : 
      29             : #include "php.h"
      30             : 
      31             : #define PHP_XML_INTERNAL
      32             : #include "zend_variables.h"
      33             : #include "ext/standard/php_string.h"
      34             : #include "ext/standard/info.h"
      35             : #include "ext/standard/html.h"
      36             : 
      37             : #if HAVE_XML
      38             : 
      39             : #include "php_xml.h"
      40             : # include "ext/standard/head.h"
      41             : #ifdef LIBXML_EXPAT_COMPAT
      42             : #include "ext/libxml/php_libxml.h"
      43             : #endif
      44             : 
      45             : /* Short-term TODO list:
      46             :  * - Implement XML_ExternalEntityParserCreate()
      47             :  * - XML_SetCommentHandler
      48             :  * - XML_SetCdataSectionHandler
      49             :  * - XML_SetParamEntityParsing
      50             :  */
      51             : 
      52             : /* Long-term TODO list:
      53             :  * - Fix the expat library so you can install your own memory manager
      54             :  *   functions
      55             :  */
      56             : 
      57             : /* Known bugs:
      58             :  * - Weird things happen with <![CDATA[]]> sections.
      59             :  */
      60             : 
      61             : ZEND_DECLARE_MODULE_GLOBALS(xml)
      62             : 
      63             : /* {{{ dynamically loadable module stuff */
      64             : #ifdef COMPILE_DL_XML
      65             : #ifdef ZTS
      66             : ZEND_TSRMLS_CACHE_DEFINE()
      67             : #endif
      68             : ZEND_GET_MODULE(xml)
      69             : #endif /* COMPILE_DL_XML */
      70             : /* }}} */
      71             : 
      72             : /* {{{ function prototypes */
      73             : PHP_MINIT_FUNCTION(xml);
      74             : PHP_MINFO_FUNCTION(xml);
      75             : static PHP_GINIT_FUNCTION(xml);
      76             : 
      77             : static void xml_parser_dtor(zend_resource *rsrc);
      78             : static void xml_set_handler(zval *, zval *);
      79             : inline static unsigned short xml_encode_iso_8859_1(unsigned char);
      80             : inline static char xml_decode_iso_8859_1(unsigned short);
      81             : inline static unsigned short xml_encode_us_ascii(unsigned char);
      82             : inline static char xml_decode_us_ascii(unsigned short);
      83             : static void xml_call_handler(xml_parser *, zval *, zend_function *, int, zval *, zval *);
      84             : static void _xml_xmlchar_zval(const XML_Char *, int, const XML_Char *, zval *);
      85             : static int _xml_xmlcharlen(const XML_Char *);
      86             : static void _xml_add_to_info(xml_parser *parser,char *name);
      87             : inline static zend_string *_xml_decode_tag(xml_parser *parser, const char *tag);
      88             : 
      89             : void _xml_startElementHandler(void *, const XML_Char *, const XML_Char **);
      90             : void _xml_endElementHandler(void *, const XML_Char *);
      91             : void _xml_characterDataHandler(void *, const XML_Char *, int);
      92             : void _xml_processingInstructionHandler(void *, const XML_Char *, const XML_Char *);
      93             : void _xml_defaultHandler(void *, const XML_Char *, int);
      94             : void _xml_unparsedEntityDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
      95             : void _xml_notationDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
      96             : int  _xml_externalEntityRefHandler(XML_Parser, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
      97             : 
      98             : void _xml_startNamespaceDeclHandler(void *, const XML_Char *, const XML_Char *);
      99             : void _xml_endNamespaceDeclHandler(void *, const XML_Char *);
     100             : /* }}} */
     101             : 
     102             : /* {{{ extension definition structures */
     103             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_create, 0, 0, 0)
     104             :         ZEND_ARG_INFO(0, encoding)
     105             : ZEND_END_ARG_INFO()
     106             : 
     107             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_create_ns, 0, 0, 0)
     108             :         ZEND_ARG_INFO(0, encoding)
     109             :         ZEND_ARG_INFO(0, sep)
     110             : ZEND_END_ARG_INFO()
     111             : 
     112             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_object, 0, 0, 2)
     113             :         ZEND_ARG_INFO(0, parser)
     114             :         ZEND_ARG_INFO(0, obj)
     115             : ZEND_END_ARG_INFO()
     116             : 
     117             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_element_handler, 0, 0, 3)
     118             :         ZEND_ARG_INFO(0, parser)
     119             :         ZEND_ARG_INFO(0, shdl)
     120             :         ZEND_ARG_INFO(0, ehdl)
     121             : ZEND_END_ARG_INFO()
     122             : 
     123             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_character_data_handler, 0, 0, 2)
     124             :         ZEND_ARG_INFO(0, parser)
     125             :         ZEND_ARG_INFO(0, hdl)
     126             : ZEND_END_ARG_INFO()
     127             : 
     128             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_processing_instruction_handler, 0, 0, 2)
     129             :         ZEND_ARG_INFO(0, parser)
     130             :         ZEND_ARG_INFO(0, hdl)
     131             : ZEND_END_ARG_INFO()
     132             : 
     133             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_default_handler, 0, 0, 2)
     134             :         ZEND_ARG_INFO(0, parser)
     135             :         ZEND_ARG_INFO(0, hdl)
     136             : ZEND_END_ARG_INFO()
     137             : 
     138             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_unparsed_entity_decl_handler, 0, 0, 2)
     139             :         ZEND_ARG_INFO(0, parser)
     140             :         ZEND_ARG_INFO(0, hdl)
     141             : ZEND_END_ARG_INFO()
     142             : 
     143             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_notation_decl_handler, 0, 0, 2)
     144             :         ZEND_ARG_INFO(0, parser)
     145             :         ZEND_ARG_INFO(0, hdl)
     146             : ZEND_END_ARG_INFO()
     147             : 
     148             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_external_entity_ref_handler, 0, 0, 2)
     149             :         ZEND_ARG_INFO(0, parser)
     150             :         ZEND_ARG_INFO(0, hdl)
     151             : ZEND_END_ARG_INFO()
     152             : 
     153             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_start_namespace_decl_handler, 0, 0, 2)
     154             :         ZEND_ARG_INFO(0, parser)
     155             :         ZEND_ARG_INFO(0, hdl)
     156             : ZEND_END_ARG_INFO()
     157             : 
     158             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_end_namespace_decl_handler, 0, 0, 2)
     159             :         ZEND_ARG_INFO(0, parser)
     160             :         ZEND_ARG_INFO(0, hdl)
     161             : ZEND_END_ARG_INFO()
     162             : 
     163             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parse, 0, 0, 2)
     164             :         ZEND_ARG_INFO(0, parser)
     165             :         ZEND_ARG_INFO(0, data)
     166             :         ZEND_ARG_INFO(0, isfinal)
     167             : ZEND_END_ARG_INFO()
     168             : 
     169             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parse_into_struct, 0, 0, 3)
     170             :         ZEND_ARG_INFO(0, parser)
     171             :         ZEND_ARG_INFO(0, data)
     172             :         ZEND_ARG_INFO(1, values)
     173             :         ZEND_ARG_INFO(1, index)
     174             : ZEND_END_ARG_INFO()
     175             : 
     176             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_error_code, 0, 0, 1)
     177             :         ZEND_ARG_INFO(0, parser)
     178             : ZEND_END_ARG_INFO()
     179             : 
     180             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_error_string, 0, 0, 1)
     181             :         ZEND_ARG_INFO(0, code)
     182             : ZEND_END_ARG_INFO()
     183             : 
     184             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_current_line_number, 0, 0, 1)
     185             :         ZEND_ARG_INFO(0, parser)
     186             : ZEND_END_ARG_INFO()
     187             : 
     188             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_current_column_number, 0, 0, 1)
     189             :         ZEND_ARG_INFO(0, parser)
     190             : ZEND_END_ARG_INFO()
     191             : 
     192             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_get_current_byte_index, 0, 0, 1)
     193             :         ZEND_ARG_INFO(0, parser)
     194             : ZEND_END_ARG_INFO()
     195             : 
     196             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_free, 0, 0, 1)
     197             :         ZEND_ARG_INFO(0, parser)
     198             : ZEND_END_ARG_INFO()
     199             : 
     200             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_set_option, 0, 0, 3)
     201             :         ZEND_ARG_INFO(0, parser)
     202             :         ZEND_ARG_INFO(0, option)
     203             :         ZEND_ARG_INFO(0, value)
     204             : ZEND_END_ARG_INFO()
     205             : 
     206             : ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_get_option, 0, 0, 2)
     207             :         ZEND_ARG_INFO(0, parser)
     208             :         ZEND_ARG_INFO(0, option)
     209             : ZEND_END_ARG_INFO()
     210             : 
     211             : ZEND_BEGIN_ARG_INFO_EX(arginfo_utf8_encode, 0, 0, 1)
     212             :         ZEND_ARG_INFO(0, data)
     213             : ZEND_END_ARG_INFO()
     214             : 
     215             : ZEND_BEGIN_ARG_INFO_EX(arginfo_utf8_decode, 0, 0, 1)
     216             :         ZEND_ARG_INFO(0, data)
     217             : ZEND_END_ARG_INFO()
     218             : 
     219             : const zend_function_entry xml_functions[] = {
     220             :         PHP_FE(xml_parser_create,                                       arginfo_xml_parser_create)
     221             :         PHP_FE(xml_parser_create_ns,                            arginfo_xml_parser_create_ns)
     222             :         PHP_FE(xml_set_object,                                          arginfo_xml_set_object)
     223             :         PHP_FE(xml_set_element_handler,                         arginfo_xml_set_element_handler)
     224             :         PHP_FE(xml_set_character_data_handler,          arginfo_xml_set_character_data_handler)
     225             :         PHP_FE(xml_set_processing_instruction_handler,  arginfo_xml_set_processing_instruction_handler)
     226             :         PHP_FE(xml_set_default_handler,                                 arginfo_xml_set_default_handler)
     227             :         PHP_FE(xml_set_unparsed_entity_decl_handler,arginfo_xml_set_unparsed_entity_decl_handler)
     228             :         PHP_FE(xml_set_notation_decl_handler,           arginfo_xml_set_notation_decl_handler)
     229             :         PHP_FE(xml_set_external_entity_ref_handler,     arginfo_xml_set_external_entity_ref_handler)
     230             :         PHP_FE(xml_set_start_namespace_decl_handler,arginfo_xml_set_start_namespace_decl_handler)
     231             :         PHP_FE(xml_set_end_namespace_decl_handler,      arginfo_xml_set_end_namespace_decl_handler)
     232             :         PHP_FE(xml_parse,                                                       arginfo_xml_parse)
     233             :         PHP_FE(xml_parse_into_struct,                           arginfo_xml_parse_into_struct)
     234             :         PHP_FE(xml_get_error_code,                                      arginfo_xml_get_error_code)
     235             :         PHP_FE(xml_error_string,                                        arginfo_xml_error_string)
     236             :         PHP_FE(xml_get_current_line_number,                     arginfo_xml_get_current_line_number)
     237             :         PHP_FE(xml_get_current_column_number,           arginfo_xml_get_current_column_number)
     238             :         PHP_FE(xml_get_current_byte_index,                      arginfo_xml_get_current_byte_index)
     239             :         PHP_FE(xml_parser_free,                                         arginfo_xml_parser_free)
     240             :         PHP_FE(xml_parser_set_option,                           arginfo_xml_parser_set_option)
     241             :         PHP_FE(xml_parser_get_option,                           arginfo_xml_parser_get_option)
     242             :         PHP_FE(utf8_encode,                                             arginfo_utf8_encode)
     243             :         PHP_FE(utf8_decode,                                             arginfo_utf8_decode)
     244             :         PHP_FE_END
     245             : };
     246             : 
     247             : #ifdef LIBXML_EXPAT_COMPAT
     248             : static const zend_module_dep xml_deps[] = {
     249             :         ZEND_MOD_REQUIRED("libxml")
     250             :         ZEND_MOD_END
     251             : };
     252             : #endif
     253             : 
     254             : zend_module_entry xml_module_entry = {
     255             : #ifdef LIBXML_EXPAT_COMPAT
     256             :     STANDARD_MODULE_HEADER_EX, NULL,
     257             :         xml_deps,
     258             : #else
     259             :     STANDARD_MODULE_HEADER,
     260             : #endif
     261             :         "xml",                /* extension name */
     262             :         xml_functions,        /* extension function list */
     263             :         PHP_MINIT(xml),       /* extension-wide startup function */
     264             :         NULL,                 /* extension-wide shutdown function */
     265             :         NULL,                 /* per-request startup function */
     266             :         NULL,                 /* per-request shutdown function */
     267             :         PHP_MINFO(xml),       /* information function */
     268             :     PHP_XML_VERSION,
     269             :     PHP_MODULE_GLOBALS(xml), /* globals descriptor */
     270             :     PHP_GINIT(xml),          /* globals ctor */
     271             :     NULL,                    /* globals dtor */
     272             :     NULL,                    /* post deactivate */
     273             :         STANDARD_MODULE_PROPERTIES_EX
     274             : };
     275             : 
     276             : /* All the encoding functions are set to NULL right now, since all
     277             :  * the encoding is currently done internally by expat/xmltok.
     278             :  */
     279             : xml_encoding xml_encodings[] = {
     280             :         { (XML_Char *)"ISO-8859-1", xml_decode_iso_8859_1, xml_encode_iso_8859_1 },
     281             :         { (XML_Char *)"US-ASCII",   xml_decode_us_ascii,   xml_encode_us_ascii   },
     282             :         { (XML_Char *)"UTF-8",      NULL,                  NULL                  },
     283             :         { (XML_Char *)NULL,         NULL,                  NULL                  }
     284             : };
     285             : 
     286             : static XML_Memory_Handling_Suite php_xml_mem_hdlrs;
     287             : 
     288             : /* True globals, no need for thread safety */
     289             : static int le_xml_parser; 
     290             : 
     291             : /* }}} */
     292             : 
     293             : /* {{{ startup, shutdown and info functions */
     294       23409 : static PHP_GINIT_FUNCTION(xml)
     295             : {
     296             : #if defined(COMPILE_DL_XML) && defined(ZTS)
     297             :         ZEND_TSRMLS_CACHE_UPDATE();
     298             : #endif
     299       23409 :         xml_globals->default_encoding = (XML_Char*)"UTF-8";
     300       23409 : }
     301             : 
     302           0 : static void *php_xml_malloc_wrapper(size_t sz)
     303             : {
     304           0 :         return emalloc(sz);
     305             : }
     306             : 
     307           0 : static void *php_xml_realloc_wrapper(void *ptr, size_t sz)
     308             : {
     309           0 :         return erealloc(ptr, sz);
     310             : }
     311             : 
     312           0 : static void php_xml_free_wrapper(void *ptr)
     313             : {
     314           0 :         if (ptr != NULL) {
     315           0 :                 efree(ptr);
     316             :         }
     317           0 : }
     318             : 
     319       23409 : PHP_MINIT_FUNCTION(xml)
     320             : {
     321       23409 :         le_xml_parser = zend_register_list_destructors_ex(xml_parser_dtor, NULL, "xml", module_number);
     322             : 
     323       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_NONE", XML_ERROR_NONE, CONST_CS|CONST_PERSISTENT);
     324       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_NO_MEMORY", XML_ERROR_NO_MEMORY, CONST_CS|CONST_PERSISTENT);
     325       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_SYNTAX", XML_ERROR_SYNTAX, CONST_CS|CONST_PERSISTENT);
     326       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_NO_ELEMENTS", XML_ERROR_NO_ELEMENTS, CONST_CS|CONST_PERSISTENT);
     327       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_INVALID_TOKEN", XML_ERROR_INVALID_TOKEN, CONST_CS|CONST_PERSISTENT);
     328       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_UNCLOSED_TOKEN", XML_ERROR_UNCLOSED_TOKEN, CONST_CS|CONST_PERSISTENT);
     329       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_PARTIAL_CHAR", XML_ERROR_PARTIAL_CHAR, CONST_CS|CONST_PERSISTENT);
     330       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_TAG_MISMATCH", XML_ERROR_TAG_MISMATCH, CONST_CS|CONST_PERSISTENT);
     331       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_DUPLICATE_ATTRIBUTE", XML_ERROR_DUPLICATE_ATTRIBUTE, CONST_CS|CONST_PERSISTENT);
     332       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_JUNK_AFTER_DOC_ELEMENT", XML_ERROR_JUNK_AFTER_DOC_ELEMENT, CONST_CS|CONST_PERSISTENT);
     333       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_PARAM_ENTITY_REF", XML_ERROR_PARAM_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
     334       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_UNDEFINED_ENTITY", XML_ERROR_UNDEFINED_ENTITY, CONST_CS|CONST_PERSISTENT);
     335       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_RECURSIVE_ENTITY_REF", XML_ERROR_RECURSIVE_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
     336       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_ASYNC_ENTITY", XML_ERROR_ASYNC_ENTITY, CONST_CS|CONST_PERSISTENT);
     337       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_BAD_CHAR_REF", XML_ERROR_BAD_CHAR_REF, CONST_CS|CONST_PERSISTENT);
     338       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_BINARY_ENTITY_REF", XML_ERROR_BINARY_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
     339       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF", XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
     340       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_MISPLACED_XML_PI", XML_ERROR_MISPLACED_XML_PI, CONST_CS|CONST_PERSISTENT);
     341       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_UNKNOWN_ENCODING", XML_ERROR_UNKNOWN_ENCODING, CONST_CS|CONST_PERSISTENT);
     342       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_INCORRECT_ENCODING", XML_ERROR_INCORRECT_ENCODING, CONST_CS|CONST_PERSISTENT);
     343       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_UNCLOSED_CDATA_SECTION", XML_ERROR_UNCLOSED_CDATA_SECTION, CONST_CS|CONST_PERSISTENT);
     344       23409 :         REGISTER_LONG_CONSTANT("XML_ERROR_EXTERNAL_ENTITY_HANDLING", XML_ERROR_EXTERNAL_ENTITY_HANDLING, CONST_CS|CONST_PERSISTENT);
     345             : 
     346       23409 :         REGISTER_LONG_CONSTANT("XML_OPTION_CASE_FOLDING", PHP_XML_OPTION_CASE_FOLDING, CONST_CS|CONST_PERSISTENT);
     347       23409 :         REGISTER_LONG_CONSTANT("XML_OPTION_TARGET_ENCODING", PHP_XML_OPTION_TARGET_ENCODING, CONST_CS|CONST_PERSISTENT);
     348       23409 :         REGISTER_LONG_CONSTANT("XML_OPTION_SKIP_TAGSTART", PHP_XML_OPTION_SKIP_TAGSTART, CONST_CS|CONST_PERSISTENT);
     349       23409 :         REGISTER_LONG_CONSTANT("XML_OPTION_SKIP_WHITE", PHP_XML_OPTION_SKIP_WHITE, CONST_CS|CONST_PERSISTENT);
     350             : 
     351             :         /* this object should not be pre-initialised at compile time,
     352             :            as the order of members may vary */  
     353             : 
     354       23409 :         php_xml_mem_hdlrs.malloc_fcn = php_xml_malloc_wrapper;
     355       23409 :         php_xml_mem_hdlrs.realloc_fcn = php_xml_realloc_wrapper;
     356       23409 :         php_xml_mem_hdlrs.free_fcn = php_xml_free_wrapper;
     357             : 
     358             : #ifdef LIBXML_EXPAT_COMPAT
     359       23409 :         REGISTER_STRING_CONSTANT("XML_SAX_IMPL", "libxml", CONST_CS|CONST_PERSISTENT);
     360             : #else
     361             :         REGISTER_STRING_CONSTANT("XML_SAX_IMPL", "expat", CONST_CS|CONST_PERSISTENT);
     362             : #endif
     363             : 
     364       23409 :         return SUCCESS;
     365             : }
     366             : 
     367         150 : PHP_MINFO_FUNCTION(xml)
     368             : {
     369         150 :         php_info_print_table_start();
     370         150 :         php_info_print_table_row(2, "XML Support", "active");
     371         150 :         php_info_print_table_row(2, "XML Namespace Support", "active");
     372             : #if defined(LIBXML_DOTTED_VERSION) && defined(LIBXML_EXPAT_COMPAT)
     373         150 :         php_info_print_table_row(2, "libxml2 Version", LIBXML_DOTTED_VERSION);
     374             : #else
     375             :         php_info_print_table_row(2, "EXPAT Version", XML_ExpatVersion());
     376             : #endif
     377         150 :         php_info_print_table_end();
     378         150 : }
     379             : /* }}} */
     380             : 
     381             : /* {{{ extension-internal functions */
     382             : 
     383          52 : static void _xml_xmlchar_zval(const XML_Char *s, int len, const XML_Char *encoding, zval *ret)
     384             : {
     385          52 :         if (s == NULL) {
     386          12 :                 ZVAL_FALSE(ret);
     387          12 :                 return;
     388             :         }
     389          40 :         if (len == 0) {
     390          21 :                 len = _xml_xmlcharlen(s);
     391             :         }
     392          40 :         ZVAL_STR(ret, xml_utf8_decode(s, len, encoding));
     393             : }
     394             : /* }}} */
     395             : 
     396             : /* {{{ xml_parser_dtor() */
     397         142 : static void xml_parser_dtor(zend_resource *rsrc)
     398             : {
     399         142 :         xml_parser *parser = (xml_parser *)rsrc->ptr;
     400             :         
     401         142 :         if (parser->parser) {
     402         142 :                 XML_ParserFree(parser->parser);
     403             :         }
     404         142 :         if (parser->ltags) {
     405             :                 int inx;
     406         262 :                 for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++)
     407         255 :                         efree(parser->ltags[ inx ]);
     408           7 :                 efree(parser->ltags);
     409             :         }
     410         284 :         if (!Z_ISUNDEF(parser->startElementHandler)) {
     411          12 :                 zval_ptr_dtor(&parser->startElementHandler);
     412             :         }
     413         284 :         if (!Z_ISUNDEF(parser->endElementHandler)) {
     414          11 :                 zval_ptr_dtor(&parser->endElementHandler);
     415             :         }
     416         284 :         if (!Z_ISUNDEF(parser->characterDataHandler)) {
     417           3 :                 zval_ptr_dtor(&parser->characterDataHandler);
     418             :         }
     419         284 :         if (!Z_ISUNDEF(parser->processingInstructionHandler)) {
     420           1 :                 zval_ptr_dtor(&parser->processingInstructionHandler);
     421             :         }
     422         284 :         if (!Z_ISUNDEF(parser->defaultHandler)) {
     423           2 :                 zval_ptr_dtor(&parser->defaultHandler);
     424             :         }
     425         284 :         if (!Z_ISUNDEF(parser->unparsedEntityDeclHandler)) {
     426           1 :                 zval_ptr_dtor(&parser->unparsedEntityDeclHandler);
     427             :         }
     428         284 :         if (!Z_ISUNDEF(parser->notationDeclHandler)) {
     429           1 :                 zval_ptr_dtor(&parser->notationDeclHandler);
     430             :         }
     431         284 :         if (!Z_ISUNDEF(parser->externalEntityRefHandler)) {
     432           0 :                 zval_ptr_dtor(&parser->externalEntityRefHandler);
     433             :         }
     434         284 :         if (!Z_ISUNDEF(parser->unknownEncodingHandler)) {
     435           0 :                 zval_ptr_dtor(&parser->unknownEncodingHandler);
     436             :         }
     437         284 :         if (!Z_ISUNDEF(parser->startNamespaceDeclHandler)) {
     438           1 :                 zval_ptr_dtor(&parser->startNamespaceDeclHandler);
     439             :         }
     440         284 :         if (!Z_ISUNDEF(parser->endNamespaceDeclHandler)) {
     441           1 :                 zval_ptr_dtor(&parser->endNamespaceDeclHandler);
     442             :         }
     443         142 :         if (parser->baseURI) {
     444           0 :                 efree(parser->baseURI);
     445             :         }
     446         284 :         if (!Z_ISUNDEF(parser->object)) {
     447           4 :                 zval_ptr_dtor(&parser->object);
     448             :         }
     449             : 
     450         142 :         efree(parser);
     451         142 : }
     452             : /* }}} */
     453             : 
     454             : /* {{{ xml_set_handler() */
     455          36 : static void xml_set_handler(zval *handler, zval *data)
     456             : {
     457             :         /* If we have already a handler, release it */
     458          36 :         if (handler) {
     459          36 :                 zval_ptr_dtor(handler);
     460             :         }
     461             : 
     462             :         /* IS_ARRAY might indicate that we're using array($obj, 'method') syntax */
     463          72 :         if (Z_TYPE_P(data) != IS_ARRAY && Z_TYPE_P(data) != IS_OBJECT) {
     464          35 :                 convert_to_string_ex(data);
     465          34 :                 if (Z_STRLEN_P(data) == 0) {
     466           1 :                         ZVAL_UNDEF(handler);
     467           1 :                         return;
     468             :                 }
     469             :         }
     470             : 
     471          35 :         ZVAL_COPY(handler, data);
     472             : }
     473             : /* }}} */
     474             : 
     475             : /* {{{ xml_call_handler() */
     476          93 : static void xml_call_handler(xml_parser *parser, zval *handler, zend_function *function_ptr, int argc, zval *argv, zval *retval)
     477             : {
     478             :         int i;  
     479             : 
     480          93 :         ZVAL_UNDEF(retval);
     481          93 :         if (parser && handler && !EG(exception)) {
     482             :                 int result;
     483             :                 zend_fcall_info fci;
     484             : 
     485          90 :                 fci.size = sizeof(fci);
     486          90 :                 ZVAL_COPY_VALUE(&fci.function_name, handler);
     487          90 :                 fci.object = Z_OBJ(parser->object);
     488          90 :                 fci.retval = retval;
     489          90 :                 fci.param_count = argc;
     490          90 :                 fci.params = argv;
     491          90 :                 fci.no_separation = 0;
     492             :                 /*fci.function_handler_cache = &function_ptr;*/
     493             : 
     494          90 :                 result = zend_call_function(&fci, NULL);
     495          90 :                 if (result == FAILURE) {
     496             :                         zval *method;
     497             :                         zval *obj;
     498             : 
     499           0 :                         if (Z_TYPE_P(handler) == IS_STRING) {
     500           0 :                                 php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(handler));
     501           0 :                         } else if ((obj = zend_hash_index_find(Z_ARRVAL_P(handler), 0)) != NULL &&
     502           0 :                                            (method = zend_hash_index_find(Z_ARRVAL_P(handler), 1)) != NULL &&
     503             :                                            Z_TYPE_P(obj) == IS_OBJECT &&
     504             :                                            Z_TYPE_P(method) == IS_STRING) {
     505           0 :                                 php_error_docref(NULL, E_WARNING, "Unable to call handler %s::%s()", ZSTR_VAL(Z_OBJCE_P(obj)->name), Z_STRVAL_P(method));
     506             :                         } else 
     507           0 :                                 php_error_docref(NULL, E_WARNING, "Unable to call handler");
     508             :                 }
     509             :         } 
     510         337 :         for (i = 0; i < argc; i++) {
     511         244 :                 zval_ptr_dtor(&argv[i]);
     512             :         }
     513          93 : }
     514             : /* }}} */
     515             : 
     516             : /* {{{ xml_encode_iso_8859_1() */
     517         138 : inline static unsigned short xml_encode_iso_8859_1(unsigned char c)
     518             : {
     519         138 :         return (unsigned short)c;
     520             : }
     521             : /* }}} */
     522             : 
     523             : /* {{{ xml_decode_iso_8859_1() */
     524         701 : inline static char xml_decode_iso_8859_1(unsigned short c)
     525             : {
     526         701 :         return (char)(c > 0xff ? '?' : c);
     527             : }
     528             : /* }}} */
     529             : 
     530             : /* {{{ xml_encode_us_ascii() */
     531           0 : inline static unsigned short xml_encode_us_ascii(unsigned char c)
     532             : {
     533           0 :         return (unsigned short)c;
     534             : }
     535             : /* }}} */
     536             : 
     537             : /* {{{ xml_decode_us_ascii() */
     538           0 : inline static char xml_decode_us_ascii(unsigned short c)
     539             : {
     540           0 :         return (char)(c > 0x7f ? '?' : c);
     541             : }
     542             : /* }}} */
     543             : 
     544             : /* {{{ xml_get_encoding() */
     545        1223 : static xml_encoding *xml_get_encoding(const XML_Char *name)
     546             : {
     547        1223 :         xml_encoding *enc = &xml_encodings[0];
     548             : 
     549        4715 :         while (enc && enc->name) {
     550        3492 :                 if (strcasecmp((char *)name, (char *)enc->name) == 0) {
     551        1223 :                         return enc;
     552             :                 }
     553        2269 :                 enc++;
     554             :         }
     555           0 :         return NULL;
     556             : }
     557             : /* }}} */
     558             : 
     559             : /* {{{ xml_utf8_encode() */
     560          25 : PHP_XML_API zend_string *xml_utf8_encode(const char *s, size_t len, const XML_Char *encoding)
     561             : {
     562          25 :         size_t pos = len;
     563             :         zend_string *str;
     564             :         unsigned int c;
     565          25 :         unsigned short (*encoder)(unsigned char) = NULL;
     566          25 :         xml_encoding *enc = xml_get_encoding(encoding);
     567             : 
     568          25 :         if (enc) {
     569          25 :                 encoder = enc->encoding_function;
     570             :         } else {
     571             :                 /* If the target encoding was unknown, fail */
     572           0 :                 return NULL;
     573             :         }
     574          25 :         if (encoder == NULL) {
     575             :                 /* If no encoder function was specified, return the data as-is.
     576             :                  */
     577           0 :                 str = zend_string_init(s, len, 0);
     578           0 :                 return str;
     579             :         }
     580             :         /* This is the theoretical max (will never get beyond len * 2 as long
     581             :          * as we are converting from single-byte characters, though) */
     582          25 :         str = zend_string_safe_alloc(len, 4, 0, 0);
     583          25 :         ZSTR_LEN(str) = 0;
     584         188 :         while (pos > 0) {
     585         138 :                 c = encoder ? encoder((unsigned char)(*s)) : (unsigned short)(*s);
     586         138 :                 if (c < 0x80) {
     587          66 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (char) c;
     588          72 :                 } else if (c < 0x800) {
     589          72 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0xc0 | (c >> 6));
     590          72 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0x80 | (c & 0x3f));
     591           0 :                 } else if (c < 0x10000) {
     592           0 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0xe0 | (c >> 12));
     593           0 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0xc0 | ((c >> 6) & 0x3f));
     594           0 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0x80 | (c & 0x3f));
     595           0 :                 } else if (c < 0x200000) {
     596           0 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0xf0 | (c >> 18));
     597           0 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0xe0 | ((c >> 12) & 0x3f));
     598           0 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0xc0 | ((c >> 6) & 0x3f));
     599           0 :                         ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0x80 | (c & 0x3f));
     600             :                 }
     601         138 :                 pos--;
     602         138 :                 s++;
     603             :         }
     604          25 :         ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0';
     605          50 :         str = zend_string_truncate(str, ZSTR_LEN(str), 0);
     606          25 :         return str;
     607             : }
     608             : /* }}} */
     609             : 
     610             : /* {{{ xml_utf8_decode() */
     611        1195 : PHP_XML_API zend_string *xml_utf8_decode(const XML_Char *s, size_t len, const XML_Char *encoding)
     612             : {
     613        1195 :         size_t pos = 0;
     614             :         unsigned int c;
     615        1195 :         char (*decoder)(unsigned short) = NULL;
     616        1195 :         xml_encoding *enc = xml_get_encoding(encoding);
     617             :         zend_string *str;
     618             : 
     619        1195 :         if (enc) {
     620        1195 :                 decoder = enc->decoding_function;
     621             :         }
     622             : 
     623        1195 :         if (decoder == NULL) {
     624             :                 /* If the target encoding was unknown, or no decoder function
     625             :                  * was specified, return the UTF-8-encoded data as-is.
     626             :                  */
     627        2266 :                 str = zend_string_init((char *)s, len, 0);
     628        1133 :                 return str;
     629             :         }
     630             : 
     631          62 :         str = zend_string_alloc(len, 0);
     632          62 :         ZSTR_LEN(str) = 0;
     633         825 :         while (pos < len) {
     634         701 :                 int status = FAILURE;
     635         701 :                 c = php_next_utf8_char((const unsigned char*)s, (size_t) len, &pos, &status);
     636             : 
     637         701 :                 if (status == FAILURE || c > 0xFFU) {
     638           8 :                         c = '?';
     639             :                 }
     640             : 
     641         701 :                 ZSTR_VAL(str)[ZSTR_LEN(str)++] = decoder ? (unsigned int)decoder(c) : c;
     642             :         }
     643          62 :         ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0';
     644          62 :         if (ZSTR_LEN(str) < len) {
     645          10 :                 str = zend_string_truncate(str, ZSTR_LEN(str), 0);
     646             :         }
     647             : 
     648          62 :         return str;
     649             : }
     650             : /* }}} */
     651             : 
     652             : /* {{{ _xml_xmlcharlen() */
     653          21 : static int _xml_xmlcharlen(const XML_Char *s)
     654             : {
     655          21 :         int len = 0;
     656             : 
     657         359 :         while (*s) {
     658         317 :                 len++;
     659         317 :                 s++;
     660             :         }
     661          21 :         return len;
     662             : }
     663             : /* }}} */
     664             : 
     665             : /* {{{ _xml_zval_strdup() */
     666           0 : PHP_XML_API char *_xml_zval_strdup(zval *val)
     667             : {
     668           0 :         if (Z_TYPE_P(val) == IS_STRING) {
     669           0 :                 char *buf = emalloc(Z_STRLEN_P(val) + 1);
     670           0 :                 memcpy(buf, Z_STRVAL_P(val), Z_STRLEN_P(val));
     671           0 :                 buf[Z_STRLEN_P(val)] = '\0';
     672           0 :                 return buf;
     673             :         }
     674           0 :         return NULL;
     675             : }
     676             : /* }}} */
     677             : 
     678             : /* {{{ _xml_add_to_info() */
     679         276 : static void _xml_add_to_info(xml_parser *parser,char *name)
     680             : {
     681             :         zval *element;
     682             : 
     683         552 :         if (Z_ISUNDEF(parser->info)) {
     684         255 :                 return;
     685             :         }
     686             : 
     687          21 :         if ((element = zend_hash_str_find(Z_ARRVAL(parser->info), name, strlen(name))) == NULL) {
     688             :                 zval values;
     689          10 :                 array_init(&values);
     690          10 :                 element = zend_hash_str_update(Z_ARRVAL(parser->info), name, strlen(name), &values);
     691             :         } 
     692             :                         
     693          21 :         add_next_index_long(element, parser->curtag);
     694             :         
     695          21 :         parser->curtag++;
     696             : }
     697             : /* }}} */
     698             : 
     699             : /* {{{ _xml_decode_tag() */
     700        1102 : static zend_string *_xml_decode_tag(xml_parser *parser, const char *tag)
     701             : {
     702             :         zend_string *str;
     703             : 
     704        1102 :         str = xml_utf8_decode((const XML_Char *)tag, strlen(tag), parser->target_encoding);
     705             : 
     706        1102 :         if (parser->case_folding) {
     707        1052 :                 php_strtoupper(ZSTR_VAL(str), ZSTR_LEN(str));
     708             :         }
     709             : 
     710        1102 :         return str;
     711             : }
     712             : /* }}} */
     713             : 
     714             : /* {{{ _xml_startElementHandler() */
     715        1046 : void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Char **attributes)
     716             : {
     717        1046 :         xml_parser *parser = (xml_parser *)userData;
     718        1046 :         const char **attrs = (const char **) attributes;
     719             :         zend_string *att, *tag_name, *val;
     720             :         zval retval, args[3];
     721             : 
     722        1046 :         if (parser) {
     723        1046 :                 parser->level++;
     724             : 
     725        1046 :                 tag_name = _xml_decode_tag(parser, (const char *)name);
     726             : 
     727        2092 :                 if (!Z_ISUNDEF(parser->startElementHandler)) {
     728          34 :                         ZVAL_COPY(&args[0], &parser->index);
     729          68 :                         ZVAL_STRING(&args[1], ZSTR_VAL(tag_name) + parser->toffset);
     730          34 :                         array_init(&args[2]);
     731             : 
     732          75 :                         while (attributes && *attributes) {
     733             :                                 zval tmp;
     734             : 
     735           7 :                                 att = _xml_decode_tag(parser, (const char *)attributes[0]);
     736           7 :                                 val = xml_utf8_decode(attributes[1], strlen((char *)attributes[1]), parser->target_encoding);
     737             : 
     738           7 :                                 ZVAL_STR(&tmp, val);
     739           7 :                                 zend_symtable_update(Z_ARRVAL(args[2]), att, &tmp);
     740             : 
     741           7 :                                 attributes += 2;
     742             : 
     743             :                                 zend_string_release(att);
     744             :                         }
     745             :                         
     746          34 :                         xml_call_handler(parser, &parser->startElementHandler, parser->startElementPtr, 3, args, &retval);
     747          34 :                         zval_ptr_dtor(&retval);
     748             :                 } 
     749             : 
     750        2092 :                 if (!Z_ISUNDEF(parser->data)) {
     751        1012 :                         if (parser->level <= XML_MAXLEVEL)  {
     752             :                                 zval tag, atr;
     753         267 :                                 int atcnt = 0;
     754             : 
     755         267 :                                 array_init(&tag);
     756         267 :                                 array_init(&atr);
     757             : 
     758         267 :                                 _xml_add_to_info(parser, ZSTR_VAL(tag_name) + parser->toffset);
     759             : 
     760         267 :                                 add_assoc_string(&tag, "tag", ZSTR_VAL(tag_name) + parser->toffset); /* cast to avoid gcc-warning */
     761         267 :                                 add_assoc_string(&tag, "type", "open");
     762         267 :                                 add_assoc_long(&tag, "level", parser->level);
     763             : 
     764         267 :                                 parser->ltags[parser->level-1] = estrdup(ZSTR_VAL(tag_name));
     765         267 :                                 parser->lastwasopen = 1;
     766             : 
     767         267 :                                 attributes = (const XML_Char **) attrs;
     768             : 
     769         538 :                                 while (attributes && *attributes) {
     770             :                                         zval tmp;
     771             : 
     772           4 :                                         att = _xml_decode_tag(parser, (const char *)attributes[0]);
     773           4 :                                         val = xml_utf8_decode(attributes[1], strlen((char *)attributes[1]), parser->target_encoding);
     774             : 
     775           4 :                                         ZVAL_STR(&tmp, val);
     776           4 :                                         zend_symtable_update(Z_ARRVAL(atr), att, &tmp);
     777             : 
     778           4 :                                         atcnt++;
     779           4 :                                         attributes += 2;
     780             : 
     781             :                                         zend_string_release(att);
     782             :                                 }
     783             : 
     784         267 :                                 if (atcnt) {
     785           3 :                                         zend_hash_str_add(Z_ARRVAL(tag), "attributes", sizeof("attributes") - 1, &atr);
     786             :                                 } else {
     787         264 :                                         zval_ptr_dtor(&atr);
     788             :                                 }
     789             : 
     790         267 :                                 parser->ctag = zend_hash_next_index_insert(Z_ARRVAL(parser->data), &tag);
     791         745 :                         } else if (parser->level == (XML_MAXLEVEL + 1)) {
     792           1 :                                                         php_error_docref(NULL, E_WARNING, "Maximum depth exceeded - Results truncated");
     793             :                         }
     794             :                 }
     795             : 
     796             :                 zend_string_release(tag_name);
     797             :         }
     798        1046 : }
     799             : /* }}} */
     800             : 
     801             : /* {{{ _xml_endElementHandler() */
     802          45 : void _xml_endElementHandler(void *userData, const XML_Char *name)
     803             : {
     804          45 :         xml_parser *parser = (xml_parser *)userData;
     805             :         zend_string *tag_name;
     806             : 
     807          45 :         if (parser) {
     808             :                 zval retval, args[2];
     809             : 
     810          45 :                 tag_name = _xml_decode_tag(parser, (const char *)name);
     811             : 
     812          90 :                 if (!Z_ISUNDEF(parser->endElementHandler)) {
     813          31 :                         ZVAL_COPY(&args[0], &parser->index);
     814          62 :                         ZVAL_STRING(&args[1], ZSTR_VAL(tag_name) + parser->toffset);
     815             : 
     816          31 :                         xml_call_handler(parser, &parser->endElementHandler, parser->endElementPtr, 2, args, &retval);
     817          31 :                         zval_ptr_dtor(&retval);
     818             :                 } 
     819             : 
     820          90 :                 if (!Z_ISUNDEF(parser->data)) {
     821             :                         zval tag;
     822             : 
     823          12 :                         if (parser->lastwasopen) {
     824           6 :                                 add_assoc_string(parser->ctag, "type", "complete");
     825             :                         } else {
     826           6 :                                 array_init(&tag);
     827             :                                   
     828           6 :                                 _xml_add_to_info(parser, ZSTR_VAL(tag_name) + parser->toffset);
     829             : 
     830           6 :                                 add_assoc_string(&tag, "tag", ZSTR_VAL(tag_name) + parser->toffset); /* cast to avoid gcc-warning */
     831           6 :                                 add_assoc_string(&tag, "type", "close");
     832           6 :                                 add_assoc_long(&tag, "level", parser->level);
     833             :                                   
     834           6 :                                 zend_hash_next_index_insert(Z_ARRVAL(parser->data), &tag);
     835             :                         }
     836             : 
     837          12 :                         parser->lastwasopen = 0;
     838             :                 }
     839             : 
     840             :                 zend_string_release(tag_name);
     841             : 
     842          45 :                 if ((parser->ltags) && (parser->level <= XML_MAXLEVEL)) {
     843          12 :                         efree(parser->ltags[parser->level-1]);
     844             :                 }
     845             : 
     846          45 :                 parser->level--;
     847             :         }
     848          45 : }
     849             : /* }}} */
     850             : 
     851             : /* {{{ _xml_characterDataHandler() */
     852          20 : void _xml_characterDataHandler(void *userData, const XML_Char *s, int len)
     853             : {
     854          20 :         xml_parser *parser = (xml_parser *)userData;
     855             : 
     856          20 :         if (parser) {
     857             :                 zval retval, args[2];
     858             : 
     859          40 :                 if (!Z_ISUNDEF(parser->characterDataHandler)) {
     860           6 :                         ZVAL_COPY(&args[0], &parser->index);
     861           6 :                         _xml_xmlchar_zval(s, len, parser->target_encoding, &args[1]);
     862           6 :                         xml_call_handler(parser, &parser->characterDataHandler, parser->characterDataPtr, 2, args, &retval);
     863           6 :                         zval_ptr_dtor(&retval);
     864             :                 } 
     865             : 
     866          40 :                 if (!Z_ISUNDEF(parser->data)) {
     867             :                         size_t i;
     868          14 :                         int doprint = 0;
     869             :                         zend_string *decoded_value;
     870             : 
     871          14 :                         decoded_value = xml_utf8_decode(s, len, parser->target_encoding);
     872          20 :                         for (i = 0; i < ZSTR_LEN(decoded_value); i++) {
     873          16 :                                 switch (ZSTR_VAL(decoded_value)[i]) {
     874             :                                         case ' ':
     875             :                                         case '\t':
     876             :                                         case '\n':
     877           6 :                                                 continue;
     878             :                                         default:
     879          10 :                                                 doprint = 1;
     880             :                                                 break;
     881             :                                 }
     882          10 :                                 if (doprint) {
     883          10 :                                         break;
     884             :                                 }
     885             :                         }
     886          26 :                         if (doprint || (! parser->skipwhite)) {
     887          14 :                                 if (parser->lastwasopen) {
     888             :                                         zval *myval;
     889             :                                         
     890             :                                         /* check if the current tag already has a value - if yes append to that! */
     891           9 :                                         if ((myval = zend_hash_str_find(Z_ARRVAL_P(parser->ctag), "value", sizeof("value") - 1))) {
     892           2 :                                                 int newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value);
     893           4 :                                                 Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0);
     894           4 :                                                 strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value),
     895           2 :                                                                 ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1);
     896             :                                                 zend_string_release(decoded_value);
     897             :                                         } else {
     898           7 :                                                 add_assoc_str(parser->ctag, "value", decoded_value);
     899             :                                         }
     900             :                                         
     901             :                                 } else {
     902             :                                         zval tag;
     903             :                                         zval *curtag, *mytype, *myval;
     904             : 
     905          15 :                                         ZEND_HASH_REVERSE_FOREACH_VAL(Z_ARRVAL(parser->data), curtag) {
     906           5 :                                                 if ((mytype = zend_hash_str_find(Z_ARRVAL_P(curtag),"type", sizeof("type") - 1))) {
     907           5 :                                                         if (!strcmp(Z_STRVAL_P(mytype), "cdata")) {
     908           2 :                                                                 if ((myval = zend_hash_str_find(Z_ARRVAL_P(curtag), "value", sizeof("value") - 1))) {
     909           2 :                                                                         int newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value);
     910           4 :                                                                         Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0);
     911           4 :                                                                         strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value),
     912           2 :                                                                                         ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1);
     913             :                                                                         zend_string_release(decoded_value);
     914           2 :                                                                         return;
     915             :                                                                 }
     916             :                                                         }
     917             :                                                 }
     918           3 :                                                 break;
     919             :                                         } ZEND_HASH_FOREACH_END();
     920             : 
     921           6 :                                         if (parser->level <= XML_MAXLEVEL && parser->level > 0) {
     922           3 :                                                 array_init(&tag);
     923             : 
     924           3 :                                                 _xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset);
     925             : 
     926           3 :                                                 add_assoc_string(&tag, "tag", parser->ltags[parser->level-1] + parser->toffset);
     927           3 :                                                 add_assoc_str(&tag, "value", decoded_value);
     928           3 :                                                 add_assoc_string(&tag, "type", "cdata");
     929           3 :                                                 add_assoc_long(&tag, "level", parser->level);
     930             : 
     931           3 :                                                 zend_hash_next_index_insert(Z_ARRVAL(parser->data), &tag);
     932           0 :                                         } else if (parser->level == (XML_MAXLEVEL + 1)) {
     933           0 :                                                                                         php_error_docref(NULL, E_WARNING, "Maximum depth exceeded - Results truncated");
     934             :                                         }
     935             :                                 }
     936             :                         } else {
     937             :                                 zend_string_release(decoded_value);
     938             :                         }
     939             :                 }
     940             :         }
     941             : }
     942             : /* }}} */
     943             : 
     944             : /* {{{ _xml_processingInstructionHandler() */
     945           1 : void _xml_processingInstructionHandler(void *userData, const XML_Char *target, const XML_Char *data)
     946             : {
     947           1 :         xml_parser *parser = (xml_parser *)userData;
     948             : 
     949           2 :         if (parser && !Z_ISUNDEF(parser->processingInstructionHandler)) {
     950             :                 zval retval, args[3];
     951             : 
     952           1 :                 ZVAL_COPY(&args[0], &parser->index);
     953           1 :                 _xml_xmlchar_zval(target, 0, parser->target_encoding, &args[1]);
     954           1 :                 _xml_xmlchar_zval(data, 0, parser->target_encoding, &args[2]);
     955           1 :                 xml_call_handler(parser, &parser->processingInstructionHandler, parser->processingInstructionPtr, 3, args, &retval);
     956           1 :                 zval_ptr_dtor(&retval);
     957             :         }
     958           1 : }
     959             : /* }}} */
     960             : 
     961             : /* {{{ _xml_defaultHandler() */
     962          13 : void _xml_defaultHandler(void *userData, const XML_Char *s, int len)
     963             : {
     964          13 :         xml_parser *parser = (xml_parser *)userData;
     965             : 
     966          26 :         if (parser && !Z_ISUNDEF(parser->defaultHandler)) {
     967             :                 zval retval, args[2];
     968             : 
     969          13 :                 ZVAL_COPY(&args[0], &parser->index);
     970          13 :                 _xml_xmlchar_zval(s, len, parser->target_encoding, &args[1]);
     971          13 :                 xml_call_handler(parser, &parser->defaultHandler, parser->defaultPtr, 2, args, &retval);
     972          13 :                 zval_ptr_dtor(&retval);
     973             :         }
     974          13 : }
     975             : /* }}} */
     976             : 
     977             : /* {{{ _xml_unparsedEntityDeclHandler() */
     978           3 : void _xml_unparsedEntityDeclHandler(void *userData, 
     979             :                                                                                  const XML_Char *entityName, 
     980             :                                                                                  const XML_Char *base,
     981             :                                                                                  const XML_Char *systemId,
     982             :                                                                                  const XML_Char *publicId,
     983             :                                                                                  const XML_Char *notationName)
     984             : {
     985           3 :         xml_parser *parser = (xml_parser *)userData;
     986             : 
     987           6 :         if (parser && !Z_ISUNDEF(parser->unparsedEntityDeclHandler)) {
     988             :                 zval retval, args[6];
     989             : 
     990           3 :                 ZVAL_COPY(&args[0], &parser->index);
     991           3 :                 _xml_xmlchar_zval(entityName, 0, parser->target_encoding, &args[1]);
     992           3 :                 _xml_xmlchar_zval(base, 0, parser->target_encoding, &args[2]);
     993           3 :                 _xml_xmlchar_zval(systemId, 0, parser->target_encoding, &args[3]);
     994           3 :                 _xml_xmlchar_zval(publicId, 0, parser->target_encoding, &args[4]);
     995           3 :                 _xml_xmlchar_zval(notationName, 0, parser->target_encoding, &args[5]);
     996           3 :                 xml_call_handler(parser, &parser->unparsedEntityDeclHandler, parser->unparsedEntityDeclPtr, 6, args, &retval);
     997           3 :                 zval_ptr_dtor(&retval);
     998             :         }
     999           3 : }
    1000             : /* }}} */
    1001             : 
    1002             : /* {{{ _xml_notationDeclHandler() */
    1003           3 : void _xml_notationDeclHandler(void *userData,
    1004             :                                                           const XML_Char *notationName,
    1005             :                                                           const XML_Char *base,
    1006             :                                                           const XML_Char *systemId,
    1007             :                                                           const XML_Char *publicId)
    1008             : {
    1009           3 :         xml_parser *parser = (xml_parser *)userData;
    1010             : 
    1011           6 :         if (parser && !Z_ISUNDEF(parser->notationDeclHandler)) {
    1012             :                 zval retval, args[5];
    1013             : 
    1014           3 :                 ZVAL_COPY(&args[0], &parser->index);
    1015           3 :                 _xml_xmlchar_zval(notationName, 0, parser->target_encoding, &args[1]);
    1016           3 :                 _xml_xmlchar_zval(base, 0, parser->target_encoding, &args[2]);
    1017           3 :                 _xml_xmlchar_zval(systemId, 0, parser->target_encoding, &args[3]);
    1018           3 :                 _xml_xmlchar_zval(publicId, 0, parser->target_encoding, &args[4]);
    1019           3 :                 xml_call_handler(parser, &parser->notationDeclHandler, parser->notationDeclPtr, 5, args, &retval);
    1020           3 :                 zval_ptr_dtor(&retval);
    1021             :         }
    1022           3 : }
    1023             : /* }}} */
    1024             : 
    1025             : /* {{{ _xml_externalEntityRefHandler() */
    1026           0 : int _xml_externalEntityRefHandler(XML_Parser parserPtr,
    1027             :                                                                    const XML_Char *openEntityNames,
    1028             :                                                                    const XML_Char *base,
    1029             :                                                                    const XML_Char *systemId,
    1030             :                                                                    const XML_Char *publicId)
    1031             : {
    1032           0 :         xml_parser *parser = XML_GetUserData(parserPtr);
    1033           0 :         int ret = 0; /* abort if no handler is set (should be configurable?) */
    1034             : 
    1035           0 :         if (parser && !Z_ISUNDEF(parser->externalEntityRefHandler)) {
    1036             :                 zval retval, args[5];
    1037             : 
    1038           0 :                 ZVAL_COPY(&args[0], &parser->index);
    1039           0 :                 _xml_xmlchar_zval(openEntityNames, 0, parser->target_encoding, &args[1]);
    1040           0 :                 _xml_xmlchar_zval(base, 0, parser->target_encoding, &args[2]);
    1041           0 :                 _xml_xmlchar_zval(systemId, 0, parser->target_encoding, &args[3]);
    1042           0 :                 _xml_xmlchar_zval(publicId, 0, parser->target_encoding, &args[4]);
    1043           0 :                 xml_call_handler(parser, &parser->externalEntityRefHandler, parser->externalEntityRefPtr, 5, args, &retval);
    1044           0 :                 if (!Z_ISUNDEF(retval)) {
    1045           0 :                         convert_to_long(&retval);
    1046           0 :                         ret = Z_LVAL(retval);
    1047             :                 } else {
    1048           0 :                         ret = 0;
    1049             :                 }
    1050             :         }
    1051           0 :         return ret;
    1052             : }
    1053             : /* }}} */
    1054             : 
    1055             : /* {{{ _xml_startNamespaceDeclHandler() */
    1056           2 : void _xml_startNamespaceDeclHandler(void *userData,const XML_Char *prefix, const XML_Char *uri)
    1057             : {
    1058           2 :         xml_parser *parser = (xml_parser *)userData;
    1059             : 
    1060           4 :         if (parser && !Z_ISUNDEF(parser->startNamespaceDeclHandler)) {
    1061             :                 zval retval, args[3];
    1062             : 
    1063           2 :                 ZVAL_COPY(&args[0], &parser->index);
    1064           2 :                 _xml_xmlchar_zval(prefix, 0, parser->target_encoding, &args[1]);
    1065           2 :                 _xml_xmlchar_zval(uri, 0, parser->target_encoding, &args[2]);
    1066           2 :                 xml_call_handler(parser, &parser->startNamespaceDeclHandler, parser->startNamespaceDeclPtr, 3, args, &retval);
    1067           2 :                 zval_ptr_dtor(&retval);
    1068             :         }
    1069           2 : }
    1070             : /* }}} */
    1071             : 
    1072             : /* {{{ _xml_endNamespaceDeclHandler() */
    1073           0 : void _xml_endNamespaceDeclHandler(void *userData, const XML_Char *prefix)
    1074             : {
    1075           0 :         xml_parser *parser = (xml_parser *)userData;
    1076             : 
    1077           0 :         if (parser && !Z_ISUNDEF(parser->endNamespaceDeclHandler)) {
    1078             :                 zval retval, args[2];
    1079             : 
    1080           0 :                 ZVAL_COPY(&args[0], &parser->index);
    1081           0 :                 _xml_xmlchar_zval(prefix, 0, parser->target_encoding, &args[1]);
    1082           0 :                 xml_call_handler(parser, &parser->endNamespaceDeclHandler, parser->endNamespaceDeclPtr, 2, args, &retval);
    1083           0 :                 zval_ptr_dtor(&retval);
    1084             :         }
    1085           0 : }
    1086             : /* }}} */
    1087             : 
    1088             : /************************* EXTENSION FUNCTIONS *************************/
    1089             : 
    1090         187 : static void php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAMETERS, int ns_support) /* {{{ */
    1091             : {
    1092             :         xml_parser *parser;
    1093         187 :         int auto_detect = 0;
    1094             : 
    1095         187 :         char *encoding_param = NULL;
    1096         187 :         size_t encoding_param_len = 0;
    1097             : 
    1098         187 :         char *ns_param = NULL;
    1099         187 :         size_t ns_param_len = 0;
    1100             :         
    1101             :         XML_Char *encoding;
    1102             :         
    1103         187 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), (ns_support ? "|ss": "|s"), &encoding_param, &encoding_param_len, &ns_param, &ns_param_len) == FAILURE) {
    1104          14 :                 RETURN_FALSE;
    1105             :         }
    1106             : 
    1107         173 :         if (encoding_param != NULL) {
    1108             :                 /* The supported encoding types are hardcoded here because
    1109             :                  * we are limited to the encodings supported by expat/xmltok.
    1110             :                  */
    1111          63 :                 if (encoding_param_len == 0) {
    1112          16 :                         encoding = XML(default_encoding);
    1113          16 :                         auto_detect = 1;
    1114          47 :                 } else if (strcasecmp(encoding_param, "ISO-8859-1") == 0) {
    1115          11 :                         encoding = (XML_Char*)"ISO-8859-1";
    1116          36 :                 } else if (strcasecmp(encoding_param, "UTF-8") == 0) {
    1117           3 :                         encoding = (XML_Char*)"UTF-8";
    1118          33 :                 } else if (strcasecmp(encoding_param, "US-ASCII") == 0) {
    1119           2 :                         encoding = (XML_Char*)"US-ASCII";
    1120             :                 } else {
    1121          31 :                         php_error_docref(NULL, E_WARNING, "unsupported source encoding \"%s\"", encoding_param);
    1122          31 :                         RETURN_FALSE;
    1123             :                 }
    1124             :         } else {
    1125         110 :                 encoding = XML(default_encoding);
    1126             :         }
    1127             : 
    1128         142 :         if (ns_support && ns_param == NULL){
    1129          22 :                 ns_param = ":";
    1130             :         }
    1131             : 
    1132         142 :         parser = ecalloc(1, sizeof(xml_parser));
    1133         142 :         parser->parser = XML_ParserCreate_MM((auto_detect ? NULL : encoding),
    1134             :                                          &php_xml_mem_hdlrs, (XML_Char*)ns_param);
    1135             : 
    1136         142 :         parser->target_encoding = encoding;
    1137         142 :         parser->case_folding = 1;
    1138         142 :         parser->isparsing = 0;
    1139             : 
    1140         142 :         XML_SetUserData(parser->parser, parser);
    1141             : 
    1142         142 :         RETVAL_RES(zend_register_resource(parser, le_xml_parser));
    1143         142 :         ZVAL_COPY(&parser->index, return_value);
    1144             : }
    1145             : /* }}} */
    1146             : 
    1147             : /* {{{ proto resource xml_parser_create([string encoding]) 
    1148             :    Create an XML parser */
    1149         139 : PHP_FUNCTION(xml_parser_create)
    1150             : {
    1151         139 :         php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);        
    1152         139 : }
    1153             : /* }}} */
    1154             : 
    1155             : /* {{{ proto resource xml_parser_create_ns([string encoding [, string sep]]) 
    1156             :    Create an XML parser */
    1157          48 : PHP_FUNCTION(xml_parser_create_ns)
    1158             : {
    1159          48 :         php_xml_parser_create_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    1160          48 : }
    1161             : /* }}} */
    1162             : 
    1163             : /* {{{ proto int xml_set_object(resource parser, object &obj) 
    1164             :    Set up object which should be used for callbacks */
    1165          61 : PHP_FUNCTION(xml_set_object)
    1166             : {
    1167             :         xml_parser *parser;
    1168             :         zval *pind, *mythis;
    1169             : 
    1170          61 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ro", &pind, &mythis) == FAILURE) {
    1171          56 :                 return;
    1172             :         }
    1173             : 
    1174           5 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1175           1 :                 RETURN_FALSE;
    1176             :         }
    1177             : 
    1178             :         /* please leave this commented - or ask thies@thieso.net before doing it (again) */
    1179           8 :         if (!Z_ISUNDEF(parser->object)) {
    1180           0 :                 zval_ptr_dtor(&parser->object);
    1181             :         }
    1182             : 
    1183             :         /* please leave this commented - or ask thies@thieso.net before doing it (again) */
    1184             :         /* zval_add_ref(&parser->object); */
    1185             : 
    1186           4 :         ZVAL_COPY(&parser->object, mythis);
    1187             : 
    1188           4 :         RETVAL_TRUE;
    1189             : }
    1190             : /* }}} */
    1191             : 
    1192             : /* {{{ proto int xml_set_element_handler(resource parser, string shdl, string ehdl) 
    1193             :    Set up start and end element handlers */
    1194          43 : PHP_FUNCTION(xml_set_element_handler)
    1195             : {
    1196             :         xml_parser *parser;
    1197             :         zval *pind, *shdl, *ehdl;
    1198             : 
    1199          43 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rzz", &pind, &shdl, &ehdl) == FAILURE) {
    1200          29 :                 return;
    1201             :         }
    1202             : 
    1203          14 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1204           1 :                 RETURN_FALSE;
    1205             :         }
    1206             : 
    1207          13 :         xml_set_handler(&parser->startElementHandler, shdl);
    1208          13 :         xml_set_handler(&parser->endElementHandler, ehdl);
    1209          13 :         XML_SetElementHandler(parser->parser, _xml_startElementHandler, _xml_endElementHandler);
    1210          13 :         RETVAL_TRUE;
    1211             : }
    1212             : /* }}} */
    1213             : 
    1214             : /* {{{ proto int xml_set_character_data_handler(resource parser, string hdl) 
    1215             :    Set up character data handler */
    1216          33 : PHP_FUNCTION(xml_set_character_data_handler)
    1217             : {
    1218             :         xml_parser *parser;
    1219             :         zval *pind, *hdl;
    1220             : 
    1221          33 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) {
    1222          29 :                 return;
    1223             :         }
    1224             : 
    1225           4 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1226           1 :                 RETURN_FALSE;
    1227             :         }
    1228             : 
    1229           3 :         xml_set_handler(&parser->characterDataHandler, hdl);
    1230           3 :         XML_SetCharacterDataHandler(parser->parser, _xml_characterDataHandler);
    1231           3 :         RETVAL_TRUE;
    1232             : }
    1233             : /* }}} */
    1234             : 
    1235             : /* {{{ proto int xml_set_processing_instruction_handler(resource parser, string hdl) 
    1236             :    Set up processing instruction (PI) handler */
    1237          31 : PHP_FUNCTION(xml_set_processing_instruction_handler)
    1238             : {
    1239             :         xml_parser *parser;
    1240             :         zval *pind, *hdl;
    1241             : 
    1242          31 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) {
    1243          29 :                 return;
    1244             :         }
    1245             : 
    1246           2 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1247           1 :                 RETURN_FALSE;
    1248             :         }
    1249             : 
    1250           1 :         xml_set_handler(&parser->processingInstructionHandler, hdl);
    1251           1 :         XML_SetProcessingInstructionHandler(parser->parser, _xml_processingInstructionHandler);
    1252           1 :         RETVAL_TRUE;
    1253             : }
    1254             : /* }}} */
    1255             : 
    1256             : /* {{{ proto int xml_set_default_handler(resource parser, string hdl) 
    1257             :    Set up default handler */
    1258          32 : PHP_FUNCTION(xml_set_default_handler)
    1259             : {
    1260             :         xml_parser *parser;
    1261             :         zval *pind, *hdl;
    1262             : 
    1263          32 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) {
    1264          29 :                 return;
    1265             :         }
    1266             : 
    1267           3 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1268           1 :                 RETURN_FALSE;
    1269             :         }
    1270             : 
    1271           2 :         xml_set_handler(&parser->defaultHandler, hdl);
    1272           2 :         XML_SetDefaultHandler(parser->parser, _xml_defaultHandler);
    1273           2 :         RETVAL_TRUE;
    1274             : }
    1275             : /* }}} */
    1276             : 
    1277             : /* {{{ proto int xml_set_unparsed_entity_decl_handler(resource parser, string hdl) 
    1278             :    Set up unparsed entity declaration handler */
    1279          31 : PHP_FUNCTION(xml_set_unparsed_entity_decl_handler)
    1280             : {
    1281             :         xml_parser *parser;
    1282             :         zval *pind, *hdl;
    1283             : 
    1284          31 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) {
    1285          29 :                 return;
    1286             :         }
    1287             : 
    1288           2 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1289           1 :                 RETURN_FALSE;
    1290             :         }
    1291             : 
    1292           1 :         xml_set_handler(&parser->unparsedEntityDeclHandler, hdl);
    1293           1 :         XML_SetUnparsedEntityDeclHandler(parser->parser, _xml_unparsedEntityDeclHandler);
    1294           1 :         RETVAL_TRUE;
    1295             : }
    1296             : /* }}} */
    1297             : 
    1298             : /* {{{ proto int xml_set_notation_decl_handler(resource parser, string hdl) 
    1299             :    Set up notation declaration handler */
    1300          31 : PHP_FUNCTION(xml_set_notation_decl_handler)
    1301             : {
    1302             :         xml_parser *parser;
    1303             :         zval *pind, *hdl;
    1304             : 
    1305          31 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) {
    1306          29 :                 return;
    1307             :         }
    1308             : 
    1309           2 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1310           1 :                 RETURN_FALSE;
    1311             :         }
    1312             : 
    1313           1 :         xml_set_handler(&parser->notationDeclHandler, hdl);
    1314           1 :         XML_SetNotationDeclHandler(parser->parser, _xml_notationDeclHandler);
    1315           1 :         RETVAL_TRUE;
    1316             : }
    1317             : /* }}} */
    1318             : 
    1319             : /* {{{ proto int xml_set_external_entity_ref_handler(resource parser, string hdl) 
    1320             :    Set up external entity reference handler */
    1321          30 : PHP_FUNCTION(xml_set_external_entity_ref_handler)
    1322             : {
    1323             :         xml_parser *parser;
    1324             :         zval *pind, *hdl;
    1325             : 
    1326          30 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) {
    1327          29 :                 return;
    1328             :         }
    1329             : 
    1330           1 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1331           1 :                 RETURN_FALSE;
    1332             :         }
    1333             : 
    1334           0 :         xml_set_handler(&parser->externalEntityRefHandler, hdl);
    1335           0 :         XML_SetExternalEntityRefHandler(parser->parser, (void *) _xml_externalEntityRefHandler);
    1336           0 :         RETVAL_TRUE;
    1337             : }
    1338             : /* }}} */
    1339             : 
    1340             : /* {{{ proto int xml_set_start_namespace_decl_handler(resource parser, string hdl) 
    1341             :    Set up character data handler */
    1342          31 : PHP_FUNCTION(xml_set_start_namespace_decl_handler)
    1343             : {
    1344             :         xml_parser *parser;
    1345             :         zval *pind, *hdl;
    1346             : 
    1347          31 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) {
    1348          29 :                 return;
    1349             :         }
    1350             : 
    1351           2 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1352           1 :                 RETURN_FALSE;
    1353             :         }
    1354             : 
    1355           1 :         xml_set_handler(&parser->startNamespaceDeclHandler, hdl);
    1356           1 :         XML_SetStartNamespaceDeclHandler(parser->parser, _xml_startNamespaceDeclHandler);
    1357           1 :         RETVAL_TRUE;
    1358             : }
    1359             : /* }}} */
    1360             : 
    1361             : /* {{{ proto int xml_set_end_namespace_decl_handler(resource parser, string hdl) 
    1362             :    Set up character data handler */
    1363          31 : PHP_FUNCTION(xml_set_end_namespace_decl_handler)
    1364             : {
    1365             :         xml_parser *parser;
    1366             :         zval *pind, *hdl;
    1367             : 
    1368          31 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pind, &hdl) == FAILURE) {
    1369          29 :                 return;
    1370             :         }
    1371             : 
    1372           2 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1373           1 :                 RETURN_FALSE;
    1374             :         }
    1375             : 
    1376           1 :         xml_set_handler(&parser->endNamespaceDeclHandler, hdl);
    1377           1 :         XML_SetEndNamespaceDeclHandler(parser->parser, _xml_endNamespaceDeclHandler);
    1378           1 :         RETVAL_TRUE;
    1379             : }
    1380             : /* }}} */
    1381             : 
    1382             : /* {{{ proto int xml_parse(resource parser, string data [, bool isFinal])
    1383             :    Start parsing an XML document */
    1384          47 : PHP_FUNCTION(xml_parse)
    1385             : {
    1386             :         xml_parser *parser;
    1387             :         zval *pind;
    1388             :         char *data;
    1389             :         size_t data_len;
    1390             :         int ret;
    1391          47 :         zend_bool isFinal = 0;
    1392             : 
    1393          47 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|b", &pind, &data, &data_len, &isFinal) == FAILURE) {
    1394          29 :                 return;
    1395             :         }
    1396             : 
    1397          18 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1398           1 :                 RETURN_FALSE;
    1399             :         }
    1400             : 
    1401          17 :         parser->isparsing = 1;
    1402          17 :         ret = XML_Parse(parser->parser, (XML_Char*)data, data_len, isFinal);
    1403          17 :         parser->isparsing = 0;
    1404          17 :         RETVAL_LONG(ret);
    1405             : }
    1406             : 
    1407             : /* }}} */
    1408             : 
    1409             : /* {{{ proto int xml_parse_into_struct(resource parser, string data, array &values [, array &index ])
    1410             :    Parsing a XML document */
    1411             : 
    1412          37 : PHP_FUNCTION(xml_parse_into_struct)
    1413             : {
    1414             :         xml_parser *parser;
    1415          37 :         zval *pind, *xdata, *info = NULL;
    1416             :         char *data;
    1417             :         size_t data_len;
    1418             :         int ret;
    1419             : 
    1420          37 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsz/|z/", &pind, &data, &data_len, &xdata, &info) == FAILURE) {
    1421          29 :                 return;
    1422             :         }
    1423             : 
    1424           8 :         if (info) {     
    1425           7 :                 zval_ptr_dtor(info);
    1426           7 :                 array_init(info);
    1427             :         }
    1428             : 
    1429           8 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1430           1 :                 RETURN_FALSE;
    1431             :         }
    1432             : 
    1433           7 :         zval_ptr_dtor(xdata);
    1434           7 :         array_init(xdata);
    1435             : 
    1436           7 :         ZVAL_COPY_VALUE(&parser->data, xdata);
    1437             :         
    1438           7 :         if (info) {
    1439           6 :                 ZVAL_COPY_VALUE(&parser->info, info);
    1440             :         }
    1441             :         
    1442           7 :         parser->level = 0;
    1443           7 :         parser->ltags = safe_emalloc(XML_MAXLEVEL, sizeof(char *), 0);
    1444             : 
    1445           7 :         XML_SetDefaultHandler(parser->parser, _xml_defaultHandler);
    1446           7 :         XML_SetElementHandler(parser->parser, _xml_startElementHandler, _xml_endElementHandler);
    1447           7 :         XML_SetCharacterDataHandler(parser->parser, _xml_characterDataHandler);
    1448             : 
    1449           7 :         parser->isparsing = 1;
    1450           7 :         ret = XML_Parse(parser->parser, (XML_Char*)data, data_len, 1);
    1451           7 :         parser->isparsing = 0;
    1452             : 
    1453           7 :         RETVAL_LONG(ret);
    1454             : }
    1455             : /* }}} */
    1456             : 
    1457             : /* {{{ proto int xml_get_error_code(resource parser) 
    1458             :    Get XML parser error code */
    1459          30 : PHP_FUNCTION(xml_get_error_code)
    1460             : {
    1461             :         xml_parser *parser;
    1462             :         zval *pind;
    1463             : 
    1464          30 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) {
    1465          29 :                 return;
    1466             :         }
    1467             : 
    1468           1 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1469           1 :                 RETURN_FALSE;
    1470             :         }
    1471             : 
    1472           0 :         RETURN_LONG((zend_long)XML_GetErrorCode(parser->parser));
    1473             : }
    1474             : /* }}} */
    1475             : 
    1476             : /* {{{ proto string xml_error_string(int code)
    1477             :    Get XML parser error string */
    1478          25 : PHP_FUNCTION(xml_error_string)
    1479             : {
    1480             :         zend_long code;
    1481             :         char *str;
    1482             : 
    1483          25 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &code) == FAILURE) {
    1484          12 :                 return;
    1485             :         }
    1486             : 
    1487          13 :         str = (char *)XML_ErrorString((int)code);
    1488          13 :         if (str) {
    1489          26 :                 RETVAL_STRING(str);
    1490             :         }
    1491             : }
    1492             : /* }}} */
    1493             : 
    1494             : /* {{{ proto int xml_get_current_line_number(resource parser) 
    1495             :    Get current line number for an XML parser */
    1496          36 : PHP_FUNCTION(xml_get_current_line_number)
    1497             : {
    1498             :         xml_parser *parser;
    1499             :         zval *pind;
    1500             : 
    1501          36 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) {
    1502          29 :                 return;
    1503             :         }
    1504             : 
    1505           7 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1506           1 :                 RETURN_FALSE;
    1507             :         }
    1508             : 
    1509           6 :         RETVAL_LONG(XML_GetCurrentLineNumber(parser->parser));
    1510             : }
    1511             : /* }}} */
    1512             : 
    1513             : /* {{{ proto int xml_get_current_column_number(resource parser)
    1514             :    Get current column number for an XML parser */
    1515          36 : PHP_FUNCTION(xml_get_current_column_number)
    1516             : {
    1517             :         xml_parser *parser;
    1518             :         zval *pind;
    1519             : 
    1520          36 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) {
    1521          29 :                 return;
    1522             :         }
    1523             : 
    1524           7 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1525           1 :                 RETURN_FALSE;
    1526             :         }
    1527             : 
    1528           6 :         RETVAL_LONG(XML_GetCurrentColumnNumber(parser->parser));
    1529             : }
    1530             : /* }}} */
    1531             : 
    1532             : /* {{{ proto int xml_get_current_byte_index(resource parser) 
    1533             :    Get current byte index for an XML parser */
    1534          36 : PHP_FUNCTION(xml_get_current_byte_index)
    1535             : {
    1536             :         xml_parser *parser;
    1537             :         zval *pind;
    1538             : 
    1539          36 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) {
    1540          29 :                 return;
    1541             :         }
    1542             : 
    1543           7 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1544           1 :                 RETURN_FALSE;
    1545             :         }
    1546             : 
    1547           6 :         RETVAL_LONG(XML_GetCurrentByteIndex(parser->parser));
    1548             : }
    1549             : /* }}} */
    1550             : 
    1551             : /* {{{ proto int xml_parser_free(resource parser) 
    1552             :    Free an XML parser */
    1553          78 : PHP_FUNCTION(xml_parser_free)
    1554             : {
    1555             :         zval *pind;
    1556             :         xml_parser *parser;
    1557             : 
    1558          78 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) {
    1559          29 :                 return;
    1560             :         }
    1561             : 
    1562          49 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1563           1 :                 RETURN_FALSE;
    1564             :         }
    1565             : 
    1566          48 :         if (parser->isparsing == 1) {
    1567           0 :                 php_error_docref(NULL, E_WARNING, "Parser cannot be freed while it is parsing.");
    1568           0 :                 RETURN_FALSE;
    1569             :         }
    1570             : 
    1571          48 :         if (zend_list_delete(Z_RES(parser->index)) == FAILURE) {
    1572           0 :                 RETURN_FALSE;
    1573             :         }
    1574             : 
    1575          48 :         RETURN_TRUE;
    1576             : }
    1577             : /* }}} */
    1578             : 
    1579             : /* {{{ proto int xml_parser_set_option(resource parser, int option, mixed value) 
    1580             :    Set options in an XML parser */
    1581         100 : PHP_FUNCTION(xml_parser_set_option)
    1582             : {
    1583             :         xml_parser *parser;
    1584             :         zval *pind, *val;
    1585             :         zend_long opt;
    1586             : 
    1587         100 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlz", &pind, &opt, &val) == FAILURE) {
    1588          39 :                 return;
    1589             :         }
    1590             : 
    1591          61 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1592           1 :                 RETURN_FALSE;
    1593             :         }
    1594             : 
    1595          60 :         switch (opt) {
    1596             :                 case PHP_XML_OPTION_CASE_FOLDING:
    1597          84 :                         convert_to_long_ex(val);
    1598          42 :                         parser->case_folding = Z_LVAL_P(val);
    1599          42 :                         break;
    1600             :                 case PHP_XML_OPTION_SKIP_TAGSTART:
    1601           4 :                         convert_to_long_ex(val);
    1602           2 :                         parser->toffset = Z_LVAL_P(val);
    1603           2 :                         break;
    1604             :                 case PHP_XML_OPTION_SKIP_WHITE:
    1605           0 :                         convert_to_long_ex(val);
    1606           0 :                         parser->skipwhite = Z_LVAL_P(val);
    1607           0 :                         break;
    1608             :                 case PHP_XML_OPTION_TARGET_ENCODING: {
    1609             :                         xml_encoding *enc;
    1610           6 :                         convert_to_string_ex(val);
    1611           3 :                         enc = xml_get_encoding((XML_Char*)Z_STRVAL_P(val));
    1612           3 :                         if (enc == NULL) {
    1613           0 :                                 php_error_docref(NULL, E_WARNING, "Unsupported target encoding \"%s\"", Z_STRVAL_P(val));
    1614           0 :                                 RETURN_FALSE;
    1615             :                         }
    1616           3 :                         parser->target_encoding = enc->name;
    1617           3 :                         break;
    1618             :                 }
    1619             :                 default:
    1620          13 :                         php_error_docref(NULL, E_WARNING, "Unknown option");
    1621          13 :                         RETURN_FALSE;
    1622             :                         break;
    1623             :         }
    1624          47 :         RETVAL_TRUE;
    1625             : }
    1626             : /* }}} */
    1627             : 
    1628             : /* {{{ proto int xml_parser_get_option(resource parser, int option) 
    1629             :    Get options from an XML parser */
    1630          63 : PHP_FUNCTION(xml_parser_get_option)
    1631             : {
    1632             :         xml_parser *parser;
    1633             :         zval *pind;
    1634             :         zend_long opt;
    1635             : 
    1636          63 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &pind, &opt) == FAILURE) {
    1637          40 :                 return;
    1638             :         }
    1639             : 
    1640          23 :         if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) {
    1641           1 :                 RETURN_FALSE;
    1642             :         }
    1643             : 
    1644          22 :         switch (opt) {
    1645             :                 case PHP_XML_OPTION_CASE_FOLDING:
    1646           5 :                         RETURN_LONG(parser->case_folding);
    1647             :                         break;
    1648             :                 case PHP_XML_OPTION_TARGET_ENCODING:
    1649           8 :                         RETURN_STRING((char *)parser->target_encoding);
    1650             :                         break;
    1651             :                 default:
    1652          13 :                         php_error_docref(NULL, E_WARNING, "Unknown option");
    1653          13 :                         RETURN_FALSE;
    1654             :                         break;
    1655             :         }
    1656             : 
    1657             :         RETVAL_FALSE;   /* never reached */
    1658             : }
    1659             : /* }}} */
    1660             : 
    1661             : /* {{{ proto string utf8_encode(string data) 
    1662             :    Encodes an ISO-8859-1 string to UTF-8 */
    1663          32 : PHP_FUNCTION(utf8_encode)
    1664             : {
    1665             :         char *arg;
    1666             :         size_t arg_len;
    1667             :         zend_string *encoded;
    1668             : 
    1669          32 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
    1670           7 :                 return;
    1671             :         }
    1672             : 
    1673          25 :         encoded = xml_utf8_encode(arg, arg_len, (XML_Char*)"ISO-8859-1");
    1674          25 :         if (encoded == NULL) {
    1675           0 :                 RETURN_FALSE;
    1676             :         }
    1677          25 :         RETURN_STR(encoded);
    1678             : }
    1679             : /* }}} */
    1680             : 
    1681             : /* {{{ proto string utf8_decode(string data) 
    1682             :    Converts a UTF-8 encoded string to ISO-8859-1 */
    1683          35 : PHP_FUNCTION(utf8_decode)
    1684             : {
    1685             :         char *arg;
    1686             :         size_t arg_len;
    1687             :         zend_string *decoded;
    1688             : 
    1689          35 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
    1690           7 :                 return;
    1691             :         }
    1692             : 
    1693          28 :         decoded = xml_utf8_decode((XML_Char*)arg, arg_len, (XML_Char*)"ISO-8859-1");
    1694          28 :         if (decoded == NULL) {
    1695           0 :                 RETURN_FALSE;
    1696             :         }
    1697          28 :         RETURN_STR(decoded);
    1698             : }
    1699             : /* }}} */
    1700             : 
    1701             : #endif
    1702             : 
    1703             : /*
    1704             :  * Local variables:
    1705             :  * tab-width: 4
    1706             :  * c-basic-offset: 4
    1707             :  * End:
    1708             :  * vim600: sw=4 ts=4 fdm=marker
    1709             :  * vim<600: sw=4 ts=4
    1710             :  */

Generated by: LCOV version 1.10

Generated at Wed, 20 Jul 2016 02:56:30 +0000 (5 days ago)

Copyright © 2005-2016 The PHP Group
All rights reserved.