mirror of
https://github.com/php/php-src.git
synced 2026-10-29 02:07:35 +08:00
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
40 lines
930 B
PHP
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
|