mirror of https://github.com/icsharpcode/ILSpy.git
Browse Source
* Use releaseTag with fallback to downloadUrl in updates.xml * Add tests * Prevent arbitrary downloadUrl - must start with BaseUrl as well * Remove custom domain ilspy.net in end-user visible placespull/3715/head
6 changed files with 144 additions and 8 deletions
@ -0,0 +1,109 @@
@@ -0,0 +1,109 @@
|
||||
using System; |
||||
using System.Net; |
||||
using System.Net.Http; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
|
||||
using AwesomeAssertions; |
||||
|
||||
using ICSharpCode.ILSpy.Updates; |
||||
|
||||
using NUnit.Framework; |
||||
|
||||
namespace ICSharpCode.ILSpy.Tests; |
||||
|
||||
[TestFixture] |
||||
public class UpdateServiceTests |
||||
{ |
||||
[Test] |
||||
public async Task GetLatestVersionAsync_UsesReleaseTag_WhenReleaseTagIsPresent() |
||||
{ |
||||
const string xml = """
|
||||
<updateInfo> |
||||
<band id="stable"> |
||||
<latestVersion>10.0.0.0</latestVersion> |
||||
<releaseTag>v10.0</releaseTag> |
||||
<downloadUrl>https://example.com/ignored.zip</downloadUrl>
|
||||
</band> |
||||
</updateInfo> |
||||
""";
|
||||
|
||||
using var client = new HttpClient(new StubHttpMessageHandler(xml)); |
||||
|
||||
var result = await UpdateService.GetLatestVersionAsync(client, new Uri("https://example.com/updates.xml")); |
||||
|
||||
result.Version.Should().Be(new Version(10, 0, 0, 0)); |
||||
result.DownloadUrl.Should().Be("https://github.com/icsharpcode/ILSpy/releases/tag/v10.0"); |
||||
} |
||||
|
||||
[Test] |
||||
public async Task GetLatestVersionAsync_ReturnsNullDownloadUrl_WhenReleaseTagContainsPathTraversalAttempt() |
||||
{ |
||||
const string xml = """
|
||||
<updateInfo> |
||||
<band id="stable"> |
||||
<latestVersion>10.0.0.0</latestVersion> |
||||
<releaseTag>../malicious</releaseTag> |
||||
<downloadUrl>https://example.com/ignored.zip</downloadUrl>
|
||||
</band> |
||||
</updateInfo> |
||||
""";
|
||||
|
||||
using var client = new HttpClient(new StubHttpMessageHandler(xml)); |
||||
|
||||
var result = await UpdateService.GetLatestVersionAsync(client, new Uri("https://example.com/updates.xml")); |
||||
|
||||
result.Version.Should().Be(new Version(10, 0, 0, 0)); |
||||
result.DownloadUrl.Should().BeNull(); |
||||
} |
||||
|
||||
[Test] |
||||
public async Task GetLatestVersionAsync_UsesDownloadUrl_WhenReleaseTagIsMissing() |
||||
{ |
||||
const string xml = """
|
||||
<updateInfo> |
||||
<band id="stable"> |
||||
<latestVersion>10.0.0.0</latestVersion> |
||||
<downloadUrl>https://github.com/icsharpcode/ILSpy/releases/tag/v10.0</downloadUrl>
|
||||
</band> |
||||
</updateInfo> |
||||
""";
|
||||
|
||||
using var client = new HttpClient(new StubHttpMessageHandler(xml)); |
||||
|
||||
var result = await UpdateService.GetLatestVersionAsync(client, new Uri("https://example.com/updates.xml")); |
||||
|
||||
result.Version.Should().Be(new Version(10, 0, 0, 0)); |
||||
result.DownloadUrl.Should().Be("https://github.com/icsharpcode/ILSpy/releases/tag/v10.0"); |
||||
} |
||||
|
||||
[Test] |
||||
public async Task GetLatestVersionAsync_UsesDownloadUrl_ButFailsBecauseBaseUrlDoesntMatch() |
||||
{ |
||||
const string xml = """
|
||||
<updateInfo> |
||||
<band id="stable"> |
||||
<latestVersion>10.0.0.0</latestVersion> |
||||
<downloadUrl>https://example.com/ilspy.zip</downloadUrl>
|
||||
</band> |
||||
</updateInfo> |
||||
""";
|
||||
|
||||
using var client = new HttpClient(new StubHttpMessageHandler(xml)); |
||||
|
||||
var result = await UpdateService.GetLatestVersionAsync(client, new Uri("https://example.com/updates.xml")); |
||||
|
||||
result.Version.Should().Be(new Version(10, 0, 0, 0)); |
||||
result.DownloadUrl.Should().BeNull(); |
||||
} |
||||
|
||||
sealed class StubHttpMessageHandler(string responseContent) : HttpMessageHandler |
||||
{ |
||||
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) |
||||
{ |
||||
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) { |
||||
Content = new StringContent(responseContent) |
||||
}); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue