Fix CTD issue during extraction

This commit is contained in:
Timothy Baldridge 2020-09-29 06:35:31 -06:00
parent d828b5b0ff
commit 18c7444541
4 changed files with 94 additions and 4 deletions

View File

@ -1,4 +1,5 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
@ -67,6 +68,34 @@ namespace Wabbajack.VirtualFileSystem.Test
}
}
[Fact]
public async Task SmallFilesShouldntCrash()
{
await using var temp = await TempFolder.Create();
await using var archive = new TempFile();
for (int i = 0; i < 1; i ++)
{
await WriteRandomData(temp.Dir.Combine($"{i}.bin"), _rng.Next(10, 10));
}
await ZipUpFolder(temp.Dir, archive.Path, false);
var results = await FileExtractor2.GatheringExtract(new NativeFileStreamFactory(archive.Path),
_ => true,
async (path, sfn) =>
{
await using var s = await sfn.GetStream();
return await s.xxHashAsync();
});
Assert.Equal(1, results.Count);
foreach (var (path, hash) in results)
{
Assert.Equal(await temp.Dir.Combine(path).FileHashAsync(), hash);
}
}
[Fact]
public async Task CanExtractEmptyFiles()
{
@ -108,14 +137,24 @@ namespace Wabbajack.VirtualFileSystem.Test
p => p.Extension == OMODExtension, async (path, sfn) =>
{
await FileExtractor2.GatheringExtract(sfn, _ => true, async (ipath, isfn) => {
// We shouldn't have any .crc files because this file should be recognized as a OMOD and extracted correctly
Assert.NotEqual(CRCExtension, ipath.Extension);
return 0;
// We shouldn't have any .crc files because this file should be recognized as a OMOD and extracted correctly
Assert.NotEqual(CRCExtension, ipath.Extension);
return 0;
});
return 0;
});
}
[Fact]
public async Task SmallZipNoLongerCrashes()
{
var src = await DownloadMod(Game.Fallout4, 29596, 120918);
await using var tmpFolder = await TempFolder.Create();
await FileExtractor2.ExtractAll(src, tmpFolder.Dir);
}
private static readonly Random _rng = new Random();
private static async Task WriteRandomData(AbsolutePath path, int size)
@ -125,6 +164,14 @@ namespace Wabbajack.VirtualFileSystem.Test
await path.WriteAllBytesAsync(buff);
}
private async Task WriteRandomData(Stream path, long size)
{
var buff = new byte[size];
_rng.NextBytes(buff);
await path.WriteAsync(buff);
}
private static async Task AddFile(AbsolutePath filename, string text)
{
filename.Parent.CreateDirectory();
@ -147,6 +194,11 @@ namespace Wabbajack.VirtualFileSystem.Test
var results = await client.GetModFiles(game, mod);
var file = results.files.FirstOrDefault(f => f.is_primary) ??
results.files.OrderByDescending(f => f.uploaded_timestamp).First();
return await DownloadNexusFile(game, mod, file);
}
private static async Task<AbsolutePath> DownloadNexusFile(Game game, int mod, NexusFileInfo file)
{
var src = _stagingFolder.Combine(file.file_name);
if (src.Exists) return src;
@ -160,6 +212,15 @@ namespace Wabbajack.VirtualFileSystem.Test
await state.Download(src);
return src;
}
private async Task<AbsolutePath> DownloadMod(Game game, int mod, int fileId)
{
using var client = await NexusApiClient.Get();
var results = await client.GetModFiles(game, mod);
var file = results.files.FirstOrDefault(f => f.file_id == fileId);
return await DownloadNexusFile(game, mod, file);
}
}
}

View File

@ -0,0 +1,8 @@
{
"profiles": {
"Wabbajack.VirtualFileSystem.Test": {
"commandName": "Project",
"nativeDebugging": true
}
}
}

View File

@ -42,7 +42,7 @@ namespace Wabbajack.VirtualFileSystem
{
_archive = ArchiveFile.Open(_stream, _sig).Result;
ulong checkPos = 1024 * 32;
_archive._archive.Open(_archive._archiveStream, ref checkPos, null);
_archive._archive.Open(_archive._archiveStream, ref checkPos, new ArchiveCallback());
_itemsCount = _archive._archive.GetNumberOfItems();
_archive._archive.Extract(null, 0xFFFFFFFF, 0, this);
_archive.Dispose();
@ -227,5 +227,18 @@ namespace Wabbajack.VirtualFileSystem
{
_killException = ex;
}
class ArchiveCallback : IArchiveOpenCallback
{
public void SetTotal(IntPtr files, IntPtr bytes)
{
}
public void SetCompleted(IntPtr files, IntPtr bytes)
{
}
}
}
}

View File

@ -0,0 +1,8 @@
{
"profiles": {
"Wabbajack.VirtualFileSystem": {
"commandName": "Project",
"nativeDebugging": true
}
}
}