diff options
author | Ondřej Surý <ondrej@sury.org> | 2012-02-01 21:25:15 +0100 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2012-02-01 21:25:15 +0100 |
commit | 96fb2ff5760132a915766f1d9ec7c63001feacd8 (patch) | |
tree | 160904a89a8f3522fa4e47632db101b045e7814a /ext/libxml | |
parent | 8f1428d29ef91d74b4d272af171675f2971eb15b (diff) | |
download | php-96fb2ff5760132a915766f1d9ec7c63001feacd8.tar.gz |
Imported Upstream version 5.4.0~rc6upstream/5.4.0_rc6
Diffstat (limited to 'ext/libxml')
-rw-r--r-- | ext/libxml/config.w32 | 2 | ||||
-rw-r--r-- | ext/libxml/libxml.c | 262 | ||||
-rw-r--r-- | ext/libxml/php_libxml.h | 4 | ||||
-rw-r--r-- | ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt | 48 | ||||
-rw-r--r-- | ext/libxml/tests/libxml_set_external_entity_loader_error1.phpt | 39 | ||||
-rw-r--r-- | ext/libxml/tests/libxml_set_external_entity_loader_variation1.phpt | 72 | ||||
-rw-r--r-- | ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt | 45 |
7 files changed, 458 insertions, 14 deletions
diff --git a/ext/libxml/config.w32 b/ext/libxml/config.w32 index 13f9347d4..92fd344e5 100644 --- a/ext/libxml/config.w32 +++ b/ext/libxml/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32 306344 2010-12-13 18:43:10Z pajoye $ +// $Id: config.w32 306241 2010-12-11 22:18:10Z pajoye $ // vim:ft=javascript ARG_WITH("libxml", "LibXML support", "yes"); diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 3aef65f4e..aaf4cad58 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -26,6 +26,7 @@ #endif #include "php.h" +#include "SAPI.h" #define PHP_XML_INTERNAL #include "zend_variables.h" @@ -53,6 +54,8 @@ /* 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; @@ -68,6 +71,7 @@ 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; @@ -109,6 +113,9 @@ 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 */ @@ -119,6 +126,7 @@ static const zend_function_entry libxml_functions[] = { 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 }; @@ -261,6 +269,18 @@ 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; +} + +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. @@ -278,8 +298,9 @@ static void *php_libxml_streams_IO_open_wrapper(const char *filename, const char TSRMLS_FETCH(); - uri = xmlParseURI((xmlChar *)filename); - if (uri && (uri->scheme == NULL || (xmlStrncmp(uri->scheme, "file", 4) == 0))) { + 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 { @@ -300,7 +321,7 @@ static void *php_libxml_streams_IO_open_wrapper(const char *filename, const char 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, ENFORCE_SAFE_MODE TSRMLS_CC); + 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) { @@ -311,8 +332,8 @@ static void *php_libxml_streams_IO_open_wrapper(const char *filename, const char } context = php_stream_context_from_zval(LIBXML(stream_context), 0); - - ret_val = php_stream_open_wrapper_ex(path_to_open, (char *)mode, ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL, context); + + ret_val = php_stream_open_wrapper_ex(path_to_open, (char *)mode, REPORT_ERRORS, NULL, context); if (isescaped) { xmlFree(resolved_path); } @@ -528,6 +549,143 @@ static void php_libxml_internal_error_handler(int error_type, void *ctx, const c } } +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) +{ + /* Check whether we're running in a PHP context, since the entity loader + * we've defined is an application level (true global) setting */ + if (xmlGenericError == php_libxml_error_handler) { + 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; @@ -565,6 +723,9 @@ 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); @@ -580,6 +741,8 @@ PHP_LIBXML_API void php_libxml_shutdown(void) #endif xmlCleanupParser(); zend_hash_destroy(&php_libxml_exports); + + xmlSetExternalEntityLoader(_php_libxml_default_entity_loader); _php_libxml_initialized = 0; } } @@ -616,6 +779,7 @@ static PHP_MINIT_FUNCTION(libxml) 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); @@ -625,6 +789,15 @@ static PHP_MINIT_FUNCTION(libxml) #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); @@ -634,22 +807,55 @@ static PHP_MINIT_FUNCTION(libxml) 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) { - /* 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); + 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); + xmlSetStructuredErrorFunc(NULL, NULL); + + xmlParserInputBufferCreateFilenameDefault(NULL); + xmlOutputBufferCreateFilenameDefault(NULL); + } php_libxml_shutdown(); return SUCCESS; @@ -659,11 +865,13 @@ static PHP_MSHUTDOWN_FUNCTION(libxml) static PHP_RSHUTDOWN_FUNCTION(libxml) { /* reset libxml generic error handling */ - xmlSetGenericErrorFunc(NULL, NULL); - xmlSetStructuredErrorFunc(NULL, NULL); + if (_php_libxml_per_request_initialization) { + xmlSetGenericErrorFunc(NULL, NULL); + xmlSetStructuredErrorFunc(NULL, NULL); - xmlParserInputBufferCreateFilenameDefault(NULL); - xmlOutputBufferCreateFilenameDefault(NULL); + xmlParserInputBufferCreateFilenameDefault(NULL); + xmlOutputBufferCreateFilenameDefault(NULL); + } if (LIBXML(stream_context)) { zval_ptr_dtor(&LIBXML(stream_context)); @@ -676,6 +884,8 @@ static PHP_RSHUTDOWN_FUNCTION(libxml) LIBXML(error_list) = NULL; } xmlResetLastError(); + + _php_libxml_destroy_fci(&LIBXML(entity_loader).fci); return SUCCESS; } @@ -858,6 +1068,32 @@ static PHP_FUNCTION(libxml_disable_entity_loader) } /* }}} */ +/* {{{ 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) { diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h index 36ec885fe..3259a61f6 100644 --- a/ext/libxml/php_libxml.h +++ b/ext/libxml/php_libxml.h @@ -43,6 +43,10 @@ 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_END_MODULE_GLOBALS(libxml) typedef struct _libxml_doc_props { 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 000000000..51ab77705 --- /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 000000000..5ed079d8d --- /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 000000000..c9c45940b --- /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 000000000..b6251bea6 --- /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. |