diff --git a/apps/encryption/lib/Command/FixEncryptedVersion.php b/apps/encryption/lib/Command/FixEncryptedVersion.php index ab9cc528c54be..bed56c3306f78 100644 --- a/apps/encryption/lib/Command/FixEncryptedVersion.php +++ b/apps/encryption/lib/Command/FixEncryptedVersion.php @@ -22,6 +22,7 @@ namespace OCA\Encryption\Command; +use OC\Files\Storage\Wrapper\Encryption; use OC\Files\View; use OC\ServerNotAvailableException; use OCA\Encryption\Util; @@ -165,6 +166,13 @@ private function walkPathOfUser(string $user, string $path, OutputInterface $out */ private function verifyFileContent(string $path, OutputInterface $output, bool $ignoreCorrectEncVersionCall = true): bool { try { + // since we're manually poking around the encrypted state we need to ensure that this isn't cached in the encryption wrapper + $mount = $this->view->getMount($path); + $storage = $mount->getStorage(); + if ($storage && $storage->instanceOfStorage(Encryption::class)) { + $storage->clearIsEncryptedCache(); + } + /** * In encryption, the files are read in a block size of 8192 bytes * Read block size of 8192 and a bit more (808 bytes) diff --git a/lib/private/Files/Storage/Wrapper/Encryption.php b/lib/private/Files/Storage/Wrapper/Encryption.php index 21db6b7bf9de4..2f7123426d116 100644 --- a/lib/private/Files/Storage/Wrapper/Encryption.php +++ b/lib/private/Files/Storage/Wrapper/Encryption.php @@ -45,6 +45,7 @@ use OC\Files\ObjectStore\ObjectStoreStorage; use OC\Files\Storage\LocalTempFileTrait; use OC\Memcache\ArrayCache; +use OCP\Cache\CappedMemoryCache; use OCP\Encryption\Exceptions\GenericEncryptionException; use OCP\Encryption\IFile; use OCP\Encryption\IManager; @@ -95,6 +96,9 @@ class Encryption extends Wrapper { /** @var ArrayCache */ private $arrayCache; + /** @var CappedMemoryCache */ + private CappedMemoryCache $encryptedPaths; + /** * @param array $parameters */ @@ -122,6 +126,7 @@ public function __construct( $this->update = $update; $this->mountManager = $mountManager; $this->arrayCache = $arrayCache; + $this->encryptedPaths = new CappedMemoryCache(); parent::__construct($parameters); } @@ -461,6 +466,7 @@ public function fopen($path, $mode) { } if ($shouldEncrypt === true && $encryptionModule !== null) { + $this->encryptedPaths->set($this->util->stripPartialFileExtension($path), true); $headerSize = $this->getHeaderSize($path); $source = $this->storage->fopen($path, $mode); if (!is_resource($source)) { @@ -970,11 +976,13 @@ protected function getHeader($path) { $result = []; - // first check if it is an encrypted file at all - // We would do query to filecache only if we know that entry in filecache exists + $isEncrypted = $this->encryptedPaths->get($realFile); + if (is_null($isEncrypted)) { + $info = $this->getCache()->get($path); + $isEncrypted = isset($info['encrypted']) && $info['encrypted'] === true; + } - $info = $this->getCache()->get($path); - if (isset($info['encrypted']) && $info['encrypted'] === true) { + if ($isEncrypted) { $firstBlock = $this->readFirstBlock($path); $result = $this->parseRawHeader($firstBlock); @@ -1087,4 +1095,8 @@ public function writeStream(string $path, $stream, int $size = null): int { return $count; } + + public function clearIsEncryptedCache(): void { + $this->encryptedPaths->clear(); + } }