diff options
Diffstat (limited to 'lib/private')
32 files changed, 124 insertions, 108 deletions
diff --git a/lib/private/Archive/Archive.php b/lib/private/Archive/Archive.php index cef306230fd..ff6456113f8 100644 --- a/lib/private/Archive/Archive.php +++ b/lib/private/Archive/Archive.php @@ -50,9 +50,8 @@ abstract class Archive { /** * get the uncompressed size of a file in the archive - * @return int|false */ - abstract public function filesize(string $path); + abstract public function filesize(string $path): false|int|float; /** * get the last modified time of a file in the archive diff --git a/lib/private/Archive/TAR.php b/lib/private/Archive/TAR.php index 79c09cbe9e2..9dc906384e0 100644 --- a/lib/private/Archive/TAR.php +++ b/lib/private/Archive/TAR.php @@ -165,10 +165,8 @@ class TAR extends Archive { /** * get the uncompressed size of a file in the archive - * - * @return int|false */ - public function filesize(string $path) { + public function filesize(string $path): false|int|float { $stat = $this->getHeader($path); return $stat['size'] ?? false; } diff --git a/lib/private/Archive/ZIP.php b/lib/private/Archive/ZIP.php index 743d313f951..f98009ecc3a 100644 --- a/lib/private/Archive/ZIP.php +++ b/lib/private/Archive/ZIP.php @@ -91,9 +91,8 @@ class ZIP extends Archive { /** * get the uncompressed size of a file in the archive - * @return int|false */ - public function filesize(string $path) { + public function filesize(string $path): false|int|float { $stat = $this->zip->statName($path); return $stat['size'] ?? false; } diff --git a/lib/private/Files/FileInfo.php b/lib/private/Files/FileInfo.php index 47c893ebbf1..b94be4c5497 100644 --- a/lib/private/Files/FileInfo.php +++ b/lib/private/Files/FileInfo.php @@ -81,10 +81,8 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { /** * The size of the file/folder without any sub mount - * - * @var int */ - private $rawSize = 0; + private int|float $rawSize = 0; /** * @param string|boolean $path @@ -207,7 +205,8 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { } /** - * @return int + * @param bool $includeMounts + * @return int|float */ public function getSize($includeMounts = true) { if ($includeMounts) { diff --git a/lib/private/Files/Filesystem.php b/lib/private/Files/Filesystem.php index 64a6fc57b27..500a13b1f9d 100644 --- a/lib/private/Files/Filesystem.php +++ b/lib/private/Files/Filesystem.php @@ -730,7 +730,7 @@ class Filesystem { * get the filesystem info * * @param string $path - * @param boolean $includeMountPoints whether to add mountpoint sizes, + * @param bool|string $includeMountPoints whether to add mountpoint sizes, * defaults to true * @return \OC\Files\FileInfo|false False if file does not exist */ diff --git a/lib/private/Files/Node/LazyFolder.php b/lib/private/Files/Node/LazyFolder.php index 1bae0f52e59..cc1f64889a1 100644 --- a/lib/private/Files/Node/LazyFolder.php +++ b/lib/private/Files/Node/LazyFolder.php @@ -225,7 +225,7 @@ class LazyFolder implements \OCP\Files\Folder { /** * @inheritDoc */ - public function getSize($includeMounts = true) { + public function getSize($includeMounts = true): int|float { return $this->__call(__FUNCTION__, func_get_args()); } diff --git a/lib/private/Files/Node/Node.php b/lib/private/Files/Node/Node.php index 8a752ff281d..6c4e0b0f908 100644 --- a/lib/private/Files/Node/Node.php +++ b/lib/private/Files/Node/Node.php @@ -209,11 +209,11 @@ class Node implements \OCP\Files\Node { /** * @param bool $includeMounts - * @return int + * @return int|float * @throws InvalidPathException * @throws NotFoundException */ - public function getSize($includeMounts = true) { + public function getSize($includeMounts = true): int|float { return $this->getFileInfo()->getSize($includeMounts); } diff --git a/lib/private/Files/Node/NonExistingFile.php b/lib/private/Files/Node/NonExistingFile.php index e1d706006ba..b21a2a6c65b 100644 --- a/lib/private/Files/Node/NonExistingFile.php +++ b/lib/private/Files/Node/NonExistingFile.php @@ -65,7 +65,7 @@ class NonExistingFile extends File { } } - public function getSize($includeMounts = true) { + public function getSize($includeMounts = true): int|float { if ($this->fileInfo) { return parent::getSize($includeMounts); } else { diff --git a/lib/private/Files/Node/NonExistingFolder.php b/lib/private/Files/Node/NonExistingFolder.php index d99446e8ff8..100687c3e6f 100644 --- a/lib/private/Files/Node/NonExistingFolder.php +++ b/lib/private/Files/Node/NonExistingFolder.php @@ -66,7 +66,7 @@ class NonExistingFolder extends Folder { } } - public function getSize($includeMounts = true) { + public function getSize($includeMounts = true): int|float { if ($this->fileInfo) { return parent::getSize($includeMounts); } else { diff --git a/lib/private/Files/Node/Root.php b/lib/private/Files/Node/Root.php index ca930c1002c..8d0a65d2a68 100644 --- a/lib/private/Files/Node/Root.php +++ b/lib/private/Files/Node/Root.php @@ -290,9 +290,9 @@ class Root extends Folder implements IRootFolder { /** * @param bool $includeMounts - * @return int + * @return int|float */ - public function getSize($includeMounts = true) { + public function getSize($includeMounts = true): int|float { return 0; } diff --git a/lib/private/Files/SimpleFS/NewSimpleFile.php b/lib/private/Files/SimpleFS/NewSimpleFile.php index e2d1ae274b1..1d0972bcc54 100644 --- a/lib/private/Files/SimpleFS/NewSimpleFile.php +++ b/lib/private/Files/SimpleFS/NewSimpleFile.php @@ -56,7 +56,7 @@ class NewSimpleFile implements ISimpleFile { /** * Get the size in bytes */ - public function getSize(): int { + public function getSize(): int|float { if ($this->file) { return $this->file->getSize(); } else { diff --git a/lib/private/Files/SimpleFS/SimpleFile.php b/lib/private/Files/SimpleFS/SimpleFile.php index a2571ac50e8..95ef332e2f5 100644 --- a/lib/private/Files/SimpleFS/SimpleFile.php +++ b/lib/private/Files/SimpleFS/SimpleFile.php @@ -46,7 +46,7 @@ class SimpleFile implements ISimpleFile { /** * Get the size in bytes */ - public function getSize(): int { + public function getSize(): int|float { return $this->file->getSize(); } diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php index 0c121feb11e..737c1e9d51e 100644 --- a/lib/private/Files/Storage/Common.php +++ b/lib/private/Files/Storage/Common.php @@ -121,7 +121,7 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage { return $this->filetype($path) === 'file'; } - public function filesize($path) { + public function filesize($path): false|int|float { if ($this->is_dir($path)) { return 0; //by definition } else { @@ -695,9 +695,9 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage { $result = $this->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, true); if ($result) { if ($sourceStorage->is_dir($sourceInternalPath)) { - $result = $result && $sourceStorage->rmdir($sourceInternalPath); + $result = $sourceStorage->rmdir($sourceInternalPath); } else { - $result = $result && $sourceStorage->unlink($sourceInternalPath); + $result = $sourceStorage->unlink($sourceInternalPath); } } return $result; diff --git a/lib/private/Files/Storage/FailedStorage.php b/lib/private/Files/Storage/FailedStorage.php index d748b3410c3..ceb802570bf 100644 --- a/lib/private/Files/Storage/FailedStorage.php +++ b/lib/private/Files/Storage/FailedStorage.php @@ -80,7 +80,7 @@ class FailedStorage extends Common { throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e); } - public function filesize($path) { + public function filesize($path): false|int|float { 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 b021d40d335..fe6a6d6e21a 100644 --- a/lib/private/Files/Storage/Local.php +++ b/lib/private/Files/Storage/Local.php @@ -171,6 +171,11 @@ class Local extends \OC\Files\Storage\Common { return false; } $statResult = @stat($fullPath); + if (PHP_INT_SIZE === 4 && $statResult && !$this->is_dir($path)) { + $filesize = $this->filesize($path); + $statResult['size'] = $filesize; + $statResult[7] = $filesize; + } if (is_array($statResult)) { $statResult['full_path'] = $fullPath; } @@ -237,11 +242,15 @@ class Local extends \OC\Files\Storage\Common { return $filetype; } - public function filesize($path) { + public function filesize($path): false|int|float { if (!$this->is_file($path)) { return 0; } $fullPath = $this->getSourcePath($path); + if (PHP_INT_SIZE === 4) { + $helper = new \OC\LargeFileHelper; + return $helper->getFileSize($fullPath) ?? false; + } return filesize($fullPath); } @@ -263,6 +272,10 @@ class Local extends \OC\Files\Storage\Common { if (!$this->file_exists($path)) { return false; } + if (PHP_INT_SIZE === 4) { + $helper = new \OC\LargeFileHelper(); + return $helper->getFileMtime($fullPath); + } return filemtime($fullPath); } diff --git a/lib/private/Files/Storage/Wrapper/Availability.php b/lib/private/Files/Storage/Wrapper/Availability.php index a4a6fa0bd16..693d943f0dc 100644 --- a/lib/private/Files/Storage/Wrapper/Availability.php +++ b/lib/private/Files/Storage/Wrapper/Availability.php @@ -165,7 +165,7 @@ class Availability extends Wrapper { } /** {@inheritdoc} */ - public function filesize($path) { + public function filesize($path): false|int|float { $this->checkAvailability(); try { return parent::filesize($path); @@ -451,6 +451,9 @@ class Availability extends Wrapper { } /** + * @template T of StorageNotAvailableException|null + * @param T $e + * @psalm-return (T is null ? void : never) * @throws StorageNotAvailableException */ protected function setUnavailable(?StorageNotAvailableException $e): void { diff --git a/lib/private/Files/Storage/Wrapper/Encoding.php b/lib/private/Files/Storage/Wrapper/Encoding.php index ed680f5045d..6aba839d26d 100644 --- a/lib/private/Files/Storage/Wrapper/Encoding.php +++ b/lib/private/Files/Storage/Wrapper/Encoding.php @@ -210,11 +210,8 @@ class Encoding extends Wrapper { /** * see https://www.php.net/manual/en/function.filesize.php * The result for filesize when called on a folder is required to be 0 - * - * @param string $path - * @return int|bool */ - public function filesize($path) { + public function filesize($path): false|int|float { return $this->storage->filesize($this->findPathToUse($path)); } diff --git a/lib/private/Files/Storage/Wrapper/Encryption.php b/lib/private/Files/Storage/Wrapper/Encryption.php index 0bd799507ff..4d860e623e0 100644 --- a/lib/private/Files/Storage/Wrapper/Encryption.php +++ b/lib/private/Files/Storage/Wrapper/Encryption.php @@ -133,11 +133,8 @@ class Encryption extends Wrapper { /** * see https://www.php.net/manual/en/function.filesize.php * The result for filesize when called on a folder is required to be 0 - * - * @param string $path - * @return int */ - public function filesize($path) { + public function filesize($path): false|int|float { $fullPath = $this->getFullPath($path); /** @var CacheEntry $info */ diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php index 9834ae5a954..4501c96d631 100644 --- a/lib/private/Files/Storage/Wrapper/Jail.php +++ b/lib/private/Files/Storage/Wrapper/Jail.php @@ -158,11 +158,8 @@ class Jail extends Wrapper { /** * see https://www.php.net/manual/en/function.filesize.php * The result for filesize when called on a folder is required to be 0 - * - * @param string $path - * @return int|bool */ - public function filesize($path) { + public function filesize($path): false|int|float { return $this->getWrapperStorage()->filesize($this->getUnjailedPath($path)); } diff --git a/lib/private/Files/Storage/Wrapper/Wrapper.php b/lib/private/Files/Storage/Wrapper/Wrapper.php index ed7e137fd88..26b4570cc75 100644 --- a/lib/private/Files/Storage/Wrapper/Wrapper.php +++ b/lib/private/Files/Storage/Wrapper/Wrapper.php @@ -148,11 +148,8 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea /** * see https://www.php.net/manual/en/function.filesize.php * The result for filesize when called on a folder is required to be 0 - * - * @param string $path - * @return int|bool */ - public function filesize($path) { + public function filesize($path): false|int|float { return $this->getWrapperStorage()->filesize($path); } diff --git a/lib/private/Files/Stream/Encryption.php b/lib/private/Files/Stream/Encryption.php index cebf7bafced..bcf0a10740b 100644 --- a/lib/private/Files/Stream/Encryption.php +++ b/lib/private/Files/Stream/Encryption.php @@ -143,8 +143,8 @@ class Encryption extends Wrapper { * @param \OC\Encryption\Util $util * @param \OC\Encryption\File $file * @param string $mode - * @param int $size - * @param int $unencryptedSize + * @param int|float $size + * @param int|float $unencryptedSize * @param int $headerSize * @param bool $signed * @param string $wrapper stream wrapper class @@ -158,7 +158,7 @@ class Encryption extends Wrapper { \OC\Files\Storage\Storage $storage, \OC\Files\Storage\Wrapper\Encryption $encStorage, \OC\Encryption\Util $util, - \OC\Encryption\File $file, + \OC\Encryption\File $file, $mode, $size, $unencryptedSize, diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index 8f073da9164..f79a992c773 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -411,7 +411,7 @@ class View { * @param string $path * @return mixed */ - public function filesize($path) { + public function filesize(string $path) { return $this->basicOperation('filesize', $path); } @@ -1372,9 +1372,8 @@ class View { * get the filesystem info * * @param string $path - * @param boolean|string $includeMountPoints true to add mountpoint sizes, + * @param bool|string $includeMountPoints true to add mountpoint sizes, * 'ext' to add only ext storage mount point sizes. Defaults to true. - * defaults to true * @return \OC\Files\FileInfo|false False if file does not exist */ public function getFileInfo($path, $includeMountPoints = true) { diff --git a/lib/private/LargeFileHelper.php b/lib/private/LargeFileHelper.php index a9c5a329620..2b2fed4e9f1 100755 --- a/lib/private/LargeFileHelper.php +++ b/lib/private/LargeFileHelper.php @@ -73,7 +73,7 @@ class LargeFileHelper { * * @return string Unsigned integer base-10 string */ - public function formatUnsignedInteger($number) { + public function formatUnsignedInteger(int|float|string $number): string { if (is_float($number)) { // Undo the effect of the php.ini setting 'precision'. return number_format($number, 0, '', ''); @@ -98,7 +98,7 @@ class LargeFileHelper { * @return null|int|float Number of bytes as number (float or int) or * null on failure. */ - public function getFileSize($filename) { + public function getFileSize(string $filename): null|int|float { $fileSize = $this->getFileSizeViaCurl($filename); if (!is_null($fileSize)) { return $fileSize; @@ -118,7 +118,7 @@ class LargeFileHelper { * @return null|int|float Number of bytes as number (float or int) or * null on failure. */ - public function getFileSizeViaCurl($fileName) { + public function getFileSizeViaCurl(string $fileName): null|int|float { if (\OC::$server->get(IniGetWrapper::class)->getString('open_basedir') === '') { $encodedFileName = rawurlencode($fileName); $ch = curl_init("file:///$encodedFileName"); @@ -146,7 +146,7 @@ class LargeFileHelper { * @return null|int|float Number of bytes as number (float or int) or * null on failure. */ - public function getFileSizeViaExec($filename) { + public function getFileSizeViaExec(string $filename): null|int|float { if (\OCP\Util::isFunctionEnabled('exec')) { $os = strtolower(php_uname('s')); $arg = escapeshellarg($filename); @@ -171,7 +171,7 @@ class LargeFileHelper { * * @return int|float Number of bytes as number (float or int). */ - public function getFileSizeNative($filename) { + public function getFileSizeNative(string $filename): int|float { $result = filesize($filename); if ($result < 0) { // For file sizes between 2 GiB and 4 GiB, filesize() will return a @@ -184,13 +184,10 @@ class LargeFileHelper { /** * Returns the current mtime for $fullPath - * - * @param string $fullPath - * @return int */ - public function getFileMtime($fullPath) { + public function getFileMtime(string $fullPath): int { try { - $result = filemtime($fullPath); + $result = filemtime($fullPath) ?: -1; } catch (\Exception $e) { $result = - 1; } @@ -198,14 +195,14 @@ class LargeFileHelper { if (\OCP\Util::isFunctionEnabled('exec')) { $os = strtolower(php_uname('s')); if (strpos($os, 'linux') !== false) { - return $this->exec('stat -c %Y ' . escapeshellarg($fullPath)); + return (int)($this->exec('stat -c %Y ' . escapeshellarg($fullPath)) ?? -1); } } } return $result; } - protected function exec($cmd) { + protected function exec(string $cmd): null|int|float { $result = trim(exec($cmd)); return ctype_digit($result) ? 0 + $result : null; } diff --git a/lib/private/Lockdown/Filesystem/NullStorage.php b/lib/private/Lockdown/Filesystem/NullStorage.php index 8427a4658d4..a3976733b1a 100644 --- a/lib/private/Lockdown/Filesystem/NullStorage.php +++ b/lib/private/Lockdown/Filesystem/NullStorage.php @@ -65,7 +65,7 @@ class NullStorage extends Common { return ($path === '') ? 'dir' : false; } - public function filesize($path) { + public function filesize($path): false|int|float { throw new \OC\ForbiddenException('This request is not allowed to access the filesystem'); } diff --git a/lib/private/MemoryInfo.php b/lib/private/MemoryInfo.php index ed6617d879d..266fb15a573 100644 --- a/lib/private/MemoryInfo.php +++ b/lib/private/MemoryInfo.php @@ -24,8 +24,11 @@ declare(strict_types=1); * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ + namespace OC; +use OCP\Util; + /** * Helper class that covers memory info. */ @@ -45,14 +48,14 @@ class MemoryInfo { /** * Returns the php memory limit. * - * @return int The memory limit in bytes. + * @return int|float The memory limit in bytes. */ - public function getMemoryLimit(): int { + public function getMemoryLimit(): int|float { $iniValue = trim(ini_get('memory_limit')); if ($iniValue === '-1') { return -1; - } elseif (is_numeric($iniValue) === true) { - return (int)$iniValue; + } elseif (is_numeric($iniValue)) { + return Util::numericToNumber($iniValue); } else { return $this->memoryLimitToBytes($iniValue); } @@ -62,11 +65,15 @@ class MemoryInfo { * Converts the ini memory limit to bytes. * * @param string $memoryLimit The "memory_limit" ini value - * @return int */ - private function memoryLimitToBytes(string $memoryLimit): int { + private function memoryLimitToBytes(string $memoryLimit): int|float { $last = strtolower(substr($memoryLimit, -1)); - $memoryLimit = (int)substr($memoryLimit, 0, -1); + $number = substr($memoryLimit, 0, -1); + if (is_numeric($number)) { + $memoryLimit = Util::numericToNumber($number); + } else { + throw new \InvalidArgumentException($number.' is not a valid numeric string (in memory_limit ini directive)'); + } // intended fall through switch ($last) { diff --git a/lib/private/Setup.php b/lib/private/Setup.php index e84a5e4987a..dc59eacbf57 100644 --- a/lib/private/Setup.php +++ b/lib/private/Setup.php @@ -247,13 +247,14 @@ class Setup { ]; } - if (PHP_INT_SIZE < 8) { + if ($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) { $errors[] = [ 'error' => $this->l10n->t( - 'It seems that this %s instance is running on a 32-bit PHP environment. 64-bit is required for 26 and higher.', + 'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' . + 'This will lead to problems with files over 4 GB and is highly discouraged.', [$this->defaults->getProductName()] ), - 'hint' => $this->l10n->t('Please switch to 64-bit PHP.'), + 'hint' => $this->l10n->t('Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP.'), ]; } diff --git a/lib/private/Streamer.php b/lib/private/Streamer.php index f96646e3365..52f824fedf8 100644 --- a/lib/private/Streamer.php +++ b/lib/private/Streamer.php @@ -40,7 +40,7 @@ use ZipStreamer\ZipStreamer; class Streamer { // array of regexp. Matching user agents will get tar instead of zip - private $preferTarFor = [ '/macintosh|mac os x/i' ]; + private array $preferTarFor = [ '/macintosh|mac os x/i' ]; // streamer instance private $streamerInstance; @@ -49,11 +49,11 @@ class Streamer { * Streamer constructor. * * @param IRequest $request - * @param int $size The size of the files in bytes + * @param int|float $size The size of the files in bytes * @param int $numberOfFiles The number of files (and directories) that will * be included in the streamed file */ - public function __construct(IRequest $request, int $size, int $numberOfFiles) { + public function __construct(IRequest $request, int|float $size, int $numberOfFiles) { /** * zip32 constraints for a basic (without compression, volumes nor * encryption) zip file according to the Zip specification: @@ -85,7 +85,7 @@ class Streamer { } elseif ($request->isUserAgent($this->preferTarFor)) { $this->streamerInstance = new TarStreamer(); } else { - $this->streamerInstance = new ZipStreamer(['zip64' => true]); + $this->streamerInstance = new ZipStreamer(['zip64' => PHP_INT_SIZE !== 4]); } } @@ -149,11 +149,11 @@ class Streamer { * * @param resource $stream Stream to read data from * @param string $internalName Filepath and name to be used in the archive. - * @param int $size Filesize - * @param int|bool $time File mtime as int, or false + * @param int|float $size Filesize + * @param int|false $time File mtime as int, or false * @return bool $success */ - public function addFileFromStream($stream, string $internalName, int $size, $time): bool { + public function addFileFromStream($stream, string $internalName, int|float $size, $time): bool { $options = []; if ($time) { $options = [ diff --git a/lib/private/User/User.php b/lib/private/User/User.php index 7044770b57e..2b975c290ba 100644 --- a/lib/private/User/User.php +++ b/lib/private/User/User.php @@ -513,13 +513,17 @@ class User implements IUser { * * @param string $quota * @return void + * @throws InvalidArgumentException * @since 9.0.0 */ public function setQuota($quota) { $oldQuota = $this->config->getUserValue($this->uid, 'files', 'quota', ''); if ($quota !== 'none' and $quota !== 'default') { - $quota = OC_Helper::computerFileSize($quota); - $quota = OC_Helper::humanFileSize((int)$quota); + $bytesQuota = OC_Helper::computerFileSize($quota); + if ($bytesQuota === false) { + throw new InvalidArgumentException('Failed to set quota to invalid value '.$quota); + } + $quota = OC_Helper::humanFileSize($bytesQuota); } if ($quota !== $oldQuota) { $this->config->setUserValue($this->uid, 'files', 'quota', $quota); diff --git a/lib/private/legacy/OC_Files.php b/lib/private/legacy/OC_Files.php index 6a3a44d6cc0..5655139b24a 100644 --- a/lib/private/legacy/OC_Files.php +++ b/lib/private/legacy/OC_Files.php @@ -59,14 +59,11 @@ class OC_Files { public const UPLOAD_MIN_LIMIT_BYTES = 1048576; // 1 MiB - private static $multipartBoundary = ''; + private static string $multipartBoundary = ''; - /** - * @return string - */ - private static function getBoundary() { + private static function getBoundary(): string { if (empty(self::$multipartBoundary)) { - self::$multipartBoundary = md5(mt_rand()); + self::$multipartBoundary = md5((string)mt_rand()); } return self::$multipartBoundary; } @@ -76,7 +73,7 @@ class OC_Files { * @param string $name * @param array $rangeArray ('from'=>int,'to'=>int), ... */ - private static function sendHeaders($filename, $name, array $rangeArray) { + private static function sendHeaders($filename, $name, array $rangeArray): void { OC_Response::setContentDispositionHeader($name, 'attachment'); header('Content-Transfer-Encoding: binary', true); header('Pragma: public');// enable caching in IE @@ -247,10 +244,10 @@ class OC_Files { /** * @param string $rangeHeaderPos - * @param int $fileSize + * @param int|float $fileSize * @return array $rangeArray ('from'=>int,'to'=>int), ... */ - private static function parseHttpRangeHeader($rangeHeaderPos, $fileSize) { + private static function parseHttpRangeHeader($rangeHeaderPos, $fileSize): array { $rArray = explode(',', $rangeHeaderPos); $minOffset = 0; $ind = 0; diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php index 9ecd05b0a73..c2036c7b863 100644 --- a/lib/private/legacy/OC_Helper.php +++ b/lib/private/legacy/OC_Helper.php @@ -49,6 +49,7 @@ use OCP\Files\Mount\IMountPoint; use OCP\ICacheFactory; use OCP\IBinaryFinder; use OCP\IUser; +use OCP\Util; use Psr\Log\LoggerInterface; /** @@ -59,12 +60,12 @@ class OC_Helper { /** * Make a human file size - * @param int $bytes file size in bytes + * @param int|float $bytes file size in bytes * @return string a human readable file size * * Makes 2048 to 2 kB. */ - public static function humanFileSize($bytes) { + public static function humanFileSize(int|float $bytes): string { if ($bytes < 0) { return "?"; } @@ -95,16 +96,16 @@ class OC_Helper { /** * Make a computer file size * @param string $str file size in human readable format - * @return int|false a file size in bytes + * @return false|int|float a file size in bytes * * Makes 2kB to 2048. * * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418 */ - public static function computerFileSize($str) { + public static function computerFileSize(string $str): false|int|float { $str = strtolower($str); if (is_numeric($str)) { - return (int)$str; + return Util::numericToNumber($str); } $bytes_array = [ @@ -129,16 +130,14 @@ class OC_Helper { return false; } - $bytes = round($bytes); - - return (int)$bytes; + return Util::numericToNumber(round($bytes)); } /** * Recursive copying of folders * @param string $src source folder * @param string $dest target folder - * + * @return void */ public static function copyr($src, $dest) { if (is_dir($src)) { @@ -387,8 +386,8 @@ class OC_Helper { * calculates the maximum upload size respecting system settings, free space and user quota * * @param string $dir the current folder where the user currently operates - * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly - * @return int number of bytes representing + * @param int|float $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly + * @return int|float number of bytes representing */ public static function maxUploadFilesize($dir, $freeSpace = null) { if (is_null($freeSpace) || $freeSpace < 0) { @@ -401,7 +400,7 @@ class OC_Helper { * Calculate free space left within user quota * * @param string $dir the current folder where the user currently operates - * @return int number of bytes representing + * @return int|float number of bytes representing */ public static function freeSpace($dir) { $freeSpace = \OC\Files\Filesystem::free_space($dir); @@ -416,12 +415,12 @@ class OC_Helper { /** * Calculate PHP upload limit * - * @return int PHP upload file size limit + * @return int|float PHP upload file size limit */ public static function uploadLimit() { $ini = \OC::$server->get(IniGetWrapper::class); - $upload_max_filesize = (int)OCP\Util::computerFileSize($ini->get('upload_max_filesize')); - $post_max_size = (int)OCP\Util::computerFileSize($ini->get('post_max_size')); + $upload_max_filesize = Util::computerFileSize($ini->get('upload_max_filesize')) ?: 0; + $post_max_size = Util::computerFileSize($ini->get('post_max_size')) ?: 0; if ($upload_max_filesize === 0 && $post_max_size === 0) { return INF; } elseif ($upload_max_filesize === 0 || $post_max_size === 0) { @@ -582,7 +581,7 @@ class OC_Helper { /** * Get storage info including all mount points and quota */ - private static function getGlobalStorageInfo(int $quota, IUser $user, IMountPoint $mount): array { + private static function getGlobalStorageInfo(int|float $quota, IUser $user, IMountPoint $mount): array { $rootInfo = \OC\Files\Filesystem::getFileInfo('', 'ext'); $used = $rootInfo['size']; if ($used < 0) { diff --git a/lib/private/legacy/OC_Response.php b/lib/private/legacy/OC_Response.php index b849710e90b..e4525fe9e10 100644 --- a/lib/private/legacy/OC_Response.php +++ b/lib/private/legacy/OC_Response.php @@ -52,6 +52,19 @@ class OC_Response { * @param string|int|float $length Length to be sent */ public static function setContentLengthHeader($length) { + if (PHP_INT_SIZE === 4) { + if ($length > PHP_INT_MAX && stripos(PHP_SAPI, 'apache') === 0) { + // Apache PHP SAPI casts Content-Length headers to PHP integers. + // This enforces a limit of PHP_INT_MAX (2147483647 on 32-bit + // platforms). So, if the length is greater than PHP_INT_MAX, + // we just do not send a Content-Length header to prevent + // bodies from being received incompletely. + return; + } + // Convert signed integer or float to unsigned base-10 string. + $lfh = new \OC\LargeFileHelper; + $length = $lfh->formatUnsignedInteger($length); + } header('Content-Length: '.$length); } diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php index 6dc08341b18..7f06900feb0 100644 --- a/lib/private/legacy/OC_Util.php +++ b/lib/private/legacy/OC_Util.php @@ -146,7 +146,7 @@ class OC_Util { /** * check if share API enforces a default expire date * - * @return boolean + * @return bool * @suppress PhanDeprecatedFunction */ public static function isDefaultExpireDateEnforced() { @@ -159,7 +159,7 @@ class OC_Util { * Get the quota of a user * * @param IUser|null $user - * @return int|\OCP\Files\FileInfo::SPACE_UNLIMITED|false Quota bytes + * @return int|\OCP\Files\FileInfo::SPACE_UNLIMITED|false|float Quota bytes */ public static function getUserQuota(?IUser $user) { if (is_null($user)) { |