From 337bc5ff4d84e3281b1a8254065fc223fedf40c2 Mon Sep 17 00:00:00 2001 From: Samy Mahmoudi Date: Mon, 19 Jan 2032 18:21:41 -0500 Subject: [PATCH] [HttpFoundation] Fix PdoSessionHandler charset-collation mismatch with the Doctrine DBAL | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | License | MIT PdoSessionHandler::configureSchema() was setting `utf8mb4_bin` as the collation without an explicit charset. The Doctrine DBAL may supply a charset from its configuration hierarchy, producing an invalid combination like `DEFAULT CHARACTER SET utf8 COLLATE utf8mb4_bin`. The `utf8mb4_bin` collation is bound to the `utf8mb4` character set: no other character set produces a valid MySQL statement. While one might aim for generality and/or optimality by omitting the charset and letting MySQL infer it, explicitly setting `charset` to `utf8mb4` ensures valid MySQL in all cases. A new test verifies that both charset and collate options are correctly set for MySQL. --- Session/Storage/Handler/PdoSessionHandler.php | 1 + .../Storage/Handler/PdoSessionHandlerTest.php | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/Session/Storage/Handler/PdoSessionHandler.php b/Session/Storage/Handler/PdoSessionHandler.php index 47d412ea368..7ffa3660d19 100644 --- a/Session/Storage/Handler/PdoSessionHandler.php +++ b/Session/Storage/Handler/PdoSessionHandler.php @@ -194,6 +194,7 @@ public function configureSchema(Schema $schema, ?\Closure $isSameDatabase = null $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true); $table->addColumn($this->lifetimeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true); $table->addColumn($this->timeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true); + $table->addOption('charset', 'utf8mb4'); $table->addOption('collate', 'utf8mb4_bin'); $table->addOption('engine', 'InnoDB'); break; diff --git a/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php index d44fdd17598..cc61855e3d4 100644 --- a/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php +++ b/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php @@ -356,6 +356,22 @@ public function testConfigureSchemaTableExistsPdo() $this->assertEmpty($table->getColumns(), 'The table was not overwritten'); } + public function testConfigureSchemaSetsUtf8mb4CharsetForMysql() + { + $pdo = new MockPdo('mysql'); + $pdo->prepareResult = $this->createMock(\PDOStatement::class); + + $schema = new Schema(); + + $pdoSessionHandler = new PdoSessionHandler($pdo); + $pdoSessionHandler->configureSchema($schema, fn () => true); + + $this->assertTrue($schema->hasTable('sessions')); + $table = $schema->getTable('sessions'); + $this->assertSame('utf8mb4', $table->getOption('charset')); + $this->assertSame('utf8mb4_bin', $table->getOption('collate')); + } + public static function provideUrlDsnPairs() { yield ['mysql://localhost/test', 'mysql:host=localhost;dbname=test;'];