diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f71d65a..2d755d110 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ All notable changes to this project will be documented in this file. - [Netkan] Improve netkan relationship error message (#4020, #4021 by: HebaruSan) - [Core] Get KSP2 version from game assembly (#4034 by: HebaruSan) - [Multiple] Build nuget package, support netstandard2.0 build (#4039 by: HebaruSan) +- [Core] Use fully sanitized archive.org bucket names (#4043 by: HebaruSan) ## v1.34.4 (Niven) diff --git a/Core/Types/CkanModule.cs b/Core/Types/CkanModule.cs index 67272748c..2b022d605 100644 --- a/Core/Types/CkanModule.cs +++ b/Core/Types/CkanModule.cs @@ -755,17 +755,34 @@ public string DescribeInstallStanzas(IGame game) /// Here it's the first 8 characters of the SHA1 of the DOWNLOADED FILE, not the URL! /// public Uri InternetArchiveDownload - { - get - { - string verStr = version.ToString().Replace(' ', '_').Replace(':', '-'); - // Some alternate registry repositories don't set download_hash - return (download_hash?.sha1 != null && license.All(l => l.Redistributable)) - ? new Uri( - $"https://archive.org/download/{identifier}-{verStr}/{download_hash.sha1.Substring(0, 8)}-{identifier}-{verStr}.zip") - : null; - } - } + => !license.Any(l => l.Redistributable) + ? null + : InternetArchiveURL( + Truncate(bucketExcludePattern.Replace(identifier + "-" + + version.ToString() + .Replace(' ', '_') + .Replace(':', '-'), + ""), + 100), + // Some alternate registry repositories don't set download_hash + download_hash?.sha1); + + private static string Truncate(string s, int len) + => s.Length <= len ? s + : s.Substring(0, len); + + private static Uri InternetArchiveURL(string bucket, string sha1) + => string.IsNullOrEmpty(sha1) + ? null + : new Uri($"https://archive.org/download/{bucket}/{sha1.Substring(0, 8)}-{bucket}.zip"); + + // InternetArchive says: + // Bucket names should be valid archive identifiers; + // try someting matching this regular expression: + // ^[a-zA-Z0-9][a-zA-Z0-9_.-]{4,100}$ + // (We enforce everything except the minimum of 4 characters) + private static readonly Regex bucketExcludePattern = new Regex(@"^[^a-zA-Z0-9]+|[^a-zA-Z0-9._-]", + RegexOptions.Compiled); private const double K = 1024;