mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Move file escape to utility and add test for filename web-uri downloading
This commit is contained in:
@@ -264,6 +264,28 @@ namespace Velopack
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Escapes file name such that the file name is safe for writing to disk in the packages folder
|
||||||
|
/// </summary>
|
||||||
|
public static string GetSafeFilename(string fileName)
|
||||||
|
{
|
||||||
|
string safeFileName = Path.GetFileName(fileName);
|
||||||
|
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
|
||||||
|
|
||||||
|
if (safeFileName.IndexOfAny(invalidFileNameChars) != -1) {
|
||||||
|
StringBuilder safeName = new();
|
||||||
|
foreach (char ch in safeFileName) {
|
||||||
|
if (Array.IndexOf(invalidFileNameChars, ch) == -1)
|
||||||
|
safeName.Append(ch);
|
||||||
|
else
|
||||||
|
safeName.Append('_');
|
||||||
|
}
|
||||||
|
safeFileName = safeName.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return safeFileName;
|
||||||
|
}
|
||||||
|
|
||||||
public static string GetDefaultTempBaseDirectory()
|
public static string GetDefaultTempBaseDirectory()
|
||||||
{
|
{
|
||||||
string tempDir;
|
string tempDir;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -232,7 +231,7 @@ namespace Velopack
|
|||||||
var appTempDir = Locator.AppTempDir!;
|
var appTempDir = Locator.AppTempDir!;
|
||||||
var appPackageDir = Locator.PackagesDir!;
|
var appPackageDir = Locator.PackagesDir!;
|
||||||
|
|
||||||
var completeFile = Path.Combine(appPackageDir, GetSafeFilename(targetRelease.FileName));
|
var completeFile = Path.Combine(appPackageDir, Utility.GetSafeFilename(targetRelease.FileName));
|
||||||
var incompleteFile = completeFile + ".partial";
|
var incompleteFile = completeFile + ".partial";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -261,7 +260,7 @@ namespace Velopack
|
|||||||
$"Only full update will be available.");
|
$"Only full update will be available.");
|
||||||
} else {
|
} else {
|
||||||
using var _1 = Utility.GetTempDirectory(out var deltaStagingDir, appTempDir);
|
using var _1 = Utility.GetTempDirectory(out var deltaStagingDir, appTempDir);
|
||||||
string basePackagePath = Path.Combine(appPackageDir, GetSafeFilename(updates.BaseRelease.FileName));
|
string basePackagePath = Path.Combine(appPackageDir, Utility.GetSafeFilename(updates.BaseRelease.FileName));
|
||||||
if (!File.Exists(basePackagePath))
|
if (!File.Exists(basePackagePath))
|
||||||
throw new Exception($"Unable to find base package {basePackagePath} for delta update.");
|
throw new Exception($"Unable to find base package {basePackagePath} for delta update.");
|
||||||
EasyZip.ExtractZipToDirectory(Log, basePackagePath, deltaStagingDir);
|
EasyZip.ExtractZipToDirectory(Log, basePackagePath, deltaStagingDir);
|
||||||
@@ -319,27 +318,6 @@ namespace Velopack
|
|||||||
|
|
||||||
CleanPackagesExcept(completeFile);
|
CleanPackagesExcept(completeFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Ensures that the file name is safe for writing to disk without escaping the packages folder
|
|
||||||
static string GetSafeFilename(string fileName)
|
|
||||||
{
|
|
||||||
string safeFileName = Path.GetFileName(fileName);
|
|
||||||
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
|
|
||||||
|
|
||||||
if (safeFileName.IndexOfAny(invalidFileNameChars) != -1 ) {
|
|
||||||
StringBuilder safeName = new();
|
|
||||||
foreach(char ch in safeFileName) {
|
|
||||||
if (Array.IndexOf(invalidFileNameChars, ch) == -1)
|
|
||||||
safeName.Append(ch);
|
|
||||||
else
|
|
||||||
safeName.Append('_');
|
|
||||||
}
|
|
||||||
safeFileName = safeName.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return safeFileName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -100,6 +100,46 @@ public class UpdateManagerTests
|
|||||||
return new FakeDownloader() { MockedResponseBytes = Encoding.UTF8.GetBytes(json) };
|
return new FakeDownloader() { MockedResponseBytes = Encoding.UTF8.GetBytes(json) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanDownloadFilesAsUrl()
|
||||||
|
{
|
||||||
|
var fixture = PathHelper.GetFixture("AvaloniaCrossPlat-1.0.11-win-full.nupkg");
|
||||||
|
|
||||||
|
using var logger = _output.BuildLoggerFor<UpdateManagerTests>();
|
||||||
|
using var _1 = Utility.GetTempDirectory(out var tempPath);
|
||||||
|
var dl = new FakeDownloader() {
|
||||||
|
MockedResponseBytes = Encoding.UTF8.GetBytes(SimpleJson.SerializeObject(
|
||||||
|
new VelopackAssetFeed {
|
||||||
|
Assets = new VelopackAsset[] {
|
||||||
|
new VelopackAsset() {
|
||||||
|
PackageId = "AvaloniaCrossPlat",
|
||||||
|
Version = new SemanticVersion(1, 0, 11),
|
||||||
|
Type = VelopackAssetType.Full,
|
||||||
|
FileName = $"https://mysite.com/releases/AvaloniaCrossPlat$-1.1.0.nupkg",
|
||||||
|
SHA1 = Utility.CalculateFileSHA1(fixture),
|
||||||
|
Size = new FileInfo(fixture).Length,
|
||||||
|
} }
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
var source = new SimpleWebSource("http://any.com", dl);
|
||||||
|
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger);
|
||||||
|
var um = new UpdateManager(source, null, logger, locator);
|
||||||
|
var info = um.CheckForUpdates();
|
||||||
|
Assert.NotNull(info);
|
||||||
|
Assert.True(new SemanticVersion(1, 0, 11) == info.TargetFullRelease.Version);
|
||||||
|
Assert.Equal(0, info.DeltasToTarget.Count());
|
||||||
|
Assert.False(info.IsDowngrade);
|
||||||
|
Assert.StartsWith($"http://any.com/releases.{VelopackRuntimeInfo.SystemOs.GetOsShortName()}.json?", dl.LastUrl);
|
||||||
|
|
||||||
|
dl.MockedResponseBytes = File.ReadAllBytes(fixture);
|
||||||
|
dl.WriteMockLocalFile = true;
|
||||||
|
um.DownloadUpdates(info);
|
||||||
|
|
||||||
|
Assert.True(File.Exists(Path.Combine(tempPath, "AvaloniaCrossPlat$-1.1.0.nupkg")));
|
||||||
|
Assert.Equal(Path.Combine(tempPath, "AvaloniaCrossPlat$-1.1.0.nupkg.partial"), dl.LastLocalFile);
|
||||||
|
Assert.Equal("https://mysite.com/releases/AvaloniaCrossPlat$-1.1.0.nupkg", dl.LastUrl);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void CheckFromLocal()
|
public void CheckFromLocal()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user