diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php index 828a4c6..4118cab 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php @@ -42,11 +42,6 @@ class DatabaseBackend implements CacheBackendInterface { protected $checksumProvider; /** - * @var boolean - */ - protected $useMbstring; - - /** * Constructs a DatabaseBackend object. * * @param \Drupal\Core\Database\Connection $connection @@ -63,9 +58,6 @@ public function __construct(Connection $connection, CacheTagsChecksumInterface $ $this->bin = $bin; $this->connection = $connection; $this->checksumProvider = $checksum_provider; - - // check if mb_check_encoding function is present - $this->useMbstring = function_exists('mb_check_encoding'); } /** @@ -429,17 +421,19 @@ protected function normalizeCid($cid) { } /** - * Checks to see if a given string is only made up of ascii characters - * Uses mb_check_encoding if present, otherwise falls back to preg_match + * Checks to see if a given string is only made up of ascii characters. + * + * This uses mb_check_encoding if that's present, otherwise this falls back + * to preg_match. * * @param string $text - * the text to check + * The text to check. * * @return boolean - * true if $text only contains ascii characters, otherwise false + * True if $text only contains ascii characters, otherwise false. */ protected function isAscii($text) { - if ($this->useMbstring) { + if ($this->mbStringExists()) { return mb_check_encoding($text, 'ASCII'); } else { @@ -448,6 +442,14 @@ protected function isAscii($text) { } /** + * Check if mb_check_encoding function is present. + * @return bool + */ + protected function mbStringExists() { + return function_exists('mb_check_encoding'); + } + + /** * Defines the schema for the {cache_*} bin tables. */ public function schemaDefinition() { diff --git a/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php b/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php index 934fe81..ccec3e8 100644 --- a/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php +++ b/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php @@ -53,4 +53,108 @@ public function testSetGet() { $this->assertIdentical($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id."); } + /** + * Tests if the correct function is chosen. + */ + function testAsciiFunctionSelection() { + + // Make method and variable accessible through reflection. + $reflection_class = new \ReflectionClass("Drupal\\Core\\Cache\\DatabaseBackend"); + $reflection_property = $reflection_class->getMethod('mbStringExists'); + $reflection_property->setAccessible(TRUE); + + // Create classes. + $mockedConnection = $this->getMockBuilder("Drupal\\Core\\Database\\Connection") + ->disableOriginalConstructor() + ->getMock(); + $mockedChecksumInterface = $this->getMockBuilder("Drupal\\Core\\Cache\\CacheTagsChecksumInterface") + ->getMock(); + + $db_cache = new DatabaseBackend( + $mockedConnection, + $mockedChecksumInterface, + 'test' + ); + + if (function_exists('mb_check_encoding')) { + $this->assertTrue( + $reflection_property->getValue($db_cache), + "Assert that mbstring will be used." + ); + } + else { + $this->assertFalse( + $reflection_property->getValue($db_cache), + "Assert that mbstring will not be used." + ); + } + + } + + /** + * Tests that the DatabaseBackend normalizeCid works. + */ + function testCidNormalization() { + + $cids = array( + // Ascii only, should return same. + array("cid" => "0000000000", "expected" => "0000000000"), + // Utf-8, should return hash. + array( + "cid" => "Some Danish characters: � �", + "expected" => "6Q10YnfEtF092na6OZOwuLniGFilOQgIPnam3IXjcBU" + ), + // Ascii, over 255 characters long, should return hash padded with + // original string to a 255 length. + array( + "cid" => str_repeat("0", 256), + "expected" => "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Z_AiGV7kBRQpaMobU64lE6i6sEBNcFd3hTFvqVIY6Lo" + ), + // Utf-8, over 255 long, should return a hash. + array( + "cid" => "Some Danish characters: � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � � �", + "expected" => "KbjIhg-2SJ5fjtlNol8DnT_tJDr65kcJsq9cpgLSVJ0" + ), + ); + + // Make method and variable accessible through reflection. + $reflection_class = new \ReflectionClass("Drupal\Core\Cache\DatabaseBackend"); + $reflection_property = $reflection_class->getMethod('mbStringExists'); + $reflection_property->setAccessible(TRUE); + $reflection_method = $reflection_class->getMethod('normalizeCid'); + $reflection_method->setAccessible(TRUE); + + // Create classes. + $mockedConnection = $this->getMockBuilder("Drupal\Core\Database\Connection") + ->disableOriginalConstructor() + ->getMock(); + $mockedChecksumInterface = $this + ->getMockBuilder("Drupal\Core\Cache\CacheTagsChecksumInterface") + ->getMock(); + + $db_cache = new DatabaseBackend($mockedConnection, $mockedChecksumInterface, 'test'); + + if (function_exists('mb_check_encoding')) { + // run checks + foreach ($cids as $cid) { + $this->assertEquals( + $cid["expected"], + $reflection_method->invoke($db_cache, $cid["cid"]), + "Assert that cid is normalized as expected." + ); + } + } + + // now force usage of preg + $reflection_property->setValue($db_cache, FALSE); + foreach ($cids as $cid) { + $this->assertEquals( + $cid["expected"], + $reflection_method->invoke($db_cache, $cid["cid"]), + "Assert that cid is normalized as expected." + ); + } + + } + } diff --git a/core/tests/Drupal/Tests/Core/Cache/DatabaseBackendTest.php b/core/tests/Drupal/Tests/Core/Cache/DatabaseBackendTest.php deleted file mode 100644 index 6511e0d..0000000 --- a/core/tests/Drupal/Tests/Core/Cache/DatabaseBackendTest.php +++ /dev/null @@ -1,91 +0,0 @@ -getProperty('useMbstring'); - $reflection_property->setAccessible(TRUE); - - // create classes - $mockedConnection = $this->getMockBuilder("Drupal\Core\Database\Connection")->disableOriginalConstructor()->getMock(); - $mockedChecksumInterface = $this->getMockBuilder("Drupal\Core\Cache\CacheTagsChecksumInterface")->getMock(); - - $db_cache = new DatabaseBackend($mockedConnection, $mockedChecksumInterface, 'test'); - - if (function_exists('mb_check_encoding')) { - $this->assertTrue($reflection_property->getValue($db_cache), "Assert that mbstring will be used"); - } - else { - $this->assertFalse($reflection_property->getValue($db_cache), "Assert that mbstring will not be used"); - } - - } - - /** - * Tests that the DatabaseBackend normalizeCid works both with or without mbstring. - */ - function testCidNormalization() - { - - $cids = array( - // ascii only, should return same - array("cid" => "0000000000", "expected" => "0000000000"), - // utf-8, should return hash - array("cid" => "Some Danish characters: æ ø", "expected" => "6Q10YnfEtF092na6OZOwuLniGFilOQgIPnam3IXjcBU"), - // ascii, over 255 long, should return hash padded with original string to a 255 length - array("cid" => str_repeat("0", 256), "expected" => "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Z_AiGV7kBRQpaMobU64lE6i6sEBNcFd3hTFvqVIY6Lo"), - // utf-8, over 255 long, should return hash - array("cid" => "Some Danish characters: æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø æ ø", "expected" => "KbjIhg-2SJ5fjtlNol8DnT_tJDr65kcJsq9cpgLSVJ0"), - ); - - // make method and variable accessible through reflection - $reflection_class = new \ReflectionClass("Drupal\Core\Cache\DatabaseBackend"); - $reflection_property = $reflection_class->getProperty('useMbstring'); - $reflection_property->setAccessible(TRUE); - $reflection_method = $reflection_class->getMethod('normalizeCid'); - $reflection_method->setAccessible(TRUE); - - // create classes - $mockedConnection = $this->getMockBuilder("Drupal\Core\Database\Connection")->disableOriginalConstructor()->getMock(); - $mockedChecksumInterface = $this->getMockBuilder("Drupal\Core\Cache\CacheTagsChecksumInterface")->getMock(); - - $db_cache = new DatabaseBackend($mockedConnection, $mockedChecksumInterface, 'test'); - - if (function_exists('mb_check_encoding')) { - // run checks - foreach ($cids as $cid) { - $this->assertEquals($cid["expected"], $reflection_method->invoke($db_cache, $cid["cid"]), "Assert that cid is normalized as expected"); - } - } - - // now force usage of preg - $reflection_property->setValue($db_cache, FALSE); - foreach ($cids as $cid) { - $this->assertEquals($cid["expected"], $reflection_method->invoke($db_cache, $cid["cid"]), "Assert that cid is normalized as expected"); - } - - } -}