|
|
|
|
@ -29,7 +29,9 @@ namespace OC\Files\Node;
|
|
|
|
|
use OC\Files\Utils\PathHelper;
|
|
|
|
|
use OCP\Files\Folder;
|
|
|
|
|
use OCP\Constants;
|
|
|
|
|
use OCP\Files\IRootFolder;
|
|
|
|
|
use OCP\Files\Mount\IMountPoint;
|
|
|
|
|
use OCP\Files\NotPermittedException;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Class LazyFolder
|
|
|
|
|
@ -41,23 +43,33 @@ use OCP\Files\Mount\IMountPoint;
|
|
|
|
|
*/
|
|
|
|
|
class LazyFolder implements Folder {
|
|
|
|
|
/** @var \Closure(): Folder */
|
|
|
|
|
private $folderClosure;
|
|
|
|
|
|
|
|
|
|
/** @var LazyFolder | null */
|
|
|
|
|
protected $folder = null;
|
|
|
|
|
|
|
|
|
|
private \Closure $folderClosure;
|
|
|
|
|
protected ?Folder $folder = null;
|
|
|
|
|
protected IRootFolder $rootFolder;
|
|
|
|
|
protected array $data;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* LazyFolder constructor.
|
|
|
|
|
*
|
|
|
|
|
* @param IRootFolder $rootFolder
|
|
|
|
|
* @param \Closure(): Folder $folderClosure
|
|
|
|
|
* @param array $data
|
|
|
|
|
*/
|
|
|
|
|
public function __construct(\Closure $folderClosure, array $data = []) {
|
|
|
|
|
public function __construct(IRootFolder $rootFolder, \Closure $folderClosure, array $data = []) {
|
|
|
|
|
$this->rootFolder = $rootFolder;
|
|
|
|
|
$this->folderClosure = $folderClosure;
|
|
|
|
|
$this->data = $data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function getRootFolder(): IRootFolder {
|
|
|
|
|
return $this->rootFolder;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function getRealFolder(): Folder {
|
|
|
|
|
if ($this->folder === null) {
|
|
|
|
|
$this->folder = call_user_func($this->folderClosure);
|
|
|
|
|
}
|
|
|
|
|
return $this->folder;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Magic method to first get the real rootFolder and then
|
|
|
|
|
* call $method with $args on it
|
|
|
|
|
@ -67,11 +79,7 @@ class LazyFolder implements Folder {
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
public function __call($method, $args) {
|
|
|
|
|
if ($this->folder === null) {
|
|
|
|
|
$this->folder = call_user_func($this->folderClosure);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return call_user_func_array([$this->folder, $method], $args);
|
|
|
|
|
return call_user_func_array([$this->getRealFolder(), $method], $args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -148,7 +156,7 @@ class LazyFolder implements Folder {
|
|
|
|
|
* @inheritDoc
|
|
|
|
|
*/
|
|
|
|
|
public function get($path) {
|
|
|
|
|
return $this->__call(__FUNCTION__, func_get_args());
|
|
|
|
|
return $this->getRootFolder()->get($this->getFullPath($path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -408,9 +416,23 @@ class LazyFolder implements Folder {
|
|
|
|
|
* @inheritDoc
|
|
|
|
|
*/
|
|
|
|
|
public function getFullPath($path) {
|
|
|
|
|
if (isset($this->data['path'])) {
|
|
|
|
|
$path = PathHelper::normalizePath($path);
|
|
|
|
|
if (!$this->isValidPath($path)) {
|
|
|
|
|
throw new NotPermittedException('Invalid path "' . $path . '"');
|
|
|
|
|
}
|
|
|
|
|
return $this->data['path'] . $path;
|
|
|
|
|
}
|
|
|
|
|
return $this->__call(__FUNCTION__, func_get_args());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function isValidPath($path) {
|
|
|
|
|
if (!str_starts_with($path, '/')) {
|
|
|
|
|
$path = '/' . $path;
|
|
|
|
|
}
|
|
|
|
|
return !(str_contains($path, '/../') || strrchr($path, '/') === '/..');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @inheritDoc
|
|
|
|
|
*/
|
|
|
|
|
|