From 71838159fed9b5672d99a6eef148c94d386dde4c Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole Date: Wed, 4 Mar 2015 15:04:01 +0000 Subject: [PATCH] Issue #2252033 by olli, dawehner: Don't serialize database connection info --- core/lib/Drupal/Core/Database/Connection.php | 9 ++++-- .../src/Tests/Database/ConnectionUnitTest.php | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/core/lib/Drupal/Core/Database/Connection.php b/core/lib/Drupal/Core/Database/Connection.php index d6717583e41..358fa71cae0 100644 --- a/core/lib/Drupal/Core/Database/Connection.php +++ b/core/lib/Drupal/Core/Database/Connection.php @@ -1273,8 +1273,9 @@ abstract class Connection implements \Serializable { */ public function serialize() { $connection = clone $this; - // Don't serialize the PDO connection and other lazy-instantiated members. - unset($connection->connection, $connection->schema, $connection->driverClasses); + // Don't serialize the PDO connection as well as everything else which + // depends on settings.php. + unset($connection->connection, $connection->connectionOptions, $connection->schema, $connection->prefixes, $connection->prefixReplace, $connection->driverClasses); return serialize(get_object_vars($connection)); } @@ -1286,6 +1287,8 @@ abstract class Connection implements \Serializable { foreach ($data as $key => $value) { $this->{$key} = $value; } + $this->connectionOptions = Database::getConnectionInfo($this->key)[$this->target]; + // Re-establish the PDO connection using the original options. $this->connection = static::open($this->connectionOptions); @@ -1293,6 +1296,8 @@ abstract class Connection implements \Serializable { if (!empty($this->statementClass)) { $this->connection->setAttribute(\PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this))); } + + $this->setPrefix(isset($this->connectionOptions['prefix']) ? $this->connectionOptions['prefix'] : ''); } } diff --git a/core/modules/system/src/Tests/Database/ConnectionUnitTest.php b/core/modules/system/src/Tests/Database/ConnectionUnitTest.php index 0d7e5060d39..74d0de76ba9 100644 --- a/core/modules/system/src/Tests/Database/ConnectionUnitTest.php +++ b/core/modules/system/src/Tests/Database/ConnectionUnitTest.php @@ -7,7 +7,9 @@ namespace Drupal\system\Tests\Database; +use Doctrine\Common\Reflection\StaticReflectionProperty; use Drupal\Core\Database\Database; +use Drupal\Core\Site\Settings; use Drupal\simpletest\KernelTestBase; /** @@ -268,6 +270,32 @@ class ConnectionUnitTest extends KernelTestBase { } } + // By using "key", we ensure that its not a key used in the serialized PHP. + $not_serialized_properties = ['"connection"', '"connectionOptions"', '"schema"', '"prefixes"', '"prefixReplace"', '"driverClasses"']; + foreach ($not_serialized_properties as $property) { + $this->assertIdentical(FALSE, strpos($serialized, $property)); + } + + // Serialize the DB connection again, but this time change the connection + // information under the hood. + $serialized = serialize($db); + $db_connection_info = Database::getAllConnectionInfo(); + + // Use reflection to empty out $databaseInfo. + $reflection_class = new \ReflectionClass('Drupal\Core\Database\Database'); + $database_info_reflection = $reflection_class->getProperty('databaseInfo'); + $database_info_reflection->setAccessible(TRUE); + $database_info_reflection->setValue(NULL, []); + + // Setup a different DB connection which should be picked up after the + // unserialize. + $db_connection_info['default']['default']['extra'] = 'value'; + + Database::setMultipleConnectionInfo($db_connection_info); + + /** @var \Drupal\Core\Database\Connection $db */ + $db = unserialize($serialized); + $this->assertEqual($db->getConnectionOptions()['extra'], 'value'); } /**