Browse Source

Support for single-file bundle from .NET 6.

This supports the new version and also the new compressed files.
pull/2373/head
vitek-karas 4 years ago
parent
commit
41c46a0414
  1. 10
      ICSharpCode.Decompiler/SingleFileBundle.cs
  2. 19
      ILSpy/LoadedPackage.cs

10
ICSharpCode.Decompiler/SingleFileBundle.cs

@ -99,6 +99,7 @@ namespace ICSharpCode.Decompiler
{ {
public long Offset; public long Offset;
public long Size; public long Size;
public long CompressedSize; // 0 if not compressed, otherwise the compressed size in the bundle
public FileType Type; public FileType Type;
public string RelativePath; // Path of an embedded file, relative to the Bundle source-directory. public string RelativePath; // Path of an embedded file, relative to the Bundle source-directory.
} }
@ -128,7 +129,9 @@ namespace ICSharpCode.Decompiler
using var reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true); using var reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);
header.MajorVersion = reader.ReadUInt32(); header.MajorVersion = reader.ReadUInt32();
header.MinorVersion = reader.ReadUInt32(); header.MinorVersion = reader.ReadUInt32();
if (header.MajorVersion < 1 || header.MajorVersion > 2)
// Major versions 3, 4 and 5 were skipped to align bundle versioning with .NET versioning scheme
if (header.MajorVersion < 1 || header.MajorVersion > 6)
{ {
throw new InvalidDataException($"Unsupported manifest version: {header.MajorVersion}.{header.MinorVersion}"); throw new InvalidDataException($"Unsupported manifest version: {header.MajorVersion}.{header.MinorVersion}");
} }
@ -145,17 +148,18 @@ namespace ICSharpCode.Decompiler
var entries = ImmutableArray.CreateBuilder<Entry>(header.FileCount); var entries = ImmutableArray.CreateBuilder<Entry>(header.FileCount);
for (int i = 0; i < header.FileCount; i++) for (int i = 0; i < header.FileCount; i++)
{ {
entries.Add(ReadEntry(reader)); entries.Add(ReadEntry(reader, header.MajorVersion));
} }
header.Entries = entries.MoveToImmutable(); header.Entries = entries.MoveToImmutable();
return header; return header;
} }
private static Entry ReadEntry(BinaryReader reader) private static Entry ReadEntry(BinaryReader reader, uint bundleMajorVersion)
{ {
Entry entry; Entry entry;
entry.Offset = reader.ReadInt64(); entry.Offset = reader.ReadInt64();
entry.Size = reader.ReadInt64(); entry.Size = reader.ReadInt64();
entry.CompressedSize = bundleMajorVersion >= 6 ? reader.ReadInt64() : 0;
entry.Type = (FileType)reader.ReadByte(); entry.Type = (FileType)reader.ReadByte();
entry.RelativePath = reader.ReadString(); entry.RelativePath = reader.ReadString();
return entry; return entry;

19
ILSpy/LoadedPackage.cs

@ -197,7 +197,24 @@ namespace ICSharpCode.ILSpy
public override Stream TryOpenStream() public override Stream TryOpenStream()
{ {
Debug.WriteLine("Open bundle member " + Name); Debug.WriteLine("Open bundle member " + Name);
return new UnmanagedMemoryStream(view.SafeMemoryMappedViewHandle, entry.Offset, entry.Size);
if (entry.CompressedSize == 0)
{
return new UnmanagedMemoryStream(view.SafeMemoryMappedViewHandle, entry.Offset, entry.Size);
}
else
{
Stream compressedStream = new UnmanagedMemoryStream(view.SafeMemoryMappedViewHandle, entry.Offset, entry.CompressedSize);
using var deflateStream = new DeflateStream(compressedStream, CompressionMode.Decompress);
Stream decompressedStream = new MemoryStream((int)entry.Size);
deflateStream.CopyTo(decompressedStream);
if (decompressedStream.Length != entry.Size)
{
throw new InvalidDataException($"Corrupted single-file entry '${entry.RelativePath}'. Declared decompressed size '${entry.Size}' is not the same as actual decompressed size '${decompressedStream.Length}'.");
}
return decompressedStream;
}
} }
} }
} }

Loading…
Cancel
Save