From a4e2a7bb7bca8a374dd5d644c0c191dedfca9201 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Sun, 27 Oct 2024 19:37:25 +0800 Subject: [PATCH 1/2] fix(appsmanagement): Fix exception on generating preview url for screenshots Some installed apps meant for older server versions might unexpectedly offer up screenshot values in a non-string format (e.g. health). Avoid an exception by checking first if the first app screenshot is indeed a string and otherwise we take the value of the parameter Signed-off-by: Claudio Cambra --- apps/settings/lib/Controller/AppSettingsController.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/settings/lib/Controller/AppSettingsController.php b/apps/settings/lib/Controller/AppSettingsController.php index e4a36c986fe23..554420862a646 100644 --- a/apps/settings/lib/Controller/AppSettingsController.php +++ b/apps/settings/lib/Controller/AppSettingsController.php @@ -254,9 +254,15 @@ private function fetchApps() { $apps = $appClass->listAllApps(); foreach ($apps as $app) { $app['installed'] = true; - // locally installed apps have a flatted screenshot property + if (isset($app['screenshot'][0])) { - $app['screenshot'] = $this->createProxyPreviewUrl($app['screenshot'][0]); + $appScreenshot = $app['screenshot'][0] ?? null; + if (is_array($appScreenshot)) { + // Screenshot with thumbnail + $appScreenshot = $appScreenshot['@value']; + } + + $app['screenshot'] = $this->createProxyPreviewUrl($appScreenshot); } $this->allApps[$app['id']] = $app; } From 849b205b597a78e76cfbd18c21a35398e9440a02 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 28 Oct 2024 08:01:22 +0100 Subject: [PATCH 2/2] fix(appinfo): Make sure screenshot, author and category are always arrays Signed-off-by: Joas Schilling --- lib/private/App/InfoParser.php | 11 ++++ tests/data/app/expected-info.json | 4 +- tests/data/app/various-single-item.json | 50 +++++++++++++++++++ .../data/app/various-single-item.json.license | 2 + tests/data/app/various-single-item.xml | 22 ++++++++ tests/lib/App/InfoParserTest.php | 1 + 6 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 tests/data/app/various-single-item.json create mode 100644 tests/data/app/various-single-item.json.license create mode 100644 tests/data/app/various-single-item.xml diff --git a/lib/private/App/InfoParser.php b/lib/private/App/InfoParser.php index 54afd0069fb15..c22db132c4737 100644 --- a/lib/private/App/InfoParser.php +++ b/lib/private/App/InfoParser.php @@ -190,6 +190,17 @@ public function parse($file) { $array['dependencies']['backend'] = [$array['dependencies']['backend']]; } + // Ensure some fields are always arrays + if (isset($array['screenshot']) && !is_array($array['screenshot'])) { + $array['screenshot'] = [$array['screenshot']]; + } + if (isset($array['author']) && !is_array($array['author'])) { + $array['author'] = [$array['author']]; + } + if (isset($array['category']) && !is_array($array['category'])) { + $array['category'] = [$array['category']]; + } + if ($this->cache !== null) { $this->cache->set($fileCacheKey, json_encode($array)); } diff --git a/tests/data/app/expected-info.json b/tests/data/app/expected-info.json index c3ea27af7d398..40ba6104104b3 100644 --- a/tests/data/app/expected-info.json +++ b/tests/data/app/expected-info.json @@ -6,7 +6,9 @@ "name": "Server-side Encryption", "description": "\n\tThis application encrypts all files accessed by ownCloud at rest, wherever they are stored. As an example, with this application enabled, external cloud based Amazon S3 storage will be encrypted, protecting this data on storage outside of the control of the Admin. When this application is enabled for the first time, all files are encrypted as users log in and are prompted for their password. The recommended recovery key option enables recovery of files in case the key is lost. \n\tNote that this app encrypts all files that are touched by ownCloud, so external storage providers and applications such as SharePoint will see new files encrypted when they are accessed. Encryption is based on AES 128 or 256 bit keys. More information is available in the Encryption documentation \n\t", "licence": "AGPL", - "author": "Sam Tuke, Bjoern Schiessle, Florin Peter", + "author": [ + "Sam Tuke, Bjoern Schiessle, Florin Peter" + ], "requiremin": "4", "shipped": "true", "documentation": { diff --git a/tests/data/app/various-single-item.json b/tests/data/app/various-single-item.json new file mode 100644 index 0000000000000..ae5e751ab498c --- /dev/null +++ b/tests/data/app/various-single-item.json @@ -0,0 +1,50 @@ +{ + "id": "notifications", + "name": "Notifications", + "description": "A single screenshot should be an array", + "version": "1.0.0", + "licence": "agpl", + "author": [ + "Joas Schilling" + ], + "dependencies": { + "nextcloud": { + "@attributes": { + "min-version": "16", + "max-version": "16" + } + }, + "backend": [] + }, + "screenshot": [ + "https://raw.githubusercontent.com/nextcloud/notifications/refs/heads/master/docs/screenshot.png" + ], + "category": [ + "monitoring" + ], + "info": [], + "background-jobs": [], + "activity": { + "filters": [], + "settings": [], + "providers": [] + }, + "commands": [], + "remote": [], + "public": [], + "repair-steps": { + "install": [], + "pre-migration": [], + "post-migration": [], + "live-migration": [], + "uninstall": [] + }, + "settings": { + "admin": [], + "admin-section": [], + "personal": [], + "personal-section": [] + }, + "two-factor-providers": [], + "types": [] +} diff --git a/tests/data/app/various-single-item.json.license b/tests/data/app/various-single-item.json.license new file mode 100644 index 0000000000000..84f7e70446ece --- /dev/null +++ b/tests/data/app/various-single-item.json.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/tests/data/app/various-single-item.xml b/tests/data/app/various-single-item.xml new file mode 100644 index 0000000000000..cb9595516e151 --- /dev/null +++ b/tests/data/app/various-single-item.xml @@ -0,0 +1,22 @@ + + + + notifications + Notifications + A single screenshot should be an array + 1.0.0 + agpl + Joas Schilling + + monitoring + + https://raw.githubusercontent.com/nextcloud/notifications/refs/heads/master/docs/screenshot.png + + + + + diff --git a/tests/lib/App/InfoParserTest.php b/tests/lib/App/InfoParserTest.php index 9affe3ff9ae39..ddd0df2543594 100644 --- a/tests/lib/App/InfoParserTest.php +++ b/tests/lib/App/InfoParserTest.php @@ -53,6 +53,7 @@ public function providesInfoXml(): array { [null, 'invalid-info.xml'], ['navigation-one-item.json', 'navigation-one-item.xml'], ['navigation-two-items.json', 'navigation-two-items.xml'], + ['various-single-item.json', 'various-single-item.xml'], ]; } }