[BUGFIX] Loosen type check of Redis identifiers and tags 91/23191/8
authorThorsten Kahler <thorsten.kahler@dkd.de>
Mon, 19 Aug 2013 17:57:27 +0000 (19:57 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Mon, 29 Jun 2015 21:59:42 +0000 (23:59 +0200)
RedisBackend denies identifiers and tags allowed in all other
implementations of caching backends. This change allows all identifiers
and tags which can be casted to string.
Specifically it adds a check for objects having a __toString method.

Change-Id: Id5cc372f6a00c68d9e44a1eb8bb38c8a3679f2a7
Resolves: #51031
Releases: master
Reviewed-on: http://review.typo3.org/23191
Reviewed-by: Benjamin Mack <benni@typo3.org>
Tested-by: Benjamin Mack <benni@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/core/Classes/Cache/Backend/RedisBackend.php

index 72791c5..eb4196d 100644 (file)
@@ -25,7 +25,7 @@ namespace TYPO3\CMS\Core\Cache\Backend;
  * @author Christian Kuhn <lolli@schwarzbu.ch>
  * @api
  */
-class RedisBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend implements \TYPO3\CMS\Core\Cache\Backend\TaggableBackendInterface {
+class RedisBackend extends AbstractBackend implements TaggableBackendInterface {
 
        /**
         * Faked unlimited lifetime = 31536000 (1 Year).
@@ -261,8 +261,8 @@ class RedisBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impleme
         * @api
         */
        public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
-               if (!is_string($entryIdentifier)) {
-                       throw new \InvalidArgumentException('The specified identifier is of type "' . gettype($entryIdentifier) . '" but a string is expected.', 1279470252);
+               if (!$this->canBeUsedInStringContext($entryIdentifier)) {
+                       throw new \InvalidArgumentException('The specified identifier is of type "' . gettype($entryIdentifier) . '" which can\'t be converted to string.', 1377006651);
                }
                if (!is_string($data)) {
                        throw new \TYPO3\CMS\Core\Cache\Exception\InvalidDataException('The specified data is of type "' . gettype($data) . '" but a string is expected.', 1279469941);
@@ -313,8 +313,8 @@ class RedisBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impleme
         * @api
         */
        public function get($entryIdentifier) {
-               if (!is_string($entryIdentifier)) {
-                       throw new \InvalidArgumentException('The specified identifier is of type "' . gettype($entryIdentifier) . '" but a string is expected.', 1279470253);
+               if (!$this->canBeUsedInStringContext($entryIdentifier)) {
+                       throw new \InvalidArgumentException('The specified identifier is of type "' . gettype($entryIdentifier) . '" which can\'t be converted to string.', 1377006652);
                }
                $storedEntry = FALSE;
                if ($this->connected) {
@@ -337,8 +337,8 @@ class RedisBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impleme
         * @api
         */
        public function has($entryIdentifier) {
-               if (!is_string($entryIdentifier)) {
-                       throw new \InvalidArgumentException('The specified identifier is of type "' . gettype($entryIdentifier) . '" but a string is expected.', 1279470254);
+               if (!$this->canBeUsedInStringContext($entryIdentifier)) {
+                       throw new \InvalidArgumentException('The specified identifier is of type "' . gettype($entryIdentifier) . '" which can\'t be converted to string.', 1377006653);
                }
                return $this->connected && $this->redis->exists(self::IDENTIFIER_DATA_PREFIX . $entryIdentifier);
        }
@@ -355,8 +355,8 @@ class RedisBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impleme
         * @api
         */
        public function remove($entryIdentifier) {
-               if (!is_string($entryIdentifier)) {
-                       throw new \InvalidArgumentException('The specified identifier is of type "' . gettype($entryIdentifier) . '" but a string is expected.', 1279470255);
+               if (!$this->canBeUsedInStringContext($entryIdentifier)) {
+                       throw new \InvalidArgumentException('The specified identifier is of type "' . gettype($entryIdentifier) . '" which can\'t be converted to string.', 1377006654);
                }
                $elementsDeleted = FALSE;
                if ($this->connected) {
@@ -387,8 +387,8 @@ class RedisBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impleme
         * @api
         */
        public function findIdentifiersByTag($tag) {
-               if (!is_string($tag)) {
-                       throw new \InvalidArgumentException('The specified tag is of type "' . gettype($tag) . '" but a string is expected.', 1279569759);
+               if (!$this->canBeUsedInStringContext($tag)) {
+                       throw new \InvalidArgumentException('The specified tag is of type "' . gettype($tag) . '" which can\'t be converted to string.', 1377006655);
                }
                $foundIdentifiers = array();
                if ($this->connected) {
@@ -423,8 +423,8 @@ class RedisBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impleme
         * @api
         */
        public function flushByTag($tag) {
-               if (!is_string($tag)) {
-                       throw new \InvalidArgumentException('The specified tag is of type "' . gettype($tag) . '" but a string is expected.', 1279578078);
+               if (!$this->canBeUsedInStringContext($tag)) {
+                       throw new \InvalidArgumentException('The specified tag is of type "' . gettype($tag) . '" which can\'t be converted to string.', 1377006656);
                }
                if ($this->connected) {
                        $identifiers = $this->redis->sMembers(self::TAG_IDENTIFIERS_PREFIX . $tag);
@@ -502,4 +502,14 @@ class RedisBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impleme
                $queue->exec();
        }
 
+       /**
+        * Helper method to catch invalid identifiers and tags
+        *
+        * @param mixed $variable Variable to be checked
+        * @return boolean
+        */
+       protected function canBeUsedInStringContext($variable) {
+               return is_scalar($variable) || (is_object($variable) && method_exists($variable, '__toString'));
+       }
+
 }