diff options
-rw-r--r-- | core/Filesystem.php | 23 | ||||
-rw-r--r-- | core/Url.php | 4 | ||||
-rw-r--r-- | core/Version.php | 2 | ||||
-rw-r--r-- | tests/PHPUnit/Unit/FilesystemTest.php | 66 |
4 files changed, 91 insertions, 4 deletions
diff --git a/core/Filesystem.php b/core/Filesystem.php index 4a7e7de106..5b8101291f 100644 --- a/core/Filesystem.php +++ b/core/Filesystem.php @@ -314,7 +314,11 @@ class Filesystem return str_replace($target, '', $file); }, $targetFiles); - $diff = array_diff($targetFiles, $sourceFiles); + if (FileSystem::isFileSystemCaseInsensitive()) { + $diff = array_udiff($targetFiles, $sourceFiles, 'strcasecmp'); + } else { + $diff = array_diff($targetFiles, $sourceFiles); + } return array_values($diff); } @@ -558,6 +562,23 @@ class Filesystem } /** + * Check if the filesystem is case sensitive by writing a temporary file + * + * @return bool + */ + public static function isFileSystemCaseInsensitive() : bool + { + $testFileName = 'caseSensitivityTest.txt'; + $pathTmp = StaticContainer::get('path.tmp'); + @file_put_contents($pathTmp.'/'.$testFileName, 'Nothing to see here.'); + if (\file_exists($pathTmp.'/'.strtolower($testFileName))) { + // Wrote caseSensitivityTest.txt but casesensitivitytest.txt exists, so case insensitive + return true; + } + return false; + } + + /** * in tmp/ (sub-)folder(s) we create empty index.htm|php files * * @param $path diff --git a/core/Url.php b/core/Url.php index a79fdecb5b..c027538cdb 100644 --- a/core/Url.php +++ b/core/Url.php @@ -206,7 +206,7 @@ class Url * value from the request. * @return bool `true` if valid; `false` otherwise. */ - public static function isValidHost($host = false) + public static function isValidHost($host = false): bool { // only do trusted host check if it's enabled if (isset(Config::getInstance()->General['enable_trusted_host_check']) @@ -215,7 +215,7 @@ class Url return true; } - if ($host === false) { + if (false === $host || null === $host) { $host = self::getHostFromServerVariable(); if (empty($host)) { // if no current host, assume valid diff --git a/core/Version.php b/core/Version.php index a5a57de219..ad030d351e 100644 --- a/core/Version.php +++ b/core/Version.php @@ -20,7 +20,7 @@ final class Version * The current Matomo version. * @var string */ - const VERSION = '4.7.1'; + const VERSION = '4.8.0'; const MAJOR_VERSION = 4; diff --git a/tests/PHPUnit/Unit/FilesystemTest.php b/tests/PHPUnit/Unit/FilesystemTest.php index b21705e796..4913ee0844 100644 --- a/tests/PHPUnit/Unit/FilesystemTest.php +++ b/tests/PHPUnit/Unit/FilesystemTest.php @@ -14,6 +14,7 @@ use Piwik\Tests\Framework\TestCase\SystemTestCase; /** * @group Core + * @group FileSystem */ class FilesystemTest extends \PHPUnit\Framework\TestCase { @@ -193,6 +194,51 @@ class FilesystemTest extends \PHPUnit\Framework\TestCase $this->assertEquals(array(), $result); } + public function test_unlockTargetFilesNotPresentInSource_doNotAttemptToUnlinkFilesWithTheSameCaseInsensitiveName() + { + $sourceInsensitive = $this->createCaseInsensitiveSourceFiles(); + $targetInsensitive = $this->createCaseInsensitiveTargetFiles(); + + // Target: /CoreHome/vue/src/Menudropdown/Menudropdown.vue' + // Source: /CoreHome/vue/src/MenuDropdown/MenuDropdown.vue' + + $result = Filesystem::directoryDiff($sourceInsensitive, $targetInsensitive); + + if (Filesystem::isFileSystemCaseInsensitive()) { + + // Case insensitive filesystem: + // Since the target and source will be treated as the same file then we do not want directoryDiff() to + // report a difference as copying the source command will overwrite the target file. Reporting a difference + // will cause the target file to be unlinked after the copy which will result in a missing file. + + $this->assertEquals(array(), $result); + + } else { + + // Case sensitive filesystem: + // directoryDiff() should report a difference and we should be able to unlink the target file safely after + // the source file has been copied. + + // make sure there is a difference between those folders + $this->assertNotEmpty($result); + + Filesystem::unlinkTargetFilesNotPresentInSource($sourceInsensitive, $targetInsensitive); + + // make sure there is no longer a difference + $result = Filesystem::directoryDiff($sourceInsensitive, $targetInsensitive); + $this->assertEquals(array(), $result); + + $result = Filesystem::directoryDiff($targetInsensitive, $sourceInsensitive); + $this->assertEquals(array( + '/CoreHome/vue/src/MenuDropdown', + '/CoreHome/vue/src/MenuDropdown/MenuDropdown.vue', + '/CoreHome/vue/src/MenuDropdown/index.htm', + '/CoreHome/vue/src/MenuDropdown/index.php', + ), $result); + + } + } + private function createSourceFiles() { $source = $this->createEmptySource(); @@ -265,6 +311,26 @@ class FilesystemTest extends \PHPUnit\Framework\TestCase return $this->testPath . '/target'; } + private function createCaseInsensitiveTargetFiles() + { + $target = $this->createEmptyTarget(); + Filesystem::mkdir($target . '/CoreHome/vue/src/Menudropdown'); + + file_put_contents($target . '/CoreHome/vue/src/Menudropdown/Menudropdown.vue', ''); + + return $target; + } + + private function createCaseInsensitiveSourceFiles() + { + $source = $this->createEmptySource(); + Filesystem::mkdir($source . '/CoreHome/vue/src/MenuDropdown'); + + file_put_contents($source . '/CoreHome/vue/src/MenuDropdown/MenuDropdown.vue', ''); + + return $source; + } + public function test_getFileSize_ZeroSize() { File::setFileSize(0); |