mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Fix memory leak when calling xml_parse_into_struct() twice Fix return type of stub of xml_parse_into_struct()
This commit is contained in:
commit
2bbe4fda75
4
NEWS
4
NEWS
@ -35,6 +35,10 @@ PHP NEWS
|
||||
foreach). (nielsdos)
|
||||
. Fixed bug #55098 (SimpleXML iteration produces infinite loop). (nielsdos)
|
||||
|
||||
- XML:
|
||||
. Fix return type of stub of xml_parse_into_struct(). (nielsdos)
|
||||
. Fix memory leak when calling xml_parse_into_struct() twice. (nielsdos)
|
||||
|
||||
14 Sep 2023, PHP 8.3.0RC2
|
||||
|
||||
- Core:
|
||||
|
31
ext/xml/tests/gh12254.phpt
Normal file
31
ext/xml/tests/gh12254.phpt
Normal file
@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
GH-12254: xml_parse_into_struct() memory leak when called twice
|
||||
--EXTENSIONS--
|
||||
xml
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$parser = xml_parser_create();
|
||||
xml_set_element_handler($parser, function ($parser, $name, $attrs) {
|
||||
echo "open\n";
|
||||
var_dump($name, $attrs);
|
||||
var_dump(xml_parse_into_struct($parser, "<container/>", $values, $tags));
|
||||
}, function ($parser, $name) {
|
||||
echo "close\n";
|
||||
var_dump($name);
|
||||
});
|
||||
xml_parse_into_struct($parser, "<container/>", $values, $tags);
|
||||
// Yes, this doesn't do anything but it at least shouldn't leak...
|
||||
xml_parse_into_struct($parser, "<container/>", $values, $tags);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
open
|
||||
string(9) "CONTAINER"
|
||||
array(0) {
|
||||
}
|
||||
|
||||
Warning: xml_parse_into_struct(): Parser must not be called recursively in %s on line %d
|
||||
bool(false)
|
||||
close
|
||||
string(9) "CONTAINER"
|
@ -312,6 +312,16 @@ static zend_object *xml_parser_create_object(zend_class_entry *class_type) {
|
||||
return &intern->std;
|
||||
}
|
||||
|
||||
static void xml_parser_free_ltags(xml_parser *parser)
|
||||
{
|
||||
if (parser->ltags) {
|
||||
int inx;
|
||||
for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++)
|
||||
efree(parser->ltags[ inx ]);
|
||||
efree(parser->ltags);
|
||||
}
|
||||
}
|
||||
|
||||
static void xml_parser_free_obj(zend_object *object)
|
||||
{
|
||||
xml_parser *parser = xml_parser_from_obj(object);
|
||||
@ -319,12 +329,7 @@ static void xml_parser_free_obj(zend_object *object)
|
||||
if (parser->parser) {
|
||||
XML_ParserFree(parser->parser);
|
||||
}
|
||||
if (parser->ltags) {
|
||||
int inx;
|
||||
for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++)
|
||||
efree(parser->ltags[ inx ]);
|
||||
efree(parser->ltags);
|
||||
}
|
||||
xml_parser_free_ltags(parser);
|
||||
if (!Z_ISUNDEF(parser->startElementHandler)) {
|
||||
zval_ptr_dtor(&parser->startElementHandler);
|
||||
}
|
||||
@ -1255,6 +1260,11 @@ PHP_FUNCTION(xml_parse_into_struct)
|
||||
|
||||
parser = Z_XMLPARSER_P(pind);
|
||||
|
||||
if (parser->isparsing) {
|
||||
php_error_docref(NULL, E_WARNING, "Parser must not be called recursively");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (info) {
|
||||
info = zend_try_array_init(info);
|
||||
if (!info) {
|
||||
@ -1274,15 +1284,12 @@ PHP_FUNCTION(xml_parse_into_struct)
|
||||
}
|
||||
|
||||
parser->level = 0;
|
||||
xml_parser_free_ltags(parser);
|
||||
parser->ltags = safe_emalloc(XML_MAXLEVEL, sizeof(char *), 0);
|
||||
|
||||
XML_SetElementHandler(parser->parser, _xml_startElementHandler, _xml_endElementHandler);
|
||||
XML_SetCharacterDataHandler(parser->parser, _xml_characterDataHandler);
|
||||
|
||||
if (parser->isparsing) {
|
||||
php_error_docref(NULL, E_WARNING, "Parser must not be called recursively");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
parser->isparsing = 1;
|
||||
ret = XML_Parse(parser->parser, (XML_Char*)data, data_len, 1);
|
||||
parser->isparsing = 0;
|
||||
|
@ -182,7 +182,7 @@ function xml_parse(XMLParser $parser, string $data, bool $is_final = false): int
|
||||
* @param array $values
|
||||
* @param array $index
|
||||
*/
|
||||
function xml_parse_into_struct(XMLParser $parser, string $data, &$values, &$index = null): int {}
|
||||
function xml_parse_into_struct(XMLParser $parser, string $data, &$values, &$index = null): int|false {}
|
||||
|
||||
function xml_get_error_code(XMLParser $parser): int {}
|
||||
|
||||
|
4
ext/xml/xml_arginfo.h
generated
4
ext/xml/xml_arginfo.h
generated
@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: cd199a8733c51c8bb5970f86b7797ca91e6e59c6 */
|
||||
* Stub hash: f87e295b35cd43db72a936ee5745297a45730090 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_xml_parser_create, 0, 0, XMLParser, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null")
|
||||
@ -46,7 +46,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_parse, 0, 2, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, is_final, _IS_BOOL, 0, "false")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xml_parse_into_struct, 0, 3, IS_LONG, 0)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_xml_parse_into_struct, 0, 3, MAY_BE_LONG|MAY_BE_FALSE)
|
||||
ZEND_ARG_OBJ_INFO(0, parser, XMLParser, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
|
||||
ZEND_ARG_INFO(1, values)
|
||||
|
Loading…
Reference in New Issue
Block a user