From d283d8c332b5147d94319bb4e1b6e2223170c05f Mon Sep 17 00:00:00 2001 From: Kevin Gatera Date: Sun, 2 Aug 2026 18:16:03 -0400 Subject: [PATCH] make backup listing resilient to corrupt archives A corrupt or unreadable zip no longer aborts the whole loadBackups loop or leaks the zip handle - the entry check now sits inside the per-file try so one bad archive is skipped like any other invalid backup. --- server/managers/BackupManager.js | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/server/managers/BackupManager.js b/server/managers/BackupManager.js index aef76bddc..277982193 100644 --- a/server/managers/BackupManager.js +++ b/server/managers/BackupManager.js @@ -390,7 +390,7 @@ class BackupManager { const fullFilePath = Path.join(this.backupPath, filename) let zip = null - let data = null + let backup = null try { zip = new StreamZip.async({ file: fullFilePath }) const entries = await zip.entries() @@ -407,25 +407,24 @@ class BackupManager { continue } - data = await zip.entryData('details') + const data = await zip.entryData('details') + const details = data.toString('utf8').split('\n') + + backup = new Backup({ details, fullPath: fullFilePath }) + const backupDialect = this.getBackupDialect(backup) + const databaseEntryName = this.getBackupEntryName(backupDialect) + + if (!backupDialect || !entries[databaseEntryName]) { + Logger.error(`[BackupManager] Unsupported database backup format found "${backup.filename}"`) + await zip.close().catch(() => {}) + continue + } } catch (error) { Logger.error(`[BackupManager] Failed to unzip backup "${fullFilePath}"`, error) if (zip) await zip.close().catch(() => {}) continue } - const details = data.toString('utf8').split('\n') - - const backup = new Backup({ details, fullPath: fullFilePath }) - const backupDialect = this.getBackupDialect(backup) - const databaseEntryName = this.getBackupEntryName(backupDialect) - - if (!backupDialect || !Object.keys(await zip.entries()).includes(databaseEntryName)) { - Logger.error(`[BackupManager] Unsupported database backup format found "${backup.filename}"`) - await zip.close() - continue - } - if (!backup.serverVersion) { // Backups before v2 Logger.error(`[BackupManager] Old unsupported backup was found "${backup.filename}"`)