Skip to content

Fix GH-23728: crash when a callback closes the statement being executed - #310

Closed
iliaal wants to merge 1 commit into
PHP-8.4from
fix/gh-23728-stmt-close-during-step
Closed

iliaal wants to merge 1 commit into
PHP-8.4from
fix/gh-23728-stmt-close-during-step

Conversation

@iliaal

@iliaal iliaal commented Sep 17, 2026

Copy link
Copy Markdown
Owner

SQLite3Stmt::close() and SQLite3Result::finalize() reach sqlite3_finalize() through the database free list, and SQLite3Stmt::reset(), SQLite3Result::reset() and a sibling result's destructor reach sqlite3_reset(). From a userland function, aggregate or collation callback, either destroys the statement sqlite3_step() is executing. Tracking per statement whether it is being stepped, throwing from the four methods and skipping the reset in the destructor, leaves the statement usable once the query finishes. The per-database in_callback counter phpGH-23650 added for SQLite3::close() is too coarse here, since finalizing an unrelated statement while another one steps is safe and keeps working, and sqlite3_stmt_busy() would reject a close after a partial fetch outside any callback.

Fixes php#23728

…xecuted

SQLite3Stmt::close() and SQLite3Result::finalize() reach sqlite3_finalize()
through the database free list, and SQLite3Stmt::reset(), SQLite3Result::
reset() and a sibling result's destructor reach sqlite3_reset(). Called from
a userland function, aggregate or collation callback, either destroys the
statement sqlite3_step() is executing, so the step returns into freed memory
or the next one walks a reset VDBE. Track per statement whether it is being
stepped, throw from the four methods while it is, and skip the reset in the
result destructor, which cannot throw. phpGH-23650 added a per-database
in_callback counter for SQLite3::close(), which destroys every statement on
the connection, but that counter is too coarse here: finalizing an unrelated
statement while another one steps is safe and keeps working.
SQLite3Stmt::clear() is left alone, sqlite3_clear_bindings() mid-step is
tolerated.

Fixes phpGH-23728
@iliaal
iliaal force-pushed the fix/gh-23728-stmt-close-during-step branch from 1a871a8 to dedba2b Compare September 17, 2026 17:50
@iliaal

iliaal commented Sep 17, 2026

Copy link
Copy Markdown
Owner Author

Submitted upstream as php#23736.

@iliaal iliaal closed this Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant