From 0cb079d274938f212e0ee871629a1b602b0b2424 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Mon, 9 Mar 2026 13:09:26 +0100 Subject: [PATCH 1/5] refactor: Deprecate url generator utils Add a new IUrlGenerator::linkToRemote and replace usage of the old API with the new one. Signed-off-by: Carl Schwan --- .../lib/OCM/CloudFederationProviderFiles.php | 5 ++++- lib/private/URLGenerator.php | 9 +++++++++ lib/public/IURLGenerator.php | 11 +++++++++++ lib/public/Util.php | 14 +++++++------- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php b/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php index a5ae8c87abd25..1902367ae1e20 100644 --- a/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php +++ b/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php @@ -569,7 +569,10 @@ private function getFile(IUser $user, int $fileSource): array { $file = null; } $args = Filesystem::is_dir($file) ? ['dir' => $file] : ['dir' => dirname($file), 'scrollto' => $file]; - $link = Util::linkToAbsolute('files', 'index.php', $args); + $urlGenerator = Server::get(IURLGenerator::class); + $link = $urlGenerator->getAbsoluteURL( + $urlGenerator->linkTo('files', 'index.php', $args) + ); return [$file, $link]; } diff --git a/lib/private/URLGenerator.php b/lib/private/URLGenerator.php index 0debd9ba99af8..c7e9c19a4b1d1 100644 --- a/lib/private/URLGenerator.php +++ b/lib/private/URLGenerator.php @@ -19,6 +19,7 @@ use OCP\IURLGenerator; use OCP\IUserSession; use OCP\Server; +use Override; use RuntimeException; class URLGenerator implements IURLGenerator { @@ -316,4 +317,12 @@ public function getBaseUrl(): string { public function getWebroot(): string { return \OC::$WEBROOT; } + + #[Override] + public function linkToRemote(string $service): string { + $remoteBase = $this->linkTo('', 'remote.php') . '/' . $service; + return $this->getAbsoluteURL( + $remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '') + ); + } } diff --git a/lib/public/IURLGenerator.php b/lib/public/IURLGenerator.php index a336d18b00fa9..e9a54f371f52b 100644 --- a/lib/public/IURLGenerator.php +++ b/lib/public/IURLGenerator.php @@ -8,10 +8,14 @@ */ namespace OCP; +use OCP\AppFramework\Attribute\Consumable; + /** * Class to generate URLs + * * @since 6.0.0 */ +#[Consumable(since: '6.0.0')] interface IURLGenerator { /** * Regex for matching http(s) urls @@ -115,4 +119,11 @@ public function getBaseUrl(): string; * @since 23.0.0 */ public function getWebroot(): string; + + /** + * Return the url to the remote DAV handler. + * + * @since 34.0.0 + */ + public function linkToRemote(string $service): string; } diff --git a/lib/public/Util.php b/lib/public/Util.php index 70a862880f19d..b2b93d8ee8108 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -245,9 +245,10 @@ public static function addHeader($tag, $attributes, $text = null) { * The value of $args will be urlencoded * @return string the url * @since 4.0.0 - parameter $args was added in 4.5.0 + * @deprecated 34.0.0 Use IUrlGenerator::getAbsoluteUrl and IUrlGenerator::linkTo */ public static function linkToAbsolute($app, $file, $args = []) { - $urlGenerator = \OCP\Server::get(IURLGenerator::class); + $urlGenerator = Server::get(IURLGenerator::class); return $urlGenerator->getAbsoluteURL( $urlGenerator->linkTo($app, $file, $args) ); @@ -255,16 +256,15 @@ public static function linkToAbsolute($app, $file, $args = []) { /** * Creates an absolute url for remote use. + * * @param string $service id * @return string the url * @since 4.0.0 + * @deprecated 34.0.0 Use IURlGenerator::linkToRemote */ - public static function linkToRemote($service) { - $urlGenerator = \OCP\Server::get(IURLGenerator::class); - $remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service; - return $urlGenerator->getAbsoluteURL( - $remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '') - ); + public static function linkToRemote(string $service): string { + $urlGenerator = Server::get(IURLGenerator::class); + return $urlGenerator->linkToRemote($service); } /** From 7cca54428bd9536f6ac1379bae5d3d481dfca7d9 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Mon, 9 Mar 2026 13:12:39 +0100 Subject: [PATCH 2/5] refactor: Replace old Utils::callRegister with new API Signed-off-by: Carl Schwan --- .../AppFramework/Middleware/Security/SecurityMiddleware.php | 4 +++- lib/private/Template/Template.php | 3 ++- lib/private/legacy/OC_User.php | 3 ++- tests/lib/NavigationManagerTest.php | 4 +++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php index 830ccd2da9416..ad7858cc690e8 100644 --- a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php @@ -17,6 +17,7 @@ use OC\AppFramework\Middleware\Security\Exceptions\NotLoggedInException; use OC\AppFramework\Middleware\Security\Exceptions\SecurityException; use OC\AppFramework\Middleware\Security\Exceptions\StrictCookieMissingException; +use OC\Security\CSRF\CsrfTokenManager; use OC\Settings\AuthorizedGroupMapper; use OC\User\Session; use OCA\Talk\Controller\PageController as TalkPageController; @@ -45,6 +46,7 @@ use OCP\IURLGenerator; use OCP\IUserSession; use OCP\Security\Ip\IRemoteAddress; +use OCP\Server; use OCP\Util; use Psr\Log\LoggerInterface; use ReflectionMethod; @@ -193,7 +195,7 @@ public function beforeController($controller, $methodName) { } } // CSRF check - also registers the CSRF token since the session may be closed later - Util::callRegister(); + Server::get(CsrfTokenManager::class)->getToken()->getEncryptedValue(); if ($this->isInvalidCSRFRequired($reflectionMethod)) { /* * Only allow the CSRF check to fail on OCS Requests. This kind of diff --git a/lib/private/Template/Template.php b/lib/private/Template/Template.php index 1eb731659b181..832da176b942b 100644 --- a/lib/private/Template/Template.php +++ b/lib/private/Template/Template.php @@ -11,6 +11,7 @@ namespace OC\Template; use OC\Security\CSP\ContentSecurityPolicyNonceManager; +use OC\Security\CSRF\CsrfTokenManager; use OC\TemplateLayout; use OCP\App\AppPathNotFoundException; use OCP\App\IAppManager; @@ -40,7 +41,7 @@ public function __construct( ) { $theme = \OC_Util::getTheme(); - $requestToken = ($registerCall ? Util::callRegister() : ''); + $requestToken = ($registerCall ? Server::get(CsrfTokenManager::class)->getToken()->getEncryptedValue() : ''); $cspNonce = Server::get(ContentSecurityPolicyNonceManager::class)->getNonce(); // fix translation when app is something like core/lostpassword diff --git a/lib/private/legacy/OC_User.php b/lib/private/legacy/OC_User.php index ddd426da942e4..f40073d6da393 100644 --- a/lib/private/legacy/OC_User.php +++ b/lib/private/legacy/OC_User.php @@ -6,6 +6,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ use OC\Authentication\Token\IProvider; +use OC\Security\CSRF\CsrfTokenManager; use OC\SystemConfig; use OC\User\Database; use OC\User\DisabledUserException; @@ -291,7 +292,7 @@ public static function getLogoutUrl(IURLGenerator $urlGenerator): string { } $logoutUrl = $urlGenerator->linkToRoute('core.login.logout'); - $logoutUrl .= '?requesttoken=' . urlencode(Util::callRegister()); + $logoutUrl .= '?requesttoken=' . urlencode(Server::get(CsrfTokenManager::class)->getToken()->getEncryptedValue()); return $logoutUrl; } diff --git a/tests/lib/NavigationManagerTest.php b/tests/lib/NavigationManagerTest.php index 53d7e81302b92..ed93b8154d701 100644 --- a/tests/lib/NavigationManagerTest.php +++ b/tests/lib/NavigationManagerTest.php @@ -11,6 +11,7 @@ use OC\App\AppManager; use OC\Group\Manager; use OC\NavigationManager; +use OC\Security\CSRF\CsrfTokenManager; use OC\SubAdmin; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; @@ -21,6 +22,7 @@ use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Navigation\Events\LoadAdditionalEntriesEvent; +use OCP\Server; use OCP\Util; use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; @@ -323,7 +325,7 @@ public static function providesNavigationConfig(): array { 'logout' => [ 'id' => 'logout', 'order' => 99999, - 'href' => 'https://example.com/logout?requesttoken=' . urlencode(Util::callRegister()), + 'href' => 'https://example.com/logout?requesttoken=' . urlencode(Server::get(CsrfTokenManager::class)->getToken()->getEncryptedValue()), 'icon' => '/apps/core/img/actions/logout.svg', 'name' => 'Log out', 'active' => false, From e14de183d40e5490cbc67a05402d28d12e1e0a43 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Mon, 9 Mar 2026 13:13:58 +0100 Subject: [PATCH 3/5] refactor(utils): Mark share related methods as deprecated The underlying OC_Utils methods are already deprecated Signed-off-by: Carl Schwan --- apps/settings/lib/Settings/Admin/Sharing.php | 2 +- lib/public/Util.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/settings/lib/Settings/Admin/Sharing.php b/apps/settings/lib/Settings/Admin/Sharing.php index 468e64793fcc4..d4f5af87a1448 100644 --- a/apps/settings/lib/Settings/Admin/Sharing.php +++ b/apps/settings/lib/Settings/Admin/Sharing.php @@ -58,7 +58,7 @@ public function getForm() { 'restrictUserEnumerationFullMatchDisplayname' => $this->shareManager->matchDisplayName(), 'restrictUserEnumerationFullMatchEmail' => $this->shareManager->matchEmail(), 'restrictUserEnumerationFullMatchIgnoreSecondDN' => $this->shareManager->ignoreSecondDisplayName(), - 'enforceLinksPassword' => Util::isPublicLinkPasswordRequired(false), + 'enforceLinksPassword' => $this->shareManager->shareApiLinkEnforcePassword(false), 'enforceLinksPasswordExcludedGroups' => json_decode($excludedPasswordGroups) ?? [], 'enforceLinksPasswordExcludedGroupsEnabled' => $this->config->getSystemValueBool('sharing.allow_disabled_password_enforcement_groups', false), 'onlyShareWithGroupMembers' => $this->shareManager->shareWithGroupMembersOnly(), diff --git a/lib/public/Util.php b/lib/public/Util.php index b2b93d8ee8108..b16b0b9d26db7 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -592,15 +592,18 @@ public static function naturalSortCompare($a, $b) { * @param bool $checkGroupMembership Check group membership exclusion * @return boolean * @since 7.0.0 + * @deprecated 34.0.0 use OCP\Share\IManager's shareApiLinkEnforcePassword directly */ public static function isPublicLinkPasswordRequired(bool $checkGroupMembership = true) { return \OC_Util::isPublicLinkPasswordRequired($checkGroupMembership); } /** - * check if share API enforces a default expire date + * Check if share API enforces a default expire date + * * @return boolean * @since 8.0.0 + * @deprecated 34.0.0 use OCP\Share\IManager's shareApiLinkDefaultExpireDateEnforced directly */ public static function isDefaultExpireDateEnforced() { return \OC_Util::isDefaultExpireDateEnforced(); From e0e77d5a3016f17d4d25ac10d211b0b040618d4f Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Mon, 9 Mar 2026 13:21:12 +0100 Subject: [PATCH 4/5] refactor: Delete deprecated code from OC_Util Signed-off-by: Carl Schwan --- .../lib/Controller/AdminController.php | 8 +- .../tests/Controller/AdminControllerTest.php | 2 + .../Security/SecurityMiddleware.php | 1 - lib/private/legacy/OC_User.php | 1 - lib/private/legacy/OC_Util.php | 77 ------------------- lib/public/ServerVersion.php | 10 +++ lib/public/Util.php | 36 +++++---- tests/lib/NavigationManagerTest.php | 1 - 8 files changed, 38 insertions(+), 98 deletions(-) diff --git a/apps/updatenotification/lib/Controller/AdminController.php b/apps/updatenotification/lib/Controller/AdminController.php index 9b05b2974d33a..3402410536b41 100644 --- a/apps/updatenotification/lib/Controller/AdminController.php +++ b/apps/updatenotification/lib/Controller/AdminController.php @@ -20,7 +20,7 @@ use OCP\IL10N; use OCP\IRequest; use OCP\Security\ISecureRandom; -use OCP\Util; +use OCP\ServerVersion; use Psr\Log\LoggerInterface; class AdminController extends Controller { @@ -35,16 +35,16 @@ public function __construct( private ITimeFactory $timeFactory, private IL10N $l10n, private LoggerInterface $logger, + private ServerVersion $serverVersion, ) { parent::__construct($appName, $request); } /** - * @param string $channel - * @return DataResponse + * @param 'beta'|'stable'|'enterprise'|'git' $channel */ public function setChannel(string $channel): DataResponse { - Util::setChannel($channel); + $this->serverVersion->setChannel($channel); $this->appConfig->setValueInt('core', 'lastupdatedat', 0); return new DataResponse(['status' => 'success', 'data' => ['message' => $this->l10n->t('Channel updated')]]); } diff --git a/apps/updatenotification/tests/Controller/AdminControllerTest.php b/apps/updatenotification/tests/Controller/AdminControllerTest.php index 566d8cfa14637..a27b409490bbf 100644 --- a/apps/updatenotification/tests/Controller/AdminControllerTest.php +++ b/apps/updatenotification/tests/Controller/AdminControllerTest.php @@ -18,6 +18,7 @@ use OCP\IL10N; use OCP\IRequest; use OCP\Security\ISecureRandom; +use OCP\ServerVersion; use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; @@ -56,6 +57,7 @@ protected function setUp(): void { $this->timeFactory, $this->l10n, $this->logger, + $this->createMock(ServerVersion::class), ); } diff --git a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php index ad7858cc690e8..92493be0670ec 100644 --- a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php @@ -47,7 +47,6 @@ use OCP\IUserSession; use OCP\Security\Ip\IRemoteAddress; use OCP\Server; -use OCP\Util; use Psr\Log\LoggerInterface; use ReflectionMethod; diff --git a/lib/private/legacy/OC_User.php b/lib/private/legacy/OC_User.php index f40073d6da393..04f5960006224 100644 --- a/lib/private/legacy/OC_User.php +++ b/lib/private/legacy/OC_User.php @@ -30,7 +30,6 @@ use OCP\User\Events\BeforeUserLoggedInEvent; use OCP\User\Events\UserLoggedInEvent; use OCP\UserInterface; -use OCP\Util; use Psr\Log\LoggerInterface; /** diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php index b3b0f4e3e20ca..26f4e76e4d90b 100644 --- a/lib/private/legacy/OC_Util.php +++ b/lib/private/legacy/OC_Util.php @@ -565,44 +565,6 @@ public static function checkLoggedIn(): void { } } - /** - * Check if the user is a admin, redirects to home if not - * - * @deprecated 32.0.0 - */ - public static function checkAdminUser(): void { - self::checkLoggedIn(); - if (!OC_User::isAdminUser(OC_User::getUser())) { - header('Location: ' . Util::linkToAbsolute('', 'index.php')); - exit(); - } - } - - /** - * Returns the URL of the default page - * based on the system configuration and - * the apps visible for the current user - * - * @return string URL - * @deprecated 32.0.0 use IURLGenerator's linkToDefaultPageUrl directly - */ - public static function getDefaultPageUrl() { - /** @var IURLGenerator $urlGenerator */ - $urlGenerator = Server::get(IURLGenerator::class); - return $urlGenerator->linkToDefaultPageUrl(); - } - - /** - * Redirect to the user default page - * - * @deprecated 32.0.0 - */ - public static function redirectToDefaultPage(): void { - $location = self::getDefaultPageUrl(); - header('Location: ' . $location); - exit(); - } - /** * get an id unique for this instance * @@ -618,45 +580,6 @@ public static function getInstanceId(): string { return $id; } - /** - * Public function to sanitize HTML - * - * This function is used to sanitize HTML and should be applied on any - * string or array of strings before displaying it on a web page. - * - * @param string|string[] $value - * @return ($value is array ? string[] : string) - * @deprecated 32.0.0 use \OCP\Util::sanitizeHTML instead - */ - public static function sanitizeHTML($value) { - if (is_array($value)) { - $value = array_map(function ($value) { - return self::sanitizeHTML($value); - }, $value); - } else { - // Specify encoding for PHP<5.4 - $value = htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); - } - return $value; - } - - /** - * Public function to encode url parameters - * - * This function is used to encode path to file before output. - * Encoding is done according to RFC 3986 with one exception: - * Character '/' is preserved as is. - * - * @param string $component part of URI to encode - * @return string - * @deprecated 32.0.0 use \OCP\Util::encodePath instead - */ - public static function encodePath($component) { - $encoded = rawurlencode($component); - $encoded = str_replace('%2F', '/', $encoded); - return $encoded; - } - /** * Check if current locale is non-UTF8 * diff --git a/lib/public/ServerVersion.php b/lib/public/ServerVersion.php index e5df2515a86c3..90d008ccfbf40 100644 --- a/lib/public/ServerVersion.php +++ b/lib/public/ServerVersion.php @@ -91,6 +91,16 @@ public function getChannel(): string { return $this->channel; } + /** + * Set current update channel. + * + * @param 'beta'|'stable'|'enterprise'|'git' $channel + * @since 34.0.0 + */ + public function setChannel(string $channel): void { + Server::get(IConfig::class)->setSystemValue('updater.release.channel', $channel); + } + /** * @since 31.0.0 */ diff --git a/lib/public/Util.php b/lib/public/Util.php index b16b0b9d26db7..4b0280db77f1c 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -51,16 +51,17 @@ public static function hasExtendedSupport(): bool { return $subscriptionRegistry->delegateHasExtendedSupport(); } catch (ContainerExceptionInterface $e) { } - return \OCP\Server::get(IConfig::class)->getSystemValueBool('extendedSupport', false); + return Server::get(IConfig::class)->getSystemValueBool('extendedSupport', false); } /** * Set current update channel * @param string $channel * @since 8.1.0 + * @deprecated 33.0.0 Use \OCP\ServerVersion::setChannel */ public static function setChannel($channel) { - \OCP\Server::get(IConfig::class)->setSystemValue('updater.release.channel', $channel); + Server::get(IConfig::class)->setSystemValue('updater.release.channel', $channel); } /** @@ -70,7 +71,7 @@ public static function setChannel($channel) { * @deprecated 31.0.0 Use \OCP\ServerVersion::getChannel */ public static function getChannel() { - return \OCP\Server::get(ServerVersion::class)->getChannel(); + return Server::get(ServerVersion::class)->getChannel(); } /** @@ -182,7 +183,7 @@ public static function addScript(string $application, ?string $file = null, stri */ public static function getScripts(): array { // Sort scriptDeps into sortedScriptDeps - $scriptSort = \OCP\Server::get(AppScriptSort::class); + $scriptSort = Server::get(AppScriptSort::class); $sortedScripts = $scriptSort->sort(self::$scripts, self::$scriptDeps); // Flatten array and remove duplicates @@ -209,7 +210,7 @@ public static function getScripts(): array { */ public static function addTranslations($application, $languageCode = null, $init = false) { if (is_null($languageCode)) { - $languageCode = \OCP\Server::get(IFactory::class)->findLanguage($application); + $languageCode = Server::get(IFactory::class)->findLanguage($application); } if (!empty($application)) { $path = "$application/l10n/$languageCode"; @@ -273,7 +274,7 @@ public static function linkToRemote(string $service): string { * @since 5.0.0 */ public static function getServerHostName() { - $host_name = \OCP\Server::get(IRequest::class)->getServerHost(); + $host_name = Server::get(IRequest::class)->getServerHost(); // strip away port number (if existing) $colon_pos = strpos($host_name, ':'); if ($colon_pos != false) { @@ -299,13 +300,13 @@ public static function getServerHostName() { * @since 5.0.0 */ public static function getDefaultEmailAddress(string $user_part): string { - $config = \OCP\Server::get(IConfig::class); + $config = Server::get(IConfig::class); $user_part = $config->getSystemValueString('mail_from_address', $user_part); $host_name = self::getServerHostName(); $host_name = $config->getSystemValueString('mail_domain', $host_name); $defaultEmailAddress = $user_part . '@' . $host_name; - $emailValidator = \OCP\Server::get(IEmailValidator::class); + $emailValidator = Server::get(IEmailValidator::class); if ($emailValidator->isValid($defaultEmailAddress)) { return $defaultEmailAddress; } @@ -447,7 +448,7 @@ public static function emitHook($signalclass, $signalname, $params = []) { */ public static function callRegister() { if (self::$token === '') { - self::$token = \OCP\Server::get(CsrfTokenManager::class)->getToken()->getEncryptedValue(); + self::$token = Server::get(CsrfTokenManager::class)->getToken()->getEncryptedValue(); } return self::$token; } @@ -462,8 +463,14 @@ public static function callRegister() { * @return ($value is array ? string[] : string) an array of sanitized strings or a single sanitized string, depends on the input parameter. * @since 4.5.0 */ - public static function sanitizeHTML($value) { - return \OC_Util::sanitizeHTML($value); + public static function sanitizeHTML(string|array $value): string|array { + if (is_array($value)) { + return array_map(function (string $value): string { + return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); + }, $value); + } + // Specify encoding for PHP<5.4 + return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); } /** @@ -477,8 +484,9 @@ public static function sanitizeHTML($value) { * @return string * @since 6.0.0 */ - public static function encodePath($component) { - return \OC_Util::encodePath($component); + public static function encodePath(string $component): string { + $encoded = rawurlencode($component); + return str_replace('%2F', '/', $encoded); } /** @@ -619,7 +627,7 @@ public static function isDefaultExpireDateEnforced() { */ public static function needUpgrade() { if (!isset(self::$needUpgradeCache)) { - self::$needUpgradeCache = \OC_Util::needUpgrade(\OCP\Server::get(\OC\SystemConfig::class)); + self::$needUpgradeCache = \OC_Util::needUpgrade(Server::get(\OC\SystemConfig::class)); } return self::$needUpgradeCache; } diff --git a/tests/lib/NavigationManagerTest.php b/tests/lib/NavigationManagerTest.php index ed93b8154d701..86f87a3292220 100644 --- a/tests/lib/NavigationManagerTest.php +++ b/tests/lib/NavigationManagerTest.php @@ -23,7 +23,6 @@ use OCP\L10N\IFactory; use OCP\Navigation\Events\LoadAdditionalEntriesEvent; use OCP\Server; -use OCP\Util; use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; From 56066b917b8421b5414bc83ab09e93fa578aeca2 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Mon, 9 Mar 2026 13:33:28 +0100 Subject: [PATCH 5/5] fix: Allow sanitizeHTML to accept null Used like this in many places Signed-off-by: Carl Schwan --- lib/public/Util.php | 4 ++-- tests/lib/UtilTest.php | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/public/Util.php b/lib/public/Util.php index 4b0280db77f1c..c2db75444a10e 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -459,11 +459,11 @@ public static function callRegister() { * This function is used to sanitize HTML and should be applied on any * string or array of strings before displaying it on a web page. * - * @param string|string[] $value + * @param string|string[]|null $value * @return ($value is array ? string[] : string) an array of sanitized strings or a single sanitized string, depends on the input parameter. * @since 4.5.0 */ - public static function sanitizeHTML(string|array $value): string|array { + public static function sanitizeHTML(string|array|null $value): string|array { if (is_array($value)) { return array_map(function (string $value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); diff --git a/tests/lib/UtilTest.php b/tests/lib/UtilTest.php index 6738cafdb1ff2..c30389ec2e614 100644 --- a/tests/lib/UtilTest.php +++ b/tests/lib/UtilTest.php @@ -36,17 +36,11 @@ public function testSanitizeHTML(): void { 'While it is unusual to pass an array', 'this function actually supports it.', 'And therefore there needs to be a for it!', - [ - 'And It Even May Nest', - ], ]; $goodArray = [ 'While it is unusual to pass an array', 'this function actually <blink>supports</blink> it.', 'And therefore there needs to be a <script>alert("Unit"+'test')</script> for it!', - [ - 'And It Even May <strong>Nest</strong>' - ], ]; $result = Util::sanitizeHTML($badArray); $this->assertEquals($goodArray, $result);