Only register error handling when observable

Closes GH-13702.
This commit is contained in:
Niels Dossche 2024-03-13 21:22:44 +01:00
parent 9fd74cfc9d
commit b955973818
5 changed files with 40 additions and 10 deletions

View File

@ -185,6 +185,7 @@ PHP 8.4 INTERNALS UPGRADE NOTES
- Removed the "properties" HashTable field from php_libxml_node_object.
- Added a way to attached private data to a php_libxml_ref_obj.
- Added a way to fix a class type onto php_libxml_ref_obj.
- Added php_libxml_uses_internal_errors().
e. ext/date
- Added the php_format_date_ex() API to format instances of php_date_obj.

View File

@ -765,6 +765,16 @@ oom:
RETURN_THROWS();
}
/* Only bother to register error handling when the error reports can become observable. */
static bool dom_should_register_error_handlers(zend_long options)
{
if (options & XML_PARSE_NOERROR) {
return false;
}
return php_libxml_uses_internal_errors() || ((EG(error_reporting) | EG(user_error_handler_error_reporting)) & E_WARNING);
}
PHP_METHOD(DOM_HTMLDocument, createFromString)
{
const char *source, *override_encoding = NULL;
@ -793,7 +803,7 @@ PHP_METHOD(DOM_HTMLDocument, createFromString)
dom_reset_line_column_cache(&application_data.cache_tokenizer);
lexbor_libxml2_bridge_parse_context ctx;
lexbor_libxml2_bridge_parse_context_init(&ctx);
if (!(options & XML_PARSE_NOERROR)) {
if (dom_should_register_error_handlers(options)) {
lexbor_libxml2_bridge_parse_set_error_callbacks(
&ctx,
dom_lexbor_libxml2_bridge_tokenizer_error_reporter,
@ -952,7 +962,7 @@ PHP_METHOD(DOM_HTMLDocument, createFromFile)
dom_reset_line_column_cache(&application_data.cache_tokenizer);
lexbor_libxml2_bridge_parse_context ctx;
lexbor_libxml2_bridge_parse_context_init(&ctx);
if (!(options & XML_PARSE_NOERROR)) {
if (dom_should_register_error_handlers(options)) {
lexbor_libxml2_bridge_parse_set_error_callbacks(
&ctx,
dom_lexbor_libxml2_bridge_tokenizer_error_reporter,

View File

@ -0,0 +1,19 @@
--TEST--
Parse HTML document with user error handler and error_reporting(0)
--EXTENSIONS--
dom
--INI--
error_reporting=0
--FILE--
<?php
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
var_dump($errno, $errstr);
}, E_WARNING);
DOM\HTMLDocument::createFromString('<html></html>');
?>
--EXPECT--
int(2)
string(113) "DOM\HTMLDocument::createFromString(): tree error unexpected-token-in-initial-mode in Entity, line: 1, column: 2-5"

View File

@ -1055,23 +1055,22 @@ PHP_FUNCTION(libxml_set_streams_context)
}
/* }}} */
PHP_LIBXML_API bool php_libxml_uses_internal_errors(void)
{
return xmlStructuredError == php_libxml_structured_error_handler;
}
/* {{{ Disable libxml errors and allow user to fetch error information as needed */
PHP_FUNCTION(libxml_use_internal_errors)
{
xmlStructuredErrorFunc current_handler;
bool use_errors, use_errors_is_null = 1, retval;
bool use_errors, use_errors_is_null = true;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL_OR_NULL(use_errors, use_errors_is_null)
ZEND_PARSE_PARAMETERS_END();
current_handler = xmlStructuredError;
if (current_handler && current_handler == php_libxml_structured_error_handler) {
retval = 1;
} else {
retval = 0;
}
bool retval = php_libxml_uses_internal_errors();
if (use_errors_is_null) {
RETURN_BOOL(retval);

View File

@ -163,6 +163,7 @@ PHP_LIBXML_API void php_libxml_issue_error(int level, const char *msg);
PHP_LIBXML_API bool php_libxml_disable_entity_loader(bool disable);
PHP_LIBXML_API void php_libxml_set_old_ns(xmlDocPtr doc, xmlNsPtr ns);
PHP_LIBXML_API php_stream_context *php_libxml_get_stream_context(void);
PHP_LIBXML_API bool php_libxml_uses_internal_errors(void);
PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_string(const char *start, const char *end);
PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_stream(const php_stream *s);