summaryrefslogtreecommitdiff
path: root/ext/libxml
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-03-14 05:42:27 +0000
committer <>2013-04-03 16:25:08 +0000
commitc4dd7a1a684490673e25aaf4fabec5df138854c4 (patch)
tree4d57c44caae4480efff02b90b9be86f44bf25409 /ext/libxml
downloadphp2-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/CREDITS2
-rw-r--r--ext/libxml/config.w3223
-rw-r--r--ext/libxml/config0.m425
-rw-r--r--ext/libxml/libxml.c1331
-rw-r--r--ext/libxml/php_libxml.h126
-rw-r--r--ext/libxml/php_libxml2.def1546
-rw-r--r--ext/libxml/tests/001.phpt31
-rw-r--r--ext/libxml/tests/002.phpt87
-rw-r--r--ext/libxml/tests/003.phpt28
-rw-r--r--ext/libxml/tests/004.phpt57
-rw-r--r--ext/libxml/tests/bug42112.phpt31
-rw-r--r--ext/libxml/tests/bug54440.phpt51
-rw-r--r--ext/libxml/tests/bug61367-read.phpt60
-rw-r--r--ext/libxml/tests/bug61367-write.phpt46
-rw-r--r--ext/libxml/tests/bug63389.phpt14
-rw-r--r--ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt48
-rw-r--r--ext/libxml/tests/libxml_set_external_entity_loader_error1.phpt39
-rw-r--r--ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt72
-rw-r--r--ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt45
-rw-r--r--ext/libxml/tests/test.xml8
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>