12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358 |
- /*
- +----------------------------------------------------------------------+
- | Copyright (c) The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | https://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Shane Caraveo <shane@php.net> |
- | Wez Furlong <wez@thebrainroom.com> |
- +----------------------------------------------------------------------+
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "php.h"
- #include "SAPI.h"
- #include "zend_variables.h"
- #include "ext/standard/php_string.h"
- #include "ext/standard/info.h"
- #include "ext/standard/file.h"
- #ifdef HAVE_LIBXML
- #include <libxml/parser.h>
- #include <libxml/parserInternals.h>
- #include <libxml/tree.h>
- #include <libxml/uri.h>
- #include <libxml/xmlerror.h>
- #include <libxml/xmlsave.h>
- #ifdef LIBXML_SCHEMAS_ENABLED
- #include <libxml/relaxng.h>
- #include <libxml/xmlschemas.h>
- #endif
- #include "php_libxml.h"
- #include "libxml_arginfo.h"
- #define PHP_LIBXML_ERROR 0
- #define PHP_LIBXML_CTX_ERROR 1
- #define PHP_LIBXML_CTX_WARNING 2
- /* a true global for initialization */
- static int _php_libxml_initialized = 0;
- static int _php_libxml_per_request_initialization = 1;
- static xmlExternalEntityLoader _php_libxml_default_entity_loader;
- typedef struct _php_libxml_func_handler {
- php_libxml_export_node export_func;
- } php_libxml_func_handler;
- static HashTable php_libxml_exports;
- static ZEND_DECLARE_MODULE_GLOBALS(libxml)
- static PHP_GINIT_FUNCTION(libxml);
- static zend_class_entry *libxmlerror_class_entry;
- /* {{{ dynamically loadable module stuff */
- #ifdef COMPILE_DL_LIBXML
- #ifdef ZTS
- ZEND_TSRMLS_CACHE_DEFINE()
- #endif
- ZEND_GET_MODULE(libxml)
- #endif /* COMPILE_DL_LIBXML */
- /* }}} */
- /* {{{ function prototypes */
- static PHP_MINIT_FUNCTION(libxml);
- static PHP_RINIT_FUNCTION(libxml);
- static PHP_RSHUTDOWN_FUNCTION(libxml);
- static PHP_MSHUTDOWN_FUNCTION(libxml);
- static PHP_MINFO_FUNCTION(libxml);
- static zend_result php_libxml_post_deactivate(void);
- /* }}} */
- zend_module_entry libxml_module_entry = {
- STANDARD_MODULE_HEADER,
- "libxml", /* extension name */
- ext_functions, /* extension function list */
- PHP_MINIT(libxml), /* extension-wide startup function */
- PHP_MSHUTDOWN(libxml), /* extension-wide shutdown function */
- PHP_RINIT(libxml), /* per-request startup function */
- PHP_RSHUTDOWN(libxml), /* per-request shutdown function */
- PHP_MINFO(libxml), /* information function */
- PHP_LIBXML_VERSION,
- PHP_MODULE_GLOBALS(libxml), /* globals descriptor */
- PHP_GINIT(libxml), /* globals ctor */
- NULL, /* globals dtor */
- php_libxml_post_deactivate, /* post deactivate */
- STANDARD_MODULE_PROPERTIES_EX
- };
- /* }}} */
- /* {{{ internal functions for interoperability */
- static int php_libxml_clear_object(php_libxml_node_object *object)
- {
- if (object->properties) {
- object->properties = NULL;
- }
- php_libxml_decrement_node_ptr(object);
- return php_libxml_decrement_doc_ref(object);
- }
- static int php_libxml_unregister_node(xmlNodePtr nodep)
- {
- php_libxml_node_object *wrapper;
- php_libxml_node_ptr *nodeptr = nodep->_private;
- if (nodeptr != NULL) {
- wrapper = nodeptr->_private;
- if (wrapper) {
- php_libxml_clear_object(wrapper);
- } else {
- if (nodeptr->node != NULL && nodeptr->node->type != XML_DOCUMENT_NODE) {
- nodeptr->node->_private = NULL;
- }
- nodeptr->node = NULL;
- }
- }
- return -1;
- }
- static void php_libxml_node_free(xmlNodePtr node)
- {
- if(node) {
- if (node->_private != NULL) {
- ((php_libxml_node_ptr *) node->_private)->node = NULL;
- }
- switch (node->type) {
- case XML_ATTRIBUTE_NODE:
- xmlFreeProp((xmlAttrPtr) node);
- break;
- case XML_ENTITY_DECL:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- break;
- case XML_NOTATION_NODE:
- /* These require special handling */
- if (node->name != NULL) {
- xmlFree((char *) node->name);
- }
- if (((xmlEntityPtr) node)->ExternalID != NULL) {
- xmlFree((char *) ((xmlEntityPtr) node)->ExternalID);
- }
- if (((xmlEntityPtr) node)->SystemID != NULL) {
- xmlFree((char *) ((xmlEntityPtr) node)->SystemID);
- }
- xmlFree(node);
- break;
- case XML_NAMESPACE_DECL:
- if (node->ns) {
- xmlFreeNs(node->ns);
- node->ns = NULL;
- }
- node->type = XML_ELEMENT_NODE;
- ZEND_FALLTHROUGH;
- default:
- xmlFreeNode(node);
- }
- }
- }
- PHP_LIBXML_API void php_libxml_node_free_list(xmlNodePtr node)
- {
- xmlNodePtr curnode;
- if (node != NULL) {
- curnode = node;
- while (curnode != NULL) {
- node = curnode;
- switch (node->type) {
- /* Skip property freeing for the following types */
- case XML_NOTATION_NODE:
- case XML_ENTITY_DECL:
- break;
- case XML_ENTITY_REF_NODE:
- php_libxml_node_free_list((xmlNodePtr) node->properties);
- break;
- case XML_ATTRIBUTE_NODE:
- if ((node->doc != NULL) && (((xmlAttrPtr) node)->atype == XML_ATTRIBUTE_ID)) {
- xmlRemoveID(node->doc, (xmlAttrPtr) node);
- }
- ZEND_FALLTHROUGH;
- case XML_ATTRIBUTE_DECL:
- case XML_DTD_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NAMESPACE_DECL:
- case XML_TEXT_NODE:
- php_libxml_node_free_list(node->children);
- break;
- default:
- php_libxml_node_free_list(node->children);
- php_libxml_node_free_list((xmlNodePtr) node->properties);
- }
- curnode = node->next;
- xmlUnlinkNode(node);
- if (php_libxml_unregister_node(node) == 0) {
- node->doc = NULL;
- }
- php_libxml_node_free(node);
- }
- }
- }
- /* }}} */
- /* {{{ startup, shutdown and info functions */
- static PHP_GINIT_FUNCTION(libxml)
- {
- #if defined(COMPILE_DL_LIBXML) && defined(ZTS)
- ZEND_TSRMLS_CACHE_UPDATE();
- #endif
- ZVAL_UNDEF(&libxml_globals->stream_context);
- libxml_globals->error_buffer.s = NULL;
- libxml_globals->error_list = NULL;
- ZVAL_UNDEF(&libxml_globals->entity_loader.object);
- libxml_globals->entity_loader.fci.size = 0;
- libxml_globals->entity_loader_disabled = 0;
- }
- static void _php_libxml_destroy_fci(zend_fcall_info *fci, zval *object)
- {
- if (fci->size > 0) {
- zval_ptr_dtor(&fci->function_name);
- fci->size = 0;
- }
- if (!Z_ISUNDEF_P(object)) {
- zval_ptr_dtor(object);
- ZVAL_UNDEF(object);
- }
- }
- /* Channel libxml file io layer through the PHP streams subsystem.
- * This allows use of ftps:// and https:// urls */
- static void *php_libxml_streams_IO_open_wrapper(const char *filename, const char *mode, const int read_only)
- {
- php_stream_statbuf ssbuf;
- php_stream_context *context = NULL;
- php_stream_wrapper *wrapper = NULL;
- char *resolved_path;
- const char *path_to_open = NULL;
- void *ret_val = NULL;
- int isescaped=0;
- xmlURI *uri;
- if (strstr(filename, "%00")) {
- php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes");
- return NULL;
- }
- uri = xmlParseURI(filename);
- if (uri && (uri->scheme == NULL ||
- (xmlStrncmp(BAD_CAST uri->scheme, BAD_CAST "file", 4) == 0))) {
- resolved_path = xmlURIUnescapeString(filename, 0, NULL);
- isescaped = 1;
- #if LIBXML_VERSION >= 20902 && defined(PHP_WIN32)
- /* Libxml 2.9.2 prefixes local paths with file:/ instead of file://,
- thus the php stream wrapper will fail on a valid case. For this
- reason the prefix is rather better cut off. */
- {
- size_t pre_len = sizeof("file:/") - 1;
- if (strncasecmp(resolved_path, "file:/", pre_len) == 0
- && '/' != resolved_path[pre_len]) {
- xmlChar *tmp = xmlStrdup(resolved_path + pre_len);
- xmlFree(resolved_path);
- resolved_path = tmp;
- }
- }
- #endif
- } else {
- resolved_path = (char *)filename;
- }
- if (uri) {
- xmlFreeURI(uri);
- }
- if (resolved_path == NULL) {
- return NULL;
- }
- /* logic copied from _php_stream_stat, but we only want to fail
- if the wrapper supports stat, otherwise, figure it out from
- the open. This logic is only to support hiding warnings
- that the streams layer puts out at times, but for libxml we
- may try to open files that don't exist, but it is not a failure
- in xml processing (eg. DTD files) */
- wrapper = php_stream_locate_url_wrapper(resolved_path, &path_to_open, 0);
- if (wrapper && read_only && wrapper->wops->url_stat) {
- if (wrapper->wops->url_stat(wrapper, path_to_open, PHP_STREAM_URL_STAT_QUIET, &ssbuf, NULL) == -1) {
- if (isescaped) {
- xmlFree(resolved_path);
- }
- return NULL;
- }
- }
- context = php_stream_context_from_zval(Z_ISUNDEF(LIBXML(stream_context))? NULL : &LIBXML(stream_context), 0);
- ret_val = php_stream_open_wrapper_ex(path_to_open, (char *)mode, REPORT_ERRORS, NULL, context);
- if (ret_val) {
- /* Prevent from closing this by fclose() */
- ((php_stream*)ret_val)->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
- }
- if (isescaped) {
- xmlFree(resolved_path);
- }
- return ret_val;
- }
- static void *php_libxml_streams_IO_open_read_wrapper(const char *filename)
- {
- return php_libxml_streams_IO_open_wrapper(filename, "rb", 1);
- }
- static void *php_libxml_streams_IO_open_write_wrapper(const char *filename)
- {
- return php_libxml_streams_IO_open_wrapper(filename, "wb", 0);
- }
- static int php_libxml_streams_IO_read(void *context, char *buffer, int len)
- {
- return php_stream_read((php_stream*)context, buffer, len);
- }
- static int php_libxml_streams_IO_write(void *context, const char *buffer, int len)
- {
- return php_stream_write((php_stream*)context, buffer, len);
- }
- static int php_libxml_streams_IO_close(void *context)
- {
- return php_stream_close((php_stream*)context);
- }
- static xmlParserInputBufferPtr
- php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc)
- {
- xmlParserInputBufferPtr ret;
- void *context = NULL;
- if (LIBXML(entity_loader_disabled)) {
- return NULL;
- }
- if (URI == NULL)
- return(NULL);
- context = php_libxml_streams_IO_open_read_wrapper(URI);
- if (context == NULL) {
- return(NULL);
- }
- /* Check if there's been an external transport protocol with an encoding information */
- if (enc == XML_CHAR_ENCODING_NONE) {
- php_stream *s = (php_stream *) context;
- if (Z_TYPE(s->wrapperdata) == IS_ARRAY) {
- zval *header;
- ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(s->wrapperdata), header) {
- const char buf[] = "Content-Type:";
- if (Z_TYPE_P(header) == IS_STRING &&
- !zend_binary_strncasecmp(Z_STRVAL_P(header), Z_STRLEN_P(header), buf, sizeof(buf)-1, sizeof(buf)-1)) {
- char *needle = estrdup("charset=");
- char *haystack = estrndup(Z_STRVAL_P(header), Z_STRLEN_P(header));
- char *encoding = php_stristr(haystack, needle, Z_STRLEN_P(header), sizeof("charset=")-1);
- if (encoding) {
- char *end;
- encoding += sizeof("charset=")-1;
- if (*encoding == '"') {
- encoding++;
- }
- end = strchr(encoding, ';');
- if (end == NULL) {
- end = encoding + strlen(encoding);
- }
- end--; /* end == encoding-1 isn't a buffer underrun */
- while (*end == ' ' || *end == '\t') {
- end--;
- }
- if (*end == '"') {
- end--;
- }
- if (encoding >= end) continue;
- *(end+1) = '\0';
- enc = xmlParseCharEncoding(encoding);
- if (enc <= XML_CHAR_ENCODING_NONE) {
- enc = XML_CHAR_ENCODING_NONE;
- }
- }
- efree(haystack);
- efree(needle);
- break; /* found content-type */
- }
- } ZEND_HASH_FOREACH_END();
- }
- }
- /* Allocate the Input buffer front-end. */
- ret = xmlAllocParserInputBuffer(enc);
- if (ret != NULL) {
- ret->context = context;
- ret->readcallback = php_libxml_streams_IO_read;
- ret->closecallback = php_libxml_streams_IO_close;
- } else
- php_libxml_streams_IO_close(context);
- return(ret);
- }
- static xmlOutputBufferPtr
- php_libxml_output_buffer_create_filename(const char *URI,
- xmlCharEncodingHandlerPtr encoder,
- int compression ATTRIBUTE_UNUSED)
- {
- xmlOutputBufferPtr ret;
- xmlURIPtr puri;
- void *context = NULL;
- char *unescaped = NULL;
- if (URI == NULL)
- return(NULL);
- if (strstr(URI, "%00")) {
- php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes");
- return NULL;
- }
- puri = xmlParseURI(URI);
- if (puri != NULL) {
- if (puri->scheme != NULL)
- unescaped = xmlURIUnescapeString(URI, 0, NULL);
- xmlFreeURI(puri);
- }
- if (unescaped != NULL) {
- context = php_libxml_streams_IO_open_write_wrapper(unescaped);
- xmlFree(unescaped);
- }
- /* try with a non-escaped URI this may be a strange filename */
- if (context == NULL) {
- context = php_libxml_streams_IO_open_write_wrapper(URI);
- }
- if (context == NULL) {
- return(NULL);
- }
- /* Allocate the Output buffer front-end. */
- ret = xmlAllocOutputBuffer(encoder);
- if (ret != NULL) {
- ret->context = context;
- ret->writecallback = php_libxml_streams_IO_write;
- ret->closecallback = php_libxml_streams_IO_close;
- }
- return(ret);
- }
- static void _php_libxml_free_error(void *ptr)
- {
- /* This will free the libxml alloc'd memory */
- xmlResetError((xmlErrorPtr) ptr);
- }
- static void _php_list_set_error_structure(xmlErrorPtr error, const char *msg)
- {
- xmlError error_copy;
- int ret;
- memset(&error_copy, 0, sizeof(xmlError));
- if (error) {
- ret = xmlCopyError(error, &error_copy);
- } else {
- error_copy.domain = 0;
- error_copy.code = XML_ERR_INTERNAL_ERROR;
- error_copy.level = XML_ERR_ERROR;
- error_copy.line = 0;
- error_copy.node = NULL;
- error_copy.int1 = 0;
- error_copy.int2 = 0;
- error_copy.ctxt = NULL;
- error_copy.message = (char*)xmlStrdup((xmlChar*)msg);
- error_copy.file = NULL;
- error_copy.str1 = NULL;
- error_copy.str2 = NULL;
- error_copy.str3 = NULL;
- ret = 0;
- }
- if (ret == 0) {
- zend_llist_add_element(LIBXML(error_list), &error_copy);
- }
- }
- static void php_libxml_ctx_error_level(int level, void *ctx, const char *msg)
- {
- xmlParserCtxtPtr parser;
- parser = (xmlParserCtxtPtr) ctx;
- if (parser != NULL && parser->input != NULL) {
- if (parser->input->filename) {
- php_error_docref(NULL, level, "%s in %s, line: %d", msg, parser->input->filename, parser->input->line);
- } else {
- php_error_docref(NULL, level, "%s in Entity, line: %d", msg, parser->input->line);
- }
- }
- }
- void php_libxml_issue_error(int level, const char *msg)
- {
- if (LIBXML(error_list)) {
- _php_list_set_error_structure(NULL, msg);
- } else {
- php_error_docref(NULL, level, "%s", msg);
- }
- }
- static void php_libxml_internal_error_handler(int error_type, void *ctx, const char **msg, va_list ap)
- {
- char *buf;
- int len, len_iter, output = 0;
- len = vspprintf(&buf, 0, *msg, ap);
- len_iter = len;
- /* remove any trailing \n */
- while (len_iter && buf[--len_iter] == '\n') {
- buf[len_iter] = '\0';
- output = 1;
- }
- smart_str_appendl(&LIBXML(error_buffer), buf, len);
- efree(buf);
- if (output == 1) {
- if (LIBXML(error_list)) {
- _php_list_set_error_structure(NULL, ZSTR_VAL(LIBXML(error_buffer).s));
- } else if (!EG(exception)) {
- /* Don't throw additional notices/warnings if an exception has already been thrown. */
- switch (error_type) {
- case PHP_LIBXML_CTX_ERROR:
- php_libxml_ctx_error_level(E_WARNING, ctx, ZSTR_VAL(LIBXML(error_buffer).s));
- break;
- case PHP_LIBXML_CTX_WARNING:
- php_libxml_ctx_error_level(E_NOTICE, ctx, ZSTR_VAL(LIBXML(error_buffer).s));
- break;
- default:
- php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(LIBXML(error_buffer).s));
- }
- }
- smart_str_free(&LIBXML(error_buffer));
- }
- }
- static xmlParserInputPtr _php_libxml_external_entity_loader(const char *URL,
- const char *ID, xmlParserCtxtPtr context)
- {
- xmlParserInputPtr ret = NULL;
- const char *resource = NULL;
- zval *ctxzv, retval;
- zval params[3];
- int status;
- zend_fcall_info *fci;
- fci = &LIBXML(entity_loader).fci;
- if (fci->size == 0) {
- /* no custom user-land callback set up; delegate to original loader */
- return _php_libxml_default_entity_loader(URL, ID, context);
- }
- if (ID != NULL) {
- ZVAL_STRING(¶ms[0], ID);
- } else {
- ZVAL_NULL(¶ms[0]);
- }
- if (URL != NULL) {
- ZVAL_STRING(¶ms[1], URL);
- } else {
- ZVAL_NULL(¶ms[1]);
- }
- ctxzv = ¶ms[2];
- array_init_size(ctxzv, 4);
- #define ADD_NULL_OR_STRING_KEY(memb) \
- if (context->memb == NULL) { \
- add_assoc_null_ex(ctxzv, #memb, sizeof(#memb) - 1); \
- } else { \
- add_assoc_string_ex(ctxzv, #memb, sizeof(#memb) - 1, \
- (char *)context->memb); \
- }
- ADD_NULL_OR_STRING_KEY(directory)
- ADD_NULL_OR_STRING_KEY(intSubName)
- ADD_NULL_OR_STRING_KEY(extSubURI)
- ADD_NULL_OR_STRING_KEY(extSubSystem)
- #undef ADD_NULL_OR_STRING_KEY
- fci->retval = &retval;
- fci->params = params;
- fci->param_count = sizeof(params)/sizeof(*params);
- status = zend_call_function(fci, &LIBXML(entity_loader).fcc);
- if (status != SUCCESS || Z_ISUNDEF(retval)) {
- php_libxml_ctx_error(context,
- "Call to user entity loader callback '%s' has failed",
- Z_STRVAL(fci->function_name));
- } else {
- /*
- retval_ptr = *fci->retval_ptr_ptr;
- if (retval_ptr == NULL) {
- php_libxml_ctx_error(context,
- "Call to user entity loader callback '%s' has failed; "
- "probably it has thrown an exception",
- fci->function_name);
- } else */ if (Z_TYPE(retval) == IS_STRING) {
- is_string:
- resource = Z_STRVAL(retval);
- } else if (Z_TYPE(retval) == IS_RESOURCE) {
- php_stream *stream;
- php_stream_from_zval_no_verify(stream, &retval);
- if (stream == NULL) {
- php_libxml_ctx_error(context,
- "The user entity loader callback '%s' has returned a "
- "resource, but it is not a stream",
- Z_STRVAL(fci->function_name));
- } else {
- /* TODO: allow storing the encoding in the stream context? */
- xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
- xmlParserInputBufferPtr pib = xmlAllocParserInputBuffer(enc);
- if (pib == NULL) {
- php_libxml_ctx_error(context, "Could not allocate parser "
- "input buffer");
- } else {
- /* make stream not being closed when the zval is freed */
- GC_ADDREF(stream->res);
- pib->context = stream;
- pib->readcallback = php_libxml_streams_IO_read;
- pib->closecallback = php_libxml_streams_IO_close;
- ret = xmlNewIOInputStream(context, pib, enc);
- if (ret == NULL) {
- xmlFreeParserInputBuffer(pib);
- }
- }
- }
- } else if (Z_TYPE(retval) != IS_NULL) {
- /* retval not string nor resource nor null; convert to string */
- if (try_convert_to_string(&retval)) {
- goto is_string;
- }
- } /* else is null; don't try anything */
- }
- if (ret == NULL) {
- if (resource == NULL) {
- if (ID == NULL) {
- ID = "NULL";
- }
- php_libxml_ctx_error(context,
- "Failed to load external entity \"%s\"\n", ID);
- } else {
- /* we got the resource in the form of a string; open it */
- ret = xmlNewInputFromFile(context, resource);
- }
- }
- zval_ptr_dtor(¶ms[0]);
- zval_ptr_dtor(¶ms[1]);
- zval_ptr_dtor(¶ms[2]);
- zval_ptr_dtor(&retval);
- return ret;
- }
- static xmlParserInputPtr _php_libxml_pre_ext_ent_loader(const char *URL,
- const char *ID, xmlParserCtxtPtr context)
- {
- /* Check whether we're running in a PHP context, since the entity loader
- * we've defined is an application level (true global) setting.
- * If we are, we also want to check whether we've finished activating
- * the modules (RINIT phase). Using our external entity loader during a
- * RINIT should not be problem per se (though during MINIT it is, because
- * we don't even have a resource list by then), but then whether one
- * extension would be using the custom external entity loader or not
- * could depend on extension loading order
- * (if _php_libxml_per_request_initialization */
- if (xmlGenericError == php_libxml_error_handler && PG(modules_activated)) {
- return _php_libxml_external_entity_loader(URL, ID, context);
- } else {
- return _php_libxml_default_entity_loader(URL, ID, context);
- }
- }
- PHP_LIBXML_API void php_libxml_ctx_error(void *ctx, const char *msg, ...)
- {
- va_list args;
- va_start(args, msg);
- php_libxml_internal_error_handler(PHP_LIBXML_CTX_ERROR, ctx, &msg, args);
- va_end(args);
- }
- PHP_LIBXML_API void php_libxml_ctx_warning(void *ctx, const char *msg, ...)
- {
- va_list args;
- va_start(args, msg);
- php_libxml_internal_error_handler(PHP_LIBXML_CTX_WARNING, ctx, &msg, args);
- va_end(args);
- }
- PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, xmlErrorPtr error)
- {
- _php_list_set_error_structure(error, NULL);
- return;
- }
- PHP_LIBXML_API void php_libxml_error_handler(void *ctx, const char *msg, ...)
- {
- va_list args;
- va_start(args, msg);
- php_libxml_internal_error_handler(PHP_LIBXML_ERROR, ctx, &msg, args);
- va_end(args);
- }
- static void php_libxml_exports_dtor(zval *zv)
- {
- free(Z_PTR_P(zv));
- }
- PHP_LIBXML_API void php_libxml_initialize(void)
- {
- if (!_php_libxml_initialized) {
- /* we should be the only one's to ever init!! */
- ZEND_IGNORE_LEAKS_BEGIN();
- xmlInitParser();
- ZEND_IGNORE_LEAKS_END();
- _php_libxml_default_entity_loader = xmlGetExternalEntityLoader();
- xmlSetExternalEntityLoader(_php_libxml_pre_ext_ent_loader);
- zend_hash_init(&php_libxml_exports, 0, NULL, php_libxml_exports_dtor, 1);
- _php_libxml_initialized = 1;
- }
- }
- PHP_LIBXML_API void php_libxml_shutdown(void)
- {
- if (_php_libxml_initialized) {
- #if defined(LIBXML_SCHEMAS_ENABLED) && LIBXML_VERSION < 21000
- xmlRelaxNGCleanupTypes();
- #endif
- /* xmlCleanupParser(); */
- zend_hash_destroy(&php_libxml_exports);
- xmlSetExternalEntityLoader(_php_libxml_default_entity_loader);
- _php_libxml_initialized = 0;
- }
- }
- PHP_LIBXML_API void php_libxml_switch_context(zval *context, zval *oldcontext)
- {
- if (oldcontext) {
- ZVAL_COPY_VALUE(oldcontext, &LIBXML(stream_context));
- }
- if (context) {
- ZVAL_COPY_VALUE(&LIBXML(stream_context), context);
- }
- }
- static PHP_MINIT_FUNCTION(libxml)
- {
- php_libxml_initialize();
- REGISTER_LONG_CONSTANT("LIBXML_VERSION", LIBXML_VERSION, CONST_CS | CONST_PERSISTENT);
- REGISTER_STRING_CONSTANT("LIBXML_DOTTED_VERSION", LIBXML_DOTTED_VERSION, CONST_CS | CONST_PERSISTENT);
- REGISTER_STRING_CONSTANT("LIBXML_LOADED_VERSION", (char *)xmlParserVersion, CONST_CS | CONST_PERSISTENT);
- /* For use with loading xml */
- REGISTER_LONG_CONSTANT("LIBXML_NOENT", XML_PARSE_NOENT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_DTDLOAD", XML_PARSE_DTDLOAD, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_DTDATTR", XML_PARSE_DTDATTR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_DTDVALID", XML_PARSE_DTDVALID, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_NOERROR", XML_PARSE_NOERROR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_NOWARNING", XML_PARSE_NOWARNING, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_NOBLANKS", XML_PARSE_NOBLANKS, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_XINCLUDE", XML_PARSE_XINCLUDE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_NSCLEAN", XML_PARSE_NSCLEAN, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_NOCDATA", XML_PARSE_NOCDATA, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_NONET", XML_PARSE_NONET, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_PEDANTIC", XML_PARSE_PEDANTIC, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_COMPACT", XML_PARSE_COMPACT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_NOXMLDECL", XML_SAVE_NO_DECL, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_PARSEHUGE", XML_PARSE_HUGE, CONST_CS | CONST_PERSISTENT);
- #if LIBXML_VERSION >= 20900
- REGISTER_LONG_CONSTANT("LIBXML_BIGLINES", XML_PARSE_BIG_LINES, CONST_CS | CONST_PERSISTENT);
- #endif
- REGISTER_LONG_CONSTANT("LIBXML_NOEMPTYTAG", LIBXML_SAVE_NOEMPTYTAG, CONST_CS | CONST_PERSISTENT);
- /* Schema validation options */
- #ifdef LIBXML_SCHEMAS_ENABLED
- REGISTER_LONG_CONSTANT("LIBXML_SCHEMA_CREATE", XML_SCHEMA_VAL_VC_I_CREATE, CONST_CS | CONST_PERSISTENT);
- #endif
- /* Additional constants for use with loading html */
- #if LIBXML_VERSION >= 20707
- REGISTER_LONG_CONSTANT("LIBXML_HTML_NOIMPLIED", HTML_PARSE_NOIMPLIED, CONST_CS | CONST_PERSISTENT);
- #endif
- #if LIBXML_VERSION >= 20708
- REGISTER_LONG_CONSTANT("LIBXML_HTML_NODEFDTD", HTML_PARSE_NODEFDTD, CONST_CS | CONST_PERSISTENT);
- #endif
- /* Error levels */
- REGISTER_LONG_CONSTANT("LIBXML_ERR_NONE", XML_ERR_NONE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_ERR_WARNING", XML_ERR_WARNING, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_ERR_ERROR", XML_ERR_ERROR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LIBXML_ERR_FATAL", XML_ERR_FATAL, CONST_CS | CONST_PERSISTENT);
- libxmlerror_class_entry = register_class_LibXMLError();
- if (sapi_module.name) {
- static const char * const supported_sapis[] = {
- "cgi-fcgi",
- "litespeed",
- NULL
- };
- const char * const *sapi_name;
- for (sapi_name = supported_sapis; *sapi_name; sapi_name++) {
- if (strcmp(sapi_module.name, *sapi_name) == 0) {
- _php_libxml_per_request_initialization = 0;
- break;
- }
- }
- }
- if (!_php_libxml_per_request_initialization) {
- /* report errors via handler rather than stderr */
- xmlSetGenericErrorFunc(NULL, php_libxml_error_handler);
- xmlParserInputBufferCreateFilenameDefault(php_libxml_input_buffer_create_filename);
- xmlOutputBufferCreateFilenameDefault(php_libxml_output_buffer_create_filename);
- }
- return SUCCESS;
- }
- static PHP_RINIT_FUNCTION(libxml)
- {
- if (_php_libxml_per_request_initialization) {
- /* report errors via handler rather than stderr */
- xmlSetGenericErrorFunc(NULL, php_libxml_error_handler);
- xmlParserInputBufferCreateFilenameDefault(php_libxml_input_buffer_create_filename);
- xmlOutputBufferCreateFilenameDefault(php_libxml_output_buffer_create_filename);
- }
- /* Enable the entity loader by default. This ensures that
- * other threads/requests that might have disabled the loader
- * do not affect the current request.
- */
- LIBXML(entity_loader_disabled) = 0;
- return SUCCESS;
- }
- static PHP_RSHUTDOWN_FUNCTION(libxml)
- {
- _php_libxml_destroy_fci(&LIBXML(entity_loader).fci, &LIBXML(entity_loader).object);
- return SUCCESS;
- }
- static PHP_MSHUTDOWN_FUNCTION(libxml)
- {
- if (!_php_libxml_per_request_initialization) {
- xmlSetGenericErrorFunc(NULL, NULL);
- xmlParserInputBufferCreateFilenameDefault(NULL);
- xmlOutputBufferCreateFilenameDefault(NULL);
- }
- php_libxml_shutdown();
- return SUCCESS;
- }
- static zend_result php_libxml_post_deactivate(void)
- {
- /* reset libxml generic error handling */
- if (_php_libxml_per_request_initialization) {
- xmlSetGenericErrorFunc(NULL, NULL);
- xmlParserInputBufferCreateFilenameDefault(NULL);
- xmlOutputBufferCreateFilenameDefault(NULL);
- }
- xmlSetStructuredErrorFunc(NULL, NULL);
- /* the steam_context resource will be released by resource list destructor */
- ZVAL_UNDEF(&LIBXML(stream_context));
- smart_str_free(&LIBXML(error_buffer));
- if (LIBXML(error_list)) {
- zend_llist_destroy(LIBXML(error_list));
- efree(LIBXML(error_list));
- LIBXML(error_list) = NULL;
- }
- xmlResetLastError();
- return SUCCESS;
- }
- static PHP_MINFO_FUNCTION(libxml)
- {
- php_info_print_table_start();
- php_info_print_table_row(2, "libXML support", "active");
- php_info_print_table_row(2, "libXML Compiled Version", LIBXML_DOTTED_VERSION);
- php_info_print_table_row(2, "libXML Loaded Version", (char *)xmlParserVersion);
- php_info_print_table_row(2, "libXML streams", "enabled");
- php_info_print_table_end();
- }
- /* }}} */
- /* {{{ Set the streams context for the next libxml document load or write */
- PHP_FUNCTION(libxml_set_streams_context)
- {
- zval *arg;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_RESOURCE(arg)
- ZEND_PARSE_PARAMETERS_END();
- if (!Z_ISUNDEF(LIBXML(stream_context))) {
- zval_ptr_dtor(&LIBXML(stream_context));
- ZVAL_UNDEF(&LIBXML(stream_context));
- }
- ZVAL_COPY(&LIBXML(stream_context), arg);
- }
- /* }}} */
- /* {{{ Disable libxml errors and allow user to fetch error information as needed */
- PHP_FUNCTION(libxml_use_internal_errors)
- {
- xmlStructuredErrorFunc current_handler;
- bool use_errors, use_errors_is_null = 1, retval;
- ZEND_PARSE_PARAMETERS_START(0, 1)
- Z_PARAM_OPTIONAL
- Z_PARAM_BOOL_OR_NULL(use_errors, use_errors_is_null)
- ZEND_PARSE_PARAMETERS_END();
- current_handler = xmlStructuredError;
- if (current_handler && current_handler == php_libxml_structured_error_handler) {
- retval = 1;
- } else {
- retval = 0;
- }
- if (use_errors_is_null) {
- RETURN_BOOL(retval);
- }
- if (use_errors == 0) {
- xmlSetStructuredErrorFunc(NULL, NULL);
- if (LIBXML(error_list)) {
- zend_llist_destroy(LIBXML(error_list));
- efree(LIBXML(error_list));
- LIBXML(error_list) = NULL;
- }
- } else {
- xmlSetStructuredErrorFunc(NULL, php_libxml_structured_error_handler);
- if (LIBXML(error_list) == NULL) {
- LIBXML(error_list) = (zend_llist *) emalloc(sizeof(zend_llist));
- zend_llist_init(LIBXML(error_list), sizeof(xmlError), _php_libxml_free_error, 0);
- }
- }
- RETURN_BOOL(retval);
- }
- /* }}} */
- /* {{{ Retrieve last error from libxml */
- PHP_FUNCTION(libxml_get_last_error)
- {
- xmlErrorPtr error;
- ZEND_PARSE_PARAMETERS_NONE();
- error = xmlGetLastError();
- if (error) {
- object_init_ex(return_value, libxmlerror_class_entry);
- add_property_long(return_value, "level", error->level);
- add_property_long(return_value, "code", error->code);
- add_property_long(return_value, "column", error->int2);
- if (error->message) {
- add_property_string(return_value, "message", error->message);
- } else {
- add_property_stringl(return_value, "message", "", 0);
- }
- if (error->file) {
- add_property_string(return_value, "file", error->file);
- } else {
- add_property_stringl(return_value, "file", "", 0);
- }
- add_property_long(return_value, "line", error->line);
- } else {
- RETURN_FALSE;
- }
- }
- /* }}} */
- /* {{{ Retrieve array of errors */
- PHP_FUNCTION(libxml_get_errors)
- {
- xmlErrorPtr error;
- ZEND_PARSE_PARAMETERS_NONE();
- if (LIBXML(error_list)) {
- array_init(return_value);
- error = zend_llist_get_first(LIBXML(error_list));
- while (error != NULL) {
- zval z_error;
- object_init_ex(&z_error, libxmlerror_class_entry);
- add_property_long_ex(&z_error, "level", sizeof("level") - 1, error->level);
- add_property_long_ex(&z_error, "code", sizeof("code") - 1, error->code);
- add_property_long_ex(&z_error, "column", sizeof("column") - 1, error->int2 );
- if (error->message) {
- add_property_string_ex(&z_error, "message", sizeof("message") - 1, error->message);
- } else {
- add_property_stringl_ex(&z_error, "message", sizeof("message") - 1, "", 0);
- }
- if (error->file) {
- add_property_string_ex(&z_error, "file", sizeof("file") - 1, error->file);
- } else {
- add_property_stringl_ex(&z_error, "file", sizeof("file") - 1, "", 0);
- }
- add_property_long_ex(&z_error, "line", sizeof("line") - 1, error->line);
- add_next_index_zval(return_value, &z_error);
- error = zend_llist_get_next(LIBXML(error_list));
- }
- } else {
- RETURN_EMPTY_ARRAY();
- }
- }
- /* }}} */
- /* {{{ Clear last error from libxml */
- PHP_FUNCTION(libxml_clear_errors)
- {
- ZEND_PARSE_PARAMETERS_NONE();
- xmlResetLastError();
- if (LIBXML(error_list)) {
- zend_llist_clean(LIBXML(error_list));
- }
- }
- /* }}} */
- PHP_LIBXML_API bool php_libxml_disable_entity_loader(bool disable) /* {{{ */
- {
- bool old = LIBXML(entity_loader_disabled);
- LIBXML(entity_loader_disabled) = disable;
- return old;
- } /* }}} */
- /* {{{ Disable/Enable ability to load external entities */
- PHP_FUNCTION(libxml_disable_entity_loader)
- {
- bool disable = 1;
- ZEND_PARSE_PARAMETERS_START(0, 1)
- Z_PARAM_OPTIONAL
- Z_PARAM_BOOL(disable)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_BOOL(php_libxml_disable_entity_loader(disable));
- }
- /* }}} */
- /* {{{ Changes the default external entity loader */
- PHP_FUNCTION(libxml_set_external_entity_loader)
- {
- zend_fcall_info fci;
- zend_fcall_info_cache fcc;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_FUNC_OR_NULL(fci, fcc)
- ZEND_PARSE_PARAMETERS_END();
- _php_libxml_destroy_fci(&LIBXML(entity_loader).fci, &LIBXML(entity_loader).object);
- if (ZEND_FCI_INITIALIZED(fci)) { /* argument not null */
- LIBXML(entity_loader).fci = fci;
- Z_ADDREF(fci.function_name);
- if (fci.object != NULL) {
- ZVAL_OBJ(&LIBXML(entity_loader).object, fci.object);
- Z_ADDREF(LIBXML(entity_loader).object);
- }
- LIBXML(entity_loader).fcc = fcc;
- }
- RETURN_TRUE;
- }
- /* }}} */
- /* {{{ Common functions shared by extensions */
- int php_libxml_xmlCheckUTF8(const unsigned char *s)
- {
- size_t i;
- unsigned char c;
- for (i = 0; (c = s[i++]);) {
- if ((c & 0x80) == 0) {
- } else if ((c & 0xe0) == 0xc0) {
- if ((s[i++] & 0xc0) != 0x80) {
- return 0;
- }
- } else if ((c & 0xf0) == 0xe0) {
- if ((s[i++] & 0xc0) != 0x80 || (s[i++] & 0xc0) != 0x80) {
- return 0;
- }
- } else if ((c & 0xf8) == 0xf0) {
- if ((s[i++] & 0xc0) != 0x80 || (s[i++] & 0xc0) != 0x80 || (s[i++] & 0xc0) != 0x80) {
- return 0;
- }
- } else {
- return 0;
- }
- }
- return 1;
- }
- zval *php_libxml_register_export(zend_class_entry *ce, php_libxml_export_node export_function)
- {
- php_libxml_func_handler export_hnd;
- /* Initialize in case this module hasn't been loaded yet */
- php_libxml_initialize();
- export_hnd.export_func = export_function;
- return zend_hash_add_mem(&php_libxml_exports, ce->name, &export_hnd, sizeof(export_hnd));
- }
- PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object)
- {
- zend_class_entry *ce = NULL;
- xmlNodePtr node = NULL;
- php_libxml_func_handler *export_hnd;
- if (Z_TYPE_P(object) == IS_OBJECT) {
- ce = Z_OBJCE_P(object);
- while (ce->parent != NULL) {
- ce = ce->parent;
- }
- if ((export_hnd = zend_hash_find_ptr(&php_libxml_exports, ce->name))) {
- node = export_hnd->export_func(object);
- }
- }
- return node;
- }
- PHP_LIBXML_API int php_libxml_increment_node_ptr(php_libxml_node_object *object, xmlNodePtr node, void *private_data)
- {
- int ret_refcount = -1;
- if (object != NULL && node != NULL) {
- if (object->node != NULL) {
- if (object->node->node == node) {
- return object->node->refcount;
- } else {
- php_libxml_decrement_node_ptr(object);
- }
- }
- if (node->_private != NULL) {
- object->node = node->_private;
- ret_refcount = ++object->node->refcount;
- /* Only dom uses _private */
- if (object->node->_private == NULL) {
- object->node->_private = private_data;
- }
- } else {
- ret_refcount = 1;
- object->node = emalloc(sizeof(php_libxml_node_ptr));
- object->node->node = node;
- object->node->refcount = 1;
- object->node->_private = private_data;
- node->_private = object->node;
- }
- }
- return ret_refcount;
- }
- PHP_LIBXML_API int php_libxml_decrement_node_ptr(php_libxml_node_object *object)
- {
- int ret_refcount = -1;
- php_libxml_node_ptr *obj_node;
- if (object != NULL && object->node != NULL) {
- obj_node = (php_libxml_node_ptr *) object->node;
- ret_refcount = --obj_node->refcount;
- if (ret_refcount == 0) {
- if (obj_node->node != NULL) {
- obj_node->node->_private = NULL;
- }
- efree(obj_node);
- }
- object->node = NULL;
- }
- return ret_refcount;
- }
- PHP_LIBXML_API int php_libxml_increment_doc_ref(php_libxml_node_object *object, xmlDocPtr docp)
- {
- int ret_refcount = -1;
- if (object->document != NULL) {
- object->document->refcount++;
- ret_refcount = object->document->refcount;
- } else if (docp != NULL) {
- ret_refcount = 1;
- object->document = emalloc(sizeof(php_libxml_ref_obj));
- object->document->ptr = docp;
- object->document->refcount = ret_refcount;
- object->document->doc_props = NULL;
- }
- return ret_refcount;
- }
- PHP_LIBXML_API int php_libxml_decrement_doc_ref(php_libxml_node_object *object)
- {
- int ret_refcount = -1;
- if (object != NULL && object->document != NULL) {
- ret_refcount = --object->document->refcount;
- if (ret_refcount == 0) {
- if (object->document->ptr != NULL) {
- xmlFreeDoc((xmlDoc *) object->document->ptr);
- }
- if (object->document->doc_props != NULL) {
- if (object->document->doc_props->classmap) {
- zend_hash_destroy(object->document->doc_props->classmap);
- FREE_HASHTABLE(object->document->doc_props->classmap);
- }
- efree(object->document->doc_props);
- }
- efree(object->document);
- }
- object->document = NULL;
- }
- return ret_refcount;
- }
- PHP_LIBXML_API void php_libxml_node_free_resource(xmlNodePtr node)
- {
- if (!node) {
- return;
- }
- switch (node->type) {
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
- break;
- default:
- if (node->parent == NULL || node->type == XML_NAMESPACE_DECL) {
- php_libxml_node_free_list((xmlNodePtr) node->children);
- switch (node->type) {
- /* Skip property freeing for the following types */
- case XML_ATTRIBUTE_DECL:
- case XML_DTD_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_ENTITY_DECL:
- case XML_ATTRIBUTE_NODE:
- case XML_NAMESPACE_DECL:
- case XML_TEXT_NODE:
- break;
- default:
- php_libxml_node_free_list((xmlNodePtr) node->properties);
- }
- if (php_libxml_unregister_node(node) == 0) {
- node->doc = NULL;
- }
- php_libxml_node_free(node);
- } else {
- php_libxml_unregister_node(node);
- }
- }
- }
- PHP_LIBXML_API void php_libxml_node_decrement_resource(php_libxml_node_object *object)
- {
- int ret_refcount = -1;
- xmlNodePtr nodep;
- php_libxml_node_ptr *obj_node;
- if (object != NULL && object->node != NULL) {
- obj_node = (php_libxml_node_ptr *) object->node;
- nodep = object->node->node;
- ret_refcount = php_libxml_decrement_node_ptr(object);
- if (ret_refcount == 0) {
- php_libxml_node_free_resource(nodep);
- } else {
- if (obj_node && object == obj_node->_private) {
- obj_node->_private = NULL;
- }
- }
- }
- if (object != NULL && object->document != NULL) {
- /* Safe to call as if the resource were freed then doc pointer is NULL */
- php_libxml_decrement_doc_ref(object);
- }
- }
- /* }}} */
- #if defined(PHP_WIN32) && defined(COMPILE_DL_LIBXML)
- PHP_LIBXML_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
- {
- return xmlDllMain(hinstDLL, fdwReason, lpvReserved);
- }
- #endif
- #endif
|