diff options
author | Côme Chilliet <91878298+come-nc@users.noreply.github.com> | 2023-04-05 10:14:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-05 10:14:55 +0200 |
commit | 8f550398c4c882eed00f09d8e40b074183b8aa93 (patch) | |
tree | 44d5c2d89124844c7a0941373a23c4b3a43ba412 /lib | |
parent | 88ab6d452b45c6d80f3bd84f919453286273e5e7 (diff) | |
parent | 6633b4ced65f97495b1c123a9283c6f187debf41 (diff) | |
download | nextcloud-server-8f550398c4c882eed00f09d8e40b074183b8aa93.tar.gz nextcloud-server-8f550398c4c882eed00f09d8e40b074183b8aa93.zip |
Merge pull request #36836 from nextcloud/fix/view-type-cleanup
Tidy up typing in OC\Files\View
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Files/FileInfo.php | 36 | ||||
-rw-r--r-- | lib/private/Files/Filesystem.php | 90 | ||||
-rw-r--r-- | lib/private/Files/Node/File.php | 2 | ||||
-rw-r--r-- | lib/private/Files/SimpleFS/NewSimpleFile.php | 2 | ||||
-rw-r--r-- | lib/private/Files/SimpleFS/SimpleFile.php | 2 | ||||
-rw-r--r-- | lib/private/Files/Storage/FailedStorage.php | 4 | ||||
-rw-r--r-- | lib/private/Files/Storage/Local.php | 4 | ||||
-rw-r--r-- | lib/private/Files/Storage/LocalTempFileTrait.php | 16 | ||||
-rw-r--r-- | lib/private/Files/Storage/Wrapper/Encoding.php | 6 | ||||
-rw-r--r-- | lib/private/Files/Storage/Wrapper/EncodingDirectoryWrapper.php | 2 | ||||
-rw-r--r-- | lib/private/Files/Storage/Wrapper/Jail.php | 6 | ||||
-rw-r--r-- | lib/private/Files/Storage/Wrapper/Wrapper.php | 6 | ||||
-rw-r--r-- | lib/private/Files/View.php | 299 | ||||
-rw-r--r-- | lib/private/Security/CertificateManager.php | 30 | ||||
-rw-r--r-- | lib/private/Server.php | 2 | ||||
-rw-r--r-- | lib/public/Files/File.php | 2 | ||||
-rw-r--r-- | lib/public/Files/FileInfo.php | 2 | ||||
-rw-r--r-- | lib/public/Files/SimpleFS/ISimpleFile.php | 2 | ||||
-rw-r--r-- | lib/public/Files/Storage.php | 8 | ||||
-rw-r--r-- | lib/public/Files/Storage/IStorage.php | 6 |
20 files changed, 204 insertions, 323 deletions
diff --git a/lib/private/Files/FileInfo.php b/lib/private/Files/FileInfo.php index b94be4c5497..d9b773cc2a6 100644 --- a/lib/private/Files/FileInfo.php +++ b/lib/private/Files/FileInfo.php @@ -37,13 +37,9 @@ use OCP\Files\Mount\IMountPoint; use OCP\IUser; class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { + private array|ICacheEntry $data; /** - * @var array $data - */ - private $data; - - /** - * @var string $path + * @var string */ private $path; @@ -53,7 +49,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { private $storage; /** - * @var string $internalPath + * @var string */ private $internalPath; @@ -62,22 +58,19 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { */ private $mount; - /** - * @var IUser - */ - private $owner; + private ?IUser $owner; /** * @var string[] */ - private $childEtags = []; + private array $childEtags = []; /** * @var IMountPoint[] */ - private $subMounts = []; + private array $subMounts = []; - private $subMountsUsed = false; + private bool $subMountsUsed = false; /** * The size of the file/folder without any sub mount @@ -89,8 +82,8 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { * @param Storage\Storage $storage * @param string $internalPath * @param array|ICacheEntry $data - * @param \OCP\Files\Mount\IMountPoint $mount - * @param \OCP\IUser|null $owner + * @param IMountPoint $mount + * @param ?IUser $owner */ public function __construct($path, $storage, $internalPath, $data, $mount, $owner = null) { $this->path = $path; @@ -107,6 +100,9 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { } public function offsetSet($offset, $value): void { + if (is_null($offset)) { + throw new \TypeError('Null offset not supported'); + } $this->data[$offset] = $value; } @@ -239,10 +235,8 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { /** * Return the currently version used for the HMAC in the encryption app - * - * @return int */ - public function getEncryptedVersion() { + public function getEncryptedVersion(): int { return isset($this->data['encryptedVersion']) ? (int) $this->data['encryptedVersion'] : 1; } @@ -357,7 +351,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { /** * Get the owner of the file * - * @return \OCP\IUser + * @return ?IUser */ public function getOwner() { return $this->owner; @@ -370,7 +364,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { $this->subMounts = $mounts; } - private function updateEntryfromSubMounts() { + private function updateEntryfromSubMounts(): void { if ($this->subMountsUsed) { return; } diff --git a/lib/private/Files/Filesystem.php b/lib/private/Files/Filesystem.php index 500a13b1f9d..367982eed72 100644 --- a/lib/private/Files/Filesystem.php +++ b/lib/private/Files/Filesystem.php @@ -42,6 +42,7 @@ use OC\Files\Mount\MountPoint; use OC\User\NoUserException; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Events\Node\FilesystemTornDownEvent; +use OCP\Files\Mount\IMountManager; use OCP\Files\NotFoundException; use OCP\Files\Storage\IStorageFactory; use OCP\IUser; @@ -49,25 +50,16 @@ use OCP\IUserManager; use OCP\IUserSession; class Filesystem { - /** - * @var Mount\Manager $mounts - */ - private static $mounts; + private static ?Mount\Manager $mounts = null; - public static $loaded = false; - /** - * @var \OC\Files\View $defaultInstance - */ - private static $defaultInstance; + public static bool $loaded = false; - private static $usersSetup = []; + private static ?View $defaultInstance = null; - private static $normalizedPathCache = null; - - private static $listeningForProviders = false; + private static ?CappedMemoryCache $normalizedPathCache = null; /** @var string[]|null */ - private static $blacklist = null; + private static ?array $blacklist = null; /** * classname which used for hooks handling @@ -186,22 +178,18 @@ class Filesystem { public const signal_param_mount_type = 'mounttype'; public const signal_param_users = 'users'; - /** - * @var \OC\Files\Storage\StorageFactory $loader - */ - private static $loader; + private static ?\OC\Files\Storage\StorageFactory $loader = null; - /** @var bool */ - private static $logWarningWhenAddingStorageWrapper = true; + private static bool $logWarningWhenAddingStorageWrapper = true; /** * @param bool $shouldLog * @return bool previous value * @internal */ - public static function logWarningWhenAddingStorageWrapper($shouldLog) { + public static function logWarningWhenAddingStorageWrapper(bool $shouldLog): bool { $previousValue = self::$logWarningWhenAddingStorageWrapper; - self::$logWarningWhenAddingStorageWrapper = (bool) $shouldLog; + self::$logWarningWhenAddingStorageWrapper = $shouldLog; return $previousValue; } @@ -232,18 +220,17 @@ class Filesystem { */ public static function getLoader() { if (!self::$loader) { - self::$loader = \OC::$server->query(IStorageFactory::class); + self::$loader = \OC::$server->get(IStorageFactory::class); } return self::$loader; } /** * Returns the mount manager - * - * @return \OC\Files\Mount\Manager */ - public static function getMountManager($user = '') { + public static function getMountManager(): Mount\Manager { self::initMountManager(); + assert(self::$mounts !== null); return self::$mounts; } @@ -313,14 +300,14 @@ class Filesystem { * resolve a path to a storage and internal path * * @param string $path - * @return array an array consisting of the storage and the internal path + * @return array{?\OCP\Files\Storage\IStorage, string} an array consisting of the storage and the internal path */ - public static function resolvePath($path) { + public static function resolvePath($path): array { $mount = self::getMountManager()->find($path); return [$mount->getStorage(), rtrim($mount->getInternalPath($path), '/')]; } - public static function init($user, $root) { + public static function init(string|IUser|null $user, string $root): bool { if (self::$defaultInstance) { return false; } @@ -332,7 +319,7 @@ class Filesystem { return true; } - public static function initInternal($root) { + public static function initInternal(string $root): bool { if (self::$defaultInstance) { return false; } @@ -342,32 +329,28 @@ class Filesystem { $eventDispatcher = \OC::$server->get(IEventDispatcher::class); $eventDispatcher->addListener(FilesystemTornDownEvent::class, function () { self::$defaultInstance = null; - self::$usersSetup = []; self::$loaded = false; }); - if (!self::$mounts) { - self::$mounts = \OC::$server->getMountManager(); - } + self::initMountManager(); self::$loaded = true; return true; } - public static function initMountManager() { + public static function initMountManager(): void { if (!self::$mounts) { - self::$mounts = \OC::$server->getMountManager(); + self::$mounts = \OC::$server->get(IMountManager::class); } } /** * Initialize system and personal mount points for a user * - * @param string|IUser|null $user * @throws \OC\User\NoUserException if the user is not available */ - public static function initMountPoints($user = '') { + public static function initMountPoints(string|IUser|null $user = ''): void { /** @var IUserManager $userManager */ $userManager = \OC::$server->get(IUserManager::class); @@ -382,11 +365,9 @@ class Filesystem { } /** - * get the default filesystem view - * - * @return View + * Get the default filesystem view */ - public static function getView() { + public static function getView(): ?View { if (!self::$defaultInstance) { /** @var IUserSession $session */ $session = \OC::$server->get(IUserSession::class); @@ -409,7 +390,7 @@ class Filesystem { /** * get the relative path of the root data directory for the current user * - * @return string + * @return ?string * * Returns path like /admin/files */ @@ -439,23 +420,12 @@ class Filesystem { * return the path to a local version of the file * we need this because we can't know if a file is stored local or not from * outside the filestorage and for some purposes a local file is needed - * - * @param string $path - * @return string */ - public static function getLocalFile($path) { + public static function getLocalFile(string $path): string|false { return self::$defaultInstance->getLocalFile($path); } /** - * @param string $path - * @return string - */ - public static function getLocalFolder($path) { - return self::$defaultInstance->getLocalFolder($path); - } - - /** * return path to file which reflects one visible in browser * * @param string $path @@ -611,9 +581,10 @@ class Filesystem { } /** - * @return string + * @param string $path + * @throws \OCP\Files\InvalidPathException */ - public static function toTmpFile($path) { + public static function toTmpFile($path): string|false { return self::$defaultInstance->toTmpFile($path); } @@ -787,11 +758,8 @@ class Filesystem { /** * get the ETag for a file or folder - * - * @param string $path - * @return string */ - public static function getETag($path) { + public static function getETag(string $path): string|false { return self::$defaultInstance->getETag($path); } } diff --git a/lib/private/Files/Node/File.php b/lib/private/Files/Node/File.php index 475930b361a..27056efef72 100644 --- a/lib/private/Files/Node/File.php +++ b/lib/private/Files/Node/File.php @@ -80,7 +80,7 @@ class File extends Node implements \OCP\Files\File { /** * @param string $mode - * @return resource + * @return resource|false * @throws NotPermittedException * @throws LockedException */ diff --git a/lib/private/Files/SimpleFS/NewSimpleFile.php b/lib/private/Files/SimpleFS/NewSimpleFile.php index 1d0972bcc54..50511b5a5f9 100644 --- a/lib/private/Files/SimpleFS/NewSimpleFile.php +++ b/lib/private/Files/SimpleFS/NewSimpleFile.php @@ -196,7 +196,7 @@ class NewSimpleFile implements ISimpleFile { /** * Open the file as stream for reading, resulting resource can be operated as stream like the result from php's own fopen * - * @return resource + * @return resource|false * @throws \OCP\Files\NotPermittedException * @since 14.0.0 */ diff --git a/lib/private/Files/SimpleFS/SimpleFile.php b/lib/private/Files/SimpleFS/SimpleFile.php index 95ef332e2f5..76ab06feaab 100644 --- a/lib/private/Files/SimpleFS/SimpleFile.php +++ b/lib/private/Files/SimpleFS/SimpleFile.php @@ -150,7 +150,7 @@ class SimpleFile implements ISimpleFile { /** * Open the file as stream for reading, resulting resource can be operated as stream like the result from php's own fopen * - * @return resource + * @return resource|false * @throws \OCP\Files\NotPermittedException * @since 14.0.0 */ diff --git a/lib/private/Files/Storage/FailedStorage.php b/lib/private/Files/Storage/FailedStorage.php index ceb802570bf..07b3b21d965 100644 --- a/lib/private/Files/Storage/FailedStorage.php +++ b/lib/private/Files/Storage/FailedStorage.php @@ -164,10 +164,6 @@ class FailedStorage extends Common { throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e); } - public function getLocalFolder($path) { - throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e); - } - public function hasUpdated($path, $time) { throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e); } diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php index 1ff733e0d92..448346e5622 100644 --- a/lib/private/Files/Storage/Local.php +++ b/lib/private/Files/Storage/Local.php @@ -433,10 +433,6 @@ class Local extends \OC\Files\Storage\Common { return $this->getSourcePath($path); } - public function getLocalFolder($path) { - return $this->getSourcePath($path); - } - /** * @param string $query * @param string $dir diff --git a/lib/private/Files/Storage/LocalTempFileTrait.php b/lib/private/Files/Storage/LocalTempFileTrait.php index 2ac0a74b692..314e38cb277 100644 --- a/lib/private/Files/Storage/LocalTempFileTrait.php +++ b/lib/private/Files/Storage/LocalTempFileTrait.php @@ -35,14 +35,10 @@ namespace OC\Files\Storage; * in classes which extend it, e.g. $this->stat() . */ trait LocalTempFileTrait { - /** @var string[] */ - protected $cachedFiles = []; + /** @var array<string,string|false> */ + protected array $cachedFiles = []; - /** - * @param string $path - * @return string - */ - protected function getCachedFile($path) { + protected function getCachedFile(string $path): string|false { if (!isset($this->cachedFiles[$path])) { $this->cachedFiles[$path] = $this->toTmpFile($path); } @@ -56,11 +52,7 @@ trait LocalTempFileTrait { unset($this->cachedFiles[$path]); } - /** - * @param string $path - * @return string - */ - protected function toTmpFile($path) { //no longer in the storage api, still useful here + protected function toTmpFile(string $path): string|false { //no longer in the storage api, still useful here $source = $this->fopen($path, 'r'); if (!$source) { return false; diff --git a/lib/private/Files/Storage/Wrapper/Encoding.php b/lib/private/Files/Storage/Wrapper/Encoding.php index d6006f746ad..dd699993e84 100644 --- a/lib/private/Files/Storage/Wrapper/Encoding.php +++ b/lib/private/Files/Storage/Wrapper/Encoding.php @@ -159,7 +159,7 @@ class Encoding extends Wrapper { * see https://www.php.net/manual/en/function.opendir.php * * @param string $path - * @return resource|bool + * @return resource|false */ public function opendir($path) { $handle = $this->storage->opendir($this->findPathToUse($path)); @@ -429,7 +429,7 @@ class Encoding extends Wrapper { * The local version of the file can be temporary and doesn't have to be persistent across requests * * @param string $path - * @return string|bool + * @return string|false */ public function getLocalFile($path) { return $this->storage->getLocalFile($this->findPathToUse($path)); @@ -481,7 +481,7 @@ class Encoding extends Wrapper { * get the ETag for a file or folder * * @param string $path - * @return string|bool + * @return string|false */ public function getETag($path) { return $this->storage->getETag($this->findPathToUse($path)); diff --git a/lib/private/Files/Storage/Wrapper/EncodingDirectoryWrapper.php b/lib/private/Files/Storage/Wrapper/EncodingDirectoryWrapper.php index fd0d2707f8d..3cda399f22d 100644 --- a/lib/private/Files/Storage/Wrapper/EncodingDirectoryWrapper.php +++ b/lib/private/Files/Storage/Wrapper/EncodingDirectoryWrapper.php @@ -46,7 +46,7 @@ class EncodingDirectoryWrapper extends DirectoryWrapper { /** * @param resource $source * @param callable $filter - * @return resource|bool + * @return resource|false */ public static function wrap($source) { return self::wrapSource($source, [ diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php index e21a2cba244..619d8b07137 100644 --- a/lib/private/Files/Storage/Wrapper/Jail.php +++ b/lib/private/Files/Storage/Wrapper/Jail.php @@ -108,7 +108,7 @@ class Jail extends Wrapper { * see https://www.php.net/manual/en/function.opendir.php * * @param string $path - * @return resource|bool + * @return resource|false */ public function opendir($path) { return $this->getWrapperStorage()->opendir($this->getUnjailedPath($path)); @@ -368,7 +368,7 @@ class Jail extends Wrapper { * The local version of the file can be temporary and doesn't have to be persistent across requests * * @param string $path - * @return string|bool + * @return string|false */ public function getLocalFile($path) { return $this->getWrapperStorage()->getLocalFile($this->getUnjailedPath($path)); @@ -431,7 +431,7 @@ class Jail extends Wrapper { * get the ETag for a file or folder * * @param string $path - * @return string|bool + * @return string|false */ public function getETag($path) { return $this->getWrapperStorage()->getETag($this->getUnjailedPath($path)); diff --git a/lib/private/Files/Storage/Wrapper/Wrapper.php b/lib/private/Files/Storage/Wrapper/Wrapper.php index c2d382f5dfc..28a1e0b1e4d 100644 --- a/lib/private/Files/Storage/Wrapper/Wrapper.php +++ b/lib/private/Files/Storage/Wrapper/Wrapper.php @@ -98,7 +98,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea * see https://www.php.net/manual/en/function.opendir.php * * @param string $path - * @return resource|bool + * @return resource|false */ public function opendir($path) { return $this->getWrapperStorage()->opendir($path); @@ -358,7 +358,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea * The local version of the file can be temporary and doesn't have to be persistent across requests * * @param string $path - * @return string|bool + * @return string|false */ public function getLocalFile($path) { return $this->getWrapperStorage()->getLocalFile($path); @@ -456,7 +456,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea * get the ETag for a file or folder * * @param string $path - * @return string|bool + * @return string|false */ public function getETag($path) { return $this->getWrapperStorage()->getETag($path); diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index 1bd131303e3..91e6cc2d60e 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -52,6 +52,7 @@ use OC\Files\Storage\Storage; use OC\User\LazyUser; use OC\Share\Share; use OC\User\User; +use OC\User\Manager as UserManager; use OCA\Files_Sharing\SharedMount; use OCP\Constants; use OCP\Files\Cache\ICacheEntry; @@ -86,31 +87,17 @@ use Psr\Log\LoggerInterface; * \OC\Files\Storage\Storage object */ class View { - /** @var string */ - private $fakeRoot = ''; - - /** - * @var \OCP\Lock\ILockingProvider - */ - protected $lockingProvider; - - private $lockingEnabled; - - private $updaterEnabled = true; - - /** @var \OC\User\Manager */ - private $userManager; - + private string $fakeRoot = ''; + private ILockingProvider $lockingProvider; + private bool $lockingEnabled; + private bool $updaterEnabled = true; + private UserManager $userManager; private LoggerInterface $logger; /** - * @param string $root * @throws \Exception If $root contains an invalid path */ - public function __construct($root = '') { - if (is_null($root)) { - throw new \InvalidArgumentException('Root can\'t be null'); - } + public function __construct(string $root = '') { if (!Filesystem::isValidPath($root)) { throw new \Exception(); } @@ -122,7 +109,13 @@ class View { $this->logger = \OC::$server->get(LoggerInterface::class); } - public function getAbsolutePath($path = '/') { + /** + * @param ?string $path + * @psalm-template S as string|null + * @psalm-param S $path + * @psalm-return (S is string ? string : null) + */ + public function getAbsolutePath($path = '/'): ?string { if ($path === null) { return null; } @@ -137,12 +130,11 @@ class View { } /** - * change the root to a fake root + * Change the root to a fake root * * @param string $fakeRoot - * @return boolean|null */ - public function chroot($fakeRoot) { + public function chroot($fakeRoot): void { if (!$fakeRoot == '') { if ($fakeRoot[0] !== '/') { $fakeRoot = '/' . $fakeRoot; @@ -152,11 +144,9 @@ class View { } /** - * get the fake root - * - * @return string + * Get the fake root */ - public function getRoot() { + public function getRoot(): string { return $this->fakeRoot; } @@ -164,9 +154,8 @@ class View { * get path relative to the root of the view * * @param string $path - * @return ?string */ - public function getRelativePath($path) { + public function getRelativePath($path): ?string { $this->assertPathLength($path); if ($this->fakeRoot == '') { return $path; @@ -192,74 +181,56 @@ class View { } /** - * get the mountpoint of the storage object for a path + * Get the mountpoint of the storage object for a path * ( note: because a storage is not always mounted inside the fakeroot, the * returned mountpoint is relative to the absolute root of the filesystem * and does not take the chroot into account ) * * @param string $path - * @return string */ - public function getMountPoint($path) { + public function getMountPoint($path): string { return Filesystem::getMountPoint($this->getAbsolutePath($path)); } /** - * get the mountpoint of the storage object for a path + * Get the mountpoint of the storage object for a path * ( note: because a storage is not always mounted inside the fakeroot, the * returned mountpoint is relative to the absolute root of the filesystem * and does not take the chroot into account ) * * @param string $path - * @return \OCP\Files\Mount\IMountPoint */ - public function getMount($path) { + public function getMount($path): IMountPoint { return Filesystem::getMountManager()->find($this->getAbsolutePath($path)); } /** - * resolve a path to a storage and internal path + * Resolve a path to a storage and internal path * * @param string $path - * @return array an array consisting of the storage and the internal path + * @return array{?\OCP\Files\Storage\IStorage, string} an array consisting of the storage and the internal path */ - public function resolvePath($path) { + public function resolvePath($path): array { $a = $this->getAbsolutePath($path); $p = Filesystem::normalizePath($a); return Filesystem::resolvePath($p); } /** - * return the path to a local version of the file + * Return the path to a local version of the file * we need this because we can't know if a file is stored local or not from * outside the filestorage and for some purposes a local file is needed * * @param string $path - * @return string */ - public function getLocalFile($path) { - $parent = substr($path, 0, strrpos($path, '/')); + public function getLocalFile($path): string|false { + $parent = substr($path, 0, strrpos($path, '/') ?: 0); $path = $this->getAbsolutePath($path); [$storage, $internalPath] = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFile($internalPath); } else { - return null; - } - } - - /** - * @param string $path - * @return string - */ - public function getLocalFolder($path) { - $parent = substr($path, 0, strrpos($path, '/')); - $path = $this->getAbsolutePath($path); - [$storage, $internalPath] = Filesystem::resolvePath($path); - if (Filesystem::isValidPath($parent) and $storage) { - return $storage->getLocalFolder($internalPath); - } else { - return null; + return false; } } @@ -277,9 +248,8 @@ class View { * * @param IMountPoint $mount * @param string $path relative to data/ - * @return boolean */ - protected function removeMount($mount, $path) { + protected function removeMount($mount, $path): bool { if ($mount instanceof MoveableMount) { // cut of /user/files to get the relative path to data/user/files $pathParts = explode('/', $path, 4); @@ -308,15 +278,15 @@ class View { } } - public function disableCacheUpdate() { + public function disableCacheUpdate(): void { $this->updaterEnabled = false; } - public function enableCacheUpdate() { + public function enableCacheUpdate(): void { $this->updaterEnabled = true; } - protected function writeUpdate(Storage $storage, $internalPath, $time = null) { + protected function writeUpdate(Storage $storage, string $internalPath, ?int $time = null): void { if ($this->updaterEnabled) { if (is_null($time)) { $time = time(); @@ -325,13 +295,13 @@ class View { } } - protected function removeUpdate(Storage $storage, $internalPath) { + protected function removeUpdate(Storage $storage, string $internalPath): void { if ($this->updaterEnabled) { $storage->getUpdater()->remove($internalPath); } } - protected function renameUpdate(Storage $sourceStorage, Storage $targetStorage, $sourceInternalPath, $targetInternalPath) { + protected function renameUpdate(Storage $sourceStorage, Storage $targetStorage, string $sourceInternalPath, string $targetInternalPath): void { if ($this->updaterEnabled) { $targetStorage->getUpdater()->renameFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } @@ -363,7 +333,7 @@ class View { /** * @param string $path - * @return resource + * @return resource|false */ public function opendir($path) { return $this->basicOperation('opendir', $path, ['read']); @@ -418,7 +388,7 @@ class View { /** * @param string $path * @return bool|mixed - * @throws \OCP\Files\InvalidPathException + * @throws InvalidPathException */ public function readfile($path) { $this->assertPathLength($path); @@ -443,7 +413,7 @@ class View { * @param int $from * @param int $to * @return bool|mixed - * @throws \OCP\Files\InvalidPathException + * @throws InvalidPathException * @throws \OCP\Files\UnseekableException */ public function readfilePart($path, $from, $to) { @@ -559,9 +529,8 @@ class View { /** * @param string $path * @param int|string $mtime - * @return bool */ - public function touch($path, $mtime = null) { + public function touch($path, $mtime = null): bool { if (!is_null($mtime) and !is_numeric($mtime)) { $mtime = strtotime($mtime); } @@ -602,12 +571,7 @@ class View { return $this->basicOperation('file_get_contents', $path, ['read']); } - /** - * @param bool $exists - * @param string $path - * @param bool $run - */ - protected function emit_file_hooks_pre($exists, $path, &$run) { + protected function emit_file_hooks_pre(bool $exists, string $path, bool &$run): void { if (!$exists) { \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_create, [ Filesystem::signal_param_path => $this->getHookPath($path), @@ -625,11 +589,7 @@ class View { ]); } - /** - * @param bool $exists - * @param string $path - */ - protected function emit_file_hooks_post($exists, $path) { + protected function emit_file_hooks_post(bool $exists, string $path): void { if (!$exists) { \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_create, [ Filesystem::signal_param_path => $this->getHookPath($path), @@ -657,6 +617,9 @@ class View { and !Filesystem::isFileBlacklisted($path) ) { $path = $this->getRelativePath($absolutePath); + if ($path === null) { + throw new InvalidPathException("Path $absolutePath is not in the expected root"); + } $this->lockFile($path, ILockingProvider::LOCK_SHARED); @@ -678,7 +641,7 @@ class View { throw $e; } - /** @var \OC\Files\Storage\Storage $storage */ + /** @var Storage $storage */ [$storage, $internalPath] = $this->resolvePath($path); $target = $storage->fopen($internalPath, 'w'); if ($target) { @@ -973,7 +936,7 @@ class View { /** * @param string $path * @param string $mode 'r' or 'w' - * @return resource + * @return resource|false * @throws LockedException */ public function fopen($path, $mode) { @@ -1018,10 +981,9 @@ class View { /** * @param string $path - * @return bool|string - * @throws \OCP\Files\InvalidPathException + * @throws InvalidPathException */ - public function toTmpFile($path) { + public function toTmpFile($path): string|false { $this->assertPathLength($path); if (Filesystem::isValidPath($path)) { $source = $this->fopen($path, 'r'); @@ -1042,7 +1004,7 @@ class View { * @param string $tmpFile * @param string $path * @return bool|mixed - * @throws \OCP\Files\InvalidPathException + * @throws InvalidPathException */ public function fromTmpFile($tmpFile, $path) { $this->assertPathLength($path); @@ -1061,9 +1023,12 @@ class View { $source = fopen($tmpFile, 'r'); if ($source) { $result = $this->file_put_contents($path, $source); - // $this->file_put_contents() might have already closed - // the resource, so we check it, before trying to close it - // to avoid messages in the error log. + /** + * $this->file_put_contents() might have already closed + * the resource, so we check it, before trying to close it + * to avoid messages in the error log. + * @psalm-suppress RedundantCondition false-positive + */ if (is_resource($source)) { fclose($source); } @@ -1081,7 +1046,7 @@ class View { /** * @param string $path * @return mixed - * @throws \OCP\Files\InvalidPathException + * @throws InvalidPathException */ public function getMimeType($path) { $this->assertPathLength($path); @@ -1092,9 +1057,8 @@ class View { * @param string $type * @param string $path * @param bool $raw - * @return bool|string */ - public function hash($type, $path, $raw = false) { + public function hash($type, $path, $raw = false): string|bool { $postFix = (substr($path, -1) === '/') ? '/' : ''; $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); if (Filesystem::isValidPath($path)) { @@ -1121,7 +1085,7 @@ class View { /** * @param string $path * @return mixed - * @throws \OCP\Files\InvalidPathException + * @throws InvalidPathException */ public function free_space($path = '/') { $this->assertPathLength($path); @@ -1135,9 +1099,6 @@ class View { /** * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage * - * @param string $operation - * @param string $path - * @param array $hooks (optional) * @param mixed $extraParam (optional) * @return mixed * @throws LockedException @@ -1146,7 +1107,7 @@ class View { * files), processes hooks and proxies, sanitises paths, and finally passes them on to * \OC\Files\Storage\Storage for delegation to a storage backend for execution */ - private function basicOperation($operation, $path, $hooks = [], $extraParam = null) { + private function basicOperation(string $operation, string $path, array $hooks = [], $extraParam = null) { $postFix = (substr($path, -1) === '/') ? '/' : ''; $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); if (Filesystem::isValidPath($path) @@ -1163,9 +1124,9 @@ class View { } $run = $this->runHooks($hooks, $path); - /** @var \OC\Files\Storage\Storage $storage */ [$storage, $internalPath] = Filesystem::resolvePath($absolutePath . $postFix); if ($run and $storage) { + /** @var Storage $storage */ if (in_array('write', $hooks) || in_array('delete', $hooks)) { try { $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE); @@ -1243,14 +1204,15 @@ class View { * @param string $path * @return ?string */ - private function getHookPath($path) { - if (!Filesystem::getView()) { + private function getHookPath($path): ?string { + $view = Filesystem::getView(); + if (!$view) { return $path; } - return Filesystem::getView()->getRelativePath($this->getAbsolutePath($path)); + return $view->getRelativePath($this->getAbsolutePath($path)); } - private function shouldEmitHooks($path = '') { + private function shouldEmitHooks(string $path = ''): bool { if ($path && Cache\Scanner::isPartialFile($path)) { return false; } @@ -1334,7 +1296,7 @@ class View { * If the file is not in cached it will be scanned * If the file has changed on storage the cache will be updated * - * @param \OC\Files\Storage\Storage $storage + * @param Storage $storage * @param string $internalPath * @param string $relativePath * @return ICacheEntry|bool @@ -1585,7 +1547,7 @@ class View { } $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** - * @var \OC\Files\Storage\Storage $storage + * @var Storage $storage * @var string $internalPath */ [$storage, $internalPath] = Filesystem::resolvePath($path); @@ -1719,18 +1681,14 @@ class View { * get the ETag for a file or folder * * @param string $path - * @return string + * @return string|false */ public function getETag($path) { - /** - * @var Storage\Storage $storage - * @var string $internalPath - */ [$storage, $internalPath] = $this->resolvePath($path); if ($storage) { return $storage->getETag($internalPath); } else { - return null; + return false; } } @@ -1788,13 +1746,13 @@ class View { * @param string $path * @throws InvalidPathException */ - private function assertPathLength($path) { + private function assertPathLength($path): void { $maxLen = min(PHP_MAXPATHLEN, 4000); // Check for the string length - performed using isset() instead of strlen() // because isset() is about 5x-40x faster. if (isset($path[$maxLen])) { $pathLen = strlen($path); - throw new \OCP\Files\InvalidPathException("Path length($pathLen) exceeds max path length($maxLen): $path"); + throw new InvalidPathException("Path length($pathLen) exceeds max path length($maxLen): $path"); } } @@ -1802,23 +1760,19 @@ class View { * check if it is allowed to move a mount point to a given target. * It is not allowed to move a mount point into a different mount point or * into an already shared folder - * - * @param IStorage $targetStorage - * @param string $targetInternalPath - * @return boolean */ - private function targetIsNotShared(IStorage $targetStorage, string $targetInternalPath) { + private function targetIsNotShared(IStorage $targetStorage, string $targetInternalPath): bool { // note: cannot use the view because the target is already locked - $fileId = (int)$targetStorage->getCache()->getId($targetInternalPath); + $fileId = $targetStorage->getCache()->getId($targetInternalPath); if ($fileId === -1) { // target might not exist, need to check parent instead - $fileId = (int)$targetStorage->getCache()->getId(dirname($targetInternalPath)); + $fileId = $targetStorage->getCache()->getId(dirname($targetInternalPath)); } // check if any of the parents were shared by the current owner (include collections) $shares = Share::getItemShared( 'folder', - $fileId, + (string)$fileId, \OC\Share\Constants::FORMAT_NONE, null, true @@ -1836,11 +1790,8 @@ class View { /** * Get a fileinfo object for files that are ignored in the cache (part files) - * - * @param string $path - * @return \OCP\Files\FileInfo */ - private function getPartFileInfo($path) { + private function getPartFileInfo(string $path): \OC\Files\FileInfo { $mount = $this->getMount($path); $storage = $mount->getStorage(); $internalPath = $mount->getInternalPath($this->getAbsolutePath($path)); @@ -1869,7 +1820,7 @@ class View { * @param string $fileName * @throws InvalidPathException */ - public function verifyPath($path, $fileName) { + public function verifyPath($path, $fileName): void { try { /** @type \OCP\Files\Storage $storage */ [$storage, $internalPath] = $this->resolvePath($path); @@ -1927,7 +1878,7 @@ class View { * is mounted directly on the given path, false otherwise * @return IMountPoint mount point for which to apply locks */ - private function getMountForLock($absolutePath, $useParentMount = false) { + private function getMountForLock(string $absolutePath, bool $useParentMount = false): IMountPoint { $mount = Filesystem::getMountManager()->find($absolutePath); if ($useParentMount) { @@ -1960,24 +1911,22 @@ class View { } $mount = $this->getMountForLock($absolutePath, $lockMountPoint); - if ($mount) { - try { - $storage = $mount->getStorage(); - if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { - $storage->acquireLock( - $mount->getInternalPath($absolutePath), - $type, - $this->lockingProvider - ); - } - } catch (LockedException $e) { - // rethrow with the a human-readable path - throw new LockedException( - $this->getPathRelativeToFiles($absolutePath), - $e, - $e->getExistingLock() + try { + $storage = $mount->getStorage(); + if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $storage->acquireLock( + $mount->getInternalPath($absolutePath), + $type, + $this->lockingProvider ); } + } catch (LockedException $e) { + // rethrow with the a human-readable path + throw new LockedException( + $this->getPathRelativeToFiles($absolutePath), + $e, + $e->getExistingLock() + ); } return true; @@ -2002,31 +1951,29 @@ class View { } $mount = $this->getMountForLock($absolutePath, $lockMountPoint); - if ($mount) { + try { + $storage = $mount->getStorage(); + if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $storage->changeLock( + $mount->getInternalPath($absolutePath), + $type, + $this->lockingProvider + ); + } + } catch (LockedException $e) { try { - $storage = $mount->getStorage(); - if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { - $storage->changeLock( - $mount->getInternalPath($absolutePath), - $type, - $this->lockingProvider - ); - } - } catch (LockedException $e) { - try { - // rethrow with the a human-readable path - throw new LockedException( - $this->getPathRelativeToFiles($absolutePath), - $e, - $e->getExistingLock() - ); - } catch (\InvalidArgumentException $ex) { - throw new LockedException( - $absolutePath, - $ex, - $e->getExistingLock() - ); - } + // rethrow with the a human-readable path + throw new LockedException( + $this->getPathRelativeToFiles($absolutePath), + $e, + $e->getExistingLock() + ); + } catch (\InvalidArgumentException $ex) { + throw new LockedException( + $absolutePath, + $ex, + $e->getExistingLock() + ); } } @@ -2051,15 +1998,13 @@ class View { } $mount = $this->getMountForLock($absolutePath, $lockMountPoint); - if ($mount) { - $storage = $mount->getStorage(); - if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { - $storage->releaseLock( - $mount->getInternalPath($absolutePath), - $type, - $this->lockingProvider - ); - } + $storage = $mount->getStorage(); + if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { + $storage->releaseLock( + $mount->getInternalPath($absolutePath), + $type, + $this->lockingProvider + ); } return true; diff --git a/lib/private/Security/CertificateManager.php b/lib/private/Security/CertificateManager.php index fa26c19ceae..be884654bd0 100644 --- a/lib/private/Security/CertificateManager.php +++ b/lib/private/Security/CertificateManager.php @@ -33,6 +33,7 @@ declare(strict_types=1); namespace OC\Security; use OC\Files\Filesystem; +use OC\Files\View; use OCP\ICertificate; use OCP\ICertificateManager; use OCP\IConfig; @@ -43,24 +44,14 @@ use Psr\Log\LoggerInterface; * Manage trusted certificates for users */ class CertificateManager implements ICertificateManager { - /** - * @var \OC\Files\View - */ - protected $view; - - /** - * @var IConfig - */ - protected $config; - + protected View $view; + protected IConfig $config; protected LoggerInterface $logger; - - /** @var ISecureRandom */ - protected $random; + protected ISecureRandom $random; private ?string $bundlePath = null; - public function __construct(\OC\Files\View $view, + public function __construct(View $view, IConfig $config, LoggerInterface $logger, ISecureRandom $random) { @@ -233,8 +224,7 @@ class CertificateManager implements ICertificateManager { /** * Get the full local path to the certificate bundle - * - * @return string + * @throws \Exception when getting bundle path fails */ public function getAbsoluteBundlePath(): string { try { @@ -247,7 +237,10 @@ class CertificateManager implements ICertificateManager { $this->createCertificateBundle(); } - $this->bundlePath = $this->view->getLocalFile($this->getCertificateBundle()); + $this->bundlePath = $this->view->getLocalFile($this->getCertificateBundle()) ?: null; + } + if ($this->bundlePath === null) { + throw new \Exception('Failed to get absolute bundle path'); } return $this->bundlePath; } catch (\Exception $e) { @@ -255,9 +248,6 @@ class CertificateManager implements ICertificateManager { } } - /** - * @return string - */ private function getPathToCertificates(): string { return '/files_external/'; } diff --git a/lib/private/Server.php b/lib/private/Server.php index 18ffc58dd15..78099f2a8d0 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -439,7 +439,7 @@ class Server extends ServerContainer implements IServerContainer { return $c->get('SystemTagManagerFactory')->getObjectMapper(); }); $this->registerService('RootFolder', function (ContainerInterface $c) { - $manager = \OC\Files\Filesystem::getMountManager(null); + $manager = \OC\Files\Filesystem::getMountManager(); $view = new View(); $root = new Root( $manager, diff --git a/lib/public/Files/File.php b/lib/public/Files/File.php index cdb868241b6..93d0ab860c1 100644 --- a/lib/public/Files/File.php +++ b/lib/public/Files/File.php @@ -68,7 +68,7 @@ interface File extends Node { * Open the file as stream, resulting resource can be operated as stream like the result from php's own fopen * * @param string $mode - * @return resource + * @return resource|false * @throws NotPermittedException * @throws LockedException * @since 6.0.0 diff --git a/lib/public/Files/FileInfo.php b/lib/public/Files/FileInfo.php index 0e521cea65c..83ae4adef92 100644 --- a/lib/public/Files/FileInfo.php +++ b/lib/public/Files/FileInfo.php @@ -250,7 +250,7 @@ interface FileInfo { /** * Get the owner of the file * - * @return \OCP\IUser + * @return ?\OCP\IUser * @since 9.0.0 */ public function getOwner(); diff --git a/lib/public/Files/SimpleFS/ISimpleFile.php b/lib/public/Files/SimpleFS/ISimpleFile.php index e55261497be..8afc3108836 100644 --- a/lib/public/Files/SimpleFS/ISimpleFile.php +++ b/lib/public/Files/SimpleFS/ISimpleFile.php @@ -107,7 +107,7 @@ interface ISimpleFile { /** * Open the file as stream for reading, resulting resource can be operated as stream like the result from php's own fopen * - * @return resource + * @return resource|false * @throws \OCP\Files\NotPermittedException * @since 14.0.0 */ diff --git a/lib/public/Files/Storage.php b/lib/public/Files/Storage.php index c91d47bdcdf..c165266a1b7 100644 --- a/lib/public/Files/Storage.php +++ b/lib/public/Files/Storage.php @@ -88,7 +88,7 @@ interface Storage extends IStorage { * see https://www.php.net/manual/en/function.opendir.php * * @param string $path - * @return resource|bool + * @return resource|false * @since 6.0.0 */ public function opendir($path); @@ -254,7 +254,7 @@ interface Storage extends IStorage { /** * see https://www.php.net/manual/en/function.copy.php * - * @param string $soruce + * @param string $source * @param string $target * @return bool * @since 6.0.0 @@ -326,7 +326,7 @@ interface Storage extends IStorage { * The local version of the file can be temporary and doesn't have to be persistent across requests * * @param string $path - * @return string|bool + * @return string|false * @since 6.0.0 */ public function getLocalFile($path); @@ -348,7 +348,7 @@ interface Storage extends IStorage { * get the ETag for a file or folder * * @param string $path - * @return string|bool + * @return string|false * @since 6.0.0 */ public function getETag($path); diff --git a/lib/public/Files/Storage/IStorage.php b/lib/public/Files/Storage/IStorage.php index 7b3b9eb484e..2f38165830b 100644 --- a/lib/public/Files/Storage/IStorage.php +++ b/lib/public/Files/Storage/IStorage.php @@ -85,7 +85,7 @@ interface IStorage { * see https://www.php.net/manual/en/function.opendir.php * * @param string $path - * @return resource|bool + * @return resource|false * @since 9.0.0 */ public function opendir($path); @@ -314,7 +314,7 @@ interface IStorage { * The local version of the file can be temporary and doesn't have to be persistent across requests * * @param string $path - * @return string|bool + * @return string|false * @since 9.0.0 */ public function getLocalFile($path); @@ -336,7 +336,7 @@ interface IStorage { * get the ETag for a file or folder * * @param string $path - * @return string|bool + * @return string|false * @since 9.0.0 */ public function getETag($path); |