summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2019-09-25 19:17:06 +0200
committerRobin Appelman <robin@icewind.nl>2019-09-25 19:17:06 +0200
commit35f317df7b3ad1f92a1e7bb1bb4ff0905d952f46 (patch)
treeaf3f1d6e51df07fe251dbb86c500dc86cb8f73ff /lib
parent507eb30e1d7ab2ea31934796621cd6614c2af750 (diff)
downloadnextcloud-server-35f317df7b3ad1f92a1e7bb1bb4ff0905d952f46.tar.gz
nextcloud-server-35f317df7b3ad1f92a1e7bb1bb4ff0905d952f46.zip
handle moveFromStorage within the same storage even when storage wrappers are applied to the source storage
the target storage doesn't need additional handling for wrappers as the wrappers implementation of moveFromStorage already deals with that Any storage based on local storage isn't affected by this as local storage already has it's own way of handling with this Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Files/Storage/Common.php30
-rw-r--r--lib/private/Files/Storage/Wrapper/Jail.php8
2 files changed, 37 insertions, 1 deletions
diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php
index 4e95c594cfa..2dbaf619c05 100644
--- a/lib/private/Files/Storage/Common.php
+++ b/lib/private/Files/Storage/Common.php
@@ -46,6 +46,8 @@ use OC\Files\Cache\Scanner;
use OC\Files\Cache\Updater;
use OC\Files\Filesystem;
use OC\Files\Cache\Watcher;
+use OC\Files\Storage\Wrapper\Jail;
+use OC\Files\Storage\Wrapper\Wrapper;
use OCP\Files\EmptyFileNameException;
use OCP\Files\FileNameTooLongException;
use OCP\Files\InvalidCharacterInPathException;
@@ -636,13 +638,39 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage {
}
/**
+ * Check if a storage is the same as the current one, including wrapped storages
+ *
+ * @param IStorage $storage
+ * @return bool
+ */
+ private function isSameStorage(IStorage $storage): bool {
+ while ($storage->instanceOfStorage(Wrapper::class)) {
+ /**
+ * @var Wrapper $sourceStorage
+ */
+ $storage = $storage->getWrapperStorage();
+ }
+
+ return $storage === $this;
+ }
+
+ /**
* @param IStorage $sourceStorage
* @param string $sourceInternalPath
* @param string $targetInternalPath
* @return bool
*/
public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- if ($sourceStorage === $this) {
+ if ($this->isSameStorage($sourceStorage)) {
+ // resolve any jailed paths
+ while ($sourceStorage->instanceOfStorage(Jail::class)) {
+ /**
+ * @var Jail $sourceStorage
+ */
+ $sourceInternalPath = $sourceStorage->getUnjailedPath($sourceInternalPath);
+ $sourceStorage = $sourceStorage->getUnjailedStorage();
+ }
+
return $this->rename($sourceInternalPath, $targetInternalPath);
}
diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php
index 3dc2024d912..35bf8449fd7 100644
--- a/lib/private/Files/Storage/Wrapper/Jail.php
+++ b/lib/private/Files/Storage/Wrapper/Jail.php
@@ -62,6 +62,14 @@ class Jail extends Wrapper {
}
}
+ /**
+ * This is separate from Wrapper::getWrapperStorage so we can get the jailed storage consistently even if the jail is inside another wrapper
+ */
+ public function getUnjailedStorage() {
+ return $this->storage;
+ }
+
+
public function getJailedPath($path) {
$root = rtrim($this->rootPath, '/') . '/';