From e68086605ae712839b69af17461ee46d3e0f171b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kucha=C5=99?= Date: Mon, 17 Sep 2018 13:01:09 +0200 Subject: [PATCH] PdoDriver: check for misconfigured PDO connections resource (#294) --- src/Dibi/Drivers/PdoDriver.php | 5 ++ tests/dibi/PdoDriver.providedConnection.phpt | 80 ++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 tests/dibi/PdoDriver.providedConnection.phpt diff --git a/src/Dibi/Drivers/PdoDriver.php b/src/Dibi/Drivers/PdoDriver.php index 66321c153..9e00a34ba 100644 --- a/src/Dibi/Drivers/PdoDriver.php +++ b/src/Dibi/Drivers/PdoDriver.php @@ -69,8 +69,13 @@ public function __construct(array &$config) } } + if ($this->connection->getAttribute(\PDO::ATTR_ERRMODE) !== \PDO::ERRMODE_SILENT) { + throw new Dibi\DriverException('PDO connection in exception or warning error mode is currently not supported. Consider upgrading to Dibi >=4.1.0.'); + } + $this->driverName = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME); $this->serverVersion = (string) ($config['version'] ?? @$this->connection->getAttribute(PDO::ATTR_SERVER_VERSION)); // @ - may be not supported + } diff --git a/tests/dibi/PdoDriver.providedConnection.phpt b/tests/dibi/PdoDriver.providedConnection.phpt new file mode 100644 index 000000000..0764bc054 --- /dev/null +++ b/tests/dibi/PdoDriver.providedConnection.phpt @@ -0,0 +1,80 @@ +getDriver(); + \assert($dibiDriver instanceof \Dibi\Drivers\PdoDriver); + + // hack: extract PDO connection from driver (no public interface for that) + $connectionProperty = (new ReflectionClass($dibiDriver)) + ->getProperty('connection'); + $connectionProperty->setAccessible(true); + $pdo = $connectionProperty->getValue($dibiDriver); + \assert($pdo instanceof PDO); + + // check that error reporting is in PHPs default value + \assert($pdo->getAttribute(\PDO::ATTR_ERRMODE) === \PDO::ERRMODE_SILENT); + + // override PDO error mode if provided + if ($errorMode !== null) { + $pdo->setAttribute(\PDO::ATTR_ERRMODE, $errorMode); + } + return $pdo; +} + + +/** @throws \Dibi\NotSupportedException */ +function buildPdoDriverWithProvidedConnection(PDO $pdo): \Dibi\Drivers\PdoDriver +{ + $driverConfig = ['resource' => $pdo]; + return new \Dibi\Drivers\PdoDriver($driverConfig); +} + + +// PDO error mode: exception +Assert::exception(function () { + $pdoConnection = buildPDOConnection(\PDO::ERRMODE_EXCEPTION); + buildPdoDriverWithProvidedConnection($pdoConnection); +}, \Dibi\DriverException::class, 'PDO connection in exception or warning error mode is currently not supported. Consider upgrading to Dibi >=4.1.0.'); + + +// PDO error mode: warning +Assert::exception(function () { + $pdoConnection = buildPDOConnection(\PDO::ERRMODE_WARNING); + buildPdoDriverWithProvidedConnection($pdoConnection); +}, \Dibi\DriverException::class, 'PDO connection in exception or warning error mode is currently not supported. Consider upgrading to Dibi >=4.1.0.'); + + +// PDO error mode: explicitly set silent +test(function () { + $pdoConnection = buildPDOConnection(\PDO::ERRMODE_SILENT); + Assert::type(\Dibi\Drivers\PdoDriver::class, buildPdoDriverWithProvidedConnection($pdoConnection)); +}); + + +// PDO error mode: implicitly set silent +test(function () { + $pdoConnection = buildPDOConnection(null); + Assert::type(\Dibi\Drivers\PdoDriver::class, buildPdoDriverWithProvidedConnection($pdoConnection)); +});