From f7874bfd672f6061e68be5333625747bd01801e8 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 18 Jul 2017 16:09:11 +0200 Subject: [PATCH] Add extra check in case of missing home storage --- lib/private/Files/Cache/Scanner.php | 5 +++ tests/lib/Files/Cache/ScannerTest.php | 50 +++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/lib/private/Files/Cache/Scanner.php b/lib/private/Files/Cache/Scanner.php index 5130676cf849..67e03332dd7a 100644 --- a/lib/private/Files/Cache/Scanner.php +++ b/lib/private/Files/Cache/Scanner.php @@ -113,6 +113,11 @@ protected function getData($path) { $data = $this->storage->getMetaData($path); if (is_null($data)) { \OCP\Util::writeLog('OC\Files\Cache\Scanner', "!!! Path '$path' is not accessible or present !!!", \OCP\Util::DEBUG); + // Last Line of Defence against potential Metadata-loss + if ($this->storage->instanceOfStorage('\OCP\Files\IHomeStorage') && !$this->storage->instanceOfStorage('OCA\Files_Sharing\ISharedStorage') && ($path === '' || $path === 'files')) { + \OCP\Util::writeLog('OC\Files\Cache\Scanner', 'Missing important folder "' . $path . '" in home storage!!! - ' . $this->storageId, \OCP\Util::ERROR); + throw new \OCP\Files\StorageNotAvailableException('Missing important folder "' . $path . '" in home storage - ' . $this->storageId); + } } return $data; } diff --git a/tests/lib/Files/Cache/ScannerTest.php b/tests/lib/Files/Cache/ScannerTest.php index 64168a88175e..370f8c03b6fe 100644 --- a/tests/lib/Files/Cache/ScannerTest.php +++ b/tests/lib/Files/Cache/ScannerTest.php @@ -343,4 +343,54 @@ public function dataTestIsPartialFile() { ]; } + public function failGetDataProvider() { + return [ + // throws for empty path and "files" in home storage + [true, false, '', true], + [true, true, '', true], + [true, false, 'files', true], + [true, true, 'files', true], + + // doesn't throw for federated shares (non-home) + [false, true, '', false], + [false, true, 'files', false], + + // doesn't throw for external storage (non-home) + [false, false, '', false], + [false, false, 'files', false], + + // doesn't throw for other paths + [true, false, 'other', false], + + // doesn't throw if metadata exists + [true, false, 'other', false, []], + ]; + } + + /** + * @dataProvider failGetDataProvider + */ + public function testFailGetData($isHomeStorage, $isSharedStorage, $scanPath, $expectedThrown, $metadata = null) { + $this->storage = $this->createMock(\OC\Files\Storage\Storage::class); + $this->storage->method('getCache')->willReturn($this->createMock(\OCP\Files\Cache\ICache::class)); + $this->storage->expects($this->any()) + ->method('getMetaData') + ->willReturn(null); + $this->storage->expects($this->any()) + ->method('instanceOfStorage') + ->will($this->returnValueMap([ + ['\OCP\Files\IHomeStorage', $isHomeStorage], + ['\OCA\Files_Sharing\ISharedStorage', $isSharedStorage], + ])); + $this->scanner = new \OC\Files\Cache\Scanner($this->storage); + $thrown = false; + try { + $this->scanner->scanFile($scanPath); + } catch (\OCP\Files\StorageNotAvailableException $e) { + $thrown = true; + } + + $this->assertEquals($expectedThrown, $thrown); + } + }