From 18d287e5b50301dd36171e4f3fb0760b23a95021 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 21 Mar 2026 07:46:13 +0000 Subject: [PATCH 1/2] ext/sqlite3: fix wrong pointer types passed to the free list comparator. SQLite3Stmt::close() and SQLite3Result::finalize() passed php_sqlite3_stmt pointer types instead of sqlite3_stmt pointers to zend_llist_del_element, causing the comparator to never match and both methods to silently become no-ops. Regression introduced in 5eae6d14052 ("Don't store the object zval directly"). --- ext/sqlite3/sqlite3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index cea3ca0e3fb00..be28e2bff4d92 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -1415,7 +1415,7 @@ PHP_METHOD(SQLite3Stmt, close) SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3); - zend_llist_del_element(&(stmt_obj->db_obj->free_list), stmt_obj, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); + zend_llist_del_element(&(stmt_obj->db_obj->free_list), stmt_obj->stmt, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); RETURN_TRUE; } @@ -2145,7 +2145,7 @@ PHP_METHOD(SQLite3Result, finalize) /* We need to finalize an internal statement */ if (!result_obj->is_prepared_statement) { - zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj, + zend_llist_del_element(&(result_obj->db_obj->free_list), result_obj->stmt_obj->stmt, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); } else { sqlite3_reset(result_obj->stmt_obj->stmt); From c66dde1bcb15540625157b925bbf6c8cad1bc852 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 21 Mar 2026 11:10:08 +0000 Subject: [PATCH 2/2] ext/sqlite3: compare php_sqlite3_stmt pointers consistently. The comparator and all call sites now use php_sqlite3_stmt pointers, matching the type stored in the free list. --- ext/sqlite3/sqlite3.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index be28e2bff4d92..7aef25bf73b5c 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -38,7 +38,7 @@ ZEND_DECLARE_MODULE_GLOBALS(sqlite3) static PHP_GINIT_FUNCTION(sqlite3); static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4); static void sqlite3_param_dtor(zval *data); -static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, sqlite3_stmt *statement); +static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, php_sqlite3_stmt *statement); static zend_always_inline void php_sqlite3_fetch_one(int n_cols, php_sqlite3_result *result_obj, zend_long mode, zval *result); #define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \ @@ -1415,7 +1415,7 @@ PHP_METHOD(SQLite3Stmt, close) SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3); - zend_llist_del_element(&(stmt_obj->db_obj->free_list), stmt_obj->stmt, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); + zend_llist_del_element(&(stmt_obj->db_obj->free_list), stmt_obj, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); RETURN_TRUE; } @@ -2145,7 +2145,7 @@ PHP_METHOD(SQLite3Result, finalize) /* We need to finalize an internal statement */ if (!result_obj->is_prepared_statement) { - zend_llist_del_element(&(result_obj->db_obj->free_list), result_obj->stmt_obj->stmt, + zend_llist_del_element(&(result_obj->db_obj->free_list), result_obj->stmt_obj, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); } else { sqlite3_reset(result_obj->stmt_obj->stmt); @@ -2260,9 +2260,9 @@ static void php_sqlite3_free_list_dtor(void **item) } /* }}} */ -static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, sqlite3_stmt *statement ) /* {{{ */ +static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, php_sqlite3_stmt *statement ) /* {{{ */ { - return ((*stmt_obj_ptr)->initialised && statement == (*stmt_obj_ptr)->stmt); + return ((*stmt_obj_ptr)->initialised && statement == *stmt_obj_ptr); } /* }}} */ @@ -2376,7 +2376,7 @@ static void php_sqlite3_stmt_object_free_storage(zend_object *object) /* {{{ */ } if (intern->initialised) { - zend_llist_del_element(&(intern->db_obj->free_list), intern->stmt, + zend_llist_del_element(&(intern->db_obj->free_list), intern, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); }