From 58946624e633977fd2ec6a0da13951c1e0e97793 Mon Sep 17 00:00:00 2001 From: Anna Larch Date: Mon, 6 Jul 2026 13:33:11 +0200 Subject: [PATCH] fix(parser): reject app IDs longer than 32 characters in info.xml Nextcloud server stores app IDs in a varchar(32) column and crashes with an uncaught InvalidArgumentException when reading config for apps whose ID exceeds that limit. Enforce the same limit at upload time via the info.xml XSD so oversized IDs are rejected with a clear error instead of being silently accepted and later crashing server installs. Fixes #1809 Signed-off-by: Anna Larch --- CHANGELOG.md | 4 ++++ REUSE.toml | 2 +- nextcloudappstore/api/v1/release/info.xsd | 1 + .../api/v1/tests/data/infoxmls/toolongid.xml | 15 +++++++++++++++ nextcloudappstore/api/v1/tests/test_parser.py | 5 +++++ 5 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 nextcloudappstore/api/v1/tests/data/infoxmls/toolongid.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 36d126e2ac7..c727c43ff33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ ## [Unreleased] +### Fixed + +- Reject app IDs longer than 32 characters during upload instead of letting Nextcloud server crash on install. #1809 + ## [4.11.3] - 2026-01-05 ### Changed diff --git a/REUSE.toml b/REUSE.toml index ebdc13de5a4..baa92b57052 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -12,7 +12,7 @@ SPDX-FileCopyrightText = "2016-2025 Nextcloud translators" SPDX-License-Identifier = "AGPL-3.0-or-later" [[annotations]] -path = [".tx/config", "docs/developer.rst", "docs/documentation.rst", "docs/index.rst", "docs/translation.rst", "nextcloudappstore/api/v1/tests/data/archives/appinfosymlink.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/appsymlink.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/changelog.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/contacts.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/empty.zip", "nextcloudappstore/api/v1/tests/data/archives/full.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/invalid.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/invalidname.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/minimal.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/multiplefolders.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/symlink.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/twofactor_u2f.tar.gz", "nextcloudappstore/certificate/tests/data/archives/minimal.tar.gz", "nextcloudappstore/api/v1/tests/data/certificates/news-old.crt", "nextcloudappstore/api/v1/tests/data/infoxmls/badcommand.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/broken-xml.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/digits.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/entities.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/full.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/fullimport.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/invalid.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/invalid-elements.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/minimal.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/news.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/nextcloud.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/no_en_description.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/no_en_name.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/no_en_summary.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/prerelease.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/repair-and-jobs.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/settings-and-activity-and-nav.xml", "nextcloudappstore/core/fixtures/categories.json", "nextcloudappstore/core/fixtures/databases.json", "nextcloudappstore/core/fixtures/licenses.json", "nextcloudappstore/core/static/assets/img/banner.jpg"] +path = [".tx/config", "docs/developer.rst", "docs/documentation.rst", "docs/index.rst", "docs/translation.rst", "nextcloudappstore/api/v1/tests/data/archives/appinfosymlink.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/appsymlink.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/changelog.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/contacts.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/empty.zip", "nextcloudappstore/api/v1/tests/data/archives/full.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/invalid.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/invalidname.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/minimal.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/multiplefolders.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/symlink.tar.gz", "nextcloudappstore/api/v1/tests/data/archives/twofactor_u2f.tar.gz", "nextcloudappstore/certificate/tests/data/archives/minimal.tar.gz", "nextcloudappstore/api/v1/tests/data/certificates/news-old.crt", "nextcloudappstore/api/v1/tests/data/infoxmls/badcommand.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/broken-xml.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/digits.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/entities.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/full.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/fullimport.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/invalid.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/invalid-elements.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/minimal.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/news.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/nextcloud.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/no_en_description.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/no_en_name.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/no_en_summary.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/prerelease.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/repair-and-jobs.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/settings-and-activity-and-nav.xml", "nextcloudappstore/api/v1/tests/data/infoxmls/toolongid.xml", "nextcloudappstore/core/fixtures/categories.json", "nextcloudappstore/core/fixtures/databases.json", "nextcloudappstore/core/fixtures/licenses.json", "nextcloudappstore/core/static/assets/img/banner.jpg"] precedence = "aggregate" SPDX-FileCopyrightText = "2016 Nextcloud GmbH and Nextcloud contributors" SPDX-License-Identifier = "AGPL-3.0-or-later" diff --git a/nextcloudappstore/api/v1/release/info.xsd b/nextcloudappstore/api/v1/release/info.xsd index 0889c7d4315..b6e594a8bde 100644 --- a/nextcloudappstore/api/v1/release/info.xsd +++ b/nextcloudappstore/api/v1/release/info.xsd @@ -310,6 +310,7 @@ + diff --git a/nextcloudappstore/api/v1/tests/data/infoxmls/toolongid.xml b/nextcloudappstore/api/v1/tests/data/infoxmls/toolongid.xml new file mode 100644 index 00000000000..77c9893fd81 --- /dev/null +++ b/nextcloudappstore/api/v1/tests/data/infoxmls/toolongid.xml @@ -0,0 +1,15 @@ + + + skynettechnologiesallinoneaccessibility + News + An RSS/Atom feed reader + An RSS/Atom feed reader + 8.8.2 + AGPL-3.0-or-later + Bernhard Posselt + multimedia + https://github.com/nextcloud/news/issues + + + + diff --git a/nextcloudappstore/api/v1/tests/test_parser.py b/nextcloudappstore/api/v1/tests/test_parser.py index ab824d869b9..8213368a535 100644 --- a/nextcloudappstore/api/v1/tests/test_parser.py +++ b/nextcloudappstore/api/v1/tests/test_parser.py @@ -96,6 +96,11 @@ def test_parse_digit_id(self): result = parse_app_metadata(xml, self.config.info_schema, self.config.pre_info_xslt, self.config.info_xslt) self.assertEqual("twofactor_u2f", result["app"]["id"]) + def test_parse_too_long_id(self): + xml = self._get_contents("data/infoxmls/toolongid.xml") + with self.assertRaises(InvalidAppMetadataXmlException): + parse_app_metadata(xml, self.config.info_schema, self.config.pre_info_xslt, self.config.info_xslt) + def test_parse_invalid_elements(self): xml = self._get_contents("data/infoxmls/invalid-elements.xml") with self.assertRaises(InvalidAppMetadataXmlException):