Files
php-src/ext/sqlite3/tests/sqlite3_close_from_callback_collation.phpt
Ilia Alshanetsky 7300fa520d ext/sqlite3: reject close() from inside a callback
SQLite3::close() called from within a userland function, aggregate,
collation or authorizer callback freed the registered statements and
functions while sqlite3 was still executing, corrupting the active
statement and crashing the request. Track callback re-entry with a
per-database counter shared by all four callback kinds and throw an
Error from close() while it is non-zero; the database stays usable and
can be closed after the query completes.

Closes GH-23650
2026-09-16 09:02:46 -04:00

40 lines
930 B
PHP

--TEST--
SQLite3::close() from within a createCollation() callback must not corrupt active statement
--EXTENSIONS--
sqlite3
--FILE--
<?php
$db = new SQLite3(':memory:');
$db->exec('CREATE TABLE t (s TEXT)');
$db->exec("INSERT INTO t VALUES ('b')");
$db->exec("INSERT INTO t VALUES ('a')");
$reported = false;
$db->createCollation('CB', function ($x, $y) use (&$db, &$reported) {
if (!$reported) {
$reported = true;
try {
var_dump($db->close());
} catch (Throwable $e) {
echo $e::class, ": ", $e->getMessage(), "\n";
}
}
return strcmp($x, $y);
});
$stmt = $db->prepare('SELECT s FROM t ORDER BY s COLLATE CB');
$res = $stmt->execute();
while ($row = $res->fetchArray(SQLITE3_NUM)) {
echo $row[0], "\n";
}
$res->finalize();
var_dump($db->close());
echo "done\n";
?>
--EXPECT--
Error: Cannot close SQLite3 database while inside a callback
a
b
bool(true)
done