summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMáté Kocsis <kocsismate@woohoolabs.com>2020-10-14 00:12:51 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-10-20 16:48:12 +0200
commitd5f92baad00ce19e096f9936a4ffdcf5c3cd1383 (patch)
tree78d1a1891fffb7a660d50bedf4c48f80d9936aa2
parent8f6cade8640f843331b3ddef2a6b96f73c89889c (diff)
downloadphp-git-d5f92baad00ce19e096f9936a4ffdcf5c3cd1383.tar.gz
Fix default value handling of mysqli_fetch_object()
Make [] acceptable both for classes without constructors and classes with a constructor that takes no arguments. Closes GH-6336.
-rw-r--r--ext/mysqli/mysqli.c18
-rw-r--r--ext/mysqli/mysqli.stub.php4
-rw-r--r--ext/mysqli/mysqli_arginfo.h6
-rw-r--r--ext/mysqli/tests/mysqli_fetch_object.phpt2
-rw-r--r--ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt2
-rw-r--r--ext/mysqli/tests/mysqli_fetch_object_oo.phpt13
-rw-r--r--ext/pdo/pdo_dbh.c8
-rw-r--r--ext/pgsql/pgsql.c18
-rw-r--r--ext/pgsql/pgsql.stub.php2
-rw-r--r--ext/pgsql/pgsql_arginfo.h4
10 files changed, 32 insertions, 45 deletions
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index 05ffffa926..48a544d0c7 100644
--- a/ext/mysqli/mysqli.c
+++ b/ext/mysqli/mysqli.c
@@ -1200,16 +1200,9 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
fci.param_count = 0;
fci.named_params = NULL;
- if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
+ if (ctor_params) {
if (zend_fcall_info_args(&fci, ctor_params) == FAILURE) {
- /* Two problems why we throw exceptions here: PHP is typeless
- * and hence passing one argument that's not an array could be
- * by mistake and the other way round is possible, too. The
- * single value is an array. Also we'd have to make that one
- * argument passed by reference.
- */
- zend_argument_error(zend_ce_exception, 3, "must be of type array, %s given", zend_zval_type_name(ctor_params));
- RETURN_THROWS();
+ ZEND_UNREACHABLE();
}
}
@@ -1223,8 +1216,11 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
zval_ptr_dtor(&retval);
}
zend_fcall_info_args_clear(&fci, 1);
- } else if (ctor_params) {
- zend_throw_exception_ex(zend_ce_exception, 0, "Class %s does not have a constructor hence you cannot use ctor_params", ZSTR_VAL(ce->name));
+ } else if (ctor_params && zend_hash_num_elements(Z_ARRVAL_P(ctor_params)) > 0) {
+ zend_argument_error(zend_ce_exception, ERROR_ARG_POS(3),
+ "must be empty when the specified class (%s) does not have a constructor",
+ ZSTR_VAL(ce->name)
+ );
}
}
}
diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php
index 4870485774..c1059254fc 100644
--- a/ext/mysqli/mysqli.stub.php
+++ b/ext/mysqli/mysqli.stub.php
@@ -364,7 +364,7 @@ class mysqli_result implements IteratorAggregate
* @return object|null
* @alias mysqli_fetch_object
*/
- public function fetch_object(string $class = "stdClass", array $params = []) {}
+ public function fetch_object(string $class = "stdClass", array $constructor_args = []) {}
/**
* @return array|null
@@ -581,7 +581,7 @@ function mysqli_fetch_array(mysqli_result $result, int $mode = MYSQLI_BOTH): arr
function mysqli_fetch_assoc(mysqli_result $result): ?array {}
-function mysqli_fetch_object(mysqli_result $result, string $class = "stdClass", array $params = []): ?object {}
+function mysqli_fetch_object(mysqli_result $result, string $class = "stdClass", array $constructor_args = []): ?object {}
function mysqli_fetch_row(mysqli_result $result): ?array {}
diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h
index 73960d38eb..509840a7fc 100644
--- a/ext/mysqli/mysqli_arginfo.h
+++ b/ext/mysqli/mysqli_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 88f90ff45ab8f9748968c39eae950d58e598b73f */
+ * Stub hash: 480939b71e1dacbdbb4634dbabf375943e399b6f */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING)
ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0)
@@ -115,7 +115,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_fetch_object, 0, 1, IS_OBJECT, 1)
ZEND_ARG_OBJ_INFO(0, result, mysqli_result, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class, IS_STRING, 0, "\"stdClass\"")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, params, IS_ARRAY, 0, "[]")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, constructor_args, IS_ARRAY, 0, "[]")
ZEND_END_ARG_INFO()
#define arginfo_mysqli_fetch_row arginfo_mysqli_fetch_assoc
@@ -614,7 +614,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_result_fetch_object, 0, 0, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class, IS_STRING, 0, "\"stdClass\"")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, params, IS_ARRAY, 0, "[]")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, constructor_args, IS_ARRAY, 0, "[]")
ZEND_END_ARG_INFO()
#define arginfo_class_mysqli_result_fetch_row arginfo_class_mysqli_character_set_name
diff --git a/ext/mysqli/tests/mysqli_fetch_object.phpt b/ext/mysqli/tests/mysqli_fetch_object.phpt
index f5708ac558..8076311112 100644
--- a/ext/mysqli/tests/mysqli_fetch_object.phpt
+++ b/ext/mysqli/tests/mysqli_fetch_object.phpt
@@ -147,6 +147,6 @@ Exception: Too few arguments to function mysqli_fetch_object_construct::__constr
NULL
NULL
mysqli_result object is already closed
-[0] mysqli_fetch_object(): Argument #3 ($params) must be of type array, string given in %s on line %d
+[0] mysqli_fetch_object(): Argument #3 ($constructor_args) must be of type array, string given in %s on line %d
mysqli_fetch_object(): Argument #2 ($class) must be a valid class name, this_class_does_not_exist given
done!
diff --git a/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt b/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt
index 979c523199..5d823648c7 100644
--- a/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt
+++ b/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt
@@ -57,7 +57,7 @@ object(mysqli_fetch_object_test)#%d (%d) {
}
Exception with mysqli. Note that at all other places we throws errors but no exceptions unless the error mode has been changed:
-Exception: Class mysqli_fetch_object_test does not have a constructor hence you cannot use ctor_params
+Exception: mysqli_fetch_object(): Argument #3 ($constructor_args) must be empty when the specified class (mysqli_fetch_object_test) does not have a constructor
Fatal error with PHP (but no exception!):
diff --git a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt
index f402db82d8..c541ad2d04 100644
--- a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt
+++ b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt
@@ -73,14 +73,9 @@ require_once('skipifconnectfailure.inc');
}
try {
- $obj = $res->fetch_object('mysqli_fetch_object_construct', null);
-
- if (($obj->ID !== "3") || ($obj->label !== "c") || ($obj->a !== NULL) || ($obj->b !== NULL) || (get_class($obj) != 'mysqli_fetch_object_construct')) {
- printf("[009] Object seems wrong. [%d] %s\n", $mysqli->errno, $mysqli->error);
- var_dump($obj);
- }
- } catch (Error $e) {
- handle_catchable_fatal($e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine());
+ $res->fetch_object('mysqli_fetch_object_construct', null);
+ } catch (TypeError $exception) {
+ echo $exception->getMessage() . "\n";
mysqli_fetch_object($res);
}
@@ -134,7 +129,7 @@ require_once('skipifconnectfailure.inc');
mysqli object is not fully initialized
[0] Object of class mysqli could not be converted to string in %s on line %d
[0] mysqli_result::fetch_object() expects at most 2 arguments, 3 given in %s on line %d
-[0] mysqli_result::fetch_object(): Argument #2 ($params) must be of type array, null given in %s on line %d
+mysqli_result::fetch_object(): Argument #2 ($constructor_args) must be of type array, null given
Exception: Too few arguments to function mysqli_fetch_object_construct::__construct(), 1 passed and exactly 2 expected
NULL
NULL
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index 2e81db2bbf..a0c2b74c33 100644
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -517,7 +517,7 @@ PHP_METHOD(PDO, prepare)
}
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 0)) == NULL) {
zend_value_error("PDO::ATTR_STATEMENT_CLASS value must be an array with the format "
- "array(classname, array(ctor_args))");
+ "array(classname, constructor_args)");
RETURN_THROWS();
}
if (Z_TYPE_P(item) != IS_STRING || (pce = zend_lookup_class(Z_STR_P(item))) == NULL) {
@@ -535,7 +535,7 @@ PHP_METHOD(PDO, prepare)
}
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 1)) != NULL) {
if (Z_TYPE_P(item) != IS_ARRAY) {
- zend_type_error("PDO::ATTR_STATEMENT_CLASS ctor_args must be of type ?array, %s given",
+ zend_type_error("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given",
zend_zval_type_name(value));
RETURN_THROWS();
}
@@ -765,7 +765,7 @@ static zend_result pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *v
}
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 0)) == NULL) {
zend_value_error("PDO::ATTR_STATEMENT_CLASS value must be an array with the format "
- "array(classname, array(ctor_args))");
+ "array(classname, constructor_args)");
return FAILURE;
}
if (Z_TYPE_P(item) != IS_STRING || (pce = zend_lookup_class(Z_STR_P(item))) == NULL) {
@@ -787,7 +787,7 @@ static zend_result pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *v
}
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 1)) != NULL) {
if (Z_TYPE_P(item) != IS_ARRAY) {
- zend_type_error("PDO::ATTR_STATEMENT_CLASS ctor_args must be of type ?array, %s given",
+ zend_type_error("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given",
zend_zval_type_name(value));
return FAILURE;
}
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index aac2afd493..4685c7cd74 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -1836,7 +1836,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
zend_class_entry *ce = NULL;
if (into_object) {
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l!Ca!", &result, &row, &row_is_null, &ce, &ctor_params) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l!Ca", &result, &row, &row_is_null, &ce, &ctor_params) == FAILURE) {
RETURN_THROWS();
}
if (!ce) {
@@ -1935,14 +1935,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
if (ctor_params) {
if (zend_fcall_info_args(&fci, ctor_params) == FAILURE) {
- /* Two problems why we throw exceptions here: PHP is typeless
- * and hence passing one argument that's not an array could be
- * by mistake and the other way round is possible, too. The
- * single value is an array. Also we'd have to make that one
- * argument passed by reference.
- */
- zend_throw_exception(zend_ce_exception, "Parameter ctor_params must be an array", 0);
- RETURN_THROWS();
+ ZEND_UNREACHABLE();
}
}
@@ -1958,8 +1951,11 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
if (fci.params) {
efree(fci.params);
}
- } else if (ctor_params) {
- zend_throw_exception_ex(zend_ce_exception, 0, "Class %s does not have a constructor hence you cannot use ctor_params", ZSTR_VAL(ce->name));
+ } else if (ctor_params && zend_hash_num_elements(Z_ARRVAL_P(ctor_params)) > 0) {
+ zend_argument_error(zend_ce_exception, 3,
+ "must be empty when the specified class (%s) does not have a constructor",
+ ZSTR_VAL(ce->name)
+ );
}
}
}
diff --git a/ext/pgsql/pgsql.stub.php b/ext/pgsql/pgsql.stub.php
index 8460fd26b6..aff847bbc4 100644
--- a/ext/pgsql/pgsql.stub.php
+++ b/ext/pgsql/pgsql.stub.php
@@ -190,7 +190,7 @@ function pg_fetch_assoc($result, ?int $row = null): array|false {}
function pg_fetch_array($result, ?int $row = null, int $mode = PGSQL_BOTH): array|false {}
/** @param resource $result */
-function pg_fetch_object($result, ?int $row = null, string $class = "stdClass", ?array $ctor_args = null): object|false {}
+function pg_fetch_object($result, ?int $row = null, string $class = "stdClass", array $constructor_args = []): object|false {}
/** @param resource $result */
function pg_fetch_all($result, int $mode = PGSQL_ASSOC): array {}
diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h
index 5bdda3ea07..3d9a4f2d5d 100644
--- a/ext/pgsql/pgsql_arginfo.h
+++ b/ext/pgsql/pgsql_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 26edbb4ade84f0faad592dd270756c17e396519b */
+ * Stub hash: de1718d3e6e66dfade25462b8461983b914120ed */
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0)
@@ -152,7 +152,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_fetch_object, 0, 1, MAY_BE_OB
ZEND_ARG_INFO(0, result)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class, IS_STRING, 0, "\"stdClass\"")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, ctor_args, IS_ARRAY, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, constructor_args, IS_ARRAY, 0, "[]")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pg_fetch_all, 0, 1, IS_ARRAY, 0)