diff options
author | Côme Chilliet <91878298+come-nc@users.noreply.github.com> | 2023-02-07 14:08:08 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-07 14:08:08 +0100 |
commit | 4e969ef8a28c8e71c22f499b738b33e695e4de90 (patch) | |
tree | 31d873e986b63f09ef75cb3f85cc6c1a3c644acd | |
parent | 17ed023be26a6b6aa8f08f27d2faf4a32c2c5b24 (diff) | |
parent | 6e276ad2e18e713754e8b0d0dec4221912f2ca11 (diff) | |
download | nextcloud-server-4e969ef8a28c8e71c22f499b738b33e695e4de90.tar.gz nextcloud-server-4e969ef8a28c8e71c22f499b738b33e695e4de90.zip |
Merge pull request #36120 from nextcloud/enh/32bits-support
Fix 32bit support and add workflow for 32bits testing
74 files changed, 363 insertions, 207 deletions
diff --git a/.github/workflows/phpunit-32bits.yml b/.github/workflows/phpunit-32bits.yml new file mode 100644 index 00000000000..1f91281bf16 --- /dev/null +++ b/.github/workflows/phpunit-32bits.yml @@ -0,0 +1,58 @@ +name: PHPUnit + +on: + workflow_dispatch: + schedule: + - cron: "15 1 * * 1-6" + +permissions: + contents: read + +concurrency: + group: phpunit-32bits-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + phpunit-32bits: + runs-on: ubuntu-latest + container: shivammathur/node:latest-i386 + + strategy: + matrix: + php-versions: ['8.0'] + + steps: + - name: Checkout server + uses: actions/checkout@v3 + with: + submodules: true + + - name: Install tools + run: | + sudo apt-get update + sudo apt-get install -y ffmpeg imagemagick libmagickcore-6.q16-3-extra + + - name: Set up php ${{ matrix.php-versions }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: ctype, curl, dom, fileinfo, gd, imagick, intl, json, mbstring, openssl, pdo_sqlite, posix, sqlite, xml, zip, apcu + tools: phpunit:9 + coverage: none + ini-values: + apc.enabled=on, + apc.enable_cli=on + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Nextcloud + env: + DB_PORT: 4444 + run: | + mkdir data + ./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=autotest --database-pass=rootpassword --admin-user admin --admin-pass admin + php -f index.php + + - name: PHPUnit + working-directory: tests + run: phpunit --configuration phpunit-autotest.xml --exclude-group PRIMARY-azure,PRIMARY-s3,PRIMARY-swift,Memcached,Redis,RoutingWeirdness diff --git a/.github/workflows/smb-kerberos.yml b/.github/workflows/smb-kerberos.yml index 896d96e592c..1cb8ae973ca 100644 --- a/.github/workflows/smb-kerberos.yml +++ b/.github/workflows/smb-kerberos.yml @@ -64,3 +64,9 @@ jobs: CONTENT=$(./client-cmd.sh ${{ env.DC_IP }} curl -b /shared/cookies/jar -s --negotiate -u testuser@DOMAIN.TEST: --delegation always http://httpd.domain.test/remote.php/webdav/smb/test.txt) CONTENT=$(echo $CONTENT | head -n 1 | tr -d '[:space:]') [[ $CONTENT == "testfile" ]] + - name: Show logs + if: failure() + run: | + docker exec --user 33 apache ./occ log:file + FILEPATH=$(docker exec --user 33 apache ./occ log:file | grep "Log file:" | cut -d' ' -f3) + docker exec --user 33 apache cat $FILEPATH diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 909a5828059..51eb505124e 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -72,7 +72,6 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IDBConnection; use OCP\IGroupManager; -use OCP\IUser; use OCP\IUserManager; use OCP\Security\ISecureRandom; use Psr\Log\LoggerInterface; @@ -120,7 +119,6 @@ use function time; * @package OCA\DAV\CalDAV */ class CalDavBackend extends AbstractBackend implements SyncSupport, SubscriptionSupport, SchedulingSupport { - use TTransactional; public const CALENDAR_TYPE_CALENDAR = 0; @@ -346,7 +344,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row['principaluri'] = (string) $row['principaluri']; $components = []; if ($row['components']) { - $components = explode(',',$row['components']); + $components = explode(',', $row['components']); } $calendar = [ @@ -420,7 +418,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row['displayname'] = $row['displayname'] . ' (' . ($this->userManager->getDisplayName($name) ?? ($name ?? '')) . ')'; $components = []; if ($row['components']) { - $components = explode(',',$row['components']); + $components = explode(',', $row['components']); } $calendar = [ 'id' => $row['id'], @@ -469,7 +467,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row['principaluri'] = (string) $row['principaluri']; $components = []; if ($row['components']) { - $components = explode(',',$row['components']); + $components = explode(',', $row['components']); } $calendar = [ 'id' => $row['id'], @@ -521,7 +519,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row['displayname'] = $row['displayname'] . "($name)"; $components = []; if ($row['components']) { - $components = explode(',',$row['components']); + $components = explode(',', $row['components']); } $calendar = [ 'id' => $row['id'], @@ -586,7 +584,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row['displayname'] = $row['displayname'] . ' ' . "($name)"; $components = []; if ($row['components']) { - $components = explode(',',$row['components']); + $components = explode(',', $row['components']); } $calendar = [ 'id' => $row['id'], @@ -639,7 +637,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row['principaluri'] = (string) $row['principaluri']; $components = []; if ($row['components']) { - $components = explode(',',$row['components']); + $components = explode(',', $row['components']); } $calendar = [ @@ -687,7 +685,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $row['principaluri'] = (string) $row['principaluri']; $components = []; if ($row['components']) { - $components = explode(',',$row['components']); + $components = explode(',', $row['components']); } $calendar = [ @@ -779,7 +777,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription if (!($properties[$sccs] instanceof SupportedCalendarComponentSet)) { throw new DAV\Exception('The ' . $sccs . ' property must be of type: \Sabre\CalDAV\Property\SupportedCalendarComponentSet'); } - $values['components'] = implode(',',$properties[$sccs]->getValue()); + $values['components'] = implode(',', $properties[$sccs]->getValue()); } elseif (isset($properties['components'])) { // Allow to provide components internally without having // to create a SupportedCalendarComponentSet object @@ -797,7 +795,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } } - [$calendarId, $calendarData] = $this->atomic(function() use ($values) { + [$calendarId, $calendarData] = $this->atomic(function () use ($values) { $query = $this->db->getQueryBuilder(); $query->insert('calendars'); foreach ($values as $column => $value) { @@ -1712,7 +1710,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $query->expr()->eq('c.calendarid', $query->createNamedParameter($id)), $query->expr()->eq('c.calendartype', - $query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR))); + $query->createNamedParameter(self::CALENDAR_TYPE_CALENDAR))); } foreach ($sharedCalendars as $id) { $calendarExpressions[] = $query->expr()->andX( @@ -1860,7 +1858,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } } - if(isset($options['uid'])) { + if (isset($options['uid'])) { $outerQuery->andWhere($outerQuery->expr()->eq('uid', $outerQuery->createNamedParameter($options['uid']))); } @@ -2435,7 +2433,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } } - [$subscriptionId, $subscriptionRow] = $this->atomic(function() use ($values) { + [$subscriptionId, $subscriptionRow] = $this->atomic(function () use ($values) { $valuesToInsert = []; $query = $this->db->getQueryBuilder(); foreach (array_keys($values) as $name) { diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php index fd8a6437222..b0f17417d21 100644 --- a/apps/dav/lib/Connector/Sabre/File.php +++ b/apps/dav/lib/Connector/Sabre/File.php @@ -138,7 +138,7 @@ class File extends Node implements IFile { public function put($data) { try { $exists = $this->fileView->file_exists($this->path); - if ($this->info && $exists && !$this->info->isUpdateable()) { + if ($exists && !$this->info->isUpdateable()) { throw new Forbidden(); } } catch (StorageNotAvailableException $e) { @@ -759,9 +759,6 @@ class File extends Node implements IFile { * @return string|null */ public function getChecksum() { - if (!$this->info) { - return null; - } return $this->info->getChecksum(); } diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php index f53c62afba2..a6c9b8b4ebe 100644 --- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php @@ -53,10 +53,8 @@ use Sabre\DAV\Server; use Sabre\DAV\Tree; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; -use Sabre\Uri; class FilesPlugin extends ServerPlugin { - // namespace public const NS_OWNCLOUD = 'http://owncloud.org/ns'; public const NS_NEXTCLOUD = 'http://nextcloud.org/ns'; @@ -352,7 +350,7 @@ class FilesPlugin extends ServerPlugin { $propFind->handle(self::HAS_PREVIEW_PROPERTYNAME, function () use ($node) { return json_encode($this->previewManager->isAvailable($node->getFileInfo()), JSON_THROW_ON_ERROR); }); - $propFind->handle(self::SIZE_PROPERTYNAME, function () use ($node): ?int { + $propFind->handle(self::SIZE_PROPERTYNAME, function () use ($node): int|float { return $node->getSize(); }); $propFind->handle(self::MOUNT_TYPE_PROPERTYNAME, function () use ($node) { @@ -382,7 +380,7 @@ class FilesPlugin extends ServerPlugin { }); /** * Return file/folder name as displayname. The primary reason to - * implement it this way is to avoid costly fallback to + * implement it this way is to avoid costly fallback to * CustomPropertiesBackend (esp. visible when querying all files * in a folder). */ diff --git a/apps/dav/lib/Connector/Sabre/Node.php b/apps/dav/lib/Connector/Sabre/Node.php index 1e32e74c325..ee159cef1d6 100644 --- a/apps/dav/lib/Connector/Sabre/Node.php +++ b/apps/dav/lib/Connector/Sabre/Node.php @@ -44,14 +44,12 @@ use OCP\Files\DavUtil; use OCP\Files\FileInfo; use OCP\Files\IRootFolder; use OCP\Files\StorageNotAvailableException; -use OCP\Share\IShare; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; abstract class Node implements \Sabre\DAV\INode { - /** - * @var \OC\Files\View + * @var View */ protected $fileView; @@ -69,10 +67,7 @@ abstract class Node implements \Sabre\DAV\INode { */ protected $property_cache = null; - /** - * @var \OCP\Files\FileInfo - */ - protected $info; + protected FileInfo $info; /** * @var IManager @@ -83,10 +78,6 @@ abstract class Node implements \Sabre\DAV\INode { /** * Sets up the node, expects a full path name - * - * @param \OC\Files\View $view - * @param \OCP\Files\FileInfo $info - * @param IManager $shareManager */ public function __construct(View $view, FileInfo $info, IManager $shareManager = null) { $this->fileView = $view; @@ -109,8 +100,12 @@ abstract class Node implements \Sabre\DAV\INode { } } - protected function refreshInfo() { - $this->info = $this->fileView->getFileInfo($this->path); + protected function refreshInfo(): void { + $info = $this->fileView->getFileInfo($this->path); + if ($info === false) { + throw new \Sabre\DAV\Exception('Failed to get fileinfo for '. $this->path); + } + $this->info = $info; $root = \OC::$server->get(IRootFolder::class); if ($this->info->getType() === FileInfo::TYPE_FOLDER) { $this->node = new Folder($root, $this->fileView, $this->path, $this->info); @@ -145,7 +140,6 @@ abstract class Node implements \Sabre\DAV\INode { * @throws \Sabre\DAV\Exception\Forbidden */ public function setName($name) { - // rename is only allowed if the update privilege is granted if (!($this->info->isUpdateable() || ($this->info->getMountPoint() instanceof MoveableMount && $this->info->getInternalPath() === ''))) { throw new \Sabre\DAV\Exception\Forbidden(); @@ -233,9 +227,10 @@ abstract class Node implements \Sabre\DAV\INode { /** * Returns the size of the node, in bytes * - * @return integer + * @psalm-suppress ImplementedReturnTypeMismatch \Sabre\DAV\IFile::getSize signature does not support 32bit + * @return int|float */ - public function getSize() { + public function getSize(): int|float { return $this->info->getSize(); } @@ -271,7 +266,6 @@ abstract class Node implements \Sabre\DAV\INode { * @return int */ public function getSharePermissions($user) { - // check of we access a federated share if ($user !== null) { try { diff --git a/apps/dav/lib/Connector/Sabre/QuotaPlugin.php b/apps/dav/lib/Connector/Sabre/QuotaPlugin.php index ff7396a0825..ddf4b2773e0 100644 --- a/apps/dav/lib/Connector/Sabre/QuotaPlugin.php +++ b/apps/dav/lib/Connector/Sabre/QuotaPlugin.php @@ -178,7 +178,7 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin { * This method is called before any HTTP method and validates there is enough free space to store the file * * @param string $path relative to the users home - * @param int $length + * @param int|float|null $length * @throws InsufficientStorage * @return bool */ diff --git a/apps/dav/lib/Direct/DirectFile.php b/apps/dav/lib/Direct/DirectFile.php index a4a1999aca7..45c2114747e 100644 --- a/apps/dav/lib/Direct/DirectFile.php +++ b/apps/dav/lib/Direct/DirectFile.php @@ -77,6 +77,10 @@ class DirectFile implements IFile { return $this->file->getEtag(); } + /** + * @psalm-suppress ImplementedReturnTypeMismatch \Sabre\DAV\IFile::getSize signature does not support 32bit + * @return int|float + */ public function getSize() { $this->getFile(); diff --git a/apps/dav/lib/Upload/UploadFile.php b/apps/dav/lib/Upload/UploadFile.php index 49a2fadecf6..023d17955c1 100644 --- a/apps/dav/lib/Upload/UploadFile.php +++ b/apps/dav/lib/Upload/UploadFile.php @@ -29,7 +29,6 @@ use OCA\DAV\Connector\Sabre\File; use Sabre\DAV\IFile; class UploadFile implements IFile { - /** @var File */ private $file; @@ -53,6 +52,10 @@ class UploadFile implements IFile { return $this->file->getETag(); } + /** + * @psalm-suppress ImplementedReturnTypeMismatch \Sabre\DAV\IFile::getSize signature does not support 32bit + * @return int|float + */ public function getSize() { return $this->file->getSize(); } diff --git a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php index cfdf82e9b4f..69096d0cfbb 100644 --- a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php @@ -125,7 +125,6 @@ class CalDavBackendTest extends AbstractCalDavBackend { * @dataProvider providesSharingData */ public function testCalendarSharing($userCanRead, $userCanWrite, $groupCanRead, $groupCanWrite, $add): void { - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject $l10n */ $l10n = $this->createMock(IL10N::class); $l10n @@ -423,7 +422,12 @@ EOD; $events[0] = $this->createEvent($calendarId, '20130912T130000Z', '20130912T140000Z'); $events[1] = $this->createEvent($calendarId, '20130912T150000Z', '20130912T170000Z'); $events[2] = $this->createEvent($calendarId, '20130912T173000Z', '20130912T220000Z'); - $events[3] = $this->createEvent($calendarId, '21130912T130000Z', '22130912T130000Z'); + if (PHP_INT_SIZE > 8) { + $events[3] = $this->createEvent($calendarId, '21130912T130000Z', '22130912T130000Z'); + } else { + /* On 32bit we do not support events after 2038 */ + $events[3] = $this->createEvent($calendarId, '20370912T130000Z', '20370912T130000Z'); + } $result = $this->backend->calendarQuery($calendarId, [ 'name' => '', @@ -471,7 +475,7 @@ EOD; 'only-events' => [[0, 1, 2, 3], [], [['name' => 'VEVENT', 'is-not-defined' => false, 'comp-filters' => [], 'time-range' => ['start' => null, 'end' => null], 'prop-filters' => []]],], 'start' => [[1, 2, 3], [], [['name' => 'VEVENT', 'is-not-defined' => false, 'comp-filters' => [], 'time-range' => ['start' => new DateTime('2013-09-12 14:00:00', new DateTimeZone('UTC')), 'end' => null], 'prop-filters' => []]],], 'end' => [[0], [], [['name' => 'VEVENT', 'is-not-defined' => false, 'comp-filters' => [], 'time-range' => ['start' => null, 'end' => new DateTime('2013-09-12 14:00:00', new DateTimeZone('UTC'))], 'prop-filters' => []]],], - 'future' => [[3], [], [['name' => 'VEVENT', 'is-not-defined' => false, 'comp-filters' => [], 'time-range' => ['start' => new DateTime('2099-09-12 14:00:00', new DateTimeZone('UTC')), 'end' => null], 'prop-filters' => []]],], + 'future' => [[3], [], [['name' => 'VEVENT', 'is-not-defined' => false, 'comp-filters' => [], 'time-range' => ['start' => new DateTime('2036-09-12 14:00:00', new DateTimeZone('UTC')), 'end' => null], 'prop-filters' => []]],], ]; } @@ -648,8 +652,15 @@ EOS; * @dataProvider providesCalDataForGetDenormalizedData */ public function testGetDenormalizedData($expected, $key, $calData): void { - $actual = $this->backend->getDenormalizedData($calData); - $this->assertEquals($expected, $actual[$key]); + try { + $actual = $this->backend->getDenormalizedData($calData); + $this->assertEquals($expected, $actual[$key]); + } catch (\ValueError $e) { + if (($e->getMessage() === 'Epoch doesn\'t fit in a PHP integer') && (PHP_INT_SIZE < 8)) { + $this->markTestSkipped('This fail on 32bits because of PHP limitations in DateTime'); + } + throw $e; + } } public function providesCalDataForGetDenormalizedData() { diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php index dfff9493762..5e638bbcd89 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php @@ -228,13 +228,13 @@ class FilesPluginTest extends TestCase { $this->assertEquals('00000123instanceid', $propFind->get(self::FILEID_PROPERTYNAME)); $this->assertEquals('123', $propFind->get(self::INTERNAL_FILEID_PROPERTYNAME)); $this->assertEquals('1973-11-29T21:33:09+00:00', $propFind->get(self::CREATIONDATE_PROPERTYNAME)); - $this->assertEquals(null, $propFind->get(self::SIZE_PROPERTYNAME)); + $this->assertEquals(0, $propFind->get(self::SIZE_PROPERTYNAME)); $this->assertEquals('DWCKMSR', $propFind->get(self::PERMISSIONS_PROPERTYNAME)); $this->assertEquals('http://example.com/', $propFind->get(self::DOWNLOADURL_PROPERTYNAME)); $this->assertEquals('foo', $propFind->get(self::OWNER_ID_PROPERTYNAME)); $this->assertEquals('M. Foo', $propFind->get(self::OWNER_DISPLAY_NAME_PROPERTYNAME)); $this->assertEquals('my_fingerprint', $propFind->get(self::DATA_FINGERPRINT_PROPERTYNAME)); - $this->assertEquals([self::SIZE_PROPERTYNAME], $propFind->get404Properties()); + $this->assertEquals([], $propFind->get404Properties()); } public function testGetPropertiesStorageNotAvailable(): void { diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php index d38031b03d4..3119d715bec 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php @@ -261,6 +261,8 @@ class FilesReportPluginTest extends \Test\TestCase { $filesNode2 = $this->getMockBuilder(File::class) ->disableOriginalConstructor() ->getMock(); + $filesNode2->method('getSize') + ->willReturn(10); $this->userFolder->expects($this->exactly(2)) ->method('getById') diff --git a/apps/files/appinfo/routes.php b/apps/files/appinfo/routes.php index dabbeab978e..e4af2367906 100644 --- a/apps/files/appinfo/routes.php +++ b/apps/files/appinfo/routes.php @@ -40,12 +40,12 @@ namespace OCA\Files\AppInfo; use OCA\Files\Controller\OpenLocalEditorController; // Legacy routes above -/** @var $this \OC\Route\Router */ +/** @var \OC\Route\Router $this */ $this->create('files_ajax_download', 'apps/files/ajax/download.php') ->actionInclude('files/ajax/download.php'); /** @var Application $application */ -$application = \OC::$server->query(Application::class); +$application = \OC::$server->get(Application::class); $application->registerRoutes( $this, [ diff --git a/apps/files/tests/HelperTest.php b/apps/files/tests/HelperTest.php index 230e2c6cea2..423fd855a9e 100644 --- a/apps/files/tests/HelperTest.php +++ b/apps/files/tests/HelperTest.php @@ -93,7 +93,10 @@ class HelperTest extends \Test\TestCase { /** * @dataProvider sortDataProvider */ - public function testSortByName($sort, $sortDescending, $expectedOrder) { + public function testSortByName(string $sort, bool $sortDescending, array $expectedOrder) { + if (($sort === 'mtime') && (PHP_INT_SIZE < 8)) { + $this->markTestSkipped('Skip mtime sorting on 32bit'); + } $files = self::getTestFileList(); $files = \OCA\Files\Helper::sortFiles($files, $sort, $sortDescending); $fileNames = []; diff --git a/apps/files_external/lib/Lib/Storage/FTP.php b/apps/files_external/lib/Lib/Storage/FTP.php index 284f438fccd..ae02f37b575 100644 --- a/apps/files_external/lib/Lib/Storage/FTP.php +++ b/apps/files_external/lib/Lib/Storage/FTP.php @@ -140,7 +140,7 @@ class FTP extends Common { } } - public function filesize($path) { + public function filesize($path): false|int|float { $result = $this->getConnection()->size($this->buildPath($path)); if ($result === -1) { return false; diff --git a/apps/files_sharing/tests/ApiTest.php b/apps/files_sharing/tests/ApiTest.php index 4d7389be24e..d7661297e9e 100644 --- a/apps/files_sharing/tests/ApiTest.php +++ b/apps/files_sharing/tests/ApiTest.php @@ -205,6 +205,9 @@ class ApiTest extends TestCase { $ocs->cleanup(); } + /** + * @group RoutingWeirdness + */ public function testCreateShareLink() { $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); $result = $ocs->createShare($this->folder, \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK); @@ -227,6 +230,9 @@ class ApiTest extends TestCase { $ocs->cleanup(); } + /** + * @group RoutingWeirdness + */ public function testCreateShareLinkPublicUpload() { $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); $result = $ocs->createShare($this->folder, \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true'); @@ -419,6 +425,7 @@ class ApiTest extends TestCase { /** * @medium + * @group RoutingWeirdness */ public function testPublicLinkUrl() { $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); @@ -837,7 +844,7 @@ class ApiTest extends TestCase { // $request = $this->createRequest(['path' => $this->subfolder]); $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); - $result1 = $ocs->getShares('false','false','false', $this->subfolder); + $result1 = $ocs->getShares('false', 'false', 'false', $this->subfolder); $ocs->cleanup(); // test should return one share within $this->folder @@ -1050,10 +1057,10 @@ class ApiTest extends TestCase { $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes'); $dateWithinRange = new \DateTime(); - $dateWithinRange->setTime(0,0,0); + $dateWithinRange->setTime(0, 0, 0); $dateWithinRange->add(new \DateInterval('P5D')); $dateOutOfRange = new \DateTime(); - $dateOutOfRange->setTime(0,0,0); + $dateOutOfRange->setTime(0, 0, 0); $dateOutOfRange->add(new \DateInterval('P8D')); // update expire date to a valid value @@ -1290,6 +1297,7 @@ class ApiTest extends TestCase { * Make sure only ISO 8601 dates are accepted * * @dataProvider datesProvider + * @group RoutingWeirdness */ public function testPublicLinkExpireDate($date, $valid) { $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); @@ -1320,6 +1328,9 @@ class ApiTest extends TestCase { $this->shareManager->deleteShare($share); } + /** + * @group RoutingWeirdness + */ public function testCreatePublicLinkExpireDateValid() { $config = \OC::$server->getConfig(); @@ -1343,7 +1354,7 @@ class ApiTest extends TestCase { $this->assertEquals($url, $data['url']); $share = $this->shareManager->getShareById('ocinternal:'.$data['id']); - $date->setTime(0,0,0); + $date->setTime(0, 0, 0); $this->assertEquals($date, $share->getExpirationDate()); $this->shareManager->deleteShare($share); diff --git a/apps/files_trashbin/lib/Sabre/AbstractTrash.php b/apps/files_trashbin/lib/Sabre/AbstractTrash.php index 412e432a19e..e02e4c5b8ba 100644 --- a/apps/files_trashbin/lib/Sabre/AbstractTrash.php +++ b/apps/files_trashbin/lib/Sabre/AbstractTrash.php @@ -57,7 +57,11 @@ abstract class AbstractTrash implements ITrash { return $this->data; } - public function getSize(): int { + /** + * @psalm-suppress ImplementedReturnTypeMismatch \Sabre\DAV\IFile::getSize signature does not support 32bit + * @return int|float + */ + public function getSize(): int|float { return $this->data->getSize(); } diff --git a/apps/files_trashbin/lib/Sabre/ITrash.php b/apps/files_trashbin/lib/Sabre/ITrash.php index dcda1abe259..b6b4e70f3b9 100644 --- a/apps/files_trashbin/lib/Sabre/ITrash.php +++ b/apps/files_trashbin/lib/Sabre/ITrash.php @@ -39,7 +39,7 @@ interface ITrash { public function getDeletionTime(): int; - public function getSize(); + public function getSize(): int|float; public function getFileId(): int; diff --git a/apps/files_trashbin/tests/BackgroundJob/ExpireTrashTest.php b/apps/files_trashbin/tests/BackgroundJob/ExpireTrashTest.php index bf5d6bc65ae..3264c11f8fa 100644 --- a/apps/files_trashbin/tests/BackgroundJob/ExpireTrashTest.php +++ b/apps/files_trashbin/tests/BackgroundJob/ExpireTrashTest.php @@ -33,7 +33,6 @@ use OCP\IConfig; use OCP\IUserManager; use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; -use Psr\Log\LoggerInterface; class ExpireTrashTest extends TestCase { /** @var IConfig|MockObject */ @@ -61,7 +60,7 @@ class ExpireTrashTest extends TestCase { $this->time = $this->createMock(ITimeFactory::class); $this->time->method('getTime') - ->willReturn(99999999999); + ->willReturn(999999999); $this->jobList->expects($this->once()) ->method('setLastRun'); diff --git a/apps/files_versions/lib/Db/VersionEntity.php b/apps/files_versions/lib/Db/VersionEntity.php index d5adbcfa104..a37171ef93f 100644 --- a/apps/files_versions/lib/Db/VersionEntity.php +++ b/apps/files_versions/lib/Db/VersionEntity.php @@ -36,8 +36,8 @@ use OCP\DB\Types; * @method void setFileId(int $fileId) * @method int getTimestamp() * @method void setTimestamp(int $timestamp) - * @method int getSize() - * @method void setSize(int $size) + * @method int|float getSize() + * @method void setSize(int|float $size) * @method int getMimetype() * @method void setMimetype(int $mimetype) * @method array|null getMetadata() @@ -78,4 +78,4 @@ class VersionEntity extends Entity implements JsonSerializable { $this->metadata['label'] = $label; $this->markFieldUpdated('metadata'); } -}
\ No newline at end of file +} diff --git a/apps/files_versions/lib/Sabre/VersionFile.php b/apps/files_versions/lib/Sabre/VersionFile.php index 20ae25a7623..8fd97b0636f 100644 --- a/apps/files_versions/lib/Sabre/VersionFile.php +++ b/apps/files_versions/lib/Sabre/VersionFile.php @@ -68,7 +68,11 @@ class VersionFile implements IFile { return (string)$this->version->getRevisionId(); } - public function getSize(): int { + /** + * @psalm-suppress ImplementedReturnTypeMismatch \Sabre\DAV\IFile::getSize signature does not support 32bit + * @return int|float + */ + public function getSize(): int|float { return $this->version->getSize(); } diff --git a/apps/files_versions/lib/Versions/IVersion.php b/apps/files_versions/lib/Versions/IVersion.php index 8ab3357b1e2..8480658fa30 100644 --- a/apps/files_versions/lib/Versions/IVersion.php +++ b/apps/files_versions/lib/Versions/IVersion.php @@ -65,10 +65,10 @@ interface IVersion { /** * Get the size of this version * - * @return int + * @return int|float * @since 15.0.0 */ - public function getSize(): int; + public function getSize(): int|float; /** * Get the name of the source file at the time of making this version diff --git a/apps/files_versions/lib/Versions/Version.php b/apps/files_versions/lib/Versions/Version.php index e87c2a593d7..0dade222abc 100644 --- a/apps/files_versions/lib/Versions/Version.php +++ b/apps/files_versions/lib/Versions/Version.php @@ -40,7 +40,7 @@ class Version implements IVersion, INameableVersion { private string $label; - /** @var int */ + /** @var int|float */ private $size; /** @var string */ @@ -62,7 +62,7 @@ class Version implements IVersion, INameableVersion { int $timestamp, $revisionId, string $name, - int $size, + int|float $size, string $mimetype, string $path, FileInfo $sourceFileInfo, @@ -98,7 +98,7 @@ class Version implements IVersion, INameableVersion { return $this->timestamp; } - public function getSize(): int { + public function getSize(): int|float { return $this->size; } diff --git a/apps/files_versions/tests/BackgroundJob/ExpireVersionsTest.php b/apps/files_versions/tests/BackgroundJob/ExpireVersionsTest.php index 442a7020d89..1d5812767ca 100644 --- a/apps/files_versions/tests/BackgroundJob/ExpireVersionsTest.php +++ b/apps/files_versions/tests/BackgroundJob/ExpireVersionsTest.php @@ -33,7 +33,6 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class ExpireVersionsTest extends TestCase { - /** @var IConfig|MockObject */ private $config; @@ -70,7 +69,7 @@ class ExpireVersionsTest extends TestCase { $timeFactory = $this->createMock(ITimeFactory::class); $timeFactory->method('getTime') ->with() - ->willReturn(99999999999); + ->willReturn(999999999); $job = new ExpireVersions($this->config, $this->userManager, $this->expiration, $timeFactory); $job->start($this->jobList); diff --git a/apps/provisioning_api/tests/Controller/UsersControllerTest.php b/apps/provisioning_api/tests/Controller/UsersControllerTest.php index e5c5678efd3..9e2da244f7b 100644 --- a/apps/provisioning_api/tests/Controller/UsersControllerTest.php +++ b/apps/provisioning_api/tests/Controller/UsersControllerTest.php @@ -73,7 +73,6 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class UsersControllerTest extends TestCase { - /** @var IUserManager|MockObject */ protected $userManager; /** @var IConfig|MockObject */ @@ -497,7 +496,7 @@ class UsersControllerTest extends TestCase { ->method('generate') ->with(10) ->willReturnCallback(function () { - return (string)rand(1000000000, 9999999999); + return (string)rand(100000000, 999999999); }); $this->assertTrue(key_exists( diff --git a/core/Command/Log/File.php b/core/Command/Log/File.php index f2c77e20174..6d6e530fe9a 100644 --- a/core/Command/Log/File.php +++ b/core/Command/Log/File.php @@ -115,14 +115,12 @@ class File extends Command implements Completion\CompletionAwareInterface { } /** - * @param mixed $rotateSize * @throws \InvalidArgumentException */ - protected function validateRotateSize(&$rotateSize) { + protected function validateRotateSize(false|int|float $rotateSize): void { if ($rotateSize === false) { throw new \InvalidArgumentException('Error parsing log rotation file size'); } - $rotateSize = (int) $rotateSize; if ($rotateSize < 0) { throw new \InvalidArgumentException('Log rotation file size must be non-negative'); } 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)) { diff --git a/lib/public/Files/FileInfo.php b/lib/public/Files/FileInfo.php index 14edf6a7645..0e521cea65c 100644 --- a/lib/public/Files/FileInfo.php +++ b/lib/public/Files/FileInfo.php @@ -84,7 +84,7 @@ interface FileInfo { * Get the size in bytes for the file or folder * * @param bool $includeMounts whether or not to include the size of any sub mounts, since 16.0.0 - * @return int + * @return int|float * @since 7.0.0 */ public function getSize($includeMounts = true); diff --git a/lib/public/Files/Node.php b/lib/public/Files/Node.php index b892d8e0a73..b49b4a0f83d 100644 --- a/lib/public/Files/Node.php +++ b/lib/public/Files/Node.php @@ -145,7 +145,7 @@ interface Node extends FileInfo { * Get the size of the file or folder in bytes * * @param bool $includeMounts - * @return int + * @return int|float * @throws InvalidPathException * @throws NotFoundException * @since 6.0.0 diff --git a/lib/public/Files/SimpleFS/ISimpleFile.php b/lib/public/Files/SimpleFS/ISimpleFile.php index 9050fe770b9..e55261497be 100644 --- a/lib/public/Files/SimpleFS/ISimpleFile.php +++ b/lib/public/Files/SimpleFS/ISimpleFile.php @@ -49,7 +49,7 @@ interface ISimpleFile { * * @since 11.0.0 */ - public function getSize(): int; + public function getSize(): int|float; /** * Get the ETag diff --git a/lib/public/Files/SimpleFS/InMemoryFile.php b/lib/public/Files/SimpleFS/InMemoryFile.php index 393449d4f1f..ace9bef465a 100644 --- a/lib/public/Files/SimpleFS/InMemoryFile.php +++ b/lib/public/Files/SimpleFS/InMemoryFile.php @@ -68,7 +68,7 @@ class InMemoryFile implements ISimpleFile { * @inheritdoc * @since 16.0.0 */ - public function getSize(): int { + public function getSize(): int|float { return strlen($this->contents); } diff --git a/lib/public/Files/Storage.php b/lib/public/Files/Storage.php index a0acb4508d2..ca5276af1e8 100644 --- a/lib/public/Files/Storage.php +++ b/lib/public/Files/Storage.php @@ -135,7 +135,7 @@ interface Storage extends IStorage { * The result for filesize when called on a folder is required to be 0 * * @param string $path - * @return int|bool + * @return false|int|float * @since 6.0.0 */ public function filesize($path); diff --git a/lib/public/Files/Storage/IStorage.php b/lib/public/Files/Storage/IStorage.php index eb5522909c6..1084eb7c941 100644 --- a/lib/public/Files/Storage/IStorage.php +++ b/lib/public/Files/Storage/IStorage.php @@ -132,7 +132,7 @@ interface IStorage { * The result for filesize when called on a folder is required to be 0 * * @param string $path - * @return int|bool + * @return false|int|float * @since 9.0.0 */ public function filesize($path); diff --git a/lib/public/Util.php b/lib/public/Util.php index b2b3322fe86..69eccbbc5f6 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -340,24 +340,35 @@ class Util { } /** + * Converts string to int of float depending if it fits an int + * @param numeric-string|float|int $number numeric string + * @return int|float int if it fits, float if it is too big + * @since 26.0.0 + */ + public static function numericToNumber(string|float|int $number): int|float { + /* This is a hack to cast to (int|float) */ + return 0 + (string)$number; + } + + /** * Make a human file size (2048 to 2 kB) - * @param int $bytes file size in bytes + * @param int|float $bytes file size in bytes * @return string a human readable file size * @since 4.0.0 */ - public static function humanFileSize($bytes) { + public static function humanFileSize(int|float $bytes): string { return \OC_Helper::humanFileSize($bytes); } /** * Make a computer file size (2 kB to 2048) * @param string $str file size in a fancy format - * @return float|false a file size in bytes + * @return false|int|float a file size in bytes * * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418 * @since 4.0.0 */ - public static function computerFileSize($str) { + public static function computerFileSize(string $str): false|int|float { return \OC_Helper::computerFileSize($str); } @@ -474,31 +485,31 @@ class Util { * 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 $free 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|null $free 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 * @since 5.0.0 */ - public static function maxUploadFilesize($dir, $free = null) { + public static function maxUploadFilesize(string $dir, int|float|null $free = null): int|float { return \OC_Helper::maxUploadFilesize($dir, $free); } /** * 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 * @since 7.0.0 */ - public static function freeSpace($dir) { + public static function freeSpace(string $dir): int|float { return \OC_Helper::freeSpace($dir); } /** * Calculate PHP upload limit * - * @return int number of bytes representing + * @return int|float number of bytes representing * @since 7.0.0 */ - public static function uploadLimit() { + public static function uploadLimit(): int|float { return \OC_Helper::uploadLimit(); } diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php index 2189e7c09f4..f2195810bb7 100644 --- a/tests/lib/Files/ViewTest.php +++ b/tests/lib/Files/ViewTest.php @@ -1798,7 +1798,18 @@ class ViewTest extends \Test\TestCase { ['is_file', ['dir'], 'dir', null], ['stat', ['dir'], 'dir', null], ['filetype', ['dir'], 'dir', null], - ['filesize', ['dir'], 'dir', null], + [ + 'filesize', + ['dir'], + 'dir', + null, + ILockingProvider::LOCK_SHARED, + ILockingProvider::LOCK_SHARED, + ILockingProvider::LOCK_SHARED, + null, + /* Return an int */ + 100 + ], ['isCreatable', ['dir'], 'dir', null], ['isReadable', ['dir'], 'dir', null], ['isUpdatable', ['dir'], 'dir', null], @@ -1832,7 +1843,8 @@ class ViewTest extends \Test\TestCase { $expectedLockBefore = ILockingProvider::LOCK_SHARED, $expectedLockDuring = ILockingProvider::LOCK_SHARED, $expectedLockAfter = ILockingProvider::LOCK_SHARED, - $expectedStrayLock = null + $expectedStrayLock = null, + $returnValue = true, ) { $view = new View('/' . $this->user . '/files/'); @@ -1853,10 +1865,10 @@ class ViewTest extends \Test\TestCase { $storage->expects($this->once()) ->method($operation) ->willReturnCallback( - function () use ($view, $lockedPath, &$lockTypeDuring) { + function () use ($view, $lockedPath, &$lockTypeDuring, $returnValue) { $lockTypeDuring = $this->getFileLockType($view, $lockedPath); - return true; + return $returnValue; } ); diff --git a/tests/lib/Memcache/APCuTest.php b/tests/lib/Memcache/APCuTest.php index 50e3984ca34..3568b8a4622 100644 --- a/tests/lib/Memcache/APCuTest.php +++ b/tests/lib/Memcache/APCuTest.php @@ -9,6 +9,10 @@ namespace Test\Memcache; +/** + * @group Memcache + * @group APCu + */ class APCuTest extends Cache { protected function setUp(): void { parent::setUp(); diff --git a/tests/lib/Memcache/ArrayCacheTest.php b/tests/lib/Memcache/ArrayCacheTest.php index 4e3623d344d..47a39a82d5d 100644 --- a/tests/lib/Memcache/ArrayCacheTest.php +++ b/tests/lib/Memcache/ArrayCacheTest.php @@ -9,6 +9,9 @@ namespace Test\Memcache; +/** + * @group Memcache + */ class ArrayCacheTest extends Cache { protected function setUp(): void { parent::setUp(); diff --git a/tests/lib/Memcache/CasTraitTest.php b/tests/lib/Memcache/CasTraitTest.php index 61972153886..f077cf143b3 100644 --- a/tests/lib/Memcache/CasTraitTest.php +++ b/tests/lib/Memcache/CasTraitTest.php @@ -23,6 +23,9 @@ namespace Test\Memcache; use Test\TestCase; +/** + * @group Memcache + */ class CasTraitTest extends TestCase { /** * @return \OC\Memcache\CasTrait diff --git a/tests/lib/Memcache/FactoryTest.php b/tests/lib/Memcache/FactoryTest.php index f16f70eddc2..9cdd7058ffa 100644 --- a/tests/lib/Memcache/FactoryTest.php +++ b/tests/lib/Memcache/FactoryTest.php @@ -61,6 +61,9 @@ class Test_Factory_Unavailable_Cache2 extends NullCache { } } +/** + * @group Memcache + */ class FactoryTest extends \Test\TestCase { public const AVAILABLE1 = '\\Test\\Memcache\\Test_Factory_Available_Cache1'; public const AVAILABLE2 = '\\Test\\Memcache\\Test_Factory_Available_Cache2'; diff --git a/tests/lib/Memcache/MemcachedTest.php b/tests/lib/Memcache/MemcachedTest.php index caebf50cd6b..24cf0ba7af3 100644 --- a/tests/lib/Memcache/MemcachedTest.php +++ b/tests/lib/Memcache/MemcachedTest.php @@ -9,6 +9,10 @@ namespace Test\Memcache; +/** + * @group Memcache + * @group Memcached + */ class MemcachedTest extends Cache { public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); diff --git a/tests/lib/Memcache/RedisTest.php b/tests/lib/Memcache/RedisTest.php index e7bb9c29d36..276dbf3a550 100644 --- a/tests/lib/Memcache/RedisTest.php +++ b/tests/lib/Memcache/RedisTest.php @@ -9,6 +9,10 @@ namespace Test\Memcache; +/** + * @group Memcache + * @group Redis + */ class RedisTest extends Cache { public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); diff --git a/tests/lib/MemoryInfoTest.php b/tests/lib/MemoryInfoTest.php index f6557eed45c..1a983f19ece 100644 --- a/tests/lib/MemoryInfoTest.php +++ b/tests/lib/MemoryInfoTest.php @@ -71,10 +71,10 @@ class MemoryInfoTest extends TestCase { * Tests that getMemoryLimit works as expected. * * @param string $iniValue The "memory_limit" ini data. - * @param int $expected The expected detected memory limit. + * @param int|float $expected The expected detected memory limit. * @dataProvider getMemoryLimitTestData */ - public function testMemoryLimit($iniValue, int $expected) { + public function testMemoryLimit(string $iniValue, int|float $expected) { ini_set('memory_limit', $iniValue); $memoryInfo = new MemoryInfo(); self::assertEquals($expected, $memoryInfo->getMemoryLimit()); diff --git a/tests/lib/Route/RouterTest.php b/tests/lib/Route/RouterTest.php index cc7eda199e2..44fef6f1d4f 100644 --- a/tests/lib/Route/RouterTest.php +++ b/tests/lib/Route/RouterTest.php @@ -30,12 +30,20 @@ use Test\TestCase; /** * Class RouterTest * + * @group RoutingWeirdness + * * @package Test\Route */ class RouterTest extends TestCase { public function testGenerateConsecutively(): void { /** @var LoggerInterface $logger */ $logger = $this->createMock(LoggerInterface::class); + $logger->method('info') + ->willReturnCallback( + function (string $message, array $data) { + $this->fail('Unexpected info log: '.(string)($data['exception'] ?? $message)); + } + ); $router = new Router($logger); $this->assertEquals('/index.php/apps/files/', $router->generate('files.view.index')); |