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

LTP GCOV extension - code coverage report
Current view: directory - libxml - libxml.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 477
Code covered: 86.0 % Executed lines: 410
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:02 +0000 (3 days ago)

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