Catch both old uppercase 5-char hash and newer lowercase 5-char hash when migrating to new hash

This commit is contained in:
SnowySailor 2026-06-15 12:59:49 +09:00
parent acac8f7bbb
commit 3574d03aac

View file

@ -39,22 +39,27 @@ internal partial class ExportAssetDownloader(string workingDirPath, bool reuse)
// Check for a file cached by the legacy naming scheme (5-char hash) and rename it // Check for a file cached by the legacy naming scheme (5-char hash) and rename it
// to the new naming scheme to preserve backwards compatibility with existing exports // to the new naming scheme to preserve backwards compatibility with existing exports
// This will catch both the 5-char lowercase hash and the 5-char uppercase hash variants
if (reuse) if (reuse)
{ {
var legacyFilePath = Path.Combine(workingDirPath, GetLegacyFileNameFromUrl(url)); var legacyFileNames = GetLegacyFileNamesFromUrl(url);
if (File.Exists(legacyFilePath)) foreach (var legacyFileName in legacyFileNames)
{ {
// Overwrite in case the destination file was created concurrently between our var legacyFilePath = Path.Combine(workingDirPath, legacyFileName);
// earlier existence check and this move operation if (File.Exists(legacyFilePath))
try
{ {
File.Move(legacyFilePath, filePath, overwrite: true); // Overwrite in case the destination file was created concurrently between our
return _previousPathsByUrl[url] = filePath; // earlier existence check and this move operation
} try
catch (IOException) {
{ File.Move(legacyFilePath, filePath, overwrite: true);
// The legacy file was moved or deleted concurrently or something else happened. return _previousPathsByUrl[url] = filePath;
// Upgrading old files is not crucial, so we can just move on. }
catch (IOException)
{
// The legacy file was moved or deleted concurrently or something else happened.
// Upgrading old files is not crucial, so we can just move on.
}
} }
} }
} }
@ -137,13 +142,23 @@ internal partial class ExportAssetDownloader
); );
// Legacy naming used a 5-char hash, kept for backwards compatibility with existing exports // Legacy naming used a 5-char hash, kept for backwards compatibility with existing exports
private static string GetLegacyFileNameFromUrl(string url) => private static string[] GetLegacyFileNamesFromUrl(string url)
GetFileNameFromUrl( {
url, var hashData = SHA256.HashData(Encoding.UTF8.GetBytes(NormalizeUrl(url)));
SHA256
.HashData(Encoding.UTF8.GetBytes(NormalizeUrl(url))) return
.Pipe(Convert.ToHexStringLower) [
// 5 chars = 20 bits, reaches 1% collision probability at ~145 files // Lowercase variant (introduced in 2.46.1)
.Truncate(5) GetFileNameFromUrl(
); url,
Convert.ToHexStringLower(hashData).Truncate(5)
),
// Uppercase variant (original)
GetFileNameFromUrl(
url,
Convert.ToHexString(hashData).Truncate(5)
)
];
}
} }