diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php index 0f15254249cc4..1f6e2b1d370b4 100644 --- a/lib/private/Files/Cache/Cache.php +++ b/lib/private/Files/Cache/Cache.php @@ -1197,6 +1197,9 @@ public function copyFromCache(ICache $sourceCache, ICacheEntry $sourceEntry, str && $sourceCache->hasEncryptionWrapper() && !$this->shouldEncrypt($targetPath)) { $data['encrypted'] = 0; + // normalizeData() prefers 'encryptedVersion' over 'encrypted' when both are + // set, so it has to be cleared too or the mark above gets ignored + unset($data['encryptedVersion']); } $fileId = $this->put($targetPath, $data); @@ -1230,6 +1233,11 @@ private function cacheEntryToArray(ICacheEntry $entry): array { if ($entry instanceof CacheEntry && isset($entry['scan_permissions'])) { $data['permissions'] = $entry['scan_permissions']; } + + if ($entry->isEncrypted() && isset($entry['encryptedVersion'])) { + $data['encryptedVersion'] = $entry['encryptedVersion']; + } + return $data; } diff --git a/tests/lib/Files/Cache/CacheTest.php b/tests/lib/Files/Cache/CacheTest.php index 0ce5a5ac2b38e..bbac04bea8356 100644 --- a/tests/lib/Files/Cache/CacheTest.php +++ b/tests/lib/Files/Cache/CacheTest.php @@ -540,6 +540,49 @@ public function testMoveFromCacheJail(): void { $this->assertEquals($this->cache->getId(''), $this->cache->get('targetsub')->getParentId()); } + public function testCopyFromCachePreservesEncryptedVersion(): void { + $data = [ + 'size' => 100, 'mtime' => 50, 'mimetype' => 'foo/bar', + 'encrypted' => true, 'encryptedVersion' => 3, + ]; + $this->cache->put('source', $data); + $sourceEntry = $this->cache->get('source'); + $this->assertSame(3, $sourceEntry['encryptedVersion']); + + $this->cache->copyFromCache($this->cache, $sourceEntry, 'target'); + + $targetEntry = $this->cache->get('target'); + $this->assertTrue($targetEntry->isEncrypted()); + $this->assertSame(3, $targetEntry['encryptedVersion']); + } + + public function testCopyFromCacheClearsEncryptedVersionWhenCopyingToNonEncryptedStorage(): void { + $data = [ + 'size' => 100, 'mtime' => 50, 'mimetype' => 'foo/bar', + 'encrypted' => true, 'encryptedVersion' => 3, + ]; + $this->cache2->put('source', $data); + $sourceEntry = $this->cache2->get('source'); + + $sourceCache = $this->getMockBuilder(Cache::class) + ->setConstructorArgs([$this->storage2]) + ->onlyMethods(['hasEncryptionWrapper']) + ->getMock(); + $sourceCache->method('hasEncryptionWrapper')->willReturn(true); + + $targetCache = $this->getMockBuilder(Cache::class) + ->setConstructorArgs([$this->storage]) + ->onlyMethods(['shouldEncrypt']) + ->getMock(); + $targetCache->method('shouldEncrypt')->willReturn(false); + + $targetCache->copyFromCache($sourceCache, $sourceEntry, 'target'); + + $targetEntry = $targetCache->get('target'); + $this->assertFalse($targetEntry->isEncrypted()); + $this->assertSame(0, $targetEntry['encryptedVersion']); + } + public function testGetIncomplete(): void { $file1 = 'folder1'; $file2 = 'folder2';