mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +01:00
Fix GH-17900 and GH-8084
Calling the constructor twice has no real world benefit. Block it to fix these two issues. We also clean up the constructor code a bit: - `in_ctor` implies `object` exist. - We surround the instance check with ZEND_DEBUG to avoid a runtime penalty. Closes GH-17900. Closes GH-8084. Closes GH-17908.
This commit is contained in:
4
NEWS
4
NEWS
@@ -56,6 +56,10 @@ PHP NEWS
|
||||
. IntlDateFormatter::setTimeZone()/datefmt_set_timezone() throws an exception
|
||||
with uninitialised classes or clone failure. (David Carlier)
|
||||
|
||||
- MySQLi:
|
||||
. Fixed bugs GH-17900 and GH-8084 (calling mysqli::__construct twice).
|
||||
(nielsdos)
|
||||
|
||||
- MySQLnd:
|
||||
. Added mysqlnd.collect_memory_statistics to ini quick reference.
|
||||
(hauk92)
|
||||
|
||||
@@ -44,6 +44,10 @@ PHP 8.5 UPGRADE NOTES
|
||||
. ldap_get_option() and ldap_set_option() now throw a ValueError when
|
||||
passing an invalid option.
|
||||
|
||||
- MySQLi:
|
||||
. Calling the mysqli constructor on an already-constructed object
|
||||
is now no longer possible and throws an Error.
|
||||
|
||||
- PCNTL:
|
||||
. pcntl_exec() now throws ValueErrors when entries of the $args parameter
|
||||
contain null bytes.
|
||||
|
||||
@@ -969,10 +969,6 @@ void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS, bool is_method)
|
||||
MYSQLI_RESOURCE *mysqli_resource;
|
||||
MY_MYSQL *mysql;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (is_method && (Z_MYSQLI_P(getThis()))->ptr) {
|
||||
return;
|
||||
}
|
||||
@@ -1004,6 +1000,7 @@ void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS, bool is_method)
|
||||
/* {{{ Initialize mysqli and return a resource for use with mysql_real_connect */
|
||||
PHP_FUNCTION(mysqli_init)
|
||||
{
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -72,7 +72,14 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b
|
||||
}
|
||||
#endif
|
||||
|
||||
if (getThis() && !ZEND_NUM_ARGS() && in_ctor) {
|
||||
if (in_ctor && !ZEND_NUM_ARGS()) {
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
if (UNEXPECTED(Z_MYSQLI_P(object)->ptr)) {
|
||||
zend_throw_error(NULL, "Cannot call constructor twice");
|
||||
return;
|
||||
}
|
||||
|
||||
php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU, in_ctor);
|
||||
return;
|
||||
}
|
||||
@@ -84,6 +91,11 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (UNEXPECTED(in_ctor && Z_MYSQLI_P(object)->ptr)) {
|
||||
zend_throw_error(NULL, "Cannot call constructor twice");
|
||||
return;
|
||||
}
|
||||
|
||||
if (object) {
|
||||
ZEND_ASSERT(instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry));
|
||||
mysqli_resource = (Z_MYSQLI_P(object))->ptr;
|
||||
@@ -325,6 +337,7 @@ PHP_METHOD(mysqli, __construct)
|
||||
/* {{{ Initialize mysqli and return a resource for use with mysql_real_connect */
|
||||
PHP_METHOD(mysqli, init)
|
||||
{
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
16
ext/mysqli/tests/gh17900.phpt
Normal file
16
ext/mysqli/tests/gh17900.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
GH-17900 (Assertion failure ext/mysqli/mysqli_prop.c)
|
||||
--EXTENSIONS--
|
||||
mysqli
|
||||
--FILE--
|
||||
<?php
|
||||
mysqli_report(MYSQLI_REPORT_OFF);
|
||||
$mysqli = new mysqli();
|
||||
try {
|
||||
$mysqli->__construct('doesnotexist');
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Cannot call constructor twice
|
||||
@@ -12,8 +12,8 @@ $mysqli->close();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: mysqli object is not fully initialized in %s:%d
|
||||
Fatal error: Uncaught Error: Cannot call constructor twice in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): mysqli->close()
|
||||
#0 %s(%d): mysqli->__construct('doesnotexist')
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
||||
|
||||
Reference in New Issue
Block a user