mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #39990 from nextcloud/recursive-share
add some recrusive detection/prevention
This commit is contained in:
commit
b32c0f7da6
3 changed files with 48 additions and 8 deletions
|
|
@ -105,6 +105,7 @@ class SmbTest extends \Test\Files\Storage\Storage {
|
|||
$this->instance->unlink('/renamed.txt');
|
||||
sleep(1); //time for all changes to be processed
|
||||
|
||||
/** @var IChange[] $changes */
|
||||
$changes = [];
|
||||
$count = 0;
|
||||
// wait up to 10 seconds for incoming changes
|
||||
|
|
@ -115,14 +116,23 @@ class SmbTest extends \Test\Files\Storage\Storage {
|
|||
}
|
||||
$notifyHandler->stop();
|
||||
|
||||
$expected = [
|
||||
new Change(IChange::ADDED, 'newfile.txt'),
|
||||
new RenameChange(IChange::RENAMED, 'newfile.txt', 'renamed.txt'),
|
||||
new Change(IChange::REMOVED, 'renamed.txt')
|
||||
];
|
||||
// depending on the server environment, the initial create might be detected as a change instead
|
||||
if ($changes[0]->getType() === IChange::MODIFIED) {
|
||||
$expected = [
|
||||
new Change(IChange::MODIFIED, 'newfile.txt'),
|
||||
new RenameChange(IChange::RENAMED, 'newfile.txt', 'renamed.txt'),
|
||||
new Change(IChange::REMOVED, 'renamed.txt')
|
||||
];
|
||||
} else {
|
||||
$expected = [
|
||||
new Change(IChange::ADDED, 'newfile.txt'),
|
||||
new RenameChange(IChange::RENAMED, 'newfile.txt', 'renamed.txt'),
|
||||
new Change(IChange::REMOVED, 'renamed.txt')
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($expected as $expectedChange) {
|
||||
$this->assertTrue(in_array($expectedChange, $changes), 'Actual changes are:' . PHP_EOL . print_r($changes, true) . PHP_EOL . 'Expected to find: ' . PHP_EOL . print_r($expectedChange, true));
|
||||
$this->assertTrue(in_array($expectedChange, $changes), "Expected changes are:\n" . print_r($expected, true) . PHP_EOL . 'Expected to find: ' . PHP_EOL . print_r($expectedChange, true) . "\nGot:\n" . print_r($changes, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +151,12 @@ class SmbTest extends \Test\Files\Storage\Storage {
|
|||
return false;//stop listening
|
||||
});
|
||||
|
||||
$this->assertEquals(new Change(IChange::ADDED, 'newfile.txt'), $result);
|
||||
// depending on the server environment, the initial create might be detected as a change instead
|
||||
if ($result->getType() === IChange::ADDED) {
|
||||
$this->assertEquals(new Change(IChange::ADDED, 'newfile.txt'), $result);
|
||||
} else {
|
||||
$this->assertEquals(new Change(IChange::MODIFIED, 'newfile.txt'), $result);
|
||||
}
|
||||
}
|
||||
|
||||
public function testRenameRoot() {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ use OC\Files\Storage\Common;
|
|||
use OC\Files\Storage\FailedStorage;
|
||||
use OC\Files\Storage\Home;
|
||||
use OC\Files\Storage\Wrapper\PermissionsMask;
|
||||
use OC\Files\Storage\Wrapper\Wrapper;
|
||||
use OC\User\NoUserException;
|
||||
use OCA\Files_External\Config\ConfigAdapter;
|
||||
use OCP\Constants;
|
||||
|
|
@ -97,6 +98,8 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
|
|||
|
||||
private string $sourcePath = '';
|
||||
|
||||
private static int $initDepth = 0;
|
||||
|
||||
public function __construct($arguments) {
|
||||
$this->ownerView = $arguments['ownerView'];
|
||||
$this->logger = \OC::$server->get(LoggerInterface::class);
|
||||
|
|
@ -136,8 +139,15 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
|
|||
if ($this->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->initialized = true;
|
||||
self::$initDepth++;
|
||||
|
||||
try {
|
||||
if (self::$initDepth > 10) {
|
||||
throw new \Exception("Maximum share depth reached");
|
||||
}
|
||||
|
||||
/** @var IRootFolder $rootFolder */
|
||||
$rootFolder = \OC::$server->get(IRootFolder::class);
|
||||
$this->ownerUserFolder = $rootFolder->getUserFolder($this->superShare->getShareOwner());
|
||||
|
|
@ -148,6 +158,9 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
|
|||
$this->cache = new FailedCache();
|
||||
$this->rootPath = '';
|
||||
} else {
|
||||
if ($this->nonMaskedStorage instanceof Wrapper && $this->nonMaskedStorage->isWrapperOf($this)) {
|
||||
throw new \Exception('recursive share detected');
|
||||
}
|
||||
$this->nonMaskedStorage = $ownerNode->getStorage();
|
||||
$this->sourcePath = $ownerNode->getPath();
|
||||
$this->rootPath = $ownerNode->getInternalPath();
|
||||
|
|
@ -176,6 +189,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
|
|||
if (!$this->nonMaskedStorage) {
|
||||
$this->nonMaskedStorage = $this->storage;
|
||||
}
|
||||
self::$initDepth--;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -409,7 +423,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
|
|||
return new FailedCache();
|
||||
}
|
||||
|
||||
$this->cache = new Cache(
|
||||
$this->cache = new \OCA\Files_Sharing\Cache(
|
||||
$storage,
|
||||
$sourceRoot,
|
||||
\OC::$server->get(CacheDependencies::class),
|
||||
|
|
|
|||
|
|
@ -654,4 +654,15 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea
|
|||
public function getDirectoryContent($directory): \Traversable {
|
||||
return $this->getWrapperStorage()->getDirectoryContent($directory);
|
||||
}
|
||||
|
||||
public function isWrapperOf(IStorage $storage) {
|
||||
$wrapped = $this->getWrapperStorage();
|
||||
if ($wrapped === $storage) {
|
||||
return true;
|
||||
}
|
||||
if ($wrapped instanceof Wrapper) {
|
||||
return $wrapped->isWrapperOf($storage);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue