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: 588 675 87.1 %
Date: 2014-09-21 Functions: 50 58 86.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sun, 21 Sep 2014 15:27:47 +0000 (22 hours ago)

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