Closed
Description
Description
The following code:
<?php
function createParser(bool $huge) {
$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_PARSE_HUGE, $huge);
xml_set_element_handler($parser, function($parser, $data) {
}, function($parser, $data) {
});
return $parser;
}
// Construct XML that is too large to parse without XML_OPTION_PARSE_HUGE
$long_text = str_repeat("A", 1000 * 1000 * 5 /* 5 MB */);
$long_xml_head = "<?xml version=\"1.0\"?><container><$long_text/><$long_text/><second>foo</second>";
$long_xml_tail = "</container>";
$parser = createParser(false);
$ret = xml_parse($parser, $long_xml_head, true);
echo "ret = $ret (", xml_error_string(xml_get_error_code($parser)), ")\n";
$parser = createParser(true);
$ret = xml_parse($parser, $long_xml_head, false);
$parser = createParser(true);
$ret = xml_parse_into_struct($parser, $long_xml_head . $long_xml_tail, $values, $index);
?>
Resulted in this output:
ret = 0 (XML_ERR_NAME_REQUIRED)
Fatal error: Allowed memory size of 34603008 bytes exhausted at /php-src/Zend/zend_string.h:176 (tried to allocate 5000032 bytes) in ./test.php on line 20
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2886881==ERROR: AddressSanitizer: SEGV on unknown address 0x0001ffff8041 (pc 0x55f2c377c0ab bp 0x7ffeb917e630 sp 0x7ffeb917e570 T0)
==2886881==The signal is caused by a READ memory access.
#0 0x55f2c377c0ab in zend_mm_free_heap /php-src/Zend/zend_alloc.c:1431:28
#1 0x55f2c3780951 in _efree /php-src/Zend/zend_alloc.c:2600:2
#2 0x55f2c34a76d2 in xml_parser_free_ltags /php-src/ext/xml/xml.c:324:4
#3 0x55f2c347d3d2 in xml_parser_free_obj /php-src/ext/xml/xml.c:336:2
#4 0x55f2c4381d2b in zend_objects_store_free_object_storage /php-src/Zend/zend_objects_API.c:122:6
#5 0x55f2c38b8399 in zend_shutdown_executor_values /php-src/Zend/zend_execute_API.c:401:2
#6 0x55f2c38b97be in shutdown_executor /php-src/Zend/zend_execute_API.c:418:2
#7 0x55f2c3989343 in zend_deactivate /php-src/Zend/zend.c:1311:2
#8 0x55f2c34f319f in php_request_shutdown /php-src/main/main.c:1894:2
#9 0x55f2c48c9868 in do_cli /php-src/sapi/cli/php_cli.c:1136:3
#10 0x55f2c48c3b02 in main /php-src/sapi/cli/php_cli.c:1340:18
#11 0x7f860337ed8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#12 0x7f860337ee3f in __libc_start_main csu/../csu/libc-start.c:392:3
#13 0x55f2c18031f4 in _start (/php-src/sapi/cli/php+0x1c031f4) (BuildId: 4b2c3013b167e0ff55e0ad4f26ad7d3438ee4f65)
AddressSanitizer can not provide additional info.
To reproduce:
USE_ZEND_ALLOC=1 /WorkSpace/phptest/php-src/sapi/cli/php -d "memory_limit=33M" ./test.php
Setting memory_limit to 25M or 50M outputs leaked memory:
==2935312==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 5000001 byte(s) in 1 object(s) allocated from:
#0 0x55ef07c88c1e in malloc (/php-src/sapi/cli/php+0x1c88c1e) (BuildId: 4b2c3013b167e0ff55e0ad4f26ad7d3438ee4f65)
#1 0x7f5e94e917f2 in xmlStrdup (/lib/x86_64-linux-gnu/libxml2.so.2+0xe37f2) (BuildId: aebf8e42966c3ce475ff9d9d51a762831adcbb61)
SUMMARY: AddressSanitizer: 5000001 byte(s) leaked in 1 allocation(s)
PHP Version
PHP 8.4.0-dev
Operating System
ubuntu 22.04