Skip to content

Commit 0512d91

Browse files
committed
make file cache updates more robust
only update the encrypted version after the write operation is finished and the stream is closed Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
1 parent a2df728 commit 0512d91

3 files changed

Lines changed: 28 additions & 3 deletions

File tree

apps/encryption/lib/Crypto/Encryption.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,6 @@ public function begin($path, $user, $mode, array $header, array $accessList) {
254254
public function end($path, $position = 0) {
255255
$result = '';
256256
if ($this->isWriteOperation) {
257-
$this->keyManager->setVersion($path, $this->version + 1, new View());
258257
// in case of a part file we remember the new signature versions
259258
// the version will be set later on update.
260259
// This way we make sure that other apps listening to the pre-hooks

lib/private/Files/Stream/Encryption.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ class Encryption extends Wrapper {
102102
/** @var array */
103103
protected $expectedContextProperties;
104104

105+
/** @var bool */
106+
protected $fileUpdated;
107+
105108
public function __construct() {
106109
$this->expectedContextProperties = array(
107110
'source',
@@ -235,6 +238,7 @@ public function stream_open($path, $mode, $options, &$opened_path) {
235238
$this->position = 0;
236239
$this->cache = '';
237240
$this->writeFlag = false;
241+
$this->fileUpdated = false;
238242
$this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed);
239243

240244
if (
@@ -313,7 +317,6 @@ public function stream_read($count) {
313317
}
314318

315319
public function stream_write($data) {
316-
317320
$length = 0;
318321
// loop over $data to fit it in 6126 sized unencrypted blocks
319322
while (isset($data[0])) {
@@ -333,6 +336,7 @@ public function stream_write($data) {
333336

334337
// switch the writeFlag so flush() will write the block
335338
$this->writeFlag = true;
339+
$this->fileUpdated = true;
336340

337341
// determine the relative position in the current block
338342
$blockPosition = ($this->position % $this->unencryptedBlockSize);
@@ -414,7 +418,18 @@ public function stream_close() {
414418
}
415419
$this->encryptionStorage->updateUnencryptedSize($this->fullPath, $this->unencryptedSize);
416420
}
417-
return parent::stream_close();
421+
$result = parent::stream_close();
422+
423+
if ($this->fileUpdated) {
424+
$cache = $this->storage->getCache();
425+
$cacheEntry = $cache->get($this->internalPath);
426+
if ($cacheEntry) {
427+
$version = $cacheEntry['encryptedVersion'] + 1;
428+
$cache->update($cacheEntry->getId(), ['encrypted' => $version, 'encryptedVersion' => $version]);
429+
}
430+
}
431+
432+
return $result;
418433
}
419434

420435
/**

tests/lib/Files/Stream/EncryptionTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace Test\Files\Stream;
44

5+
use OC\Files\Cache\CacheEntry;
56
use OC\Files\View;
67
use OC\Memcache\ArrayCache;
8+
use OCP\Files\Cache\ICache;
79
use OCP\IConfig;
810

911
class EncryptionTest extends \Test\TestCase {
@@ -26,6 +28,7 @@ protected function getStream($fileName, $mode, $unencryptedSize, $wrapper = '\OC
2628
$header = [];
2729
$uid = '';
2830
$this->encryptionModule = $this->buildMockModule();
31+
$cache = $this->createMock(ICache::class);
2932
$storage = $this->getMockBuilder('\OC\Files\Storage\Storage')
3033
->disableOriginalConstructor()->getMock();
3134
$encStorage = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
@@ -49,6 +52,13 @@ protected function getStream($fileName, $mode, $unencryptedSize, $wrapper = '\OC
4952
$util->expects($this->any())
5053
->method('getUidAndFilename')
5154
->willReturn(['user1', $internalPath]);
55+
$storage->expects($this->any())->method('getCache')->willReturn($cache);
56+
$entry = new CacheEntry([
57+
'fileid' => 5,
58+
'encryptedVersion' => 2,
59+
]);
60+
$cache->expects($this->any())->method('get')->willReturn($entry );
61+
$cache->expects($this->any())->method('update')->with(5, ['encrypted' => 3, 'encryptedVersion' => 3]);
5262

5363

5464
return $wrapper::wrap($source, $internalPath,
@@ -208,6 +218,7 @@ public function testRewind() {
208218

209219
public function testSeek() {
210220
$fileName = tempnam("/tmp", "FOO");
221+
211222
$stream = $this->getStream($fileName, 'w+', 0);
212223
$this->assertEquals(6, fwrite($stream, 'foobar'));
213224
$this->assertEquals(0, fseek($stream, 3));

0 commit comments

Comments
 (0)