mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.5'
* PHP-8.5: Fix GH-20374: PHP with tidy and custom-tags pgsql: Fix memory leak when object init fails (#20387)
This commit is contained in:
@@ -2076,6 +2076,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
|
||||
ZVAL_COPY_VALUE(&dataset, return_value);
|
||||
zend_result obj_initialized = object_init_ex(return_value, ce);
|
||||
if (UNEXPECTED(obj_initialized == FAILURE)) {
|
||||
zval_ptr_dtor(&dataset);
|
||||
RETURN_THROWS();
|
||||
}
|
||||
if (!ce->default_properties_count && !ce->__set) {
|
||||
|
||||
@@ -7,7 +7,7 @@ tidy
|
||||
$x = tidy_repair_string("<p>abra\0cadabra</p>",
|
||||
array( 'show-body-only' => true,
|
||||
'clean' => false,
|
||||
'newline' => "\n")
|
||||
'newline' => "LF")
|
||||
);
|
||||
var_dump($x);
|
||||
?>
|
||||
|
||||
175
ext/tidy/tests/gh20374.phpt
Normal file
175
ext/tidy/tests/gh20374.phpt
Normal file
@@ -0,0 +1,175 @@
|
||||
--TEST--
|
||||
GH-20374 (PHP with tidy and custom-tags)
|
||||
--EXTENSIONS--
|
||||
tidy
|
||||
--CREDITS--
|
||||
franck-paul
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyStringable {
|
||||
public function __construct(private $ret) {}
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->ret;
|
||||
}
|
||||
}
|
||||
|
||||
class MyThrowingStringable {
|
||||
public function __toString(): string {
|
||||
throw new Error('no');
|
||||
}
|
||||
}
|
||||
|
||||
$values = [
|
||||
'string blocklevel' => 'blocklevel',
|
||||
'int' => 1,
|
||||
'double overflow' => (string) (2.0**80.0),
|
||||
'numeric string int 1' => '1',
|
||||
'numeric string double 1.0' => '1.0',
|
||||
'false' => false,
|
||||
'true' => true,
|
||||
'NAN' => NAN,
|
||||
'INF' => INF,
|
||||
'object with numeric string int 0' => new MyStringable('0'),
|
||||
'object with string blocklevel' => new MyStringable('blocklevel'),
|
||||
'object with string empty' => new MyStringable('empty'),
|
||||
'object with exception' => new MyThrowingStringable,
|
||||
];
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
echo "--- $key ---\n";
|
||||
$str = '<custom-html-element>test</custom-html-element>';
|
||||
|
||||
$config = [
|
||||
'custom-tags' => $value,
|
||||
];
|
||||
|
||||
$tidy = new tidy();
|
||||
try {
|
||||
$tidy->parseString($str, $config, 'utf8');
|
||||
echo $tidy->value, "\n";
|
||||
} catch (Throwable $e) {
|
||||
echo $e::class, ": ", $e->getMessage(), "\n";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
--- string blocklevel ---
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<custom-html-element>test</custom-html-element>
|
||||
</body>
|
||||
</html>
|
||||
--- int ---
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<custom-html-element>test</custom-html-element>
|
||||
</body>
|
||||
</html>
|
||||
--- double overflow ---
|
||||
|
||||
Warning: The float-string "1.2089258196146E+24" is not representable as an int, cast occurred in %s on line %d
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
test
|
||||
</body>
|
||||
</html>
|
||||
--- numeric string int 1 ---
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<custom-html-element>test</custom-html-element>
|
||||
</body>
|
||||
</html>
|
||||
--- numeric string double 1.0 ---
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<custom-html-element>test</custom-html-element>
|
||||
</body>
|
||||
</html>
|
||||
--- false ---
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
test
|
||||
</body>
|
||||
</html>
|
||||
--- true ---
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<custom-html-element>test</custom-html-element>
|
||||
</body>
|
||||
</html>
|
||||
--- NAN ---
|
||||
|
||||
Warning: The float NAN is not representable as an int, cast occurred in %s on line %d
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
test
|
||||
</body>
|
||||
</html>
|
||||
--- INF ---
|
||||
|
||||
Warning: The float INF is not representable as an int, cast occurred in %s on line %d
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
test
|
||||
</body>
|
||||
</html>
|
||||
--- object with numeric string int 0 ---
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
test
|
||||
</body>
|
||||
</html>
|
||||
--- object with string blocklevel ---
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<custom-html-element>test</custom-html-element>
|
||||
</body>
|
||||
</html>
|
||||
--- object with string empty ---
|
||||
<custom-html-element>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
test
|
||||
</body>
|
||||
</html>
|
||||
--- object with exception ---
|
||||
Error: no
|
||||
@@ -719,6 +719,7 @@ static bool php_tidy_set_tidy_opt(TidyDoc doc, const char *optname, zval *value,
|
||||
{
|
||||
TidyOption opt = tidyGetOptionByName(doc, optname);
|
||||
zend_long lval;
|
||||
zend_string *tmp_str;
|
||||
|
||||
if (!opt) {
|
||||
zend_argument_value_error(arg, "Unknown Tidy configuration option \"%s\"", optname);
|
||||
@@ -736,7 +737,6 @@ static bool php_tidy_set_tidy_opt(TidyDoc doc, const char *optname, zval *value,
|
||||
|
||||
TidyOptionType type = tidyOptGetType(opt);
|
||||
if (type == TidyString) {
|
||||
zend_string *tmp_str;
|
||||
const zend_string *str = zval_get_tmp_string(value, &tmp_str);
|
||||
const bool result = tidyOptSetValue(doc, tidyOptGetId(opt), ZSTR_VAL(str));
|
||||
if (UNEXPECTED(!result)) {
|
||||
@@ -744,9 +744,35 @@ static bool php_tidy_set_tidy_opt(TidyDoc doc, const char *optname, zval *value,
|
||||
}
|
||||
zend_tmp_string_release(tmp_str);
|
||||
return result;
|
||||
} else if (type == TidyInteger) {
|
||||
lval = zval_get_long(value);
|
||||
return tidyOptSetInt(doc, tidyOptGetId(opt), lval);
|
||||
} else if (type == TidyInteger) { /* integer or enum */
|
||||
ZVAL_DEREF(value);
|
||||
/* Enum will correspond to a non-numeric string or object */
|
||||
if (Z_TYPE_P(value) == IS_STRING || Z_TYPE_P(value) == IS_OBJECT) {
|
||||
double dval;
|
||||
bool result;
|
||||
const zend_string *str = zval_try_get_tmp_string(value, &tmp_str);
|
||||
if (UNEXPECTED(!str)) {
|
||||
return false;
|
||||
}
|
||||
uint8_t type = is_numeric_string(ZSTR_VAL(str), ZSTR_LEN(str), &lval, &dval, true);
|
||||
if (type == IS_DOUBLE) {
|
||||
lval = zend_dval_to_lval_cap(dval, str);
|
||||
type = IS_LONG;
|
||||
}
|
||||
if (type == IS_LONG) {
|
||||
result = tidyOptSetInt(doc, tidyOptGetId(opt), lval);
|
||||
} else {
|
||||
result = tidyOptSetValue(doc, tidyOptGetId(opt), ZSTR_VAL(str));
|
||||
if (UNEXPECTED(!result)) {
|
||||
zend_argument_type_error(arg, "option \"%s\" does not accept \"%s\" as a value", optname, ZSTR_VAL(str));
|
||||
}
|
||||
}
|
||||
zend_tmp_string_release(tmp_str);
|
||||
return result;
|
||||
} else {
|
||||
lval = zval_get_long(value);
|
||||
return tidyOptSetInt(doc, tidyOptGetId(opt), lval);
|
||||
}
|
||||
} else {
|
||||
ZEND_ASSERT(type == TidyBoolean);
|
||||
lval = zval_get_long(value);
|
||||
|
||||
Reference in New Issue
Block a user