From e5b8bf3d601bec0099252c8ee2f54e5571385f1a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 28 Sep 2026 19:49:35 -0400 Subject: [PATCH] fix malware blacklist compatibility with SMAPI 4.5.2 and earlier The revamped blacklist is more compact, which triggers the bug fixed in f090df0db30e823017501525c66ebf67762456de (where syncing a smaller new version corrupts the file). This pads the file to the largest previous blacklist size to avoid the issue. --- src/SMAPI.Web/BackgroundJobs/MalwareBlacklistJob.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/SMAPI.Web/BackgroundJobs/MalwareBlacklistJob.cs b/src/SMAPI.Web/BackgroundJobs/MalwareBlacklistJob.cs index 85a353b4..e892418b 100644 --- a/src/SMAPI.Web/BackgroundJobs/MalwareBlacklistJob.cs +++ b/src/SMAPI.Web/BackgroundJobs/MalwareBlacklistJob.cs @@ -20,6 +20,10 @@ internal class MalwareBlacklistJob : IBackgroundJob /********* ** Fields *********/ + /// The minimum size in bytes for the generated malware blacklist file. + /// The generated file is padded to this length, to avoid a bug in SMAPI 4.5.2 and earlier where a smaller newer version corrupts the file (since it overwrites the previous file without truncating). + private const int MinBlacklistBytes = 8589; + /// The HTTP client for fetching data from GitHub. private readonly IGitHubClient GitHubClient; @@ -64,6 +68,7 @@ internal class MalwareBlacklistJob : IBackgroundJob MalwareBlacklistConfig config = this.Config.Value; string repo = config.GitHubRepo ?? throw new InvalidOperationException("Can't update the malware blacklist: no GitHub repository is configured."); string outputPath = Path.Combine(this.WebRootPath, Startup.BlacklistFileName); + UTF8Encoding encoding = new(encoderShouldEmitUTF8Identifier: false); // fetch file GitFile file; @@ -93,10 +98,15 @@ internal class MalwareBlacklistJob : IBackgroundJob string publicJson = MalwareBlacklistConverter.ToPublicJson(blacklist); context.WriteLine($"Updated malware blacklist ({blacklist.Blacklist.Length} mod entries and {blacklist.LooseFileBlacklist.Length} loose file entries)."); + // pad to minimum size + int byteCount = encoding.GetByteCount(publicJson); + if (byteCount < MalwareBlacklistJob.MinBlacklistBytes) + publicJson += new string(' ', MalwareBlacklistJob.MinBlacklistBytes - byteCount); + // save file { string tempPath = $"{outputPath}.tmp"; - await File.WriteAllTextAsync(tempPath, publicJson, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); + await File.WriteAllTextAsync(tempPath, publicJson, encoding); File.Move(tempPath, outputPath, overwrite: true); context.WriteLine($"Saved to {Startup.BlacklistFileName}.");