From 6a2eda1252d1f03d56bc0664f943f8f6911190b4 Mon Sep 17 00:00:00 2001 From: Sucukdeluxe <259325684+Sucukdeluxe@users.noreply.github.com> Date: Mon, 17 Aug 2026 03:29:00 +0200 Subject: [PATCH] fix: accept equivalent installer metadata names Allow updater manifests from the Gitea and GitHub release pipelines to use different separator characters in the same installer filename while preserving exact version, size, checksum, and executable validation. --- lib/updater.js | 6 +++++- tests/updater-version.test.js | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/updater.js b/lib/updater.js index 59be8ee..733084c 100644 --- a/lib/updater.js +++ b/lib/updater.js @@ -61,6 +61,10 @@ function findLatestYml(assets) { return assets.find(a => /^latest\.yml$/i.test(a.name)) || null; } +function normalizeInstallerName(value) { + return path.basename(String(value || '')).toLowerCase().replace(/[ ._]+/g, ''); +} + async function fetchJson(url, signal) { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT); @@ -180,7 +184,7 @@ async function parseLatestYml(url, expected = {}, fetchImpl = fetch) { if (expected.version && version !== expected.version) { throw new Error('Prüfsummen-Metadaten gehören zu einer anderen Version'); } - if (expected.assetName && path.basename(assetPath) !== path.basename(expected.assetName)) { + if (expected.assetName && normalizeInstallerName(assetPath) !== normalizeInstallerName(expected.assetName)) { throw new Error('Prüfsummen-Metadaten gehören nicht zum ausgewählten Installer'); } if (expected.assetSize && size !== Number(expected.assetSize)) { diff --git a/tests/updater-version.test.js b/tests/updater-version.test.js index f73b715..2db6d33 100644 --- a/tests/updater-version.test.js +++ b/tests/updater-version.test.js @@ -336,3 +336,18 @@ test('existing release recovery rejects a mismatched transport tag', async () => /existing release tag "v9\.9\.9" does not match "v2\.1\.20"/ ); }); + +test('checksum metadata accepts equivalent transport-specific installer separators', async () => { + const sha = crypto.randomBytes(64).toString('base64'); + const metadata = await parseLatestYml('https://update.invalid/latest.yml', { + version: '2.1.22', + assetName: 'Multi-Hoster-Upload Setup 2.1.22.exe', + assetSize: 456 + }, async () => ({ + ok: true, + status: 200, + text: async () => `version: 2.1.22\npath: Multi-Hoster-Upload.Setup.2.1.22.exe\nsha512: ${sha}\nsize: 456\n` + })); + + assert.equal(metadata.path, 'Multi-Hoster-Upload.Setup.2.1.22.exe'); +});