From 3b6668804c59b3333773a1b3f34cae511b1c28b6 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Thu, 12 Dec 2019 23:07:10 +0300 Subject: [PATCH] Fix #17710: Fix MemCache duration normalization to avoid memcached/system timestamp mismatch --- framework/CHANGELOG.md | 1 + framework/caching/MemCache.php | 41 ++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 5a856e894c..76cfadc40d 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -13,6 +13,7 @@ Yii Framework 2 Change Log - Bug #17723: Fix incorrect decoding of default binary value for PostgreSQL (samdark) - Bug #17723: Fix incorrect type-casting of reflection type to string (samdark) - Bug #17725: Ensure we do not use external polyfills for pbkdf2() as these may be implemented incorrectly (samdark) +- Bug #17710: Fix MemCache duration normalization to avoid memcached/system timestamp mismatch (samdark) 2.0.30 November 19, 2019 diff --git a/framework/caching/MemCache.php b/framework/caching/MemCache.php index 8b4312068a..0f2bcdcd04 100644 --- a/framework/caching/MemCache.php +++ b/framework/caching/MemCache.php @@ -292,11 +292,7 @@ class MemCache extends Cache */ protected function setValue($key, $value, $duration) { - // Use UNIX timestamp since it doesn't have any limitation - // @see https://secure.php.net/manual/en/memcache.set.php - // @see https://secure.php.net/manual/en/memcached.expiration.php - $expire = $duration > 0 ? $duration + time() : 0; - + $expire = $this->normalizeDuration($duration); return $this->useMemcached ? $this->_cache->set($key, $value, $expire) : $this->_cache->set($key, $value, 0, $expire); } @@ -309,10 +305,7 @@ class MemCache extends Cache protected function setValues($data, $duration) { if ($this->useMemcached) { - // Use UNIX timestamp since it doesn't have any limitation - // @see https://secure.php.net/manual/en/memcache.set.php - // @see https://secure.php.net/manual/en/memcached.expiration.php - $expire = $duration > 0 ? $duration + time() : 0; + $expire = $this->normalizeDuration($duration); // Memcached::setMulti() returns boolean // @see https://secure.php.net/manual/en/memcached.setmulti.php @@ -334,11 +327,7 @@ class MemCache extends Cache */ protected function addValue($key, $value, $duration) { - // Use UNIX timestamp since it doesn't have any limitation - // @see https://secure.php.net/manual/en/memcache.set.php - // @see https://secure.php.net/manual/en/memcached.expiration.php - $expire = $duration > 0 ? $duration + time() : 0; - + $expire = $this->normalizeDuration($duration); return $this->useMemcached ? $this->_cache->add($key, $value, $expire) : $this->_cache->add($key, $value, 0, $expire); } @@ -362,4 +351,28 @@ class MemCache extends Cache { return $this->_cache->flush(); } + + /** + * Normalizes duration value + * + * @see https://github.com/yiisoft/yii2/issues/17710 + * @see https://secure.php.net/manual/en/memcache.set.php + * @see https://secure.php.net/manual/en/memcached.expiration.php + * + * @since 2.0.31 + * @param int $duration + * @return int + */ + protected function normalizeDuration($duration) + { + if ($duration < 0) { + return 0; + } + + if ($duration < 2592001) { + return $duration; + } + + return $duration + time(); + } }