Commit 0b0784a66e4 for php.net

commit 0b0784a66e454722095849071951e47ebb6cf81d
Merge: 6a2023c5e0c 7300fa520dd
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date:   Wed Sep 16 09:03:20 2026 -0400

    Merge branch 'PHP-8.4' into PHP-8.5

    * PHP-8.4:
      ext/sqlite3: reject close() from inside a callback

diff --cc NEWS
index 47ac440813a,50815738590..76e317006c0
--- a/NEWS
+++ b/NEWS
@@@ -31,11 -27,16 +31,15 @@@ PH
    . Fixed PDOStatement::getColumnMeta() reading out of bounds for an invalid
      column index. (Ilia Alshanetsky)

 +- PGSQL:
 +  . Fixed pg_lo_write() rejecting data containing null bytes. (Ilia Alshanetsky)
 +
+ - SQLite:
+   . Fixed a crash when SQLite3::close() is called from a userland callback.
+     (Ilia Alshanetsky)
+
 -- Zip:
 -  . Fixed ZipArchive::extractTo() ignoring files given in a non-list array.
 -    (David Carlier)

 -
 -24 Sep 2026, PHP 8.4.26
 +24 Sep 2026, PHP 8.5.11

  - BCMath:
    . Fixed out-of-bounds read in bc_is_zero_for_scale() when scale exceeds
diff --cc ext/sqlite3/php_sqlite3_structs.h
index 5d9f69cc577,43e595affe1..e5002751cea
--- a/ext/sqlite3/php_sqlite3_structs.h
+++ b/ext/sqlite3/php_sqlite3_structs.h
@@@ -56,8 -57,9 +57,9 @@@ typedef struct _php_sqlite3_func
  typedef struct _php_sqlite3_collation {
  	struct _php_sqlite3_collation *next;

 -	const char *collation_name;
 +	zend_string *collation_name;
  	zend_fcall_info_cache cmp_func;
+ 	unsigned int *in_callback_ptr;
  } php_sqlite3_collation;

  /* Structure for SQLite Database object. */
@@@ -70,6 -70,9 +72,8 @@@ typedef struct _php_sqlite3_db_object
  	php_sqlite3_collation *collations;
  	zend_fcall_info_cache authorizer_fcc;

 -	bool exception;
+ 	unsigned int in_callback;
+
  	zend_llist free_list;
  	zend_object zo;
  } php_sqlite3_db_object;
diff --cc ext/sqlite3/sqlite3.c
index c9a30cb52e0,93e50b97c7f..c6898aedc1b
--- a/ext/sqlite3/sqlite3.c
+++ b/ext/sqlite3/sqlite3.c
@@@ -983,9 -1027,10 +1022,10 @@@ PHP_METHOD(SQLite3, createFunction
  	}

  	func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
+ 	func->in_callback_ptr = &db_obj->in_callback;

 -	if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, flags | SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) {
 -		func->func_name = estrdup(sql_func);
 +	if (sqlite3_create_function(db_obj->db, ZSTR_VAL(sql_func), sql_func_num_args, flags | SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) {
 +		func->func_name = zend_string_copy(sql_func);
  		zend_fcc_dup(&func->func, &fcc);

  		func->argc = sql_func_num_args;
@@@ -1031,9 -1077,10 +1071,10 @@@ PHP_METHOD(SQLite3, createAggregate
  	}

  	func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
+ 	func->in_callback_ptr = &db_obj->in_callback;

 -	if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, NULL, php_sqlite3_callback_step, php_sqlite3_callback_final) == SQLITE_OK) {
 -		func->func_name = estrdup(sql_func);
 +	if (sqlite3_create_function(db_obj->db, ZSTR_VAL(sql_func), sql_func_num_args, SQLITE_UTF8, func, NULL, php_sqlite3_callback_step, php_sqlite3_callback_final) == SQLITE_OK) {
 +		func->func_name = zend_string_copy(sql_func);

  		zend_fcc_dup(&func->step, &step_fcc);
  		zend_fcc_dup(&func->fini, &fini_fcc);
@@@ -1078,8 -1126,9 +1119,9 @@@ PHP_METHOD(SQLite3, createCollation
  	}

  	collation = (php_sqlite3_collation *)ecalloc(1, sizeof(*collation));
+ 	collation->in_callback_ptr = &db_obj->in_callback;
 -	if (sqlite3_create_collation(db_obj->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_callback_compare) == SQLITE_OK) {
 -		collation->collation_name = estrdup(collation_name);
 +	if (sqlite3_create_collation(db_obj->db, ZSTR_VAL(collation_name), SQLITE_UTF8, collation, php_sqlite3_callback_compare) == SQLITE_OK) {
 +		collation->collation_name = zend_string_copy(collation_name);

  		zend_fcc_dup(&collation->cmp_func, &fcc);