Merge pull request #8636 from nextcloud/8289_13

[stable13] AppData hardening
This commit is contained in:
Joas Schilling 2018-03-05 12:38:43 +01:00 committed by GitHub
commit 6104a7043e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 1 deletions

View File

@ -23,6 +23,7 @@
namespace OC\Files\SimpleFS; namespace OC\Files\SimpleFS;
use OCP\Files\File; use OCP\Files\File;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException; use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFile; use OCP\Files\SimpleFS\ISimpleFile;
@ -79,10 +80,18 @@ class SimpleFile implements ISimpleFile {
/** /**
* Get the content * Get the content
* *
* @throws NotPermittedException
* @throws NotFoundException
* @return string * @return string
*/ */
public function getContent() { public function getContent() {
return $this->file->getContent(); $result = $this->file->getContent();
if ($result === false) {
$this->checkFile();
}
return $result;
} }
/** /**
@ -95,6 +104,31 @@ class SimpleFile implements ISimpleFile {
$this->file->putContent($data); $this->file->putContent($data);
} }
/**
* 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 * Delete the file
* *

View File

@ -22,6 +22,7 @@
*/ */
namespace OCP\Files\SimpleFS; namespace OCP\Files\SimpleFS;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException; use OCP\Files\NotPermittedException;
/** /**
@ -67,6 +68,8 @@ interface ISimpleFile {
/** /**
* Get the content * Get the content
* *
* @throws NotPermittedException
* @throws NotFoundException
* @return string * @return string
* @since 11.0.0 * @since 11.0.0
*/ */

View File

@ -24,6 +24,9 @@ namespace Test\File\SimpleFS;
use OC\Files\SimpleFS\SimpleFile; use OC\Files\SimpleFS\SimpleFile;
use OCP\Files\File; use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
class SimpleFileTest extends \Test\TestCase { class SimpleFileTest extends \Test\TestCase {
/** @var File|\PHPUnit_Framework_MockObject_MockObject */ /** @var File|\PHPUnit_Framework_MockObject_MockObject */
@ -101,4 +104,23 @@ class SimpleFileTest extends \Test\TestCase {
$this->assertEquals('app/awesome', $this->simpleFile->getMimeType()); $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();
}
} }