aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files_external/tests/Storage/SmbTest.php29
-rw-r--r--apps/files_sharing/lib/SharedStorage.php16
-rw-r--r--lib/private/Files/Storage/Wrapper/Wrapper.php11
3 files changed, 48 insertions, 8 deletions
diff --git a/apps/files_external/tests/Storage/SmbTest.php b/apps/files_external/tests/Storage/SmbTest.php
index 30040e499c8..6d21f696683 100644
--- a/apps/files_external/tests/Storage/SmbTest.php
+++ b/apps/files_external/tests/Storage/SmbTest.php
@@ -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() {
diff --git a/apps/files_sharing/lib/SharedStorage.php b/apps/files_sharing/lib/SharedStorage.php
index 35e2c0a7e36..80041afb96c 100644
--- a/apps/files_sharing/lib/SharedStorage.php
+++ b/apps/files_sharing/lib/SharedStorage.php
@@ -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),
diff --git a/lib/private/Files/Storage/Wrapper/Wrapper.php b/lib/private/Files/Storage/Wrapper/Wrapper.php
index 9f5564b4490..665914df2a7 100644
--- a/lib/private/Files/Storage/Wrapper/Wrapper.php
+++ b/lib/private/Files/Storage/Wrapper/Wrapper.php
@@ -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;
+ }
}