diff --git a/docs/changelogs/v4.7.7.md b/docs/changelogs/v4.7.7.md index cdf4eb2db148..c7ca7a926614 100644 --- a/docs/changelogs/v4.7.7.md +++ b/docs/changelogs/v4.7.7.md @@ -14,6 +14,7 @@ Release Date: Unreleased ## Bugs Fixed +- **Database:** Fixed a bug where `SQLite3\Table::dropIndexes()` used single-quoted string literals instead of escaped identifiers in `DROP INDEX IF EXISTS`, causing syntax errors on index names containing quotes or special characters. - **Security:** Fixed a bug where `Security::__construct()` threw a `TypeError` when the CSRF cookie was an array, causing an HTTP 500 response for affected requests. - **Worker Mode:** Fixed a bug where every request that ended with an uncaught exception, including a `404 Page Not Found` without a 404 override, called `exit()` in the exception handler. This ended the worker script, so FrankenPHP booted a new one, and the worker loop skipped its cleanup after the request. The exception handler now returns to the worker loop. diff --git a/system/Database/SQLite3/Table.php b/system/Database/SQLite3/Table.php index 3737822eaeeb..2d5e650e7cf6 100644 --- a/system/Database/SQLite3/Table.php +++ b/system/Database/SQLite3/Table.php @@ -496,7 +496,7 @@ protected function dropIndexes() continue; } - $this->db->query("DROP INDEX IF EXISTS '{$name}'"); + $this->db->query('DROP INDEX IF EXISTS ' . $this->db->escapeIdentifiers($name)); } } } diff --git a/tests/system/Database/Live/SQLite3/AlterTableTest.php b/tests/system/Database/Live/SQLite3/AlterTableTest.php index a7ba8ad13f03..742a73b73412 100644 --- a/tests/system/Database/Live/SQLite3/AlterTableTest.php +++ b/tests/system/Database/Live/SQLite3/AlterTableTest.php @@ -333,6 +333,21 @@ public function testDropColumnKeepsForeignKeyTableNameWhenPrefixIsSet(): void $forge->dropTable('bandit_fk', true); } + public function testDropIndexesWithSpecialIndexName(): void + { + $this->createTable('special_table'); + $this->db->query("CREATE INDEX `special'index` ON `special_table`(`name`)"); + + $result = $this->table + ->fromTable('special_table') + ->dropColumn('email') + ->run(); + + $this->assertTrue($result); + $this->forge->dropTable('special_table', true); + $this->forge->dropTable('special_table_fk', true); + } + protected function createTable(string $tableName = 'foo'): void { // Create support table for foreign keys