Commit 8c78c97f196 for php
commit 8c78c97f1960438d2c7e586139a9f33762fac68c
Merge: f2469f6684f 357fcf12f4e
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Wed Sep 30 13:56:03 2026 -0400
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
ext/pdo: Make PDOStatement::setFetchMode() updates atomic
diff --cc ext/pdo/pdo_stmt.c
index d0bb89ea6a2,b5b74351419..8a33cb74ddb
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@@ -1678,14 -1772,20 +1678,17 @@@ bool pdo_stmt_setup_fetch_mode(pdo_stmt
uint32_t arg1_arg_num = mode_arg_num + 1;
uint32_t constructor_arg_num = mode_arg_num + 2;
uint32_t total_num_args = mode_arg_num + variadic_num_args;
-
- pdo_stmt_free_default_fetch_mode(stmt);
-
- stmt->default_fetch_type = stmt->dbh->default_fetch_type;
+ zend_long fetch_type = mode & ~PDO_FETCH_FLAGS;
+ zend_long fetch_column = 0;
+ zend_class_entry *fetch_class = NULL;
- zend_array *fetch_ctor_args = NULL;
++ HashTable *fetch_ctor_args = NULL;
+ zend_object *fetch_into = NULL;
- zval old_ctor_args;
- zval old_into;
-
- ZVAL_UNDEF(&old_ctor_args);
- ZVAL_UNDEF(&old_into);
++ zend_object *old_into = NULL;
++ HashTable *old_ctor_args = NULL;
flags = mode & PDO_FETCH_FLAGS;
- if (!pdo_verify_fetch_mode(stmt->default_fetch_type, mode, mode_arg_num, false)) {
- if (!pdo_stmt_verify_mode(stmt, mode, mode_arg_num, false)) {
++ if (!pdo_verify_fetch_mode(stmt->dbh->default_fetch_type, mode, mode_arg_num, false)) {
return false;
}
@@@ -1774,15 -1873,19 +1775,14 @@@
return false;
}
if (Z_TYPE(args[1]) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL(args[1]))) {
- constructor_args = Z_ARRVAL(args[1]);
+ if (cep->constructor == NULL) {
+ zend_argument_value_error(3, "must be empty when class provided in argument #2 ($class) does not have a constructor");
+ return false;
+ }
- GC_TRY_ADDREF(Z_ARRVAL(args[1]));
- stmt->fetch.cls.ctor_args = Z_ARRVAL(args[1]);
++ fetch_ctor_args = Z_ARRVAL(args[1]);
}
}
- stmt->fetch.cls.ce = cep;
+ fetch_class = cep;
-
- /* If constructor arguments are present and not empty */
- if (constructor_args) {
- if (!cep->constructor) {
- zend_throw_error(NULL, "User-supplied statement does not accept constructor arguments");
- return false;
- }
- fetch_ctor_args = zend_array_dup(constructor_args);
- }
}
break;
}
@@@ -1807,10 -1909,50 +1806,45 @@@
return false;
}
- if (!use_default) {
+ if ((stmt->default_fetch_type & ~PDO_FETCH_FLAGS) == PDO_FETCH_INTO) {
- ZVAL_COPY_VALUE(&old_into, &stmt->fetch.into);
- ZVAL_UNDEF(&stmt->fetch.into);
++ old_into = stmt->fetch.into;
+ } else if ((stmt->default_fetch_type & ~PDO_FETCH_FLAGS) == PDO_FETCH_CLASS) {
- do_fetch_opt_finish(stmt, 0);
- ZVAL_COPY_VALUE(&old_ctor_args, &stmt->fetch.cls.ctor_args);
- ZVAL_UNDEF(&stmt->fetch.cls.ctor_args);
- } else {
- do_fetch_opt_finish(stmt, 1);
++ old_ctor_args = stmt->fetch.cls.ctor_args;
+ }
++ memset(&stmt->fetch, 0, sizeof(stmt->fetch));
+
+ switch (fetch_type) {
+ case PDO_FETCH_COLUMN:
+ stmt->fetch.column = fetch_column;
+ break;
+ case PDO_FETCH_CLASS:
+ stmt->fetch.cls.ce = fetch_class;
+ if (fetch_ctor_args) {
- ZVAL_ARR(&stmt->fetch.cls.ctor_args, fetch_ctor_args);
- } else {
- ZVAL_UNDEF(&stmt->fetch.cls.ctor_args);
++ GC_TRY_ADDREF(fetch_ctor_args);
++ stmt->fetch.cls.ctor_args = fetch_ctor_args;
+ }
- do_fetch_class_prepare(stmt);
+ break;
+ case PDO_FETCH_INTO:
- ZVAL_OBJ_COPY(&stmt->fetch.into, fetch_into);
++ GC_ADDREF(fetch_into);
++ stmt->fetch.into = fetch_into;
+ break;
+ default:
+ break;
+ }
+
+ if (fetch_type == PDO_FETCH_USE_DEFAULT) {
+ stmt->default_fetch_type = stmt->dbh->default_fetch_type;
+ } else {
stmt->default_fetch_type = mode;
}
- if (!Z_ISUNDEF(old_into)) {
- zval_ptr_dtor(&old_into);
++ if (old_into) {
++ OBJ_RELEASE(old_into);
+ }
- if (!Z_ISUNDEF(old_ctor_args)) {
- zval_ptr_dtor(&old_ctor_args);
++ if (old_ctor_args) {
++ zend_array_release(old_ctor_args);
+ }
+
return true;
}