diff options
author | Joas Schilling <coding@schilljs.com> | 2018-03-05 12:38:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-05 12:38:43 +0100 |
commit | 6104a7043e9300421ed2ba430a08f1da755e8cbf (patch) | |
tree | 1e0821fee5f185520862f39ee8c0cf53ccc6ec97 | |
parent | 479b9465c0159973315bd56104742a8b0da85460 (diff) | |
parent | 9413f97b9234ea94cfa881c5f0640f524ae98257 (diff) | |
download | nextcloud-server-6104a7043e9300421ed2ba430a08f1da755e8cbf.tar.gz nextcloud-server-6104a7043e9300421ed2ba430a08f1da755e8cbf.zip |
Merge pull request #8636 from nextcloud/8289_13
[stable13] AppData hardening
-rw-r--r-- | lib/private/Files/SimpleFS/SimpleFile.php | 36 | ||||
-rw-r--r-- | lib/public/Files/SimpleFS/ISimpleFile.php | 3 | ||||
-rw-r--r-- | tests/lib/Files/SimpleFS/SimpleFileTest.php | 22 |
3 files changed, 60 insertions, 1 deletions
diff --git a/lib/private/Files/SimpleFS/SimpleFile.php b/lib/private/Files/SimpleFS/SimpleFile.php index 5eadfd98b60..1f2b497a192 100644 --- a/lib/private/Files/SimpleFS/SimpleFile.php +++ b/lib/private/Files/SimpleFS/SimpleFile.php @@ -23,6 +23,7 @@ namespace OC\Files\SimpleFS; use OCP\Files\File; +use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFile; @@ -79,10 +80,18 @@ class SimpleFile implements ISimpleFile { /** * Get the content * + * @throws NotPermittedException + * @throws NotFoundException * @return string */ public function getContent() { - return $this->file->getContent(); + $result = $this->file->getContent(); + + if ($result === false) { + $this->checkFile(); + } + + return $result; } /** @@ -96,6 +105,31 @@ class SimpleFile implements ISimpleFile { } /** + * Sometimes there are some issues with the AppData. Most of them are from + * user error. But we should handle them gracefull anyway. + * + * If for some reason the current file can't be found. We remove it. + * Then traverse up and check all folders if they exists. This so that the + * next request will have a valid appdata structure again. + * + * @throws NotFoundException + */ + private function checkFile() { + $cur = $this->file; + + while ($cur->stat() === false) { + $parent = $cur->getParent(); + $cur->delete(); + $cur = $parent; + } + + if ($cur !== $this->file) { + throw new NotFoundException('File does not exist'); + } + } + + + /** * Delete the file * * @throws NotPermittedException diff --git a/lib/public/Files/SimpleFS/ISimpleFile.php b/lib/public/Files/SimpleFS/ISimpleFile.php index e9182377cb5..e03509d7abf 100644 --- a/lib/public/Files/SimpleFS/ISimpleFile.php +++ b/lib/public/Files/SimpleFS/ISimpleFile.php @@ -22,6 +22,7 @@ */ namespace OCP\Files\SimpleFS; +use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; /** @@ -67,6 +68,8 @@ interface ISimpleFile { /** * Get the content * + * @throws NotPermittedException + * @throws NotFoundException * @return string * @since 11.0.0 */ diff --git a/tests/lib/Files/SimpleFS/SimpleFileTest.php b/tests/lib/Files/SimpleFS/SimpleFileTest.php index 4e623eafa22..ab4970804a4 100644 --- a/tests/lib/Files/SimpleFS/SimpleFileTest.php +++ b/tests/lib/Files/SimpleFS/SimpleFileTest.php @@ -24,6 +24,9 @@ namespace Test\File\SimpleFS; use OC\Files\SimpleFS\SimpleFile; use OCP\Files\File; +use OCP\Files\Folder; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; class SimpleFileTest extends \Test\TestCase { /** @var File|\PHPUnit_Framework_MockObject_MockObject */ @@ -101,4 +104,23 @@ class SimpleFileTest extends \Test\TestCase { $this->assertEquals('app/awesome', $this->simpleFile->getMimeType()); } + + public function testGetContentInvalidAppData() { + $this->file->method('getContent') + ->willReturn(false); + $this->file->method('stat')->willReturn(false); + + $parent = $this->createMock(Folder::class); + $parent->method('stat')->willReturn(false); + + $root = $this->createMock(Folder::class); + $root->method('stat')->willReturn([]); + + $this->file->method('getParent')->willReturn($parent); + $parent->method('getParent')->willReturn($root); + + $this->expectException(NotFoundException::class); + + $this->simpleFile->getContent(); + } } |