From 634303b0b31936e1e547643ced55e2b8301c7ea5 Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Wed, 18 Apr 2018 09:05:13 +0200 Subject: [PATCH 1/4] Test Travis envs --- .travis.yml | 4 +++ tests/framework/caching/FileCacheTest.php | 35 +++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/.travis.yml b/.travis.yml index f5f27c03ca3..ac5cb295bf5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,7 @@ env: - TASK_TESTS_PHP=1 - TASK_TESTS_JS=0 - TASK_TESTS_COVERAGE=0 + - TRAVIS_SECOND_USER=travis_two services: @@ -147,6 +148,9 @@ install: travis_retry npm install fi + # Needed for FileCacheTest + - sudo useradd $TRAVIS_SECOND_USER --gid $(id -g) -M + before_script: # # Disable: diff --git a/tests/framework/caching/FileCacheTest.php b/tests/framework/caching/FileCacheTest.php index 5c6dbd130e0..3f19ee6aca3 100644 --- a/tests/framework/caching/FileCacheTest.php +++ b/tests/framework/caching/FileCacheTest.php @@ -52,4 +52,39 @@ public function testExpireAdd() static::$time++; $this->assertFalse($cache->get('expire_testa')); } + + public function testCacheRenewalOnDifferentOwnership() + { + $TRAVIS_SECOND_USER = getenv('TRAVIS_SECOND_USER'); + if (empty($TRAVIS_SECOND_USER)) { + $this->markTestSkipped('Travis second user not found'); + } + + $cache = $this->getCacheInstance(); + + $cacheValue = uniqid('value_'); + $cachePublicKey = uniqid('key_'); + $cacheInternalKey = $cache->buildKey($cachePublicKey); + + static::$time = \time(); + $this->assertTrue($cache->set($cachePublicKey, $cacheValue, 2)); + $this->assertSame($cacheValue, $cache->get($cachePublicKey)); + + $refClass = new \ReflectionClass($cache); + $refMethodGetCacheFile = $refClass->getMethod('getCacheFile'); + $refMethodGetCacheFile->setAccessible(true); + $cacheFile = $refMethodGetCacheFile->invoke($cache, $cacheInternalKey); + $refMethodGetCacheFile->setAccessible(false); + + $output = array(); + $returnVar = null; + exec(sprintf('sudo chown %s %s', + escapeshellarg($TRAVIS_SECOND_USER), + escapeshellarg($cacheFile) + ), $output, $returnVar); + + $this->assertSame(0, $returnVar, 'Cannot change ownership of cache file to test cache renewal'); + + $this->assertTrue($cache->set($cachePublicKey, uniqid('value_2_'), 2), 'Cannot rebuild cache on different file ownership'); + } } From a0fca13f87741a8ae2d1e147fecb5668e925566a Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Wed, 18 Apr 2018 10:21:16 +0200 Subject: [PATCH 2/4] The fix --- framework/caching/FileCache.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/framework/caching/FileCache.php b/framework/caching/FileCache.php index d884f8097d4..919a05a5893 100644 --- a/framework/caching/FileCache.php +++ b/framework/caching/FileCache.php @@ -141,6 +141,12 @@ protected function setValue($key, $value, $duration) if ($this->directoryLevel > 0) { @FileHelper::createDirectory(dirname($cacheFile), $this->dirMode, true); } + // If ownership differs the touch call will fail, so we try to + // rebuild the file from scratch by deleting it first + // https://github.com/yiisoft/yii2/pull/16120 + if (is_file($cacheFile) && fileowner($cacheFile) !== posix_geteuid()) { + @unlink($cacheFile); + } if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) { if ($this->fileMode !== null) { @chmod($cacheFile, $this->fileMode); From 4afc900731e409a4b4ef0ae5c2d104be9850b047 Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Thu, 19 Apr 2018 08:42:30 +0200 Subject: [PATCH 3/4] posix_geteuid only exists on Linux --- framework/caching/FileCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/caching/FileCache.php b/framework/caching/FileCache.php index 919a05a5893..08f292084e9 100644 --- a/framework/caching/FileCache.php +++ b/framework/caching/FileCache.php @@ -144,7 +144,7 @@ protected function setValue($key, $value, $duration) // If ownership differs the touch call will fail, so we try to // rebuild the file from scratch by deleting it first // https://github.com/yiisoft/yii2/pull/16120 - if (is_file($cacheFile) && fileowner($cacheFile) !== posix_geteuid()) { + if (is_file($cacheFile) && function_exists('posix_geteuid') && fileowner($cacheFile) !== posix_geteuid()) { @unlink($cacheFile); } if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) { From 5597f0241100ab230252c97181c2737d7e43c688 Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Fri, 20 Apr 2018 08:11:21 +0200 Subject: [PATCH 4/4] Added PR to changelog --- framework/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 972049ba9fd..2233263001b 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -10,6 +10,7 @@ Yii Framework 2 Change Log - Bug #15988: Fixed bash completion (alekciy) - Bug #15117: Fixed `yii\db\Schema::getTableMetadata` cache refreshing (boboldehampsink) - Bug #16073: Fixed regression in Oracle `IN` condition builder for more than 1000 items (cebe) +- Bug #16120: FileCache: rebuild cache file before touch when different file owner (Slamdunk) 2.0.15.1 March 21, 2018