Skip to content

Commit 863faee

Browse files
authored
fix: encapsulation violation in BasePreparedQuery class (#9603)
* fix: add BaseConnection::handleTransStatus() method to fix protected property access * fix test
1 parent 5c7181e commit 863faee

File tree

4 files changed

+55
-6
lines changed

4 files changed

+55
-6
lines changed

system/Database/BaseConnection.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -652,9 +652,7 @@ public function query(string $sql, $binds = null, bool $setEscapeFlags = true, s
652652
$query->setDuration($startTime, $startTime);
653653

654654
// This will trigger a rollback if transactions are being used
655-
if ($this->transDepth !== 0) {
656-
$this->transStatus = false;
657-
}
655+
$this->handleTransStatus();
658656

659657
if (
660658
$this->DBDebug
@@ -904,6 +902,18 @@ public function resetTransStatus(): static
904902
return $this;
905903
}
906904

905+
/**
906+
* Handle transaction status when a query fails
907+
*
908+
* @internal This method is for internal database component use only
909+
*/
910+
public function handleTransStatus(): void
911+
{
912+
if ($this->transDepth !== 0) {
913+
$this->transStatus = false;
914+
}
915+
}
916+
907917
/**
908918
* Begin Transaction
909919
*/

system/Database/BasePreparedQuery.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,7 @@ public function execute(...$data)
134134
$query->setDuration($startTime, $startTime);
135135

136136
// This will trigger a rollback if transactions are being used
137-
if ($this->db->transDepth !== 0) {
138-
$this->db->transStatus = false;
139-
}
137+
$this->db->handleTransStatus();
140138

141139
if ($this->db->DBDebug) {
142140
// We call this function in order to roll-back queries

tests/system/Database/Live/PreparedQueryTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,4 +304,44 @@ public function testInsertBinaryData(): void
304304

305305
$this->assertSame(strlen($fileContent), strlen($file));
306306
}
307+
308+
public function testHandleTransStatusMarksTransactionFailedDuringTransaction(): void
309+
{
310+
$this->db->transStart();
311+
312+
// Verify we're in a transaction
313+
$this->assertSame(1, $this->db->transDepth);
314+
315+
// Prepare a query that will fail (duplicate key)
316+
$this->query = $this->db->prepare(static fn ($db) => $db->table('without_auto_increment')->insert([
317+
'key' => 'a',
318+
'value' => 'b',
319+
]));
320+
321+
$this->disableDBDebug();
322+
323+
$this->assertTrue($this->query->execute('test_key', 'test_value'));
324+
$this->assertTrue($this->db->transStatus());
325+
326+
$this->seeInDatabase($this->db->DBPrefix . 'without_auto_increment', [
327+
'key' => 'test_key',
328+
'value' => 'test_value'
329+
]);
330+
331+
$this->assertFalse($this->query->execute('test_key', 'different_value'));
332+
$this->assertFalse($this->db->transStatus());
333+
334+
$this->enableDBDebug();
335+
336+
// Complete the transaction - should rollback due to failed status
337+
$this->assertFalse($this->db->transComplete());
338+
339+
// Verify the first insert was rolled back
340+
$this->dontSeeInDatabase($this->db->DBPrefix . 'without_auto_increment', [
341+
'key' => 'test_key',
342+
'value' => 'test_value'
343+
]);
344+
345+
$this->db->resetTransStatus();
346+
}
307347
}

user_guide_src/source/changelogs/v4.6.2.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Bugs Fixed
3737

3838
- **Cache:** Fixed a bug where a corrupted or unreadable cache file could cause an unhandled exception in ``FileHandler::getItem()``.
3939
- **Database:** Fixed a bug where ``when()`` and ``whenNot()`` in ``ConditionalTrait`` incorrectly evaluated certain falsy values (such as ``[]``, ``0``, ``0.0``, and ``'0'``) as truthy, causing callbacks to be executed unexpectedly. These methods now cast the condition to a boolean using ``(bool)`` to ensure consistent behavior with PHP's native truthiness.
40+
- **Database:** Fixed encapsulation violation in ``BasePreparedQuery`` when accessing ``BaseConnection::transStatus`` protected property.
4041
- **Email:** Fixed a bug where ``Email::getHostname()`` failed to use ``$_SERVER['SERVER_ADDR']`` when ``$_SERVER['SERVER_NAME']`` was not set.
4142
- **Security:** Fixed a bug where the ``sanitize_filename()`` function from the Security helper would throw an error when used in CLI requests.
4243
- **Session:** Fixed a bug where using the ``DatabaseHandler`` with an unsupported database driver (such as ``SQLSRV``, ``OCI8``, or ``SQLite3``) did not throw an appropriate error.

0 commit comments

Comments
 (0)