Skip to content

Commit e680866

Browse files
jkuchardg
authored andcommitted
PdoDriver: check for misconfigured PDO connections resource (#294)
1 parent e880631 commit e680866

2 files changed

Lines changed: 85 additions & 0 deletions

File tree

src/Dibi/Drivers/PdoDriver.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,13 @@ public function __construct(array &$config)
6969
}
7070
}
7171

72+
if ($this->connection->getAttribute(\PDO::ATTR_ERRMODE) !== \PDO::ERRMODE_SILENT) {
73+
throw new Dibi\DriverException('PDO connection in exception or warning error mode is currently not supported. Consider upgrading to Dibi >=4.1.0.');
74+
}
75+
7276
$this->driverName = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME);
7377
$this->serverVersion = (string) ($config['version'] ?? @$this->connection->getAttribute(PDO::ATTR_SERVER_VERSION)); // @ - may be not supported
78+
7479
}
7580

7681

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/**
4+
* @dataProvider ../databases.ini != nothing, pdo
5+
*/
6+
7+
// Background:
8+
// When PDO connection is passed into Dibi it can be in (re)configured in various ways.
9+
// This affects how connection is then internally handled.
10+
// There should be no visible difference in Dibi behaviour regardless of PDO configuration (except unsupported configurations).
11+
12+
13+
declare(strict_types=1);
14+
15+
use Tester\Assert;
16+
17+
require __DIR__ . '/bootstrap.php';
18+
19+
20+
function buildPDOConnection(int $errorMode = null): PDO
21+
{
22+
global $config;
23+
24+
// used to parse config, establish connection
25+
$connection = new \Dibi\Connection($config);
26+
$dibiDriver = $connection->getDriver();
27+
\assert($dibiDriver instanceof \Dibi\Drivers\PdoDriver);
28+
29+
// hack: extract PDO connection from driver (no public interface for that)
30+
$connectionProperty = (new ReflectionClass($dibiDriver))
31+
->getProperty('connection');
32+
$connectionProperty->setAccessible(true);
33+
$pdo = $connectionProperty->getValue($dibiDriver);
34+
\assert($pdo instanceof PDO);
35+
36+
// check that error reporting is in PHPs default value
37+
\assert($pdo->getAttribute(\PDO::ATTR_ERRMODE) === \PDO::ERRMODE_SILENT);
38+
39+
// override PDO error mode if provided
40+
if ($errorMode !== null) {
41+
$pdo->setAttribute(\PDO::ATTR_ERRMODE, $errorMode);
42+
}
43+
return $pdo;
44+
}
45+
46+
47+
/** @throws \Dibi\NotSupportedException */
48+
function buildPdoDriverWithProvidedConnection(PDO $pdo): \Dibi\Drivers\PdoDriver
49+
{
50+
$driverConfig = ['resource' => $pdo];
51+
return new \Dibi\Drivers\PdoDriver($driverConfig);
52+
}
53+
54+
55+
// PDO error mode: exception
56+
Assert::exception(function () {
57+
$pdoConnection = buildPDOConnection(\PDO::ERRMODE_EXCEPTION);
58+
buildPdoDriverWithProvidedConnection($pdoConnection);
59+
}, \Dibi\DriverException::class, 'PDO connection in exception or warning error mode is currently not supported. Consider upgrading to Dibi >=4.1.0.');
60+
61+
62+
// PDO error mode: warning
63+
Assert::exception(function () {
64+
$pdoConnection = buildPDOConnection(\PDO::ERRMODE_WARNING);
65+
buildPdoDriverWithProvidedConnection($pdoConnection);
66+
}, \Dibi\DriverException::class, 'PDO connection in exception or warning error mode is currently not supported. Consider upgrading to Dibi >=4.1.0.');
67+
68+
69+
// PDO error mode: explicitly set silent
70+
test(function () {
71+
$pdoConnection = buildPDOConnection(\PDO::ERRMODE_SILENT);
72+
Assert::type(\Dibi\Drivers\PdoDriver::class, buildPdoDriverWithProvidedConnection($pdoConnection));
73+
});
74+
75+
76+
// PDO error mode: implicitly set silent
77+
test(function () {
78+
$pdoConnection = buildPDOConnection(null);
79+
Assert::type(\Dibi\Drivers\PdoDriver::class, buildPdoDriverWithProvidedConnection($pdoConnection));
80+
});

0 commit comments

Comments
 (0)