Skip to content

Commit a6ab47a

Browse files
Use releaseTag with fallback to downloadUrl in updates.xml
1 parent 79b0cbb commit a6ab47a

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

ILSpy/Updates/UpdateService.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace ICSharpCode.ILSpy.Updates
2828
{
2929
internal static class UpdateService
3030
{
31+
const string ReleaseTagBaseUrl = "https://github.com/icsharpcode/ILSpy/releases/tag/";
3132
static readonly Uri UpdateUrl = new Uri("https://icsharpcode.github.io/ILSpy/updates.xml");
3233
const string band = "stable";
3334

@@ -39,15 +40,32 @@ public static async Task<AvailableVersionInfo> GetLatestVersionAsync()
3940
UseProxy = true,
4041
UseDefaultCredentials = true
4142
});
43+
44+
// Issue #3707: Remove 301 redirect logic once ilspy.net CNAME gone
4245
string data = await GetWithRedirectsAsync(client, UpdateUrl).ConfigureAwait(false);
4346

4447
XDocument doc = XDocument.Load(new StringReader(data));
4548
var bands = doc.Root.Elements("band").ToList();
4649
var currentBand = bands.FirstOrDefault(b => (string)b.Attribute("id") == band) ?? bands.First();
4750
Version version = new Version((string)currentBand.Element("latestVersion"));
48-
string url = (string)currentBand.Element("downloadUrl");
49-
if (!(url.StartsWith("http://", StringComparison.Ordinal) || url.StartsWith("https://", StringComparison.Ordinal)))
50-
url = null; // don't accept non-urls
51+
52+
string url = null;
53+
string releaseTag = (string)currentBand.Element("releaseTag");
54+
55+
if (releaseTag != null)
56+
{
57+
url = ReleaseTagBaseUrl + releaseTag;
58+
// Prevent path traversal: normalize the URI and verify it still starts with the expected base
59+
if (!new Uri(url).AbsoluteUri.StartsWith(ReleaseTagBaseUrl, StringComparison.Ordinal))
60+
url = null;
61+
}
62+
else
63+
{
64+
// Issue #3707: Remove else branch fallback logic once releaseTag version has shipped + 6 months
65+
url = (string)currentBand.Element("downloadUrl");
66+
if (!(url.StartsWith("http://", StringComparison.Ordinal) || url.StartsWith("https://", StringComparison.Ordinal)))
67+
url = null; // don't accept non-urls
68+
}
5169

5270
LatestAvailableVersion = new AvailableVersionInfo { Version = version, DownloadUrl = url };
5371
return LatestAvailableVersion;

0 commit comments

Comments
 (0)