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/libxml - libxml.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 421 478 88.1 %
Date: 2014-07-27 Functions: 44 46 95.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2013 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: Shane Caraveo <shane@php.net>                               |
      16             :    |          Wez Furlong <wez@thebrainroom.com>                          |
      17             :    +----------------------------------------------------------------------+
      18             :  */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #define IS_EXT_MODULE
      23             : 
      24             : #ifdef HAVE_CONFIG_H
      25             : #include "config.h"
      26             : #endif
      27             : 
      28             : #include "php.h"
      29             : 
      30             : #define PHP_XML_INTERNAL
      31             : #include "zend_variables.h"
      32             : #include "ext/standard/php_string.h"
      33             : #include "ext/standard/info.h"
      34             : #include "ext/standard/file.h"
      35             : 
      36             : #if HAVE_LIBXML
      37             : 
      38             : #include <libxml/parser.h>
      39             : #include <libxml/parserInternals.h>
      40             : #include <libxml/tree.h>
      41             : #include <libxml/uri.h>
      42             : #include <libxml/xmlerror.h>
      43             : #include <libxml/xmlsave.h>
      44             : #ifdef LIBXML_SCHEMAS_ENABLED
      45             : #include <libxml/relaxng.h>
      46             : #endif
      47             : 
      48             : #include "php_libxml.h"
      49             : 
      50             : #define PHP_LIBXML_ERROR 0
      51             : #define PHP_LIBXML_CTX_ERROR 1
      52             : #define PHP_LIBXML_CTX_WARNING 2
      53             : 
      54             : /* a true global for initialization */
      55             : static int _php_libxml_initialized = 0;
      56             : 
      57             : typedef struct _php_libxml_func_handler {
      58             :         php_libxml_export_node export_func;
      59             : } php_libxml_func_handler;
      60             : 
      61             : static HashTable php_libxml_exports;
      62             : 
      63             : static ZEND_DECLARE_MODULE_GLOBALS(libxml)
      64             : static PHP_GINIT_FUNCTION(libxml);
      65             : 
      66             : static PHP_FUNCTION(libxml_set_streams_context);
      67             : static PHP_FUNCTION(libxml_use_internal_errors);
      68             : static PHP_FUNCTION(libxml_get_last_error);
      69             : static PHP_FUNCTION(libxml_clear_errors);
      70             : static PHP_FUNCTION(libxml_get_errors);
      71             : static PHP_FUNCTION(libxml_disable_entity_loader);
      72             : 
      73             : static zend_class_entry *libxmlerror_class_entry;
      74             : 
      75             : /* {{{ dynamically loadable module stuff */
      76             : #ifdef COMPILE_DL_LIBXML
      77             : ZEND_GET_MODULE(libxml)
      78             : #endif /* COMPILE_DL_LIBXML */
      79             : /* }}} */
      80             : 
      81             : /* {{{ function prototypes */
      82             : static PHP_MINIT_FUNCTION(libxml);
      83             : static PHP_RINIT_FUNCTION(libxml);
      84             : static PHP_MSHUTDOWN_FUNCTION(libxml);
      85             : static PHP_MINFO_FUNCTION(libxml);
      86             : static int php_libxml_post_deactivate();
      87             : 
      88             : /* }}} */
      89             : 
      90             : /* {{{ arginfo */
      91             : ZEND_BEGIN_ARG_INFO(arginfo_libxml_set_streams_context, 0)
      92             :         ZEND_ARG_INFO(0, context)
      93             : ZEND_END_ARG_INFO()
      94             : 
      95             : ZEND_BEGIN_ARG_INFO_EX(arginfo_libxml_use_internal_errors, 0, 0, 0)
      96             :         ZEND_ARG_INFO(0, use_errors)
      97             : ZEND_END_ARG_INFO()
      98             : 
      99             : ZEND_BEGIN_ARG_INFO(arginfo_libxml_get_last_error, 0)
     100             : ZEND_END_ARG_INFO()
     101             : 
     102             : ZEND_BEGIN_ARG_INFO(arginfo_libxml_get_errors, 0)
     103             : ZEND_END_ARG_INFO()
     104             : 
     105             : ZEND_BEGIN_ARG_INFO(arginfo_libxml_clear_errors, 0)
     106             : ZEND_END_ARG_INFO()
     107             : 
     108             : ZEND_BEGIN_ARG_INFO_EX(arginfo_libxml_disable_entity_loader, 0, 0, 0)
     109             :         ZEND_ARG_INFO(0, disable)
     110             : ZEND_END_ARG_INFO()
     111             : 
     112             : /* }}} */
     113             : 
     114             : /* {{{ extension definition structures */
     115             : static const zend_function_entry libxml_functions[] = {
     116             :         PHP_FE(libxml_set_streams_context, arginfo_libxml_set_streams_context)
     117             :         PHP_FE(libxml_use_internal_errors, arginfo_libxml_use_internal_errors)
     118             :         PHP_FE(libxml_get_last_error, arginfo_libxml_get_last_error)
     119             :         PHP_FE(libxml_clear_errors, arginfo_libxml_clear_errors)
     120             :         PHP_FE(libxml_get_errors, arginfo_libxml_get_errors)
     121             :         PHP_FE(libxml_disable_entity_loader, arginfo_libxml_disable_entity_loader)
     122             :         PHP_FE_END
     123             : };
     124             : 
     125             : zend_module_entry libxml_module_entry = {
     126             :         STANDARD_MODULE_HEADER,
     127             :         "libxml",                /* extension name */
     128             :         libxml_functions,        /* extension function list */
     129             :         PHP_MINIT(libxml),       /* extension-wide startup function */
     130             :         PHP_MSHUTDOWN(libxml),   /* extension-wide shutdown function */
     131             :         PHP_RINIT(libxml),       /* per-request startup function */
     132             :         NULL,                    /* per-request shutdown function */
     133             :         PHP_MINFO(libxml),       /* information function */
     134             :         NO_VERSION_YET,
     135             :         PHP_MODULE_GLOBALS(libxml), /* globals descriptor */
     136             :         PHP_GINIT(libxml),          /* globals ctor */
     137             :         NULL,                       /* globals dtor */
     138             :         php_libxml_post_deactivate, /* post deactivate */
     139             :         STANDARD_MODULE_PROPERTIES_EX
     140             : };
     141             : 
     142             : /* }}} */
     143             : 
     144             : /* {{{ internal functions for interoperability */
     145           7 : static int php_libxml_clear_object(php_libxml_node_object *object TSRMLS_DC)
     146             : {
     147           7 :         if (object->properties) {
     148           7 :                 object->properties = NULL;
     149             :         }
     150           7 :         php_libxml_decrement_node_ptr(object TSRMLS_CC);
     151           7 :         return php_libxml_decrement_doc_ref(object TSRMLS_CC);
     152             : }
     153             : 
     154      203512 : static int php_libxml_unregister_node(xmlNodePtr nodep TSRMLS_DC)
     155             : {
     156             :         php_libxml_node_object *wrapper;
     157             : 
     158      203512 :         php_libxml_node_ptr *nodeptr = nodep->_private;
     159             : 
     160      203512 :         if (nodeptr != NULL) {
     161          10 :                 wrapper = nodeptr->_private;
     162          10 :                 if (wrapper) {
     163           7 :                         php_libxml_clear_object(wrapper TSRMLS_CC);
     164             :                 } else {
     165           3 :                         if (nodeptr->node != NULL && nodeptr->node->type != XML_DOCUMENT_NODE) {
     166           3 :                                 nodeptr->node->_private = NULL;
     167             :                         }
     168           3 :                         nodeptr->node = NULL;
     169             :                 }
     170             :         }
     171             : 
     172      203512 :         return -1;
     173             : }
     174             : 
     175         275 : static void php_libxml_node_free(xmlNodePtr node)
     176             : {
     177         275 :         if(node) {
     178         275 :                 if (node->_private != NULL) {
     179           0 :                         ((php_libxml_node_ptr *) node->_private)->node = NULL;
     180             :                 }
     181         275 :                 switch (node->type) {
     182             :                         case XML_ATTRIBUTE_NODE:
     183          30 :                                 xmlFreeProp((xmlAttrPtr) node);
     184          30 :                                 break;
     185             :                         case XML_ENTITY_DECL:
     186             :                         case XML_ELEMENT_DECL:
     187             :                         case XML_ATTRIBUTE_DECL:
     188           2 :                                 break;
     189             :                         case XML_NOTATION_NODE:
     190             :                                 /* These require special handling */
     191           5 :                                 if (node->name != NULL) {
     192           5 :                                         xmlFree((char *) node->name);
     193             :                                 }
     194           5 :                                 if (((xmlEntityPtr) node)->ExternalID != NULL) {
     195           5 :                                         xmlFree((char *) ((xmlEntityPtr) node)->ExternalID);
     196             :                                 }
     197           5 :                                 if (((xmlEntityPtr) node)->SystemID != NULL) {
     198           4 :                                         xmlFree((char *) ((xmlEntityPtr) node)->SystemID);
     199             :                                 }
     200           5 :                                 xmlFree(node);
     201           5 :                                 break;
     202             :                         case XML_NAMESPACE_DECL:
     203           0 :                                 if (node->ns) {
     204           0 :                                         xmlFreeNs(node->ns);
     205           0 :                                         node->ns = NULL;
     206             :                                 }
     207           0 :                                 node->type = XML_ELEMENT_NODE;
     208             :                         default:
     209         238 :                                 xmlFreeNode(node);
     210             :                 }
     211             :         }
     212         275 : }
     213             : 
     214         386 : static void php_libxml_node_free_list(xmlNodePtr node TSRMLS_DC)
     215             : {
     216             :         xmlNodePtr curnode;
     217             : 
     218         386 :         if (node != NULL) {
     219          85 :                 curnode = node;
     220         316 :                 while (curnode != NULL) {
     221         146 :                         node = curnode;
     222         146 :                         switch (node->type) {
     223             :                                 /* Skip property freeing for the following types */
     224             :                                 case XML_NOTATION_NODE:
     225             :                                 case XML_ENTITY_DECL:
     226           2 :                                         break;
     227             :                                 case XML_ENTITY_REF_NODE:
     228           0 :                                         php_libxml_node_free_list((xmlNodePtr) node->properties TSRMLS_CC);
     229           0 :                                         break;
     230             :                                 case XML_ATTRIBUTE_NODE:
     231          17 :                                                 if ((node->doc != NULL) && (((xmlAttrPtr) node)->atype == XML_ATTRIBUTE_ID)) {
     232           1 :                                                         xmlRemoveID(node->doc, (xmlAttrPtr) node);
     233             :                                                 }
     234             :                                 case XML_ATTRIBUTE_DECL:
     235             :                                 case XML_DTD_NODE:
     236             :                                 case XML_DOCUMENT_TYPE_NODE:
     237             :                                 case XML_NAMESPACE_DECL:
     238             :                                 case XML_TEXT_NODE:
     239         112 :                                         php_libxml_node_free_list(node->children TSRMLS_CC);
     240         112 :                                         break;
     241             :                                 default:
     242          32 :                                         php_libxml_node_free_list(node->children TSRMLS_CC);
     243          32 :                                         php_libxml_node_free_list((xmlNodePtr) node->properties TSRMLS_CC);
     244             :                         }
     245             : 
     246         146 :                         curnode = node->next;
     247         146 :                         xmlUnlinkNode(node);
     248         146 :                         if (php_libxml_unregister_node(node TSRMLS_CC) == 0) {
     249           0 :                                 node->doc = NULL;
     250             :                         }
     251         146 :                         php_libxml_node_free(node);
     252             :                 }
     253             :         }
     254         386 : }
     255             : 
     256             : /* }}} */
     257             : 
     258             : /* {{{ startup, shutdown and info functions */
     259       19341 : static PHP_GINIT_FUNCTION(libxml)
     260             : {
     261       19341 :         libxml_globals->stream_context = NULL;
     262       19341 :         libxml_globals->error_buffer.c = NULL;
     263       19341 :         libxml_globals->error_list = NULL;
     264       19341 :         libxml_globals->entity_loader_disabled = 0;
     265       19341 : }
     266             : 
     267             : /* Channel libxml file io layer through the PHP streams subsystem.
     268             :  * This allows use of ftps:// and https:// urls */
     269             : 
     270         916 : static void *php_libxml_streams_IO_open_wrapper(const char *filename, const char *mode, const int read_only)
     271             : {
     272             :         php_stream_statbuf ssbuf;
     273         916 :         php_stream_context *context = NULL;
     274         916 :         php_stream_wrapper *wrapper = NULL;
     275         916 :         char *resolved_path, *path_to_open = NULL;
     276         916 :         void *ret_val = NULL;
     277         916 :         int isescaped=0;
     278             :         xmlURI *uri;
     279             : 
     280             :         TSRMLS_FETCH();
     281             : 
     282         916 :         uri = xmlParseURI((xmlChar *)filename);
     283        1823 :         if (uri && (uri->scheme == NULL || (xmlStrncmp(uri->scheme, "file", 4) == 0))) {
     284         907 :                 resolved_path = xmlURIUnescapeString(filename, 0, NULL);
     285         907 :                 isescaped = 1;
     286             :         } else {
     287           9 :                 resolved_path = (char *)filename;
     288             :         }
     289             : 
     290         916 :         if (uri) {
     291         916 :                 xmlFreeURI(uri);
     292             :         }
     293             : 
     294         916 :         if (resolved_path == NULL) {
     295           0 :                 return NULL;
     296             :         }
     297             : 
     298             :         /* logic copied from _php_stream_stat, but we only want to fail
     299             :            if the wrapper supports stat, otherwise, figure it out from
     300             :            the open.  This logic is only to support hiding warnings
     301             :            that the streams layer puts out at times, but for libxml we
     302             :            may try to open files that don't exist, but it is not a failure
     303             :            in xml processing (eg. DTD files)  */
     304         916 :         wrapper = php_stream_locate_url_wrapper(resolved_path, &path_to_open, ENFORCE_SAFE_MODE TSRMLS_CC);
     305         916 :         if (wrapper && read_only && wrapper->wops->url_stat) {
     306         891 :                 if (wrapper->wops->url_stat(wrapper, path_to_open, PHP_STREAM_URL_STAT_QUIET, &ssbuf, NULL TSRMLS_CC) == -1) {
     307          15 :                         if (isescaped) {
     308          14 :                                 xmlFree(resolved_path);
     309             :                         }
     310          15 :                         return NULL;
     311             :                 }
     312             :         }
     313             : 
     314         901 :         context = php_stream_context_from_zval(LIBXML(stream_context), 0);
     315             : 
     316         901 :         ret_val = php_stream_open_wrapper_ex(path_to_open, (char *)mode, ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL, context);
     317         901 :         if (isescaped) {
     318         893 :                 xmlFree(resolved_path);
     319             :         }
     320         901 :         return ret_val;
     321             : }
     322             : 
     323         897 : static void *php_libxml_streams_IO_open_read_wrapper(const char *filename)
     324             : {
     325         897 :         return php_libxml_streams_IO_open_wrapper(filename, "rb", 1);
     326             : }
     327             : 
     328          19 : static void *php_libxml_streams_IO_open_write_wrapper(const char *filename)
     329             : {
     330          19 :         return php_libxml_streams_IO_open_wrapper(filename, "wb", 0);
     331             : }
     332             : 
     333        3735 : static int php_libxml_streams_IO_read(void *context, char *buffer, int len)
     334             : {
     335             :         TSRMLS_FETCH();
     336        3735 :         return php_stream_read((php_stream*)context, buffer, len);
     337             : }
     338             : 
     339          35 : static int php_libxml_streams_IO_write(void *context, const char *buffer, int len)
     340             : {
     341             :         TSRMLS_FETCH();
     342          35 :         return php_stream_write((php_stream*)context, buffer, len);
     343             : }
     344             : 
     345         898 : static int php_libxml_streams_IO_close(void *context)
     346             : {
     347             :         TSRMLS_FETCH();
     348         898 :         return php_stream_close((php_stream*)context);
     349             : }
     350             : 
     351             : static xmlParserInputBufferPtr
     352         897 : php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc)
     353             : {
     354             :         xmlParserInputBufferPtr ret;
     355         897 :         void *context = NULL;
     356             :         TSRMLS_FETCH();
     357             : 
     358         897 :         if (LIBXML(entity_loader_disabled)) {
     359           0 :                 return NULL;
     360             :         }
     361             : 
     362         897 :         if (URI == NULL)
     363           0 :                 return(NULL);
     364             : 
     365         897 :         context = php_libxml_streams_IO_open_read_wrapper(URI);
     366             : 
     367         897 :         if (context == NULL) {
     368          17 :                 return(NULL);
     369             :         }
     370             : 
     371             :         /* Allocate the Input buffer front-end. */
     372         880 :         ret = xmlAllocParserInputBuffer(enc);
     373         880 :         if (ret != NULL) {
     374         880 :                 ret->context = context;
     375         880 :                 ret->readcallback = php_libxml_streams_IO_read;
     376         880 :                 ret->closecallback = php_libxml_streams_IO_close;
     377             :         } else
     378           0 :                 php_libxml_streams_IO_close(context);
     379             : 
     380         880 :         return(ret);
     381             : }
     382             : 
     383             : static xmlOutputBufferPtr
     384          19 : php_libxml_output_buffer_create_filename(const char *URI,
     385             :                               xmlCharEncodingHandlerPtr encoder,
     386             :                               int compression ATTRIBUTE_UNUSED)
     387             : {
     388             :         xmlOutputBufferPtr ret;
     389             :         xmlURIPtr puri;
     390          19 :         void *context = NULL;
     391          19 :         char *unescaped = NULL;
     392             : 
     393          19 :         if (URI == NULL)
     394           0 :                 return(NULL);
     395             : 
     396          19 :         puri = xmlParseURI(URI);
     397          19 :         if (puri != NULL) {
     398          19 :                 if (puri->scheme != NULL)
     399           1 :                         unescaped = xmlURIUnescapeString(URI, 0, NULL);
     400          19 :                 xmlFreeURI(puri);
     401             :         }
     402             : 
     403          19 :         if (unescaped != NULL) {
     404           1 :                 context = php_libxml_streams_IO_open_write_wrapper(unescaped);
     405           1 :                 xmlFree(unescaped);
     406             :         }
     407             : 
     408             :         /* try with a non-escaped URI this may be a strange filename */
     409          19 :         if (context == NULL) {
     410          18 :                 context = php_libxml_streams_IO_open_write_wrapper(URI);
     411             :         }
     412             : 
     413          19 :         if (context == NULL) {
     414           1 :                 return(NULL);
     415             :         }
     416             : 
     417             :         /* Allocate the Output buffer front-end. */
     418          18 :         ret = xmlAllocOutputBuffer(encoder);
     419          18 :         if (ret != NULL) {
     420          18 :                 ret->context = context;
     421          18 :                 ret->writecallback = php_libxml_streams_IO_write;
     422          18 :                 ret->closecallback = php_libxml_streams_IO_close;
     423             :         }
     424             : 
     425          18 :         return(ret);
     426             : }
     427             : 
     428           2 : static int _php_libxml_free_error(xmlErrorPtr error)
     429             : {
     430             :         /* This will free the libxml alloc'd memory */
     431           2 :         xmlResetError(error);
     432           2 :         return 1;
     433             : }
     434             : 
     435           2 : static void _php_list_set_error_structure(xmlErrorPtr error, const char *msg)
     436             : {
     437             :         xmlError error_copy;
     438             :         int ret;
     439             : 
     440             :         TSRMLS_FETCH();
     441             : 
     442           2 :         memset(&error_copy, 0, sizeof(xmlError));
     443             : 
     444           2 :         if (error) {
     445           2 :                 ret = xmlCopyError(error, &error_copy);
     446             :         } else {
     447           0 :                 error_copy.domain = 0;
     448           0 :                 error_copy.code = XML_ERR_INTERNAL_ERROR;
     449           0 :                 error_copy.level = XML_ERR_ERROR;
     450           0 :                 error_copy.line = 0;
     451           0 :                 error_copy.node = NULL;
     452           0 :                 error_copy.int1 = 0;
     453           0 :                 error_copy.int2 = 0;
     454           0 :                 error_copy.ctxt = NULL;
     455           0 :                 error_copy.message = xmlStrdup(msg);
     456           0 :                 error_copy.file = NULL;
     457           0 :                 error_copy.str1 = NULL;
     458           0 :                 error_copy.str2 = NULL;
     459           0 :                 error_copy.str3 = NULL;
     460           0 :                 ret = 0;
     461             :         }
     462             : 
     463           2 :         if (ret == 0) {
     464           2 :                 zend_llist_add_element(LIBXML(error_list), &error_copy);
     465             :         }
     466           2 : }
     467             : 
     468           6 : static void php_libxml_ctx_error_level(int level, void *ctx, const char *msg TSRMLS_DC)
     469             : {
     470             :         xmlParserCtxtPtr parser;
     471             : 
     472           6 :         parser = (xmlParserCtxtPtr) ctx;
     473             : 
     474           6 :         if (parser != NULL && parser->input != NULL) {
     475           6 :                 if (parser->input->filename) {
     476           0 :                         php_error_docref(NULL TSRMLS_CC, level, "%s in %s, line: %d", msg, parser->input->filename, parser->input->line);
     477             :                 } else {
     478           6 :                         php_error_docref(NULL TSRMLS_CC, level, "%s in Entity, line: %d", msg, parser->input->line);
     479             :                 }
     480             :         }
     481           6 : }
     482             : 
     483           9 : void php_libxml_issue_error(int level, const char *msg TSRMLS_DC)
     484             : {
     485           9 :         if (LIBXML(error_list)) {
     486           0 :                 _php_list_set_error_structure(NULL, msg);
     487             :         } else {
     488           9 :                 php_error_docref(NULL TSRMLS_CC, level, "%s", msg);
     489             :         }
     490           9 : }
     491             : 
     492          83 : static void php_libxml_internal_error_handler(int error_type, void *ctx, const char **msg, va_list ap)
     493             : {
     494             :         char *buf;
     495          83 :         int len, len_iter, output = 0;
     496             : 
     497             :         TSRMLS_FETCH();
     498             : 
     499          83 :         len = vspprintf(&buf, 0, *msg, ap);
     500          83 :         len_iter = len;
     501             : 
     502             :         /* remove any trailing \n */
     503         222 :         while (len_iter && buf[--len_iter] == '\n') {
     504          56 :                 buf[len_iter] = '\0';
     505          56 :                 output = 1;
     506             :         }
     507             : 
     508          83 :         smart_str_appendl(&LIBXML(error_buffer), buf, len);
     509             : 
     510          83 :         efree(buf);
     511             : 
     512          83 :         if (output == 1) {
     513          56 :                 if (LIBXML(error_list)) {
     514           0 :                         _php_list_set_error_structure(NULL, LIBXML(error_buffer).c);
     515             :                 } else {
     516          56 :                         switch (error_type) {
     517             :                                 case PHP_LIBXML_CTX_ERROR:
     518           6 :                                         php_libxml_ctx_error_level(E_WARNING, ctx, LIBXML(error_buffer).c TSRMLS_CC);
     519           6 :                                         break;
     520             :                                 case PHP_LIBXML_CTX_WARNING:
     521           0 :                                         php_libxml_ctx_error_level(E_NOTICE, ctx, LIBXML(error_buffer).c TSRMLS_CC);
     522           0 :                                         break;
     523             :                                 default:
     524          50 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", LIBXML(error_buffer).c);
     525             :                         }
     526             :                 }
     527          56 :                 smart_str_free(&LIBXML(error_buffer));
     528             :         }
     529          83 : }
     530             : 
     531           6 : PHP_LIBXML_API void php_libxml_ctx_error(void *ctx, const char *msg, ...)
     532             : {
     533             :         va_list args;
     534           6 :         va_start(args, msg);
     535           6 :         php_libxml_internal_error_handler(PHP_LIBXML_CTX_ERROR, ctx, &msg, args);
     536           6 :         va_end(args);
     537           6 : }
     538             : 
     539           0 : PHP_LIBXML_API void php_libxml_ctx_warning(void *ctx, const char *msg, ...)
     540             : {
     541             :         va_list args;
     542           0 :         va_start(args, msg);
     543           0 :         php_libxml_internal_error_handler(PHP_LIBXML_CTX_WARNING, ctx, &msg, args);
     544           0 :         va_end(args);
     545           0 : }
     546             : 
     547           2 : PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, xmlErrorPtr error)
     548             : {
     549           2 :         _php_list_set_error_structure(error, NULL);
     550             : 
     551           2 :         return;
     552             : }
     553             : 
     554          77 : PHP_LIBXML_API void php_libxml_error_handler(void *ctx, const char *msg, ...)
     555             : {
     556             :         va_list args;
     557          77 :         va_start(args, msg);
     558          77 :         php_libxml_internal_error_handler(PHP_LIBXML_ERROR, ctx, &msg, args);
     559          77 :         va_end(args);
     560          77 : }
     561             : 
     562             : 
     563       58023 : PHP_LIBXML_API void php_libxml_initialize(void)
     564             : {
     565       58023 :         if (!_php_libxml_initialized) {
     566             :                 /* we should be the only one's to ever init!! */
     567       19341 :                 xmlInitParser();
     568             : 
     569       19341 :                 zend_hash_init(&php_libxml_exports, 0, NULL, NULL, 1);
     570             : 
     571       19341 :                 _php_libxml_initialized = 1;
     572             :         }
     573       58023 : }
     574             : 
     575       19376 : PHP_LIBXML_API void php_libxml_shutdown(void)
     576             : {
     577       19376 :         if (_php_libxml_initialized) {
     578             : #if defined(LIBXML_SCHEMAS_ENABLED)
     579       19376 :                 xmlRelaxNGCleanupTypes();
     580             : #endif
     581       19376 :                 xmlCleanupParser();
     582       19376 :                 zend_hash_destroy(&php_libxml_exports);
     583       19376 :                 _php_libxml_initialized = 0;
     584             :         }
     585       19376 : }
     586             : 
     587        1407 : PHP_LIBXML_API zval *php_libxml_switch_context(zval *context TSRMLS_DC)
     588             : {
     589             :         zval *oldcontext;
     590             : 
     591        1407 :         oldcontext = LIBXML(stream_context);
     592        1407 :         LIBXML(stream_context) = context;
     593        1407 :         return oldcontext;
     594             : 
     595             : }
     596             : 
     597       19341 : static PHP_MINIT_FUNCTION(libxml)
     598             : {
     599             :         zend_class_entry ce;
     600             : 
     601       19341 :         php_libxml_initialize();
     602             : 
     603       19341 :         REGISTER_LONG_CONSTANT("LIBXML_VERSION",                      LIBXML_VERSION,                 CONST_CS | CONST_PERSISTENT);
     604       19341 :         REGISTER_STRING_CONSTANT("LIBXML_DOTTED_VERSION",     LIBXML_DOTTED_VERSION,  CONST_CS | CONST_PERSISTENT);
     605       19341 :         REGISTER_STRING_CONSTANT("LIBXML_LOADED_VERSION",     (char *)xmlParserVersion,               CONST_CS | CONST_PERSISTENT);
     606             : 
     607             :         /* For use with loading xml */
     608       19341 :         REGISTER_LONG_CONSTANT("LIBXML_NOENT",                XML_PARSE_NOENT,                CONST_CS | CONST_PERSISTENT);
     609       19341 :         REGISTER_LONG_CONSTANT("LIBXML_DTDLOAD",      XML_PARSE_DTDLOAD,              CONST_CS | CONST_PERSISTENT);
     610       19341 :         REGISTER_LONG_CONSTANT("LIBXML_DTDATTR",      XML_PARSE_DTDATTR,              CONST_CS | CONST_PERSISTENT);
     611       19341 :         REGISTER_LONG_CONSTANT("LIBXML_DTDVALID",     XML_PARSE_DTDVALID,             CONST_CS | CONST_PERSISTENT);
     612       19341 :         REGISTER_LONG_CONSTANT("LIBXML_NOERROR",      XML_PARSE_NOERROR,              CONST_CS | CONST_PERSISTENT);
     613       19341 :         REGISTER_LONG_CONSTANT("LIBXML_NOWARNING",    XML_PARSE_NOWARNING,    CONST_CS | CONST_PERSISTENT);
     614       19341 :         REGISTER_LONG_CONSTANT("LIBXML_NOBLANKS",     XML_PARSE_NOBLANKS,             CONST_CS | CONST_PERSISTENT);
     615       19341 :         REGISTER_LONG_CONSTANT("LIBXML_XINCLUDE",     XML_PARSE_XINCLUDE,             CONST_CS | CONST_PERSISTENT);
     616       19341 :         REGISTER_LONG_CONSTANT("LIBXML_NSCLEAN",      XML_PARSE_NSCLEAN,              CONST_CS | CONST_PERSISTENT);
     617       19341 :         REGISTER_LONG_CONSTANT("LIBXML_NOCDATA",      XML_PARSE_NOCDATA,              CONST_CS | CONST_PERSISTENT);
     618       19341 :         REGISTER_LONG_CONSTANT("LIBXML_NONET",                XML_PARSE_NONET,                CONST_CS | CONST_PERSISTENT);
     619             : #if LIBXML_VERSION >= 20621
     620       19341 :         REGISTER_LONG_CONSTANT("LIBXML_COMPACT",      XML_PARSE_COMPACT,              CONST_CS | CONST_PERSISTENT);
     621       19341 :         REGISTER_LONG_CONSTANT("LIBXML_NOXMLDECL",    XML_SAVE_NO_DECL,               CONST_CS | CONST_PERSISTENT);
     622             : #endif
     623             : #if LIBXML_VERSION >= 20703
     624       19341 :         REGISTER_LONG_CONSTANT("LIBXML_PARSEHUGE",    XML_PARSE_HUGE,                 CONST_CS | CONST_PERSISTENT);
     625             : #endif
     626       19341 :         REGISTER_LONG_CONSTANT("LIBXML_NOEMPTYTAG",   LIBXML_SAVE_NOEMPTYTAG, CONST_CS | CONST_PERSISTENT);
     627             : 
     628             :         /* Error levels */
     629       19341 :         REGISTER_LONG_CONSTANT("LIBXML_ERR_NONE",             XML_ERR_NONE,           CONST_CS | CONST_PERSISTENT);
     630       19341 :         REGISTER_LONG_CONSTANT("LIBXML_ERR_WARNING",  XML_ERR_WARNING,        CONST_CS | CONST_PERSISTENT);
     631       19341 :         REGISTER_LONG_CONSTANT("LIBXML_ERR_ERROR",            XML_ERR_ERROR,          CONST_CS | CONST_PERSISTENT);
     632       19341 :         REGISTER_LONG_CONSTANT("LIBXML_ERR_FATAL",            XML_ERR_FATAL,          CONST_CS | CONST_PERSISTENT);
     633             : 
     634       19341 :         INIT_CLASS_ENTRY(ce, "LibXMLError", NULL);
     635       19341 :         libxmlerror_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
     636             : 
     637       19341 :         return SUCCESS;
     638             : }
     639             : 
     640             : 
     641       19327 : static PHP_RINIT_FUNCTION(libxml)
     642             : {
     643             :         /* report errors via handler rather than stderr */
     644       19327 :         xmlSetGenericErrorFunc(NULL, php_libxml_error_handler);
     645       19327 :         xmlParserInputBufferCreateFilenameDefault(php_libxml_input_buffer_create_filename);
     646       19327 :         xmlOutputBufferCreateFilenameDefault(php_libxml_output_buffer_create_filename);
     647       19327 :         return SUCCESS;
     648             : }
     649             : 
     650             : 
     651       19376 : static PHP_MSHUTDOWN_FUNCTION(libxml)
     652             : {
     653       19376 :         php_libxml_shutdown();
     654             : 
     655       19376 :         return SUCCESS;
     656             : }
     657             : 
     658       19362 : static int php_libxml_post_deactivate()
     659             : {
     660             :         TSRMLS_FETCH();
     661             :         /* reset libxml generic error handling */
     662       19362 :         xmlSetGenericErrorFunc(NULL, NULL);
     663       19362 :         xmlSetStructuredErrorFunc(NULL, NULL);
     664             : 
     665       19362 :         xmlParserInputBufferCreateFilenameDefault(NULL);
     666       19362 :         xmlOutputBufferCreateFilenameDefault(NULL);
     667             : 
     668       19362 :         if (LIBXML(stream_context)) {
     669             :                 /* the steam_context resource will be released by resource list destructor */
     670           8 :                 efree(LIBXML(stream_context));
     671           8 :                 LIBXML(stream_context) = NULL;
     672             :         }
     673       19362 :         smart_str_free(&LIBXML(error_buffer));
     674       19362 :         if (LIBXML(error_list)) {
     675           2 :                 zend_llist_destroy(LIBXML(error_list));
     676           2 :                 efree(LIBXML(error_list));
     677           2 :                 LIBXML(error_list) = NULL;
     678             :         }
     679       19362 :         xmlResetLastError();
     680             : 
     681       19362 :         return SUCCESS;
     682             : }
     683             : 
     684             : 
     685         148 : static PHP_MINFO_FUNCTION(libxml)
     686             : {
     687         148 :         php_info_print_table_start();
     688         148 :         php_info_print_table_row(2, "libXML support", "active");
     689         148 :         php_info_print_table_row(2, "libXML Compiled Version", LIBXML_DOTTED_VERSION);
     690         148 :         php_info_print_table_row(2, "libXML Loaded Version", (char *)xmlParserVersion);
     691         148 :         php_info_print_table_row(2, "libXML streams", "enabled");
     692         148 :         php_info_print_table_end();
     693         148 : }
     694             : /* }}} */
     695             : 
     696             : /* {{{ proto void libxml_set_streams_context(resource streams_context) 
     697             :    Set the streams context for the next libxml document load or write */
     698          11 : static PHP_FUNCTION(libxml_set_streams_context)
     699             : {
     700             :         zval *arg;
     701             : 
     702          11 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg) == FAILURE) {
     703           6 :                 return;
     704             :         }
     705           5 :         if (LIBXML(stream_context)) {
     706           2 :                 zval_ptr_dtor(&LIBXML(stream_context));
     707           2 :                 LIBXML(stream_context) = NULL;
     708             :         }
     709           5 :         Z_ADDREF_P(arg);
     710           5 :         LIBXML(stream_context) = arg;
     711             : }
     712             : /* }}} */
     713             : 
     714             : /* {{{ proto bool libxml_use_internal_errors([boolean use_errors]) 
     715             :    Disable libxml errors and allow user to fetch error information as needed */
     716           7 : static PHP_FUNCTION(libxml_use_internal_errors)
     717             : {
     718             :         xmlStructuredErrorFunc current_handler;
     719           7 :         zend_bool use_errors=0, retval;
     720             : 
     721           7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &use_errors) == FAILURE) {
     722           1 :                 return;
     723             :         }
     724             : 
     725           6 :         current_handler = xmlStructuredError;
     726           8 :         if (current_handler && current_handler == php_libxml_structured_error_handler) {
     727           2 :                 retval = 1;
     728             :         } else {
     729           4 :                 retval = 0;
     730             :         }
     731             : 
     732           6 :         if (ZEND_NUM_ARGS() == 0) {
     733           1 :                 RETURN_BOOL(retval);
     734             :         }
     735             : 
     736           5 :         if (use_errors == 0) {
     737           2 :                 xmlSetStructuredErrorFunc(NULL, NULL);
     738           2 :                 if (LIBXML(error_list)) {
     739           1 :                         zend_llist_destroy(LIBXML(error_list));
     740           1 :                         efree(LIBXML(error_list));
     741           1 :                         LIBXML(error_list) = NULL;
     742             :                 }
     743             :         } else {
     744           3 :                 xmlSetStructuredErrorFunc(NULL, php_libxml_structured_error_handler);
     745           3 :                 if (LIBXML(error_list) == NULL) {
     746           3 :                         LIBXML(error_list) = (zend_llist *) emalloc(sizeof(zend_llist));
     747           3 :                         zend_llist_init(LIBXML(error_list), sizeof(xmlError), (llist_dtor_func_t) _php_libxml_free_error, 0);
     748             :                 }
     749             :         }
     750           5 :         RETURN_BOOL(retval);
     751             : }
     752             : /* }}} */
     753             : 
     754             : /* {{{ proto object libxml_get_last_error() 
     755             :    Retrieve last error from libxml */
     756           2 : static PHP_FUNCTION(libxml_get_last_error)
     757             : {
     758             :         xmlErrorPtr error;
     759             : 
     760           2 :         error = xmlGetLastError();
     761             :         
     762           2 :         if (error) {
     763           1 :                 object_init_ex(return_value, libxmlerror_class_entry);
     764           1 :                 add_property_long(return_value, "level", error->level);
     765           1 :                 add_property_long(return_value, "code", error->code);
     766           1 :                 add_property_long(return_value, "column", error->int2);
     767           1 :                 if (error->message) {
     768           1 :                         add_property_string(return_value, "message", error->message, 1);
     769             :                 } else {
     770           0 :                         add_property_stringl(return_value, "message", "", 0, 1);
     771             :                 }
     772           1 :                 if (error->file) {
     773           0 :                         add_property_string(return_value, "file", error->file, 1);
     774             :                 } else {
     775           1 :                         add_property_stringl(return_value, "file", "", 0, 1);
     776             :                 }
     777           1 :                 add_property_long(return_value, "line", error->line);
     778             :         } else {
     779           1 :                 RETURN_FALSE;
     780             :         }
     781             : }
     782             : /* }}} */
     783             : 
     784             : /* {{{ proto object libxml_get_errors()
     785             :    Retrieve array of errors */
     786           2 : static PHP_FUNCTION(libxml_get_errors)
     787             : {
     788             :         
     789             :         xmlErrorPtr error;
     790             : 
     791           2 :         if (array_init(return_value) == FAILURE) {
     792           0 :                 RETURN_FALSE;
     793             :         }
     794             : 
     795           2 :         if (LIBXML(error_list)) {
     796             : 
     797           2 :                 error = zend_llist_get_first(LIBXML(error_list));
     798             : 
     799           5 :                 while (error != NULL) {
     800             :                         zval *z_error;
     801           1 :                         MAKE_STD_ZVAL(z_error);
     802             : 
     803           1 :                         object_init_ex(z_error, libxmlerror_class_entry);
     804           1 :                         add_property_long(z_error, "level", error->level);
     805           1 :                         add_property_long(z_error, "code", error->code);
     806           1 :                         add_property_long(z_error, "column", error->int2);
     807           1 :                         if (error->message) {
     808           1 :                                 add_property_string(z_error, "message", error->message, 1);
     809             :                         } else {
     810           0 :                                 add_property_stringl(z_error, "message", "", 0, 1);
     811             :                         }
     812           1 :                         if (error->file) {
     813           0 :                                 add_property_string(z_error, "file", error->file, 1);
     814             :                         } else {
     815           1 :                                 add_property_stringl(z_error, "file", "", 0, 1);
     816             :                         }
     817           1 :                         add_property_long(z_error, "line", error->line);
     818           1 :                         add_next_index_zval(return_value, z_error);
     819             : 
     820           1 :                         error = zend_llist_get_next(LIBXML(error_list));
     821             :                 }
     822             :         }
     823             : }
     824             : /* }}} */
     825             : 
     826             : /* {{{ proto void libxml_clear_errors() 
     827             :    Clear last error from libxml */
     828           1 : static PHP_FUNCTION(libxml_clear_errors)
     829             : {
     830           1 :         xmlResetLastError();
     831           1 :         if (LIBXML(error_list)) {
     832           1 :                 zend_llist_clean(LIBXML(error_list));
     833             :         }
     834           1 : }
     835             : /* }}} */
     836             : 
     837        2552 : PHP_LIBXML_API zend_bool php_libxml_disable_entity_loader(zend_bool disable TSRMLS_DC)
     838             : {
     839        2552 :         zend_bool old = LIBXML(entity_loader_disabled);
     840             : 
     841        2552 :         LIBXML(entity_loader_disabled) = disable;
     842        2552 :         return old;
     843             : }
     844             : 
     845             : /* {{{ proto bool libxml_disable_entity_loader([boolean disable]) 
     846             :    Disable/Enable ability to load external entities */
     847           0 : static PHP_FUNCTION(libxml_disable_entity_loader)
     848             : {
     849           0 :         zend_bool disable = 1;
     850             : 
     851           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &disable) == FAILURE) {
     852           0 :                 return;
     853             :         }
     854             : 
     855           0 :         RETURN_BOOL(php_libxml_disable_entity_loader(disable TSRMLS_CC));
     856             : }
     857             : /* }}} */
     858             : 
     859             : /* {{{ Common functions shared by extensions */
     860         805 : int php_libxml_xmlCheckUTF8(const unsigned char *s)
     861             : {
     862             :         int i;
     863             :         unsigned char c;
     864             : 
     865        9344 :         for (i = 0; (c = s[i++]);) {
     866        7735 :                 if ((c & 0x80) == 0) {
     867         157 :                 } else if ((c & 0xe0) == 0xc0) {
     868         156 :                         if ((s[i++] & 0xc0) != 0x80) {
     869           0 :                                 return 0;
     870             :                         }
     871           1 :                 } else if ((c & 0xf0) == 0xe0) {
     872           0 :                         if ((s[i++] & 0xc0) != 0x80 || (s[i++] & 0xc0) != 0x80) {
     873           0 :                                 return 0;
     874             :                         }
     875           1 :                 } else if ((c & 0xf8) == 0xf0) {
     876           0 :                         if ((s[i++] & 0xc0) != 0x80 || (s[i++] & 0xc0) != 0x80 || (s[i++] & 0xc0) != 0x80) {
     877           0 :                                 return 0;
     878             :                         }
     879             :                 } else {
     880           1 :                         return 0;
     881             :                 }
     882             :         }
     883         804 :         return 1;
     884             : }
     885             : 
     886       38682 : int php_libxml_register_export(zend_class_entry *ce, php_libxml_export_node export_function)
     887             : {
     888             :         php_libxml_func_handler export_hnd;
     889             :         
     890             :         /* Initialize in case this module hasnt been loaded yet */
     891       38682 :         php_libxml_initialize();
     892       38682 :         export_hnd.export_func = export_function;
     893             : 
     894       38682 :         return zend_hash_add(&php_libxml_exports, ce->name, ce->name_length + 1, &export_hnd, sizeof(export_hnd), NULL);
     895             : }
     896             : 
     897          64 : PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object TSRMLS_DC)
     898             : {
     899          64 :         zend_class_entry *ce = NULL;
     900          64 :         xmlNodePtr node = NULL;
     901             :         php_libxml_func_handler *export_hnd;
     902             : 
     903          64 :         if (object->type == IS_OBJECT) {
     904          64 :                 ce = Z_OBJCE_P(object);
     905         191 :                 while (ce->parent != NULL) {
     906          63 :                         ce = ce->parent;
     907             :                 }
     908          64 :                 if (zend_hash_find(&php_libxml_exports, ce->name, ce->name_length + 1, (void **) &export_hnd)  == SUCCESS) {
     909          64 :                         node = export_hnd->export_func(object TSRMLS_CC);
     910             :                 }
     911             :         }
     912          64 :         return node;
     913             : }
     914             : 
     915      404426 : PHP_LIBXML_API int php_libxml_increment_node_ptr(php_libxml_node_object *object, xmlNodePtr node, void *private_data TSRMLS_DC)
     916             : {
     917      404426 :         int ret_refcount = -1;
     918             : 
     919      404426 :         if (object != NULL && node != NULL) {
     920      404426 :                 if (object->node != NULL) {
     921           0 :                         if (object->node->node == node) {
     922           0 :                                 return object->node->refcount;
     923             :                         } else {
     924           0 :                                 php_libxml_decrement_node_ptr(object TSRMLS_CC);
     925             :                         }
     926             :                 }
     927      404426 :                 if (node->_private != NULL) {
     928      200633 :                         object->node = node->_private;
     929      200633 :                         ret_refcount = ++object->node->refcount;
     930             :                         /* Only dom uses _private */
     931      200633 :                         if (object->node->_private == NULL) {
     932      200633 :                                 object->node->_private = private_data;
     933             :                         }
     934             :                 } else {
     935      203793 :                         ret_refcount = 1;
     936      203793 :                         object->node = emalloc(sizeof(php_libxml_node_ptr));
     937      203793 :                         object->node->node = node;
     938      203793 :                         object->node->refcount = 1;
     939      203793 :                         object->node->_private = private_data;
     940      203793 :                         node->_private = object->node;
     941             :                 }
     942             :         }
     943             : 
     944      404426 :         return ret_refcount;
     945             : }
     946             : 
     947      404426 : PHP_LIBXML_API int php_libxml_decrement_node_ptr(php_libxml_node_object *object TSRMLS_DC)
     948             : {
     949      404426 :         int ret_refcount = -1;
     950             :         php_libxml_node_ptr *obj_node;
     951             : 
     952      404426 :         if (object != NULL && object->node != NULL) {
     953      404426 :                 obj_node = (php_libxml_node_ptr *) object->node;
     954      404426 :                 ret_refcount = --obj_node->refcount;
     955      404426 :                 if (ret_refcount == 0) {
     956      203793 :                         if (obj_node->node != NULL) {
     957      203790 :                                 obj_node->node->_private = NULL;
     958             :                         }
     959      203793 :                         efree(obj_node);
     960             :                 } 
     961      404426 :                 object->node = NULL;
     962             :         }
     963             : 
     964      404426 :         return ret_refcount;
     965             : }
     966             : 
     967        3157 : PHP_LIBXML_API int php_libxml_increment_doc_ref(php_libxml_node_object *object, xmlDocPtr docp TSRMLS_DC)
     968             : {
     969        3157 :         int ret_refcount = -1;
     970             : 
     971        3157 :         if (object->document != NULL) {
     972         564 :                 object->document->refcount++;
     973         564 :                 ret_refcount = object->document->refcount;
     974        2593 :         } else if (docp != NULL) {
     975        2593 :                 ret_refcount = 1;
     976        2593 :                 object->document = emalloc(sizeof(php_libxml_ref_obj));
     977        2593 :                 object->document->ptr = docp;
     978        2593 :                 object->document->refcount = ret_refcount;
     979        2593 :                 object->document->doc_props = NULL;
     980             :         }
     981             : 
     982        3157 :         return ret_refcount;
     983             : }
     984             : 
     985      404591 : PHP_LIBXML_API int php_libxml_decrement_doc_ref(php_libxml_node_object *object TSRMLS_DC)
     986             : {
     987      404591 :         int ret_refcount = -1;
     988             : 
     989      404591 :         if (object != NULL && object->document != NULL) {
     990      404441 :                 ret_refcount = --object->document->refcount;
     991      404441 :                 if (ret_refcount == 0) {
     992        2593 :                         if (object->document->ptr != NULL) {
     993        2593 :                                 xmlFreeDoc((xmlDoc *) object->document->ptr);
     994             :                         }
     995        2593 :                         if (object->document->doc_props != NULL) {
     996         261 :                                 if (object->document->doc_props->classmap) {
     997           1 :                                         zend_hash_destroy(object->document->doc_props->classmap);
     998           1 :                                         FREE_HASHTABLE(object->document->doc_props->classmap);
     999             :                                 }
    1000         261 :                                 efree(object->document->doc_props);
    1001             :                         }
    1002        2593 :                         efree(object->document);
    1003        2593 :                         object->document = NULL;
    1004             :                 }
    1005             :         }
    1006             : 
    1007      404591 :         return ret_refcount;
    1008             : }
    1009             : 
    1010      203369 : PHP_LIBXML_API void php_libxml_node_free_resource(xmlNodePtr node TSRMLS_DC)
    1011             : {
    1012      203369 :         if (!node) {
    1013           3 :                 return;
    1014             :         }
    1015             : 
    1016      203366 :         switch (node->type) {
    1017             :                 case XML_DOCUMENT_NODE:
    1018             :                 case XML_HTML_DOCUMENT_NODE:
    1019           0 :                         break;
    1020             :                 default:
    1021      203495 :                         if (node->parent == NULL || node->type == XML_NAMESPACE_DECL) {
    1022         129 :                                 php_libxml_node_free_list((xmlNodePtr) node->children TSRMLS_CC);
    1023         129 :                                 switch (node->type) {
    1024             :                                         /* Skip property freeing for the following types */
    1025             :                                         case XML_ATTRIBUTE_DECL:
    1026             :                                         case XML_DTD_NODE:
    1027             :                                         case XML_DOCUMENT_TYPE_NODE:
    1028             :                                         case XML_ENTITY_DECL:
    1029             :                                         case XML_ATTRIBUTE_NODE:
    1030             :                                         case XML_NAMESPACE_DECL:
    1031             :                                         case XML_TEXT_NODE:
    1032          48 :                                                 break;
    1033             :                                         default:
    1034          81 :                                                 php_libxml_node_free_list((xmlNodePtr) node->properties TSRMLS_CC);
    1035             :                                 }
    1036         129 :                                 if (php_libxml_unregister_node(node TSRMLS_CC) == 0) {
    1037           0 :                                         node->doc = NULL;
    1038             :                                 }
    1039         129 :                                 php_libxml_node_free(node);
    1040             :                         } else {
    1041      203237 :                                 php_libxml_unregister_node(node TSRMLS_CC);
    1042             :                         }
    1043             :         }
    1044             : }
    1045             : 
    1046      403961 : PHP_LIBXML_API void php_libxml_node_decrement_resource(php_libxml_node_object *object TSRMLS_DC)
    1047             : {
    1048      403961 :         int ret_refcount = -1;
    1049             :         xmlNodePtr nodep;
    1050             :         php_libxml_node_ptr *obj_node;
    1051             : 
    1052      403961 :         if (object != NULL && object->node != NULL) {
    1053      403961 :                 obj_node = (php_libxml_node_ptr *) object->node;
    1054      403961 :                 nodep = object->node->node;
    1055      403961 :                 ret_refcount = php_libxml_decrement_node_ptr(object TSRMLS_CC);
    1056      403961 :                 if (ret_refcount == 0) {
    1057      203328 :                         php_libxml_node_free_resource(nodep TSRMLS_CC);
    1058             :                 } else {
    1059      200633 :                         if (obj_node && object == obj_node->_private) {
    1060           1 :                                 obj_node->_private = NULL;
    1061             :                         }
    1062             :                 }
    1063             :         }
    1064      403961 :         if (object != NULL && object->document != NULL) {
    1065             :                 /* Safe to call as if the resource were freed then doc pointer is NULL */
    1066      403938 :                 php_libxml_decrement_doc_ref(object TSRMLS_CC);
    1067             :         }
    1068      403961 : }
    1069             : /* }}} */
    1070             : 
    1071             : #ifdef PHP_WIN32
    1072             : PHP_LIBXML_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    1073             : {
    1074             :         return xmlDllMain(hinstDLL, fdwReason, lpvReserved);
    1075             : }
    1076             : #endif
    1077             : 
    1078             : #endif
    1079             : 
    1080             : /*
    1081             :  * Local variables:
    1082             :  * tab-width: 4
    1083             :  * c-basic-offset: 4
    1084             :  * End:
    1085             :  * vim600: sw=4 ts=4 fdm=marker
    1086             :  * vim<600: sw=4 ts=4
    1087             :  */

Generated by: LCOV version 1.10

Generated at Sun, 27 Jul 2014 12:58:30 +0000 (5 days ago)

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