Skip to content

Commit 2bad1be

Browse files
Merge pull request #64521 from nextcloud/backport/64445/stable35
[stable35] fix: Merge driverOptions correctly
2 parents 9cc92af + 1cf5322 commit 2bad1be

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

‎lib/private/DB/ConnectionFactory.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ public function createConnectionParams(string $configPrefix = '', array $additio
210210
//additional driver options, eg. for mysql ssl
211211
$driverOptions = $this->config->getValue($configPrefix . 'dbdriveroptions', $this->config->getValue('dbdriveroptions', null));
212212
if ($driverOptions) {
213-
$connectionParams['driverOptions'] = array_merge($connectionParams['driverOptions'], $driverOptions);
213+
$connectionParams['driverOptions'] = $driverOptions + ($connectionParams['driverOptions'] ?? []);
214214
}
215215

216216
// set default table creation options

‎tests/lib/DB/ConnectionFactoryTest.php‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,64 @@ public function testSplitHostFromPortAndSocket($host, array $expected): void {
4141
$this->assertEquals($expected, self::invokePrivate($factory, 'splitHostFromPortAndSocket', [$host]));
4242
}
4343

44+
/**
45+
* The numeric value of a PDO MySQL attribute, e.g. `SSL_CA`.
46+
*
47+
* The values are not stable across PHP versions, so they must never be hardcoded.
48+
* Since PHP 8.5 the `PDO::MYSQL_ATTR_*` constants are deprecated in favor of
49+
* `Pdo\Mysql::ATTR_*`, and either only exists with the MySQL driver installed.
50+
*/
51+
private function mysqlAttribute(string $name): int {
52+
if (!extension_loaded('pdo_mysql')) {
53+
$this->markTestSkipped('The pdo_mysql extension is required to resolve the PDO attribute values');
54+
}
55+
if (PHP_VERSION_ID >= 80500 && class_exists(\Pdo\Mysql::class)) {
56+
return (int)constant('Pdo\Mysql::ATTR_' . $name);
57+
}
58+
return (int)constant('PDO::MYSQL_ATTR_' . $name);
59+
}
60+
61+
public function testMysqlSslConnection(): void {
62+
/** @var SystemConfig|\PHPUnit\Framework\MockObject\MockObject $config */
63+
$config = $this->createMock(SystemConfig::class);
64+
$config->method('getValue')
65+
->willReturnCallback(function ($key, $default) {
66+
return match ($key) {
67+
'dbdriveroptions' => [
68+
$this->mysqlAttribute('SSL_CA') => 'rootCA.crt',
69+
$this->mysqlAttribute('SSL_CERT') => 'client.crt',
70+
$this->mysqlAttribute('SSL_KEY') => 'client.key',
71+
$this->mysqlAttribute('SSL_VERIFY_SERVER_CERT') => true,
72+
],
73+
'dbtype' => 'mysql',
74+
default => $default,
75+
};
76+
});
77+
$factory = new ConnectionFactory($config);
78+
79+
$params = $factory->createConnectionParams();
80+
81+
$this->assertEquals('pdo_mysql', $params['driver']);
82+
$this->assertEquals([
83+
$this->mysqlAttribute('FOUND_ROWS') => true,
84+
$this->mysqlAttribute('SSL_CA') => 'rootCA.crt',
85+
$this->mysqlAttribute('SSL_CERT') => 'client.crt',
86+
$this->mysqlAttribute('SSL_KEY') => 'client.key',
87+
$this->mysqlAttribute('SSL_VERIFY_SERVER_CERT') => true,
88+
], $params['driverOptions']);
89+
}
90+
4491
public function testPgsqlSslConnection(): void {
4592
/** @var SystemConfig|\PHPUnit\Framework\MockObject\MockObject $config */
4693
$config = $this->createMock(SystemConfig::class);
4794
$config->method('getValue')
4895
->willReturnCallback(function ($key, $default) {
4996
return match ($key) {
5097
'dbtype' => 'pgsql',
98+
'dbdriveroptions' => [
99+
1 => 'foo',
100+
3 => 'bar',
101+
],
51102
'pgsql_ssl' => [
52103
'mode' => 'verify-full',
53104
'cert' => 'client.crt',
@@ -68,5 +119,9 @@ public function testPgsqlSslConnection(): void {
68119
$this->assertEquals('client.crt', $params['sslcert']);
69120
$this->assertEquals('client.key', $params['sslkey']);
70121
$this->assertEquals('client.crl', $params['sslcrl']);
122+
$this->assertEquals([
123+
1 => 'foo',
124+
3 => 'bar',
125+
], $params['driverOptions']);
71126
}
72127
}

0 commit comments

Comments
 (0)