diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-03-14 05:42:27 +0000 |
---|---|---|
committer | <> | 2013-04-03 16:25:08 +0000 |
commit | c4dd7a1a684490673e25aaf4fabec5df138854c4 (patch) | |
tree | 4d57c44caae4480efff02b90b9be86f44bf25409 /ext/libxml | |
download | php2-master.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/libxml')
-rw-r--r-- | ext/libxml/CREDITS | 2 | ||||
-rw-r--r-- | ext/libxml/config.w32 | 23 | ||||
-rw-r--r-- | ext/libxml/config0.m4 | 25 | ||||
-rw-r--r-- | ext/libxml/libxml.c | 1331 | ||||
-rw-r--r-- | ext/libxml/php_libxml.h | 126 | ||||
-rw-r--r-- | ext/libxml/php_libxml2.def | 1546 | ||||
-rw-r--r-- | ext/libxml/tests/001.phpt | 31 | ||||
-rw-r--r-- | ext/libxml/tests/002.phpt | 87 | ||||
-rw-r--r-- | ext/libxml/tests/003.phpt | 28 | ||||
-rw-r--r-- | ext/libxml/tests/004.phpt | 57 | ||||
-rw-r--r-- | ext/libxml/tests/bug42112.phpt | 31 | ||||
-rw-r--r-- | ext/libxml/tests/bug54440.phpt | 51 | ||||
-rw-r--r-- | ext/libxml/tests/bug61367-read.phpt | 60 | ||||
-rw-r--r-- | ext/libxml/tests/bug61367-write.phpt | 46 | ||||
-rw-r--r-- | ext/libxml/tests/bug63389.phpt | 14 | ||||
-rw-r--r-- | ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt | 48 | ||||
-rw-r--r-- | ext/libxml/tests/libxml_set_external_entity_loader_error1.phpt | 39 | ||||
-rw-r--r-- | ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt | 72 | ||||
-rw-r--r-- | ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt | 45 | ||||
-rw-r--r-- | ext/libxml/tests/test.xml | 8 |
20 files changed, 3670 insertions, 0 deletions
diff --git a/ext/libxml/CREDITS b/ext/libxml/CREDITS new file mode 100644 index 0000000..9b744ae --- /dev/null +++ b/ext/libxml/CREDITS @@ -0,0 +1,2 @@ +LIBXML +Christian Stocker, Rob Richards, Marcus Boerger, Wez Furlong, Shane Caraveo diff --git a/ext/libxml/config.w32 b/ext/libxml/config.w32 new file mode 100644 index 0000000..92144f9 --- /dev/null +++ b/ext/libxml/config.w32 @@ -0,0 +1,23 @@ +// $Id$ +// vim:ft=javascript + +ARG_WITH("libxml", "LibXML support", "yes"); + +if (PHP_LIBXML == "yes") { + if (CHECK_LIB("libxml2_a_dll.lib;libxml2_a.lib", "libxml") && + CHECK_LIB("libiconv_a.lib;iconv_a.lib;libiconv.lib;iconv.lib", "libxml") && + CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_LIBXML") && + ADD_EXTENSION_DEP('libxml', 'iconv')) { + + EXTENSION("libxml", "libxml.c", false /* never shared */); + AC_DEFINE("HAVE_LIBXML", 1, "LibXML support"); + ADD_FLAG("CFLAGS_LIBXML", "/D LIBXML_STATIC /D LIBXML_STATIC_FOR_DLL /D HAVE_WIN32_THREADS "); + if (!PHP_LIBXML_SHARED) { + ADD_DEF_FILE("ext\\libxml\\php_libxml2.def"); + } + PHP_INSTALL_HEADERS("ext/libxml/", "php_libxml.h"); + } else { + WARNING("libxml support can't be enabled, iconv or libxml are missing") + PHP_LIBXML = "no" + } +} diff --git a/ext/libxml/config0.m4 b/ext/libxml/config0.m4 new file mode 100644 index 0000000..14f5868 --- /dev/null +++ b/ext/libxml/config0.m4 @@ -0,0 +1,25 @@ +dnl +dnl $Id$ +dnl + +PHP_ARG_ENABLE(libxml, whether to enable LIBXML support, +[ --disable-libxml Disable LIBXML support], yes) + +if test -z "$PHP_LIBXML_DIR"; then + PHP_ARG_WITH(libxml-dir, libxml2 install dir, + [ --with-libxml-dir[=DIR] LIBXML: libxml2 install prefix], no, no) +fi + +if test "$PHP_LIBXML" != "no"; then + + dnl This extension can not be build as shared + ext_shared=no + + PHP_SETUP_LIBXML(LIBXML_SHARED_LIBADD, [ + AC_DEFINE(HAVE_LIBXML,1,[ ]) + PHP_NEW_EXTENSION(libxml, [libxml.c], $ext_shared) + PHP_INSTALL_HEADERS([ext/libxml/php_libxml.h]) + ], [ + AC_MSG_ERROR([xml2-config not found. Please check your libxml2 installation.]) + ]) +fi diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c new file mode 100644 index 0000000..b1cb45d --- /dev/null +++ b/ext/libxml/libxml.c @@ -0,0 +1,1331 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 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: | + | http://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> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#define IS_EXT_MODULE + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "SAPI.h" + +#define PHP_XML_INTERNAL +#include "zend_variables.h" +#include "ext/standard/php_string.h" +#include "ext/standard/info.h" +#include "ext/standard/file.h" + +#if 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> +#endif + +#include "php_libxml.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 PHP_FUNCTION(libxml_set_streams_context); +static PHP_FUNCTION(libxml_use_internal_errors); +static PHP_FUNCTION(libxml_get_last_error); +static PHP_FUNCTION(libxml_clear_errors); +static PHP_FUNCTION(libxml_get_errors); +static PHP_FUNCTION(libxml_set_external_entity_loader); +static PHP_FUNCTION(libxml_disable_entity_loader); + +static zend_class_entry *libxmlerror_class_entry; + +/* {{{ dynamically loadable module stuff */ +#ifdef COMPILE_DL_LIBXML +ZEND_GET_MODULE(libxml) +#endif /* COMPILE_DL_LIBXML */ +/* }}} */ + +/* {{{ function prototypes */ +static PHP_MINIT_FUNCTION(libxml); +static PHP_RINIT_FUNCTION(libxml); +static PHP_MSHUTDOWN_FUNCTION(libxml); +static PHP_MINFO_FUNCTION(libxml); +static int php_libxml_post_deactivate(); + +/* }}} */ + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO(arginfo_libxml_set_streams_context, 0) + ZEND_ARG_INFO(0, context) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_libxml_use_internal_errors, 0, 0, 0) + ZEND_ARG_INFO(0, use_errors) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_libxml_get_last_error, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_libxml_get_errors, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_libxml_clear_errors, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_libxml_disable_entity_loader, 0, 0, 0) + ZEND_ARG_INFO(0, disable) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_libxml_set_external_entity_loader, 0, 0, 1) + ZEND_ARG_INFO(0, resolver_function) +ZEND_END_ARG_INFO() +/* }}} */ + +/* {{{ extension definition structures */ +static const zend_function_entry libxml_functions[] = { + PHP_FE(libxml_set_streams_context, arginfo_libxml_set_streams_context) + PHP_FE(libxml_use_internal_errors, arginfo_libxml_use_internal_errors) + PHP_FE(libxml_get_last_error, arginfo_libxml_get_last_error) + PHP_FE(libxml_clear_errors, arginfo_libxml_clear_errors) + PHP_FE(libxml_get_errors, arginfo_libxml_get_errors) + PHP_FE(libxml_disable_entity_loader, arginfo_libxml_disable_entity_loader) + PHP_FE(libxml_set_external_entity_loader, arginfo_libxml_set_external_entity_loader) + PHP_FE_END +}; + +zend_module_entry libxml_module_entry = { + STANDARD_MODULE_HEADER, + "libxml", /* extension name */ + libxml_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 */ + NULL, /* per-request shutdown function */ + PHP_MINFO(libxml), /* information function */ + NO_VERSION_YET, + 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 TSRMLS_DC) +{ + if (object->properties) { + object->properties = NULL; + } + php_libxml_decrement_node_ptr(object TSRMLS_CC); + return php_libxml_decrement_doc_ref(object TSRMLS_CC); +} + +static int php_libxml_unregister_node(xmlNodePtr nodep TSRMLS_DC) +{ + 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 TSRMLS_CC); + } 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; + default: + xmlFreeNode(node); + } + } +} + +static void php_libxml_node_free_list(xmlNodePtr node TSRMLS_DC) +{ + 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 TSRMLS_CC); + break; + case XML_ATTRIBUTE_NODE: + if ((node->doc != NULL) && (((xmlAttrPtr) node)->atype == XML_ATTRIBUTE_ID)) { + xmlRemoveID(node->doc, (xmlAttrPtr) node); + } + 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 TSRMLS_CC); + break; + default: + php_libxml_node_free_list(node->children TSRMLS_CC); + php_libxml_node_free_list((xmlNodePtr) node->properties TSRMLS_CC); + } + + curnode = node->next; + xmlUnlinkNode(node); + if (php_libxml_unregister_node(node TSRMLS_CC) == 0) { + node->doc = NULL; + } + php_libxml_node_free(node); + } + } +} + +/* }}} */ + +/* {{{ startup, shutdown and info functions */ +static PHP_GINIT_FUNCTION(libxml) +{ + libxml_globals->stream_context = NULL; + libxml_globals->error_buffer.c = NULL; + libxml_globals->error_list = NULL; + libxml_globals->entity_loader.fci.size = 0; + libxml_globals->entity_loader_disabled = 0; +} + +static void _php_libxml_destroy_fci(zend_fcall_info *fci) +{ + if (fci->size > 0) { + zval_ptr_dtor(&fci->function_name); + if (fci->object_ptr != NULL) { + zval_ptr_dtor(&fci->object_ptr); + } + fci->size = 0; + } +} + +/* 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, *path_to_open = NULL; + void *ret_val = NULL; + int isescaped=0; + xmlURI *uri; + + TSRMLS_FETCH(); + + 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; + } 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 TSRMLS_CC); + if (wrapper && read_only && wrapper->wops->url_stat) { + if (wrapper->wops->url_stat(wrapper, path_to_open, PHP_STREAM_URL_STAT_QUIET, &ssbuf, NULL TSRMLS_CC) == -1) { + if (isescaped) { + xmlFree(resolved_path); + } + return NULL; + } + } + + context = php_stream_context_from_zval(LIBXML(stream_context), 0); + + ret_val = php_stream_open_wrapper_ex(path_to_open, (char *)mode, REPORT_ERRORS, NULL, context); + 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) +{ + TSRMLS_FETCH(); + return php_stream_read((php_stream*)context, buffer, len); +} + +static int php_libxml_streams_IO_write(void *context, const char *buffer, int len) +{ + TSRMLS_FETCH(); + return php_stream_write((php_stream*)context, buffer, len); +} + +static int php_libxml_streams_IO_close(void *context) +{ + TSRMLS_FETCH(); + 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; + TSRMLS_FETCH(); + + 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); + } + + /* 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); + + 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 int _php_libxml_free_error(xmlErrorPtr error) +{ + /* This will free the libxml alloc'd memory */ + xmlResetError(error); + return 1; +} + +static void _php_list_set_error_structure(xmlErrorPtr error, const char *msg) +{ + xmlError error_copy; + int ret; + + TSRMLS_FETCH(); + + 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 = xmlStrdup(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 TSRMLS_DC) +{ + xmlParserCtxtPtr parser; + + parser = (xmlParserCtxtPtr) ctx; + + if (parser != NULL && parser->input != NULL) { + if (parser->input->filename) { + php_error_docref(NULL TSRMLS_CC, level, "%s in %s, line: %d", msg, parser->input->filename, parser->input->line); + } else { + php_error_docref(NULL TSRMLS_CC, level, "%s in Entity, line: %d", msg, parser->input->line); + } + } +} + +void php_libxml_issue_error(int level, const char *msg TSRMLS_DC) +{ + if (LIBXML(error_list)) { + _php_list_set_error_structure(NULL, msg); + } else { + php_error_docref(NULL TSRMLS_CC, 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; + + TSRMLS_FETCH(); + + 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, LIBXML(error_buffer).c); + } else { + switch (error_type) { + case PHP_LIBXML_CTX_ERROR: + php_libxml_ctx_error_level(E_WARNING, ctx, LIBXML(error_buffer).c TSRMLS_CC); + break; + case PHP_LIBXML_CTX_WARNING: + php_libxml_ctx_error_level(E_NOTICE, ctx, LIBXML(error_buffer).c TSRMLS_CC); + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", LIBXML(error_buffer).c); + } + } + 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 *public = NULL, + *system = NULL, + *ctxzv = NULL, + **params[] = {&public, &system, &ctxzv}, + *retval_ptr = NULL; + int retval; + zend_fcall_info *fci; + TSRMLS_FETCH(); + + 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); + } + + ALLOC_INIT_ZVAL(public); + if (ID != NULL) { + ZVAL_STRING(public, ID, 1); + } + ALLOC_INIT_ZVAL(system); + if (URL != NULL) { + ZVAL_STRING(system, URL, 1); + } + MAKE_STD_ZVAL(ctxzv); + array_init_size(ctxzv, 4); + +#define ADD_NULL_OR_STRING_KEY(memb) \ + if (context->memb == NULL) { \ + add_assoc_null_ex(ctxzv, #memb, sizeof(#memb)); \ + } else { \ + add_assoc_string_ex(ctxzv, #memb, sizeof(#memb), \ + (char *)context->memb, 1); \ + } + + 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_ptr_ptr = &retval_ptr; + fci->params = params; + fci->param_count = sizeof(params)/sizeof(*params); + fci->no_separation = 1; + + retval = zend_call_function(fci, &LIBXML(entity_loader).fcc TSRMLS_CC); + if (retval != SUCCESS || fci->retval_ptr_ptr == NULL) { + php_libxml_ctx_error(context, + "Call to user entity loader callback '%s' has failed", + 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_P(retval_ptr) == IS_STRING) { +is_string: + resource = Z_STRVAL_P(retval_ptr); + } else if (Z_TYPE_P(retval_ptr) == IS_RESOURCE) { + php_stream *stream; + php_stream_from_zval_no_verify(stream, &retval_ptr); + if (stream == NULL) { + php_libxml_ctx_error(context, + "The user entity loader callback '%s' has returned a " + "resource, but it is not a stream", + 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 */ + zend_list_addref(stream->rsrc_id); + 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_P(retval_ptr) != IS_NULL) { + /* retval not string nor resource nor null; convert to string */ + SEPARATE_ZVAL(&retval_ptr); + convert_to_string(retval_ptr); + 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(&public); + zval_ptr_dtor(&system); + zval_ptr_dtor(&ctxzv); + if (retval_ptr != NULL) { + zval_ptr_dtor(&retval_ptr); + } + return ret; +} + +static xmlParserInputPtr _php_libxml_pre_ext_ent_loader(const char *URL, + const char *ID, xmlParserCtxtPtr context) +{ + TSRMLS_FETCH(); + + /* 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); +} + + +PHP_LIBXML_API void php_libxml_initialize(void) +{ + if (!_php_libxml_initialized) { + /* we should be the only one's to ever init!! */ + xmlInitParser(); + + _php_libxml_default_entity_loader = xmlGetExternalEntityLoader(); + xmlSetExternalEntityLoader(_php_libxml_pre_ext_ent_loader); + + zend_hash_init(&php_libxml_exports, 0, NULL, NULL, 1); + + _php_libxml_initialized = 1; + } +} + +PHP_LIBXML_API void php_libxml_shutdown(void) +{ + if (_php_libxml_initialized) { +#if defined(LIBXML_SCHEMAS_ENABLED) + xmlRelaxNGCleanupTypes(); +#endif + xmlCleanupParser(); + zend_hash_destroy(&php_libxml_exports); + + xmlSetExternalEntityLoader(_php_libxml_default_entity_loader); + _php_libxml_initialized = 0; + } +} + +PHP_LIBXML_API zval *php_libxml_switch_context(zval *context TSRMLS_DC) +{ + zval *oldcontext; + + oldcontext = LIBXML(stream_context); + LIBXML(stream_context) = context; + return oldcontext; + +} + +static PHP_MINIT_FUNCTION(libxml) +{ + zend_class_entry ce; + + 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); +#if LIBXML_VERSION >= 20621 + 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); +#endif +#if LIBXML_VERSION >= 20703 + REGISTER_LONG_CONSTANT("LIBXML_PARSEHUGE", XML_PARSE_HUGE, CONST_CS | CONST_PERSISTENT); +#endif + REGISTER_LONG_CONSTANT("LIBXML_NOEMPTYTAG", LIBXML_SAVE_NOEMPTYTAG, CONST_CS | CONST_PERSISTENT); + + /* 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); + + INIT_CLASS_ENTRY(ce, "LibXMLError", NULL); + libxmlerror_class_entry = zend_register_internal_class(&ce TSRMLS_CC); + + if (sapi_module.name) { + static const char * const supported_sapis[] = { + "cgi-fcgi", + "fpm-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); + } + 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 int php_libxml_post_deactivate() +{ + TSRMLS_FETCH(); + /* reset libxml generic error handling */ + if (_php_libxml_per_request_initialization) { + xmlSetGenericErrorFunc(NULL, NULL); + + xmlParserInputBufferCreateFilenameDefault(NULL); + xmlOutputBufferCreateFilenameDefault(NULL); + } + xmlSetStructuredErrorFunc(NULL, NULL); + + if (LIBXML(stream_context)) { + /* the steam_context resource will be released by resource list destructor */ + efree(LIBXML(stream_context)); + LIBXML(stream_context) = NULL; + } + 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(); + + _php_libxml_destroy_fci(&LIBXML(entity_loader).fci); + + 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(); +} +/* }}} */ + +/* {{{ proto void libxml_set_streams_context(resource streams_context) + Set the streams context for the next libxml document load or write */ +static PHP_FUNCTION(libxml_set_streams_context) +{ + zval *arg; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg) == FAILURE) { + return; + } + if (LIBXML(stream_context)) { + zval_ptr_dtor(&LIBXML(stream_context)); + LIBXML(stream_context) = NULL; + } + Z_ADDREF_P(arg); + LIBXML(stream_context) = arg; +} +/* }}} */ + +/* {{{ proto bool libxml_use_internal_errors([boolean use_errors]) + Disable libxml errors and allow user to fetch error information as needed */ +static PHP_FUNCTION(libxml_use_internal_errors) +{ + xmlStructuredErrorFunc current_handler; + zend_bool use_errors=0, retval; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &use_errors) == FAILURE) { + return; + } + + current_handler = xmlStructuredError; + if (current_handler && current_handler == php_libxml_structured_error_handler) { + retval = 1; + } else { + retval = 0; + } + + if (ZEND_NUM_ARGS() == 0) { + 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), (llist_dtor_func_t) _php_libxml_free_error, 0); + } + } + RETURN_BOOL(retval); +} +/* }}} */ + +/* {{{ proto object libxml_get_last_error() + Retrieve last error from libxml */ +static PHP_FUNCTION(libxml_get_last_error) +{ + xmlErrorPtr error; + + 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, 1); + } else { + add_property_stringl(return_value, "message", "", 0, 1); + } + if (error->file) { + add_property_string(return_value, "file", error->file, 1); + } else { + add_property_stringl(return_value, "file", "", 0, 1); + } + add_property_long(return_value, "line", error->line); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto object libxml_get_errors() + Retrieve array of errors */ +static PHP_FUNCTION(libxml_get_errors) +{ + + xmlErrorPtr error; + + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + + if (LIBXML(error_list)) { + + error = zend_llist_get_first(LIBXML(error_list)); + + while (error != NULL) { + zval *z_error; + MAKE_STD_ZVAL(z_error); + + object_init_ex(z_error, libxmlerror_class_entry); + add_property_long(z_error, "level", error->level); + add_property_long(z_error, "code", error->code); + add_property_long(z_error, "column", error->int2); + if (error->message) { + add_property_string(z_error, "message", error->message, 1); + } else { + add_property_stringl(z_error, "message", "", 0, 1); + } + if (error->file) { + add_property_string(z_error, "file", error->file, 1); + } else { + add_property_stringl(z_error, "file", "", 0, 1); + } + add_property_long(z_error, "line", error->line); + add_next_index_zval(return_value, z_error); + + error = zend_llist_get_next(LIBXML(error_list)); + } + } +} +/* }}} */ + +/* {{{ proto void libxml_clear_errors() + Clear last error from libxml */ +static PHP_FUNCTION(libxml_clear_errors) +{ + xmlResetLastError(); + if (LIBXML(error_list)) { + zend_llist_clean(LIBXML(error_list)); + } +} +/* }}} */ + +PHP_LIBXML_API zend_bool php_libxml_disable_entity_loader(zend_bool disable TSRMLS_DC) +{ + zend_bool old = LIBXML(entity_loader_disabled); + + LIBXML(entity_loader_disabled) = disable; + return old; +} + +/* {{{ proto bool libxml_disable_entity_loader([boolean disable]) + Disable/Enable ability to load external entities */ +static PHP_FUNCTION(libxml_disable_entity_loader) +{ + zend_bool disable = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &disable) == FAILURE) { + return; + } + + RETURN_BOOL(php_libxml_disable_entity_loader(disable TSRMLS_CC)); +} +/* }}} */ + +/* {{{ proto void libxml_set_external_entity_loader(callback resolver_function) + Changes the default external entity loader */ +static PHP_FUNCTION(libxml_set_external_entity_loader) +{ + zend_fcall_info fci; + zend_fcall_info_cache fcc; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f!", &fci, &fcc) + == FAILURE) { + return; + } + + _php_libxml_destroy_fci(&LIBXML(entity_loader).fci); + + if (fci.size > 0) { /* argument not null */ + LIBXML(entity_loader).fci = fci; + Z_ADDREF_P(fci.function_name); + if (fci.object_ptr != NULL) { + Z_ADDREF_P(fci.object_ptr); + } + LIBXML(entity_loader).fcc = fcc; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Common functions shared by extensions */ +int php_libxml_xmlCheckUTF8(const unsigned char *s) +{ + int 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; +} + +int 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 hasnt been loaded yet */ + php_libxml_initialize(); + export_hnd.export_func = export_function; + + return zend_hash_add(&php_libxml_exports, ce->name, ce->name_length + 1, &export_hnd, sizeof(export_hnd), NULL); +} + +PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object TSRMLS_DC) +{ + zend_class_entry *ce = NULL; + xmlNodePtr node = NULL; + php_libxml_func_handler *export_hnd; + + if (object->type == IS_OBJECT) { + ce = Z_OBJCE_P(object); + while (ce->parent != NULL) { + ce = ce->parent; + } + if (zend_hash_find(&php_libxml_exports, ce->name, ce->name_length + 1, (void **) &export_hnd) == SUCCESS) { + node = export_hnd->export_func(object TSRMLS_CC); + } + } + return node; +} + +PHP_LIBXML_API int php_libxml_increment_node_ptr(php_libxml_node_object *object, xmlNodePtr node, void *private_data TSRMLS_DC) +{ + 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 TSRMLS_CC); + } + } + 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 TSRMLS_DC) +{ + 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 TSRMLS_DC) +{ + 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 TSRMLS_DC) +{ + 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 TSRMLS_DC) +{ + 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 TSRMLS_CC); + 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 TSRMLS_CC); + } + if (php_libxml_unregister_node(node TSRMLS_CC) == 0) { + node->doc = NULL; + } + php_libxml_node_free(node); + } else { + php_libxml_unregister_node(node TSRMLS_CC); + } + } +} + +PHP_LIBXML_API void php_libxml_node_decrement_resource(php_libxml_node_object *object TSRMLS_DC) +{ + 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 TSRMLS_CC); + if (ret_refcount == 0) { + php_libxml_node_free_resource(nodep TSRMLS_CC); + } 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 TSRMLS_CC); + } +} +/* }}} */ + +#ifdef PHP_WIN32 +PHP_LIBXML_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + return xmlDllMain(hinstDLL, fdwReason, lpvReserved); +} +#endif + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h new file mode 100644 index 0000000..04f8b49 --- /dev/null +++ b/ext/libxml/php_libxml.h @@ -0,0 +1,126 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 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: | + | http://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> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_LIBXML_H +#define PHP_LIBXML_H + +#if HAVE_LIBXML +extern zend_module_entry libxml_module_entry; +#define libxml_module_ptr &libxml_module_entry + +#ifdef PHP_WIN32 +# define PHP_LIBXML_API __declspec(dllexport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define PHP_LIBXML_API __attribute__ ((visibility("default"))) +#else +# define PHP_LIBXML_API +#endif + +#include "ext/standard/php_smart_str.h" +#include <libxml/tree.h> + +#define LIBXML_SAVE_NOEMPTYTAG 1<<2 + +ZEND_BEGIN_MODULE_GLOBALS(libxml) + zval *stream_context; + smart_str error_buffer; + zend_llist *error_list; + struct _php_libxml_entity_resolver { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + } entity_loader; + zend_bool entity_loader_disabled; +ZEND_END_MODULE_GLOBALS(libxml) + +typedef struct _libxml_doc_props { + int formatoutput; + int validateonparse; + int resolveexternals; + int preservewhitespace; + int substituteentities; + int stricterror; + int recover; + HashTable *classmap; +} libxml_doc_props; + +typedef struct _php_libxml_ref_obj { + void *ptr; + int refcount; + libxml_doc_props *doc_props; +} php_libxml_ref_obj; + +typedef struct _php_libxml_node_ptr { + xmlNodePtr node; + int refcount; + void *_private; +} php_libxml_node_ptr; + +typedef struct _php_libxml_node_object { + zend_object std; + php_libxml_node_ptr *node; + php_libxml_ref_obj *document; + HashTable *properties; +} php_libxml_node_object; + +typedef void * (*php_libxml_export_node) (zval *object TSRMLS_DC); + +PHP_LIBXML_API int php_libxml_increment_node_ptr(php_libxml_node_object *object, xmlNodePtr node, void *private_data TSRMLS_DC); +PHP_LIBXML_API int php_libxml_decrement_node_ptr(php_libxml_node_object *object TSRMLS_DC); +PHP_LIBXML_API int php_libxml_increment_doc_ref(php_libxml_node_object *object, xmlDocPtr docp TSRMLS_DC); +PHP_LIBXML_API int php_libxml_decrement_doc_ref(php_libxml_node_object *object TSRMLS_DC); +PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object TSRMLS_DC); +PHP_LIBXML_API int php_libxml_register_export(zend_class_entry *ce, php_libxml_export_node export_function); +/* When an explicit freeing of node and children is required */ +PHP_LIBXML_API void php_libxml_node_free_resource(xmlNodePtr node TSRMLS_DC); +/* When object dtor is called as node may still be referenced */ +PHP_LIBXML_API void php_libxml_node_decrement_resource(php_libxml_node_object *object TSRMLS_DC); +PHP_LIBXML_API void php_libxml_error_handler(void *ctx, const char *msg, ...); +PHP_LIBXML_API void php_libxml_ctx_warning(void *ctx, const char *msg, ...); +PHP_LIBXML_API void php_libxml_ctx_error(void *ctx, const char *msg, ...); +PHP_LIBXML_API int php_libxml_xmlCheckUTF8(const unsigned char *s); +PHP_LIBXML_API zval *php_libxml_switch_context(zval *context TSRMLS_DC); +PHP_LIBXML_API void php_libxml_issue_error(int level, const char *msg TSRMLS_DC); +PHP_LIBXML_API zend_bool php_libxml_disable_entity_loader(zend_bool disable TSRMLS_DC); + +/* Init/shutdown functions*/ +PHP_LIBXML_API void php_libxml_initialize(void); +PHP_LIBXML_API void php_libxml_shutdown(void); + +#ifdef ZTS +#define LIBXML(v) TSRMG(libxml_globals_id, zend_libxml_globals *, v) +#else +#define LIBXML(v) (libxml_globals.v) +#endif + +#else /* HAVE_LIBXML */ +#define libxml_module_ptr NULL +#endif + +#define phpext_libxml_ptr libxml_module_ptr + +#endif /* PHP_LIBXML_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/ext/libxml/php_libxml2.def b/ext/libxml/php_libxml2.def new file mode 100644 index 0000000..42a939e --- /dev/null +++ b/ext/libxml/php_libxml2.def @@ -0,0 +1,1546 @@ +EXPORTS +__docbDefaultSAXHandler +__htmlDefaultSAXHandler +__oldXMLWDcompatibility +__xmlBufferAllocScheme +__xmlDefaultBufferSize +__xmlDefaultSAXHandler +__xmlDefaultSAXLocator +__xmlDeregisterNodeDefaultValue +__xmlDoValidityCheckingDefaultValue +xmlFree DATA +__xmlGenericError +__xmlGenericErrorContext +__xmlGetWarningsDefaultValue +__xmlIndentTreeOutput +xmlIsBaseCharGroup DATA +xmlIsCharGroup DATA +xmlIsCombiningGroup DATA +xmlIsDigitGroup DATA +xmlIsExtenderGroup DATA +xmlIsIdeographicGroup DATA +xmlIsPubidChar_tab DATA +__xmlKeepBlanksDefaultValue +xmlLastError DATA +__xmlLineNumbersDefaultValue +__xmlLoadExtDtdDefaultValue +xmlMalloc DATA +xmlMallocAtomic DATA +xmlMemStrdup DATA +xmlOutputBufferCreateFilenameValue DATA +__xmlParserDebugEntities +xmlParserInputBufferCreateFilenameValue DATA +xmlParserMaxDepth DATA +__xmlParserVersion +__xmlPedanticParserDefaultValue +xmlRealloc DATA +__xmlRegisterNodeDefaultValue +__xmlSaveNoEmptyTags +xmlStringComment DATA +xmlStringText DATA +xmlStringTextNoenc DATA +xmlStructuredError DATA +__xmlSubstituteEntitiesDefaultValue +__xmlTreeIndentString +xmlXPathNAN DATA +xmlXPathNINF DATA +xmlXPathPINF DATA +UTF8ToHtml +UTF8Toisolat1 +attribute +attributeDecl +cdataBlock +characters +checkNamespace +comment +docbCreateFileParserCtxt +docbCreatePushParserCtxt +docbDefaultSAXHandlerInit +docbEncodeEntities +docbFreeParserCtxt +docbParseChunk +docbParseDoc +docbParseDocument +docbParseFile +docbSAXParseDoc +docbSAXParseFile +elementDecl +endDocument +endElement +entityDecl +externalSubset +getColumnNumber +getEntity +getLineNumber +getNamespace +getParameterEntity +getPublicId +getSystemId +globalNamespace +hasExternalSubset +hasInternalSubset +htmlAttrAllowed +htmlAutoCloseTag +htmlCreateFileParserCtxt +htmlCreateMemoryParserCtxt +htmlCreatePushParserCtxt +htmlCtxtReadDoc +htmlCtxtReadFd +htmlCtxtReadFile +htmlCtxtReadIO +htmlCtxtReadMemory +htmlCtxtReset +htmlCtxtUseOptions +htmlDefaultSAXHandlerInit +htmlDocContentDumpFormatOutput +htmlDocContentDumpOutput +htmlDocDump +htmlDocDumpMemory +htmlElementAllowedHere +htmlElementStatusHere +htmlEncodeEntities +htmlEntityLookup +htmlEntityValueLookup +htmlFreeParserCtxt +htmlGetMetaEncoding +htmlHandleOmittedElem +htmlInitAutoClose +htmlIsAutoClosed +htmlIsBooleanAttr +htmlIsScriptAttribute +htmlNewDoc +htmlNewDocNoDtD +htmlNodeDump +htmlNodeDumpFile +htmlNodeDumpFileFormat +htmlNodeDumpFormatOutput +htmlNodeDumpOutput +htmlNodeStatus +htmlParseCharRef +htmlParseChunk +htmlParseDoc +htmlParseDocument +htmlParseElement +htmlParseEntityRef +htmlParseFile +htmlReadDoc +htmlReadFd +htmlReadFile +htmlReadIO +htmlReadMemory +htmlSAXParseDoc +htmlSAXParseFile +htmlSaveFile +htmlSaveFileEnc +htmlSaveFileFormat +htmlSetMetaEncoding +htmlTagLookup +ignorableWhitespace +initGenericErrorDefaultFunc +initdocbDefaultSAXHandler +inithtmlDefaultSAXHandler +initxmlDefaultSAXHandler +inputPop +inputPush +internalSubset +isStandalone +isolat1ToUTF8 +namePop +namePush +namespaceDecl +nodePop +nodePush +notationDecl +processingInstruction +reference +resolveEntity +setDocumentLocator +setNamespace +startDocument +startElement +unparsedEntityDecl +valuePop +valuePush +xmlACatalogAdd +xmlACatalogDump +xmlACatalogRemove +xmlACatalogResolve +xmlACatalogResolvePublic +xmlACatalogResolveSystem +xmlACatalogResolveURI +xmlAddAttributeDecl +xmlAddChild +xmlAddChildList +xmlAddDocEntity +xmlAddDtdEntity +xmlAddElementDecl +xmlAddEncodingAlias +xmlAddID +xmlAddNextSibling +xmlAddNotationDecl +xmlAddPrevSibling +xmlAddRef +xmlAddSibling +xmlAllocOutputBuffer +xmlAllocParserInputBuffer +xmlAttrSerializeTxtContent +xmlAutomataCompile +xmlAutomataGetInitState +xmlAutomataIsDeterminist +xmlAutomataNewAllTrans +xmlAutomataNewCountTrans +xmlAutomataNewCountTrans2 +xmlAutomataNewCountedTrans +xmlAutomataNewCounter +xmlAutomataNewCounterTrans +xmlAutomataNewEpsilon +xmlAutomataNewOnceTrans +xmlAutomataNewOnceTrans2 +xmlAutomataNewState +xmlAutomataNewTransition +xmlAutomataNewTransition2 +xmlAutomataSetFinalState +xmlBoolToText +xmlBufferAdd +xmlBufferAddHead +xmlBufferCCat +xmlBufferCat +xmlBufferContent +xmlBufferCreate +xmlBufferCreateSize +xmlBufferCreateStatic +xmlBufferDump +xmlBufferEmpty +xmlBufferFree +xmlBufferGrow +xmlBufferLength +xmlBufferResize +xmlBufferSetAllocationScheme +xmlBufferShrink +xmlBufferWriteCHAR +xmlBufferWriteChar +xmlBufferWriteQuotedString +xmlBuildQName +xmlBuildRelativeURI +xmlBuildURI +xmlByteConsumed +xmlC14NDocDumpMemory +xmlC14NDocSave +xmlC14NDocSaveTo +xmlC14NExecute +xmlCanonicPath +xmlCatalogAdd +xmlCatalogAddLocal +xmlCatalogCleanup +xmlCatalogConvert +xmlCatalogDump +xmlCatalogFreeLocal +xmlCatalogGetDefaults +xmlCatalogGetPublic +xmlCatalogGetSystem +xmlCatalogIsEmpty +xmlCatalogLocalResolve +xmlCatalogLocalResolveURI +xmlCatalogRemove +xmlCatalogResolve +xmlCatalogResolvePublic +xmlCatalogResolveSystem +xmlCatalogResolveURI +xmlCatalogSetDebug +xmlCatalogSetDefaultPrefer +xmlCatalogSetDefaults +xmlCharEncCloseFunc +xmlCharEncFirstLine +xmlCharEncInFunc +xmlCharEncOutFunc +xmlCharInRange +xmlCharStrdup +xmlCharStrndup +xmlCheckFilename +xmlCheckHTTPInput +xmlCheckLanguageID +xmlCheckUTF8 +xmlCheckVersion +xmlCleanupCharEncodingHandlers +xmlCleanupEncodingAliases +xmlCleanupGlobals +xmlCleanupInputCallbacks +xmlCleanupMemory +xmlCleanupOutputCallbacks +xmlCleanupParser +xmlCleanupPredefinedEntities +xmlCleanupThreads +xmlClearNodeInfoSeq +xmlClearParserCtxt +xmlConvertSGMLCatalog +xmlCopyAttributeTable +xmlCopyChar +xmlCopyCharMultiByte +xmlCopyDoc +xmlCopyDtd +xmlCopyElementContent +xmlCopyElementTable +xmlCopyEntitiesTable +xmlCopyEnumeration +xmlCopyError +xmlCopyNamespace +xmlCopyNamespaceList +xmlCopyNode +xmlCopyNodeList +xmlCopyNotationTable +xmlCopyProp +xmlCopyPropList +xmlCreateDocParserCtxt +xmlCreateEntitiesTable +xmlCreateEntityParserCtxt +xmlCreateEnumeration +xmlCreateFileParserCtxt +xmlCreateIOParserCtxt +xmlCreateIntSubset +xmlCreateMemoryParserCtxt +xmlCreatePushParserCtxt +xmlCreateURI +xmlCreateURLParserCtxt +xmlCtxtGetLastError +xmlCtxtReadDoc +xmlCtxtReadFd +xmlCtxtReadFile +xmlCtxtReadIO +xmlCtxtReadMemory +xmlCtxtReset +xmlCtxtResetLastError +xmlCtxtResetPush +xmlCtxtUseOptions +xmlCurrentChar +xmlDebugCheckDocument +xmlDebugDumpAttr +xmlDebugDumpAttrList +xmlDebugDumpDTD +xmlDebugDumpDocument +xmlDebugDumpDocumentHead +xmlDebugDumpEntities +xmlDebugDumpNode +xmlDebugDumpNodeList +xmlDebugDumpOneNode +xmlDebugDumpString +xmlDecodeEntities +xmlDefaultSAXHandlerInit +xmlDelEncodingAlias +xmlDeregisterNodeDefault +xmlDetectCharEncoding +xmlDictCreate +xmlDictCreateSub +xmlDictFree +xmlDictLookup +xmlDictOwns +xmlDictQLookup +xmlDictReference +xmlDictSize +xmlDocCopyNode +xmlDocCopyNodeList +xmlDocDump +xmlDocDumpFormatMemory +xmlDocDumpFormatMemoryEnc +xmlDocDumpMemory +xmlDocDumpMemoryEnc +xmlDocFormatDump +xmlDocGetRootElement +xmlDocSetRootElement +xmlDumpAttributeDecl +xmlDumpAttributeTable +xmlDumpElementDecl +xmlDumpElementTable +xmlDumpEntitiesTable +xmlDumpEntityDecl +xmlDumpNotationDecl +xmlDumpNotationTable +xmlElemDump +xmlEncodeEntities +xmlEncodeEntitiesReentrant +xmlEncodeSpecialChars +xmlErrMemory +xmlFileClose +xmlFileMatch +xmlFileOpen +xmlFileRead +xmlFindCharEncodingHandler +xmlFreeAttributeTable +xmlFreeAutomata +xmlFreeCatalog +xmlFreeDoc +xmlFreeDtd +xmlFreeElementContent +xmlFreeElementTable +xmlFreeEntitiesTable +xmlFreeEnumeration +xmlFreeIDTable +xmlFreeInputStream +xmlFreeMutex +xmlFreeNode +xmlFreeNodeList +xmlFreeNotationTable +xmlFreeNs +xmlFreeNsList +xmlFreeParserCtxt +xmlFreeParserInputBuffer +xmlFreePattern +xmlFreePatternList +xmlFreeProp +xmlFreePropList +xmlFreeRMutex +xmlFreeRefTable +xmlFreeTextReader +xmlFreeTextWriter +xmlFreeURI +xmlFreeValidCtxt +xmlGcMemGet +xmlGcMemSetup +xmlGetBufferAllocationScheme +xmlGetCharEncodingHandler +xmlGetCharEncodingName +xmlGetCompressMode +xmlGetDocCompressMode +xmlGetDocEntity +xmlGetDtdAttrDesc +xmlGetDtdElementDesc +xmlGetDtdEntity +xmlGetDtdNotationDesc +xmlGetDtdQAttrDesc +xmlGetDtdQElementDesc +xmlGetEncodingAlias +xmlGetExternalEntityLoader +xmlGetFeature +xmlGetFeaturesList +xmlGetGlobalState +xmlGetID +xmlGetIntSubset +xmlGetLastChild +xmlGetLastError +xmlGetLineNo +xmlGetNoNsProp +xmlGetNodePath +xmlGetNsList +xmlGetNsProp +xmlGetParameterEntity +xmlGetPredefinedEntity +xmlGetProp +xmlGetRefs +xmlGetThreadId +xmlGetUTF8Char +xmlHandleEntity +xmlHasNsProp +xmlHasProp +xmlHashAddEntry +xmlHashAddEntry2 +xmlHashAddEntry3 +xmlHashCopy +xmlHashCreate +xmlHashFree +xmlHashLookup +xmlHashLookup2 +xmlHashLookup3 +xmlHashQLookup +xmlHashQLookup2 +xmlHashQLookup3 +xmlHashRemoveEntry +xmlHashRemoveEntry2 +xmlHashRemoveEntry3 +xmlHashScan +xmlHashScan3 +xmlHashScanFull +xmlHashScanFull3 +xmlHashSize +xmlHashUpdateEntry +xmlHashUpdateEntry2 +xmlHashUpdateEntry3 +xmlIOFTPClose +xmlIOFTPMatch +xmlIOFTPOpen +xmlIOFTPRead +xmlIOHTTPClose +xmlIOHTTPMatch +xmlIOHTTPOpen +xmlIOHTTPOpenW +xmlIOHTTPRead +xmlIOParseDTD +xmlInitCharEncodingHandlers +xmlInitGlobals +xmlInitMemory +xmlInitNodeInfoSeq +xmlInitParser +xmlInitParserCtxt +xmlInitThreads +xmlInitializeCatalog +xmlInitializeGlobalState +xmlInitializePredefinedEntities +xmlIsBaseChar +xmlIsBlank +xmlIsBlankNode +xmlIsChar +xmlIsCombining +xmlIsDigit +xmlIsExtender +xmlIsID +xmlIsIdeographic +xmlIsLetter +xmlIsMainThread +xmlIsMixedElement +xmlIsPubidChar +xmlIsRef +xmlIsXHTML +xmlKeepBlanksDefault +xmlLineNumbersDefault +xmlLinkGetData +xmlListAppend +xmlListClear +xmlListCopy +xmlListCreate +xmlListDelete +xmlListDup +xmlListEmpty +xmlListEnd +xmlListFront +xmlListInsert +xmlListMerge +xmlListPopBack +xmlListPopFront +xmlListPushBack +xmlListPushFront +xmlListRemoveAll +xmlListRemoveFirst +xmlListRemoveLast +xmlListReverse +xmlListReverseSearch +xmlListReverseWalk +xmlListSearch +xmlListSize +xmlListSort +xmlListWalk +xmlLoadACatalog +xmlLoadCatalog +xmlLoadCatalogs +xmlLoadExternalEntity +xmlLoadSGMLSuperCatalog +xmlLockLibrary +xmlLsCountNode +xmlLsOneNode +xmlMallocAtomicLoc +xmlMallocLoc +xmlMemBlocks +xmlMemDisplay +xmlMemFree +xmlMemGet +xmlMemMalloc +xmlMemRealloc +xmlMemSetup +xmlMemShow +xmlMemStrdupLoc +xmlMemUsed +xmlMemoryDump +xmlMemoryStrdup +xmlModuleClose +xmlModuleFree +xmlModuleOpen +xmlModuleSymbol +xmlMutexLock +xmlMutexUnlock +xmlNamespaceParseNCName +xmlNamespaceParseNSDef +xmlNamespaceParseQName +xmlNanoFTPCheckResponse +xmlNanoFTPCleanup +xmlNanoFTPClose +xmlNanoFTPCloseConnection +xmlNanoFTPConnect +xmlNanoFTPConnectTo +xmlNanoFTPCwd +xmlNanoFTPDele +xmlNanoFTPFreeCtxt +xmlNanoFTPGet +xmlNanoFTPGetConnection +xmlNanoFTPGetResponse +xmlNanoFTPGetSocket +xmlNanoFTPInit +xmlNanoFTPList +xmlNanoFTPNewCtxt +xmlNanoFTPOpen +xmlNanoFTPProxy +xmlNanoFTPQuit +xmlNanoFTPRead +xmlNanoFTPScanProxy +xmlNanoFTPUpdateURL +xmlNanoHTTPAuthHeader +xmlNanoHTTPCleanup +xmlNanoHTTPClose +xmlNanoHTTPContentLength +xmlNanoHTTPEncoding +xmlNanoHTTPFetch +xmlNanoHTTPInit +xmlNanoHTTPMethod +xmlNanoHTTPMethodRedir +xmlNanoHTTPMimeType +xmlNanoHTTPOpen +xmlNanoHTTPOpenRedir +xmlNanoHTTPRead +xmlNanoHTTPRedir +xmlNanoHTTPReturnCode +xmlNanoHTTPSave +xmlNanoHTTPScanProxy +xmlNewAutomata +xmlNewCDataBlock +xmlNewCatalog +xmlNewCharEncodingHandler +xmlNewCharRef +xmlNewChild +xmlNewComment +xmlNewDoc +xmlNewDocComment +xmlNewDocFragment +xmlNewDocNode +xmlNewDocNodeEatName +xmlNewDocPI +xmlNewDocProp +xmlNewDocRawNode +xmlNewDocText +xmlNewDocTextLen +xmlNewDtd +xmlNewElementContent +xmlNewEntityInputStream +xmlNewGlobalNs +xmlNewIOInputStream +xmlNewInputFromFile +xmlNewInputStream +xmlNewMutex +xmlNewNode +xmlNewNodeEatName +xmlNewNs +xmlNewNsProp +xmlNewNsPropEatName +xmlNewPI +xmlNewParserCtxt +xmlNewProp +xmlNewRMutex +xmlNewReference +xmlNewStringInputStream +xmlNewText +xmlNewTextChild +xmlNewTextLen +xmlNewTextReader +xmlNewTextReaderFilename +xmlNewTextWriter +xmlNewTextWriterDoc +xmlNewTextWriterFilename +xmlNewTextWriterMemory +xmlNewTextWriterPushParser +xmlNewTextWriterTree +xmlNewValidCtxt +xmlNextChar +xmlNoNetExternalEntityLoader +xmlNodeAddContent +xmlNodeAddContentLen +xmlNodeBufGetContent +xmlNodeDump +xmlNodeDumpOutput +xmlNodeGetBase +xmlNodeGetContent +xmlNodeGetLang +xmlNodeGetSpacePreserve +xmlNodeIsText +xmlNodeListGetRawString +xmlNodeListGetString +xmlNodeSetBase +xmlNodeSetContent +xmlNodeSetContentLen +xmlNodeSetLang +xmlNodeSetName +xmlNodeSetSpacePreserve +xmlNormalizeURIPath +xmlNormalizeWindowsPath +xmlOutputBufferClose +xmlOutputBufferCreateFd +xmlOutputBufferCreateFile +xmlOutputBufferCreateFilename +xmlOutputBufferCreateFilenameDefault +xmlOutputBufferCreateIO +xmlOutputBufferFlush +xmlOutputBufferWrite +xmlOutputBufferWriteEscape +xmlOutputBufferWriteString +xmlParseAttValue +xmlParseAttribute +xmlParseAttributeListDecl +xmlParseAttributeType +xmlParseBalancedChunkMemory +xmlParseBalancedChunkMemoryRecover +xmlParseCDSect +xmlParseCatalogFile +xmlParseCharData +xmlParseCharEncoding +xmlParseCharRef +xmlParseChunk +xmlParseComment +xmlParseContent +xmlParseCtxtExternalEntity +xmlParseDTD +xmlParseDefaultDecl +xmlParseDoc +xmlParseDocTypeDecl +xmlParseDocument +xmlParseElement +xmlParseElementChildrenContentDecl +xmlParseElementContentDecl +xmlParseElementDecl +xmlParseElementMixedContentDecl +xmlParseEncName +xmlParseEncodingDecl +xmlParseEndTag +xmlParseEntity +xmlParseEntityDecl +xmlParseEntityRef +xmlParseEntityValue +xmlParseEnumeratedType +xmlParseEnumerationType +xmlParseExtParsedEnt +xmlParseExternalEntity +xmlParseExternalID +xmlParseExternalSubset +xmlParseFile +xmlParseInNodeContext +xmlParseMarkupDecl +xmlParseMemory +xmlParseMisc +xmlParseName +xmlParseNamespace +xmlParseNmtoken +xmlParseNotationDecl +xmlParseNotationType +xmlParsePEReference +xmlParsePI +xmlParsePITarget +xmlParsePubidLiteral +xmlParseQuotedString +xmlParseReference +xmlParseSDDecl +xmlParseStartTag +xmlParseSystemLiteral +xmlParseTextDecl +xmlParseURI +xmlParseURIReference +xmlParseVersionInfo +xmlParseVersionNum +xmlParseXMLDecl +xmlParserAddNodeInfo +xmlParserError +xmlParserFindNodeInfo +xmlParserFindNodeInfoIndex +xmlParserGetDirectory +xmlParserHandlePEReference +xmlParserHandleReference +xmlParserInputBufferCreateFd +xmlParserInputBufferCreateFile +xmlParserInputBufferCreateFilename +xmlParserInputBufferCreateFilenameDefault +xmlParserInputBufferCreateIO +xmlParserInputBufferCreateMem +xmlParserInputBufferCreateStatic +xmlParserInputBufferGrow +xmlParserInputBufferPush +xmlParserInputBufferRead +xmlParserInputGrow +xmlParserInputRead +xmlParserInputShrink +xmlParserPrintFileContext +xmlParserPrintFileInfo +xmlParserValidityError +xmlParserValidityWarning +xmlParserWarning +xmlPatternMatch +xmlPatterncompile +xmlPedanticParserDefault +xmlPopInput +xmlPopInputCallbacks +xmlPrintURI +xmlPushInput +xmlRMutexLock +xmlRMutexUnlock +xmlReadDoc +xmlReadFd +xmlReadFile +xmlReadIO +xmlReadMemory +xmlReaderForDoc +xmlReaderForFd +xmlReaderForFile +xmlReaderForIO +xmlReaderForMemory +xmlReaderNewDoc +xmlReaderNewFd +xmlReaderNewFile +xmlReaderNewIO +xmlReaderNewMemory +xmlReaderNewWalker +xmlReaderWalker +xmlReallocLoc +xmlReconciliateNs +xmlRecoverDoc +xmlRecoverFile +xmlRecoverMemory +xmlRegExecPushString +xmlRegExecPushString2 +xmlRegFreeExecCtxt +xmlRegFreeRegexp +xmlRegNewExecCtxt +xmlRegexpCompile +xmlRegexpExec +xmlRegexpIsDeterminist +xmlRegexpPrint +xmlRegisterCharEncodingHandler +xmlRegisterDefaultInputCallbacks +xmlRegisterDefaultOutputCallbacks +xmlRegisterHTTPPostCallbacks +xmlRegisterInputCallbacks +xmlRegisterNodeDefault +xmlRegisterOutputCallbacks +xmlRelaxNGCleanupTypes +xmlRelaxNGDump +xmlRelaxNGDumpTree +xmlRelaxNGFree +xmlRelaxNGFreeParserCtxt +xmlRelaxNGFreeValidCtxt +xmlRelaxNGGetParserErrors +xmlRelaxNGGetValidErrors +xmlRelaxNGInitTypes +xmlRelaxNGNewDocParserCtxt +xmlRelaxNGNewMemParserCtxt +xmlRelaxNGNewParserCtxt +xmlRelaxNGNewValidCtxt +xmlRelaxNGParse +xmlRelaxNGSetParserErrors +xmlRelaxNGSetValidErrors +xmlRelaxNGValidateDoc +xmlRelaxNGValidateFullElement +xmlRelaxNGValidatePopElement +xmlRelaxNGValidatePushCData +xmlRelaxNGValidatePushElement +xmlRelaxParserSetFlag +xmlRemoveID +xmlRemoveProp +xmlRemoveRef +xmlReplaceNode +xmlResetError +xmlResetLastError +xmlSAX2AttributeDecl +xmlSAX2CDataBlock +xmlSAX2Characters +xmlSAX2Comment +xmlSAX2ElementDecl +xmlSAX2EndDocument +xmlSAX2EndElement +xmlSAX2EndElementNs +xmlSAX2EntityDecl +xmlSAX2ExternalSubset +xmlSAX2GetColumnNumber +xmlSAX2GetEntity +xmlSAX2GetLineNumber +xmlSAX2GetParameterEntity +xmlSAX2GetPublicId +xmlSAX2GetSystemId +xmlSAX2HasExternalSubset +xmlSAX2HasInternalSubset +xmlSAX2IgnorableWhitespace +xmlSAX2InitDefaultSAXHandler +xmlSAX2InitDocbDefaultSAXHandler +xmlSAX2InitHtmlDefaultSAXHandler +xmlSAX2InternalSubset +xmlSAX2IsStandalone +xmlSAX2NotationDecl +xmlSAX2ProcessingInstruction +xmlSAX2Reference +xmlSAX2ResolveEntity +xmlSAX2SetDocumentLocator +xmlSAX2StartDocument +xmlSAX2StartElement +xmlSAX2StartElementNs +xmlSAX2UnparsedEntityDecl +xmlSAXDefaultVersion +xmlSAXParseDTD +xmlSAXParseDoc +xmlSAXParseEntity +xmlSAXParseFile +xmlSAXParseFileWithData +xmlSAXParseMemory +xmlSAXParseMemoryWithData +xmlSAXUserParseFile +xmlSAXUserParseMemory +xmlSAXVersion +xmlSaveClose +xmlSaveDoc +xmlSaveFile +xmlSaveFileEnc +xmlSaveFileTo +xmlSaveFlush +xmlSaveFormatFile +xmlSaveFormatFileEnc +xmlSaveFormatFileTo +xmlSaveSetAttrEscape +xmlSaveSetEscape +xmlSaveToFd +xmlSaveToFilename +xmlSaveToIO +xmlSaveTree +xmlSaveUri +xmlScanName +xmlSchemaCheckFacet +xmlSchemaCleanupTypes +xmlSchemaCollapseString +xmlSchemaCompareValues +xmlSchemaDump +xmlSchemaFree +xmlSchemaFreeFacet +xmlSchemaFreeParserCtxt +xmlSchemaFreeType +xmlSchemaFreeValidCtxt +xmlSchemaFreeValue +xmlSchemaFreeWildcard +xmlSchemaGetBuiltInListSimpleTypeItemType +xmlSchemaGetBuiltInType +xmlSchemaGetFacetValueAsULong +xmlSchemaGetParserErrors +xmlSchemaGetPredefinedType +xmlSchemaGetValidErrors +xmlSchemaInitTypes +xmlSchemaIsBuiltInTypeFacet +xmlSchemaNewDocParserCtxt +xmlSchemaNewFacet +xmlSchemaNewMemParserCtxt +xmlSchemaNewParserCtxt +xmlSchemaNewValidCtxt +xmlSchemaParse +xmlSchemaSetParserErrors +xmlSchemaSetValidErrors +xmlSchemaSetValidOptions +xmlSchemaValPredefTypeNode +xmlSchemaValPredefTypeNodeNoNorm +xmlSchemaValidCtxtGetOptions +xmlSchemaValidateDoc +xmlSchemaValidateFacet +xmlSchemaValidateLengthFacet +xmlSchemaValidateListSimpleTypeFacet +xmlSchemaValidateOneElement +xmlSchemaValidatePredefinedType +xmlSchemaValidateStream +xmlSearchNs +xmlSearchNsByHref +xmlSetBufferAllocationScheme +xmlSetCompressMode +xmlSetDocCompressMode +xmlSetEntityReferenceFunc +xmlSetExternalEntityLoader +xmlSetFeature +xmlSetGenericErrorFunc +xmlSetListDoc +xmlSetNs +xmlSetNsProp +xmlSetProp +xmlSetStructuredErrorFunc +xmlSetTreeDoc +xmlSetupParserForBuffer +xmlShell +xmlShellBase +xmlShellCat +xmlShellDir +xmlShellDu +xmlShellList +xmlShellLoad +xmlShellPrintNode +xmlShellPrintXPathError +xmlShellPrintXPathResult +xmlShellPwd +xmlShellSave +xmlShellValidate +xmlShellWrite +xmlSkipBlankChars +xmlSnprintfElementContent +xmlSplitQName +xmlSplitQName2 +xmlSplitQName3 +xmlSprintfElementContent +xmlStopParser +xmlStrEqual +xmlStrPrintf +xmlStrQEqual +xmlStrVPrintf +xmlStrcasecmp +xmlStrcasestr +xmlStrcat +xmlStrchr +xmlStrcmp +xmlStrdup +xmlStringCurrentChar +xmlStringDecodeEntities +xmlStringGetNodeList +xmlStringLenDecodeEntities +xmlStringLenGetNodeList +xmlStrlen +xmlStrncasecmp +xmlStrncat +xmlStrncatNew +xmlStrncmp +xmlStrndup +xmlStrstr +xmlStrsub +xmlSubstituteEntitiesDefault +xmlSwitchEncoding +xmlSwitchInputEncoding +xmlSwitchToEncoding +xmlTextConcat +xmlTextMerge +xmlTextReaderAttributeCount +xmlTextReaderBaseUri +xmlTextReaderClose +xmlTextReaderConstBaseUri +xmlTextReaderConstEncoding +xmlTextReaderConstLocalName +xmlTextReaderConstName +xmlTextReaderConstNamespaceUri +xmlTextReaderConstPrefix +xmlTextReaderConstString +xmlTextReaderConstValue +xmlTextReaderConstXmlLang +xmlTextReaderConstXmlVersion +xmlTextReaderCurrentDoc +xmlTextReaderCurrentNode +xmlTextReaderDepth +xmlTextReaderExpand +xmlTextReaderGetAttribute +xmlTextReaderGetAttributeNo +xmlTextReaderGetAttributeNs +xmlTextReaderGetErrorHandler +xmlTextReaderGetParserProp +xmlTextReaderGetRemainder +xmlTextReaderHasAttributes +xmlTextReaderHasValue +xmlTextReaderIsDefault +xmlTextReaderIsEmptyElement +xmlTextReaderIsNamespaceDecl +xmlTextReaderIsValid +xmlTextReaderLocalName +xmlTextReaderLocatorBaseURI +xmlTextReaderLocatorLineNumber +xmlTextReaderLookupNamespace +xmlTextReaderMoveToAttribute +xmlTextReaderMoveToAttributeNo +xmlTextReaderMoveToAttributeNs +xmlTextReaderMoveToElement +xmlTextReaderMoveToFirstAttribute +xmlTextReaderMoveToNextAttribute +xmlTextReaderName +xmlTextReaderNamespaceUri +xmlTextReaderNext +xmlTextReaderNextSibling +xmlTextReaderNodeType +xmlTextReaderNormalization +xmlTextReaderPrefix +xmlTextReaderPreserve +xmlTextReaderPreservePattern +xmlTextReaderQuoteChar +xmlTextReaderRead +xmlTextReaderReadAttributeValue +xmlTextReaderReadInnerXml +xmlTextReaderReadOuterXml +xmlTextReaderReadState +xmlTextReaderReadString +xmlTextReaderRelaxNGSetSchema +xmlTextReaderRelaxNGValidate +xmlTextReaderSchemaValidate +xmlTextReaderSetErrorHandler +xmlTextReaderSetParserProp +xmlTextReaderSetStructuredErrorHandler +xmlTextReaderSetup +xmlTextReaderStandalone +xmlTextReaderValue +xmlTextReaderXmlLang +xmlTextWriterEndAttribute +xmlTextWriterEndCDATA +xmlTextWriterEndComment +xmlTextWriterEndDTD +xmlTextWriterEndDTDAttlist +xmlTextWriterEndDTDElement +xmlTextWriterEndDTDEntity +xmlTextWriterEndDocument +xmlTextWriterEndElement +xmlTextWriterEndPI +xmlTextWriterFlush +xmlTextWriterFullEndElement +xmlTextWriterSetIndent +xmlTextWriterSetIndentString +xmlTextWriterStartAttribute +xmlTextWriterStartAttributeNS +xmlTextWriterStartCDATA +xmlTextWriterStartComment +xmlTextWriterStartDTD +xmlTextWriterStartDTDAttlist +xmlTextWriterStartDTDElement +xmlTextWriterStartDTDEntity +xmlTextWriterStartDocument +xmlTextWriterStartElement +xmlTextWriterStartElementNS +xmlTextWriterStartPI +xmlTextWriterWriteAttribute +xmlTextWriterWriteAttributeNS +xmlTextWriterWriteBase64 +xmlTextWriterWriteBinHex +xmlTextWriterWriteCDATA +xmlTextWriterWriteComment +xmlTextWriterWriteDTD +xmlTextWriterWriteDTDAttlist +xmlTextWriterWriteDTDElement +xmlTextWriterWriteDTDEntity +xmlTextWriterWriteDTDExternalEntity +xmlTextWriterWriteDTDExternalEntityContents +xmlTextWriterWriteDTDInternalEntity +xmlTextWriterWriteDTDNotation +xmlTextWriterWriteElement +xmlTextWriterWriteElementNS +xmlTextWriterWriteFormatAttribute +xmlTextWriterWriteFormatAttributeNS +xmlTextWriterWriteFormatCDATA +xmlTextWriterWriteFormatComment +xmlTextWriterWriteFormatDTD +xmlTextWriterWriteFormatDTDAttlist +xmlTextWriterWriteFormatDTDElement +xmlTextWriterWriteFormatDTDInternalEntity +xmlTextWriterWriteFormatElement +xmlTextWriterWriteFormatElementNS +xmlTextWriterWriteFormatPI +xmlTextWriterWriteFormatRaw +xmlTextWriterWriteFormatString +xmlTextWriterWritePI +xmlTextWriterWriteRaw +xmlTextWriterWriteRawLen +xmlTextWriterWriteString +xmlTextWriterWriteVFormatAttribute +xmlTextWriterWriteVFormatAttributeNS +xmlTextWriterWriteVFormatCDATA +xmlTextWriterWriteVFormatComment +xmlTextWriterWriteVFormatDTD +xmlTextWriterWriteVFormatDTDAttlist +xmlTextWriterWriteVFormatDTDElement +xmlTextWriterWriteVFormatDTDInternalEntity +xmlTextWriterWriteVFormatElement +xmlTextWriterWriteVFormatElementNS +xmlTextWriterWriteVFormatPI +xmlTextWriterWriteVFormatRaw +xmlTextWriterWriteVFormatString +xmlThrDefBufferAllocScheme +xmlThrDefDefaultBufferSize +xmlThrDefDeregisterNodeDefault +xmlThrDefDoValidityCheckingDefaultValue +xmlThrDefGetWarningsDefaultValue +xmlThrDefIndentTreeOutput +xmlThrDefKeepBlanksDefaultValue +xmlThrDefLineNumbersDefaultValue +xmlThrDefLoadExtDtdDefaultValue +xmlThrDefOutputBufferCreateFilenameDefault +xmlThrDefParserDebugEntities +xmlThrDefParserInputBufferCreateFilenameDefault +xmlThrDefPedanticParserDefaultValue +xmlThrDefRegisterNodeDefault +xmlThrDefSaveNoEmptyTags +xmlThrDefSetGenericErrorFunc +xmlThrDefSetStructuredErrorFunc +xmlThrDefSubstituteEntitiesDefaultValue +xmlThrDefTreeIndentString +xmlUCSIsAegeanNumbers +xmlUCSIsAlphabeticPresentationForms +xmlUCSIsArabic +xmlUCSIsArabicPresentationFormsA +xmlUCSIsArabicPresentationFormsB +xmlUCSIsArmenian +xmlUCSIsArrows +xmlUCSIsBasicLatin +xmlUCSIsBengali +xmlUCSIsBlock +xmlUCSIsBlockElements +xmlUCSIsBopomofo +xmlUCSIsBopomofoExtended +xmlUCSIsBoxDrawing +xmlUCSIsBraillePatterns +xmlUCSIsBuhid +xmlUCSIsByzantineMusicalSymbols +xmlUCSIsCJKCompatibility +xmlUCSIsCJKCompatibilityForms +xmlUCSIsCJKCompatibilityIdeographs +xmlUCSIsCJKCompatibilityIdeographsSupplement +xmlUCSIsCJKRadicalsSupplement +xmlUCSIsCJKSymbolsandPunctuation +xmlUCSIsCJKUnifiedIdeographs +xmlUCSIsCJKUnifiedIdeographsExtensionA +xmlUCSIsCJKUnifiedIdeographsExtensionB +xmlUCSIsCat +xmlUCSIsCatC +xmlUCSIsCatCc +xmlUCSIsCatCf +xmlUCSIsCatCo +xmlUCSIsCatCs +xmlUCSIsCatL +xmlUCSIsCatLl +xmlUCSIsCatLm +xmlUCSIsCatLo +xmlUCSIsCatLt +xmlUCSIsCatLu +xmlUCSIsCatM +xmlUCSIsCatMc +xmlUCSIsCatMe +xmlUCSIsCatMn +xmlUCSIsCatN +xmlUCSIsCatNd +xmlUCSIsCatNl +xmlUCSIsCatNo +xmlUCSIsCatP +xmlUCSIsCatPc +xmlUCSIsCatPd +xmlUCSIsCatPe +xmlUCSIsCatPf +xmlUCSIsCatPi +xmlUCSIsCatPo +xmlUCSIsCatPs +xmlUCSIsCatS +xmlUCSIsCatSc +xmlUCSIsCatSk +xmlUCSIsCatSm +xmlUCSIsCatSo +xmlUCSIsCatZ +xmlUCSIsCatZl +xmlUCSIsCatZp +xmlUCSIsCatZs +xmlUCSIsCherokee +xmlUCSIsCombiningDiacriticalMarks +xmlUCSIsCombiningDiacriticalMarksforSymbols +xmlUCSIsCombiningHalfMarks +xmlUCSIsCombiningMarksforSymbols +xmlUCSIsControlPictures +xmlUCSIsCurrencySymbols +xmlUCSIsCypriotSyllabary +xmlUCSIsCyrillic +xmlUCSIsCyrillicSupplement +xmlUCSIsDeseret +xmlUCSIsDevanagari +xmlUCSIsDingbats +xmlUCSIsEnclosedAlphanumerics +xmlUCSIsEnclosedCJKLettersandMonths +xmlUCSIsEthiopic +xmlUCSIsGeneralPunctuation +xmlUCSIsGeometricShapes +xmlUCSIsGeorgian +xmlUCSIsGothic +xmlUCSIsGreek +xmlUCSIsGreekExtended +xmlUCSIsGreekandCoptic +xmlUCSIsGujarati +xmlUCSIsGurmukhi +xmlUCSIsHalfwidthandFullwidthForms +xmlUCSIsHangulCompatibilityJamo +xmlUCSIsHangulJamo +xmlUCSIsHangulSyllables +xmlUCSIsHanunoo +xmlUCSIsHebrew +xmlUCSIsHighPrivateUseSurrogates +xmlUCSIsHighSurrogates +xmlUCSIsHiragana +xmlUCSIsIPAExtensions +xmlUCSIsIdeographicDescriptionCharacters +xmlUCSIsKanbun +xmlUCSIsKangxiRadicals +xmlUCSIsKannada +xmlUCSIsKatakana +xmlUCSIsKatakanaPhoneticExtensions +xmlUCSIsKhmer +xmlUCSIsKhmerSymbols +xmlUCSIsLao +xmlUCSIsLatin1Supplement +xmlUCSIsLatinExtendedA +xmlUCSIsLatinExtendedAdditional +xmlUCSIsLatinExtendedB +xmlUCSIsLetterlikeSymbols +xmlUCSIsLimbu +xmlUCSIsLinearBIdeograms +xmlUCSIsLinearBSyllabary +xmlUCSIsLowSurrogates +xmlUCSIsMalayalam +xmlUCSIsMathematicalAlphanumericSymbols +xmlUCSIsMathematicalOperators +xmlUCSIsMiscellaneousMathematicalSymbolsA +xmlUCSIsMiscellaneousMathematicalSymbolsB +xmlUCSIsMiscellaneousSymbols +xmlUCSIsMiscellaneousSymbolsandArrows +xmlUCSIsMiscellaneousTechnical +xmlUCSIsMongolian +xmlUCSIsMusicalSymbols +xmlUCSIsMyanmar +xmlUCSIsNumberForms +xmlUCSIsOgham +xmlUCSIsOldItalic +xmlUCSIsOpticalCharacterRecognition +xmlUCSIsOriya +xmlUCSIsOsmanya +xmlUCSIsPhoneticExtensions +xmlUCSIsPrivateUse +xmlUCSIsPrivateUseArea +xmlUCSIsRunic +xmlUCSIsShavian +xmlUCSIsSinhala +xmlUCSIsSmallFormVariants +xmlUCSIsSpacingModifierLetters +xmlUCSIsSpecials +xmlUCSIsSuperscriptsandSubscripts +xmlUCSIsSupplementalArrowsA +xmlUCSIsSupplementalArrowsB +xmlUCSIsSupplementalMathematicalOperators +xmlUCSIsSupplementaryPrivateUseAreaA +xmlUCSIsSupplementaryPrivateUseAreaB +xmlUCSIsSyriac +xmlUCSIsTagalog +xmlUCSIsTagbanwa +xmlUCSIsTags +xmlUCSIsTaiLe +xmlUCSIsTaiXuanJingSymbols +xmlUCSIsTamil +xmlUCSIsTelugu +xmlUCSIsThaana +xmlUCSIsThai +xmlUCSIsTibetan +xmlUCSIsUgaritic +xmlUCSIsUnifiedCanadianAboriginalSyllabics +xmlUCSIsVariationSelectors +xmlUCSIsVariationSelectorsSupplement +xmlUCSIsYiRadicals +xmlUCSIsYiSyllables +xmlUCSIsYijingHexagramSymbols +xmlURIEscape +xmlURIEscapeStr +xmlURIUnescapeString +xmlUTF8Charcmp +xmlUTF8Size +xmlUTF8Strlen +xmlUTF8Strloc +xmlUTF8Strndup +xmlUTF8Strpos +xmlUTF8Strsize +xmlUTF8Strsub +xmlUnlinkNode +xmlUnlockLibrary +xmlUnsetNsProp +xmlUnsetProp +xmlValidBuildContentModel +xmlValidCtxtNormalizeAttributeValue +xmlValidGetPotentialChildren +xmlValidGetValidElements +xmlValidNormalizeAttributeValue +xmlValidateAttributeDecl +xmlValidateAttributeValue +xmlValidateDocument +xmlValidateDocumentFinal +xmlValidateDtd +xmlValidateDtdFinal +xmlValidateElement +xmlValidateElementDecl +xmlValidateNCName +xmlValidateNMToken +xmlValidateName +xmlValidateNameValue +xmlValidateNamesValue +xmlValidateNmtokenValue +xmlValidateNmtokensValue +xmlValidateNotationDecl +xmlValidateNotationUse +xmlValidateOneAttribute +xmlValidateOneElement +xmlValidateOneNamespace +xmlValidatePopElement +xmlValidatePushCData +xmlValidatePushElement +xmlValidateQName +xmlValidateRoot +xmlXIncludeFreeContext +xmlXIncludeNewContext +xmlXIncludeProcess +xmlXIncludeProcessFlags +xmlXIncludeProcessNode +xmlXIncludeProcessTree +xmlXIncludeProcessTreeFlags +xmlXIncludeSetFlags +xmlXPathAddValues +xmlXPathBooleanFunction +xmlXPathCastBooleanToNumber +xmlXPathCastBooleanToString +xmlXPathCastNodeSetToBoolean +xmlXPathCastNodeSetToNumber +xmlXPathCastNodeSetToString +xmlXPathCastNodeToNumber +xmlXPathCastNodeToString +xmlXPathCastNumberToBoolean +xmlXPathCastNumberToString +xmlXPathCastStringToBoolean +xmlXPathCastStringToNumber +xmlXPathCastToBoolean +xmlXPathCastToNumber +xmlXPathCastToString +xmlXPathCeilingFunction +xmlXPathCmpNodes +xmlXPathCompareValues +xmlXPathCompile +xmlXPathCompiledEval +xmlXPathCompiledEvalToBoolean +xmlXPathConcatFunction +xmlXPathContainsFunction +xmlXPathContextSetCache +xmlXPathConvertBoolean +xmlXPathConvertNumber +xmlXPathConvertString +xmlXPathCountFunction +xmlXPathCtxtCompile +xmlXPathDebugDumpCompExpr +xmlXPathDebugDumpObject +xmlXPathDifference +xmlXPathDistinct +xmlXPathDistinctSorted +xmlXPathDivValues +xmlXPathEqualValues +xmlXPathErr +xmlXPathEval +xmlXPathEvalExpr +xmlXPathEvalExpression +xmlXPathEvalPredicate +xmlXPathEvaluatePredicateResult +xmlXPathFalseFunction +xmlXPathFloorFunction +xmlXPathFreeCompExpr +xmlXPathFreeContext +xmlXPathFreeNodeSet +xmlXPathFreeNodeSetList +xmlXPathFreeObject +xmlXPathFreeParserContext +xmlXPathFunctionLookup +xmlXPathFunctionLookupNS +xmlXPathHasSameNodes +xmlXPathIdFunction +xmlXPathInit +xmlXPathIntersection +xmlXPathIsInf +xmlXPathIsNaN +xmlXPathIsNodeType +xmlXPathLangFunction +xmlXPathLastFunction +xmlXPathLeading +xmlXPathLeadingSorted +xmlXPathLocalNameFunction +xmlXPathModValues +xmlXPathMultValues +xmlXPathNamespaceURIFunction +xmlXPathNewBoolean +xmlXPathNewCString +xmlXPathNewContext +xmlXPathNewFloat +xmlXPathNewNodeSet +xmlXPathNewNodeSetList +xmlXPathNewParserContext +xmlXPathNewString +xmlXPathNewValueTree +xmlXPathNextAncestor +xmlXPathNextAncestorOrSelf +xmlXPathNextAttribute +xmlXPathNextChild +xmlXPathNextDescendant +xmlXPathNextDescendantOrSelf +xmlXPathNextFollowing +xmlXPathNextFollowingSibling +xmlXPathNextNamespace +xmlXPathNextParent +xmlXPathNextPreceding +xmlXPathNextPrecedingSibling +xmlXPathNextSelf +xmlXPathNodeLeading +xmlXPathNodeLeadingSorted +xmlXPathNodeSetAdd +xmlXPathNodeSetAddNs +xmlXPathNodeSetAddUnique +xmlXPathNodeSetContains +xmlXPathNodeSetCreate +xmlXPathNodeSetDel +xmlXPathNodeSetFreeNs +xmlXPathNodeSetMerge +xmlXPathNodeSetRemove +xmlXPathNodeSetSort +xmlXPathNodeTrailing +xmlXPathNodeTrailingSorted +xmlXPathNormalizeFunction +xmlXPathNotEqualValues +xmlXPathNotFunction +xmlXPathNsLookup +xmlXPathNumberFunction +xmlXPathObjectCopy +xmlXPathOrderDocElems +xmlXPathParseNCName +xmlXPathParseName +xmlXPathPopBoolean +xmlXPathPopExternal +xmlXPathPopNodeSet +xmlXPathPopNumber +xmlXPathPopString +xmlXPathPositionFunction +xmlXPathRegisterAllFunctions +xmlXPathRegisterFunc +xmlXPathRegisterFuncLookup +xmlXPathRegisterFuncNS +xmlXPathRegisterNs +xmlXPathRegisterVariable +xmlXPathRegisterVariableLookup +xmlXPathRegisterVariableNS +xmlXPathRegisteredFuncsCleanup +xmlXPathRegisteredNsCleanup +xmlXPathRegisteredVariablesCleanup +xmlXPathRoot +xmlXPathRoundFunction +xmlXPathStartsWithFunction +xmlXPathStringEvalNumber +xmlXPathStringFunction +xmlXPathStringLengthFunction +xmlXPathSubValues +xmlXPathSubstringAfterFunction +xmlXPathSubstringBeforeFunction +xmlXPathSubstringFunction +xmlXPathSumFunction +xmlXPathTrailing +xmlXPathTrailingSorted +xmlXPathTranslateFunction +xmlXPathTrueFunction +xmlXPathValueFlipSign +xmlXPathVariableLookup +xmlXPathVariableLookupNS +xmlXPathWrapCString +xmlXPathWrapExternal +xmlXPathWrapNodeSet +xmlXPathWrapString +xmlXPatherror +xmlXPtrBuildNodeList +xmlXPtrEval +xmlXPtrEvalRangePredicate +xmlXPtrFreeLocationSet +xmlXPtrLocationSetAdd +xmlXPtrLocationSetCreate +xmlXPtrLocationSetDel +xmlXPtrLocationSetMerge +xmlXPtrLocationSetRemove +xmlXPtrNewCollapsedRange +xmlXPtrNewContext +xmlXPtrNewLocationSetNodeSet +xmlXPtrNewLocationSetNodes +xmlXPtrNewRange +xmlXPtrNewRangeNodeObject +xmlXPtrNewRangeNodePoint +xmlXPtrNewRangeNodes +xmlXPtrNewRangePointNode +xmlXPtrNewRangePoints +xmlXPtrRangeToFunction +xmlXPtrWrapLocationSet diff --git a/ext/libxml/tests/001.phpt b/ext/libxml/tests/001.phpt new file mode 100644 index 0000000..6f68cb4 --- /dev/null +++ b/ext/libxml/tests/001.phpt @@ -0,0 +1,31 @@ +--TEST-- +libxml_use_internal_errors() +--SKIPIF-- +<?php if (!extension_loaded('libxml')) die('skip'); ?> +--FILE-- +<?php + +var_dump(libxml_use_internal_errors(false)); +var_dump(libxml_use_internal_errors(true)); +var_dump(libxml_use_internal_errors()); +var_dump(libxml_use_internal_errors(new stdclass)); + +var_dump(libxml_get_errors()); +var_dump(libxml_get_last_error()); + +var_dump(libxml_clear_errors()); + +echo "Done\n"; +?> +--EXPECTF-- +bool(false) +bool(false) +bool(true) + +Warning: libxml_use_internal_errors() expects parameter 1 to be boolean, object given in %s001.php on line 6 +NULL +array(0) { +} +bool(false) +NULL +Done diff --git a/ext/libxml/tests/002.phpt b/ext/libxml/tests/002.phpt new file mode 100644 index 0000000..f803d7a --- /dev/null +++ b/ext/libxml/tests/002.phpt @@ -0,0 +1,87 @@ +--TEST-- +libxml_get_errors() +--SKIPIF-- +<?php if (!extension_loaded('simplexml')) die('skip'); ?> +--FILE-- +<?php + +var_dump(libxml_use_internal_errors(true)); + +$xmlstr = <<< XML +<?xml version='1.0' standalone='yes'?> + <movies> + <movie> + <titles>PHP: Behind the Parser</title> + </movie> + </movies> +XML; + +$doc = simplexml_load_string($xmlstr); +$xml = explode("\n", $xmlstr); + +if (!$doc) { + $errors = libxml_get_errors(); + + foreach ($errors as $error) { + echo display_xml_error($error, $xml); + } + + var_dump(libxml_get_last_error()); +} + + +function display_xml_error($error, $xml) +{ + $return = $xml[$error->line - 1] . "\n"; + $return .= str_repeat('-', $error->column) . "^\n"; + + switch ($error->level) { + case LIBXML_ERR_WARNING: + $return .= "Warning $error->code: "; + break; + case LIBXML_ERR_ERROR: + $return .= "Error $error->code: "; + break; + case LIBXML_ERR_FATAL: + $return .= "Fatal Error $error->code: "; + break; + } + + $return .= trim($error->message) . "\n Line: $error->line" . "\n Column: $error->column"; + + if ($error->file) { + $return .= "\n File: $error->file"; + } + + return "$return\n\n--------------------------------------------\n\n"; +} + + +echo "Done\n"; +?> +--EXPECTF-- +bool(false) + <titles>PHP: Behind the Parser</title> +%s +Fatal Error 76: Opening and ending tag mismatch: titles line 4 and title + Line: 4 + Column: %d + +-------------------------------------------- + +object(LibXMLError)#%d (6) { + ["level"]=> + int(3) + ["code"]=> + int(76) + ["column"]=> + int(%d) + ["message"]=> + string(57) "Opening and ending tag mismatch: titles line 4 and title +" + ["file"]=> + string(0) "" + ["line"]=> + int(4) +} +Done diff --git a/ext/libxml/tests/003.phpt b/ext/libxml/tests/003.phpt new file mode 100644 index 0000000..dcf6c0b --- /dev/null +++ b/ext/libxml/tests/003.phpt @@ -0,0 +1,28 @@ +--TEST-- +libxml_use_internal_errors() memory leaks +--SKIPIF-- +<?php if (!extension_loaded('simplexml')) die('skip'); ?> +--FILE-- +<?php +var_dump(libxml_use_internal_errors(true)); + +$xmlstr = <<< XML +<?xml version='1.0' standalone='yes'?> + <movies> + <movie> + <titles>PHP: Behind the Parser</title> + </movie> + </movies> +XML; + +simplexml_load_string($xmlstr); + +// test memleaks here +var_dump(libxml_use_internal_errors(false)); + +echo "Done\n"; +?> +--EXPECTF-- +bool(false) +bool(true) +Done diff --git a/ext/libxml/tests/004.phpt b/ext/libxml/tests/004.phpt new file mode 100644 index 0000000..aa87ab7 --- /dev/null +++ b/ext/libxml/tests/004.phpt @@ -0,0 +1,57 @@ +--TEST-- +libxml_set_streams_context() +--SKIPIF-- +<?php if (!extension_loaded('dom')) die('skip'); ?> +--FILE-- +<?php + +$ctxs = array( + NULL, + 'bogus', + 123, + new stdclass, + array('a'), + stream_context_create(), + stream_context_create(array('file')), + stream_context_create(array('file' => array('some_opt' => 'aaa'))) +); + + +foreach ($ctxs as $ctx) { + var_dump(libxml_set_streams_context($ctx)); + $dom = new DOMDocument(); + var_dump($dom->load(dirname(__FILE__).'/test.xml')); +} + +echo "Done\n"; + +?> +--EXPECTF-- +Warning: stream_context_create(): options should have the form ["wrappername"]["optionname"] = $value in %s004.php on line %d + +Warning: libxml_set_streams_context() expects parameter 1 to be resource, null given in %s004.php on line %d +NULL +bool(true) + +Warning: libxml_set_streams_context() expects parameter 1 to be resource, string given in %s004.php on line %d +NULL +bool(true) + +Warning: libxml_set_streams_context() expects parameter 1 to be resource, integer given in %s004.php on line %d +NULL +bool(true) + +Warning: libxml_set_streams_context() expects parameter 1 to be resource, object given in %s004.php on line %d +NULL +bool(true) + +Warning: libxml_set_streams_context() expects parameter 1 to be resource, array given in %s004.php on line %d +NULL +bool(true) +NULL +bool(true) +NULL +bool(true) +NULL +bool(true) +Done diff --git a/ext/libxml/tests/bug42112.phpt b/ext/libxml/tests/bug42112.phpt new file mode 100644 index 0000000..b5a3f40 --- /dev/null +++ b/ext/libxml/tests/bug42112.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #42112 (deleting a node produces memory corruption) +--SKIPIF-- +<?php if (!extension_loaded('dom')) die('skip'); ?> +--FILE-- +<?php +$xml = <<<EOXML +<root><child xml:id="id1">baz</child></root> +EOXML; + +function remove_node($doc) { + $node = $doc->getElementById( 'id1' ); + print 'Deleting Node: '.$node->nodeName."\n"; + $node->parentNode->removeChild( $node ); +} + +$doc = new DOMDocument(); +$doc->loadXML($xml); + +remove_node($doc); + +$node = $doc->getElementById( 'id1' ); +if ($node) { + print 'Found Node: '.$node->nodeName."\n"; +} +$root = $doc->documentElement; +print 'Root Node: '.$root->nodeName."\n"; +?> +--EXPECT-- +Deleting Node: child +Root Node: root diff --git a/ext/libxml/tests/bug54440.phpt b/ext/libxml/tests/bug54440.phpt new file mode 100644 index 0000000..4074ff9 --- /dev/null +++ b/ext/libxml/tests/bug54440.phpt @@ -0,0 +1,51 @@ +--TEST-- +Bug #54440: libxml extension ignores default context +--SKIPIF-- +<?php if (!extension_loaded('simplexml')) die('skip simplexml required for this test'); ?> +--FILE-- +<?php + +class TestWrapper { + +function stream_open($path, $mode, $options, &$opened_path) +{ + if ($this->context) + print_r(stream_context_get_options($this->context)); + return false; +} + +function url_stat($path, $flags) +{ +return array(); +} + +} + +stream_wrapper_register("test", "TestWrapper") + or die("Failed to register protocol"); + +$ctx1 = stream_context_create(array('test'=>array('test'=>'test 1'))); +$ctx2 = stream_context_create(array('test'=>array('test'=>'test 2'))); + +stream_context_set_default(stream_context_get_options($ctx1)); +@simplexml_load_file('test://sdfsdf'); + +libxml_set_streams_context($ctx2); +@simplexml_load_file('test://sdfsdf'); +--EXPECT-- +Array +( + [test] => Array + ( + [test] => test 1 + ) + +) +Array +( + [test] => Array + ( + [test] => test 2 + ) + +) diff --git a/ext/libxml/tests/bug61367-read.phpt b/ext/libxml/tests/bug61367-read.phpt new file mode 100644 index 0000000..94da3d8 --- /dev/null +++ b/ext/libxml/tests/bug61367-read.phpt @@ -0,0 +1,60 @@ +--TEST-- +Bug #61367: open_basedir bypass in libxml RSHUTDOWN: read test +--SKIPIF-- +<?php if(!extension_loaded('dom')) echo 'skip'; ?> +--INI-- +open_basedir=. +error_reporting=E_ALL & ~E_NOTICE +--FILE-- +<?php +/* + * Note: Using error_reporting=E_ALL & ~E_NOTICE to supress "Trying to get property of non-object" notices. + */ +class StreamExploiter { + public function stream_close ( ) { + $doc = new DOMDocument; + $doc->resolveExternals = true; + $doc->substituteEntities = true; + $dir = htmlspecialchars(dirname(getcwd())); + $dir = str_replace('\\', '/', $dir); // fix for windows + $doc->loadXML( <<<XML +<!DOCTYPE doc [ + <!ENTITY file SYSTEM "file:///$dir/bad"> +]> +<doc>&file;</doc> +XML + ); + print $doc->documentElement->firstChild->nodeValue; + } + + public function stream_open ( $path , $mode , $options , &$opened_path ) { + return true; + } +} + +var_dump(mkdir('test_bug_61367')); +var_dump(mkdir('test_bug_61367/base')); +var_dump(file_put_contents('test_bug_61367/bad', 'blah')); +var_dump(chdir('test_bug_61367/base')); + +stream_wrapper_register( 'exploit', 'StreamExploiter' ); +$s = fopen( 'exploit://', 'r' ); + +?> +--CLEAN-- +<?php +unlink('test_bug_61367/bad'); +rmdir('test_bug_61367/base'); +rmdir('test_bug_61367'); +?> +--EXPECTF-- +bool(true) +bool(true) +int(4) +bool(true) + +Warning: DOMDocument::loadXML(): I/O warning : failed to load external entity "file:///%s/test_bug_61367/bad" in %s on line %d + +Warning: DOMDocument::loadXML(): Failure to process entity file in Entity, line: 4 in %s on line %d + +Warning: DOMDocument::loadXML(): Entity 'file' not defined in Entity, line: 4 in %s on line %d diff --git a/ext/libxml/tests/bug61367-write.phpt b/ext/libxml/tests/bug61367-write.phpt new file mode 100644 index 0000000..e18b071 --- /dev/null +++ b/ext/libxml/tests/bug61367-write.phpt @@ -0,0 +1,46 @@ +--TEST-- +Bug #61367: open_basedir bypass in libxml RSHUTDOWN: write test +--SKIPIF-- +<?php if(!extension_loaded('dom')) echo 'skip'; ?> +--INI-- +open_basedir=. +--FILE-- +<?php + +class StreamExploiter { + public function stream_close ( ) { + $doc = new DOMDocument; + $doc->appendChild($doc->createTextNode('hello')); + var_dump($doc->save(dirname(getcwd()) . '/bad')); + } + + public function stream_open ( $path , $mode , $options , &$opened_path ) { + return true; + } +} + +var_dump(mkdir('test_bug_61367')); +var_dump(mkdir('test_bug_61367/base')); +var_dump(file_put_contents('test_bug_61367/bad', 'blah')); +var_dump(chdir('test_bug_61367/base')); + +stream_wrapper_register( 'exploit', 'StreamExploiter' ); +$s = fopen( 'exploit://', 'r' ); + +?> +--CLEAN-- +<?php +@unlink('test_bug_61367/bad'); +rmdir('test_bug_61367/base'); +rmdir('test_bug_61367'); +?> +--EXPECTF-- +bool(true) +bool(true) +int(4) +bool(true) + +Warning: DOMDocument::save(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (.) in %s on line %d + +Warning: DOMDocument::save(%s): failed to open stream: Operation not permitted in %s on line %d +bool(false) diff --git a/ext/libxml/tests/bug63389.phpt b/ext/libxml/tests/bug63389.phpt new file mode 100644 index 0000000..e9498aa --- /dev/null +++ b/ext/libxml/tests/bug63389.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #63389 (Missing context check on libxml_set_streams_context() causes memleak) +--SKIPIF-- +<?php if (!extension_loaded('libxml')) die('skip'); ?> +--FILE-- +<?php +$fp = fopen("php://input", "r"); +libxml_set_streams_context($fp); +libxml_set_streams_context("a"); +echo "okey"; +?> +--EXPECTF-- +Warning: libxml_set_streams_context() expects parameter 1 to be resource, string given in %sbug63389.php on line %d +okey diff --git a/ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt b/ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt new file mode 100644 index 0000000..51ab777 --- /dev/null +++ b/ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt @@ -0,0 +1,48 @@ +--TEST-- +libxml_set_external_entity_loader() basic test +--SKIPIF-- +<?php if (!extension_loaded('dom')) die('skip'); ?> +--FILE-- +<?php +$xml = <<<XML +<!DOCTYPE foo PUBLIC "-//FOO/BAR" "http://example.com/foobar"> +<foo>bar</foo> +XML; + +$dtd = <<<DTD +<!ELEMENT foo (#PCDATA)> +DTD; + +libxml_set_external_entity_loader( + function ($public, $system, $context) use($dtd){ + var_dump($public); + var_dump($system); + var_dump($context); + $f = fopen("php://temp", "r+"); + fwrite($f, $dtd); + rewind($f); + return $f; + } +); + +$dd = new DOMDocument; +$r = $dd->loadXML($xml); +var_dump($dd->validate()); + +echo "Done.\n"; + +--EXPECT-- +string(10) "-//FOO/BAR" +string(25) "http://example.com/foobar" +array(4) { + ["directory"]=> + NULL + ["intSubName"]=> + NULL + ["extSubURI"]=> + NULL + ["extSubSystem"]=> + NULL +} +bool(true) +Done. diff --git a/ext/libxml/tests/libxml_set_external_entity_loader_error1.phpt b/ext/libxml/tests/libxml_set_external_entity_loader_error1.phpt new file mode 100644 index 0000000..5ed079d --- /dev/null +++ b/ext/libxml/tests/libxml_set_external_entity_loader_error1.phpt @@ -0,0 +1,39 @@ +--TEST-- +libxml_set_external_entity_loader() error: bad arguments +--SKIPIF-- +<?php if (!extension_loaded('dom')) die('skip'); ?> +--FILE-- +<?php +$xml = <<<XML +<!DOCTYPE foo PUBLIC "-//FOO/BAR" "http://example.com/foobar"> +<foo>bar</foo> +XML; + +$dd = new DOMDocument; +$r = $dd->loadXML($xml); + +var_dump(libxml_set_external_entity_loader([])); +var_dump(libxml_set_external_entity_loader()); +var_dump(libxml_set_external_entity_loader(function() {}, 2)); + +var_dump(libxml_set_external_entity_loader(function($a, $b, $c, $d) {})); +var_dump($dd->validate()); + +echo "Done.\n"; + +--EXPECTF-- +Warning: libxml_set_external_entity_loader() expects parameter 1 to be a valid callback, array must have exactly two members in %s on line %d +NULL + +Warning: libxml_set_external_entity_loader() expects exactly 1 parameter, 0 given in %s on line %d +NULL + +Warning: libxml_set_external_entity_loader() expects exactly 1 parameter, 2 given in %s on line %d +NULL +bool(true) + +Warning: Missing argument 4 for {closure}() in %s on line %d + +Warning: DOMDocument::validate(): Could not load the external subset "http://example.com/foobar" in %s on line %d +bool(false) +Done. diff --git a/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt b/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt new file mode 100644 index 0000000..c9c4594 --- /dev/null +++ b/ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt @@ -0,0 +1,72 @@ +--TEST-- +libxml_set_external_entity_loader() variation: resolve externals and entities +--SKIPIF-- +<?php if (!extension_loaded('dom')) die('skip'); ?> +--FILE-- +<?php +chdir(__DIR__); +$xml = <<<XML +<!DOCTYPE foo PUBLIC "-//FOO/BAR" "http://example.com/foobar"> +<foo>bar&fooz;</foo> +XML; + +$dtd = <<<DTD +<!ELEMENT foo (#PCDATA)> +<!ENTITY % fooentity PUBLIC + "-//FOO/ENTITY" + "fooentity.ent"> +%fooentity; +DTD; + +$entity = <<<ENT +<!ENTITY fooz "baz"> +ENT; + +libxml_set_external_entity_loader( + function ($public, $system, $context) use($dtd,$entity){ + static $first = true; + var_dump($public); + var_dump($system); + var_dump($context); + $f = fopen("php://temp", "r+"); + fwrite($f, $first ? $dtd : $entity); + $first = false; + rewind($f); + return $f; + } +); + +$dd = new DOMDocument; +$dd->resolveExternals = true; +$r = $dd->loadXML($xml); +var_dump($dd->validate()); + +echo "Done.\n"; + +--EXPECTF-- +string(10) "-//FOO/BAR" +string(25) "http://example.com/foobar" +array(4) { + ["directory"]=> + string(%d) "%s" + ["intSubName"]=> + string(3) "foo" + ["extSubURI"]=> + string(25) "http://example.com/foobar" + ["extSubSystem"]=> + string(10) "-//FOO/BAR" +} +string(13) "-//FOO/ENTITY" +string(32) "http://example.com/fooentity.ent" +array(4) { + ["directory"]=> + string(%d) "%s" + ["intSubName"]=> + string(3) "foo" + ["extSubURI"]=> + string(25) "http://example.com/foobar" + ["extSubSystem"]=> + string(10) "-//FOO/BAR" +} +bool(true) +Done. diff --git a/ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt b/ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt new file mode 100644 index 0000000..b6251be --- /dev/null +++ b/ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt @@ -0,0 +1,45 @@ +--TEST-- +libxml_set_external_entity_loader() variation: restore original handler; returning NULL +--SKIPIF-- +<?php if (!extension_loaded('dom')) die('skip'); ?> +--CLEAN-- +<?php +@unlink(__DIR__ . "/foobar.dtd"); +--FILE-- +<?php +chdir(__DIR__); +$xml = <<<XML +<!DOCTYPE foo PUBLIC "-//FOO/BAR" "foobar.dtd"> +<foo>bar</foo> +XML; + +$dtd = <<<DTD +<!ELEMENT foo (#PCDATA)> +DTD; + + +libxml_set_external_entity_loader( + function ($public, $system, $context) { + var_dump($public,$system); + return null; + } +); + +$dd = new DOMDocument; +$r = $dd->loadXML($xml); +var_dump($dd->validate()); + +libxml_set_external_entity_loader(NULL); +file_put_contents(__DIR__ . "/foobar.dtd", $dtd); +var_dump($dd->validate()); + +echo "Done.\n"; + +--EXPECTF-- +string(10) "-//FOO/BAR" +string(%d) "%sfoobar.dtd" + +Warning: DOMDocument::validate(): Could not load the external subset "foobar.dtd" in %s on line %d +bool(false) +bool(true) +Done. diff --git a/ext/libxml/tests/test.xml b/ext/libxml/tests/test.xml new file mode 100644 index 0000000..fc1d328 --- /dev/null +++ b/ext/libxml/tests/test.xml @@ -0,0 +1,8 @@ +<library> + <book> + <title>PHP made simple</title> + </book> + <book> + <title>learn PHP easily</title> + </book> +</library> |