Skip to content

Commit

Permalink
PdoDriver: check for misconfigured PDO connections resource (#294)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkuchar authored and dg committed Sep 17, 2018
1 parent e880631 commit e680866
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Dibi/Drivers/PdoDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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

}


Expand Down
80 changes: 80 additions & 0 deletions tests/dibi/PdoDriver.providedConnection.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

/**
* @dataProvider ../databases.ini != nothing, pdo
*/

// Background:
// When PDO connection is passed into Dibi it can be in (re)configured in various ways.
// This affects how connection is then internally handled.
// There should be no visible difference in Dibi behaviour regardless of PDO configuration (except unsupported configurations).


declare(strict_types=1);

use Tester\Assert;

require __DIR__ . '/bootstrap.php';


function buildPDOConnection(int $errorMode = null): PDO
{
global $config;

// used to parse config, establish connection
$connection = new \Dibi\Connection($config);
$dibiDriver = $connection->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));
});

0 comments on commit e680866

Please sign in to comment.