From cf2199b405b6616bbafbc89c73a7a3fb37a462ce Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Wed, 17 Jun 2026 15:21:01 -0400 Subject: [PATCH] Fix GH-22051: report errors from SQLite3Result reset and finalize SQLite3Stmt::reset() reports a failed sqlite3_reset() through php_sqlite3_error(), but SQLite3Result::reset() returned false silently and SQLite3Result::finalize() ignored the result. Both now surface the underlying SQLite error the same way; finalize() keeps its : true return type and reports without altering the return value. Fixes GH-22051 --- NEWS | 2 ++ ext/sqlite3/sqlite3.c | 5 +++- ext/sqlite3/tests/gh22051.phpt | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 ext/sqlite3/tests/gh22051.phpt diff --git a/NEWS b/NEWS index 2bbe43032ece..f2a58d6f8c46 100644 --- a/NEWS +++ b/NEWS @@ -230,6 +230,8 @@ PHP NEWS - Sqlite3: . Fix NUL byte truncation in sqlite3 TEXT column handling. (ndossche) + . Fixed bug GH-22051 (Inconsistent error reporting in SQLite3Result::reset() + and SQLite3Result::finalize()). (iliaal) - Standard: . Fixed bug GH-19926 (reset internal pointer earlier while splicing array diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index bef568a62dfd..547a93cdbf17 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -2125,6 +2125,7 @@ PHP_METHOD(SQLite3Result, reset) sqlite3result_clear_column_names_cache(result_obj); if (sqlite3_reset(result_obj->stmt_obj->stmt) != SQLITE_OK) { + php_sqlite3_error(result_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(result_obj->stmt_obj->stmt)), "Unable to reset statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt))); RETURN_FALSE; } @@ -2150,7 +2151,9 @@ PHP_METHOD(SQLite3Result, finalize) 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); + if (sqlite3_reset(result_obj->stmt_obj->stmt) != SQLITE_OK) { + php_sqlite3_error(result_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(result_obj->stmt_obj->stmt)), "Unable to reset statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt))); + } } RETURN_TRUE; diff --git a/ext/sqlite3/tests/gh22051.phpt b/ext/sqlite3/tests/gh22051.phpt new file mode 100644 index 000000000000..1e23903366da --- /dev/null +++ b/ext/sqlite3/tests/gh22051.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-22051 (SQLite3Result::reset()/finalize() report the error on failure) +--EXTENSIONS-- +sqlite3 +--FILE-- +query($sql); +var_dump($result->fetchArray(SQLITE3_NUM)); +var_dump(@$result->fetchArray(SQLITE3_NUM)); +var_dump($result->reset()); + +echo "--- SQLite3Result::finalize() ---\n"; +$stmt = $db->prepare($sql); +$result = $stmt->execute(); +var_dump($result->fetchArray(SQLITE3_NUM)); +var_dump(@$result->fetchArray(SQLITE3_NUM)); +var_dump($result->finalize()); +?> +--EXPECTF-- +--- SQLite3Result::reset() --- +array(1) { + [0]=> + int(1) +} +bool(false) + +Warning: SQLite3Result::reset(): Unable to reset statement: integer overflow in %s on line %d +bool(false) +--- SQLite3Result::finalize() --- +array(1) { + [0]=> + int(1) +} +bool(false) + +Warning: SQLite3Result::finalize(): Unable to reset statement: integer overflow in %s on line %d +bool(true)