Compare commits

...

2 Commits

Author SHA1 Message Date
Matt Nadareski
f5a8d239fa Set the window bits for IS-CAB zlib 2025-11-14 20:13:42 -05:00
Matt Nadareski
ba0161ce02 Attempt to replace old zlib implementations 2025-11-14 19:56:19 -05:00
5 changed files with 74 additions and 123 deletions

View File

@@ -44,6 +44,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="GrindCore" Version="0.5.3" Condition="!$(TargetFramework.StartsWith(`net2`))" />
<PackageReference Include="GrindCore.SharpCompress" Version="0.40.4-alpha" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
<PackageReference Include="NetLegacySupport.Numerics" Version="1.0.1" Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />

View File

@@ -1,6 +1,11 @@
using System;
using System.IO;
#if NET20
using SabreTools.IO.Compression.Deflate;
#else
using Nanook.GrindCore;
using Nanook.GrindCore.ZLib;
#endif
namespace SabreTools.Serialization.Wrappers
{
@@ -93,7 +98,11 @@ namespace SabreTools.Serialization.Wrappers
else
{
using var ms = new MemoryStream(data);
#if NET20
using var zs = new ZlibStream(ms, CompressionMode.Decompress);
#else
using var zs = new ZLibStream(ms, CompressionOptions.DefaultDecompress());
#endif
zs.CopyTo(fs);
fs.Flush();
}

View File

@@ -3,7 +3,12 @@ using System.IO;
using System.Text.RegularExpressions;
using SabreTools.Data.Models.InstallShieldCabinet;
using SabreTools.Hashing;
using SabreTools.IO.Compression.zlib;
#if NET20
using SabreTools.IO.Compression.Deflate;
#else
using Nanook.GrindCore;
using Nanook.GrindCore.ZLib;
#endif
using SabreTools.IO.Extensions;
using static SabreTools.Data.Models.InstallShieldCabinet.Constants;
@@ -268,7 +273,7 @@ namespace SabreTools.Serialization.Wrappers
/// <summary>
/// Save the file at the given index to the filename specified
/// </summary>
public bool FileSave(int index, string filename, bool includeDebug, bool useOld = false)
public bool FileSave(int index, string filename, bool includeDebug)
{
// Get the file descriptor
if (!TryGetFileDescriptor(index, out var fileDescriptor) || fileDescriptor == null)
@@ -276,7 +281,7 @@ namespace SabreTools.Serialization.Wrappers
// If the file is split
if (fileDescriptor.LinkFlags == LinkFlags.LINK_PREV)
return FileSave((int)fileDescriptor.LinkPrevious, filename, includeDebug, useOld);
return FileSave((int)fileDescriptor.LinkPrevious, filename, includeDebug);
// Get the reader at the index
var reader = Reader.Create(this, index, fileDescriptor);
@@ -285,7 +290,7 @@ namespace SabreTools.Serialization.Wrappers
// Create the output file and hasher
using var fs = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.None);
var md5 = new HashWrapper(HashType.MD5);
var md5 = new HashWrapper(Hashing.HashType.MD5);
long readBytesLeft = (long)GetReadableBytes(fileDescriptor);
long writeBytesLeft = (long)GetWritableBytes(fileDescriptor);
@@ -297,7 +302,7 @@ namespace SabreTools.Serialization.Wrappers
while (readBytesLeft > 0 && writeBytesLeft > 0)
{
long bytesToWrite = BUFFER_SIZE;
int result;
bool result;
// Handle compressed files
#if NET20 || NET35
@@ -329,18 +334,15 @@ namespace SabreTools.Serialization.Wrappers
// Add a null byte to make inflate happy
inputBuffer[bytesToRead] = 0;
ulong readBytes = (ulong)(bytesToRead + 1);
int readBytes = bytesToRead + 1;
// Uncompress into a buffer
if (useOld)
result = UncompressOld(outputBuffer, ref bytesToWrite, inputBuffer, ref readBytes);
else
result = Uncompress(outputBuffer, ref bytesToWrite, inputBuffer, ref readBytes);
result = Uncompress(outputBuffer, inputBuffer, readBytes);
// If we didn't get a positive result that's not a data error (false positives)
if (result != zlibConst.Z_OK && result != zlibConst.Z_DATA_ERROR)
if (!result)
{
Console.Error.WriteLine($"Decompression failed with code {result.ToZlibConstName()}. bytes_to_read={bytesToRead}, volume={fileDescriptor.Volume}, read_bytes={readBytes}");
Console.Error.WriteLine($"Decompression failed. bytes_to_read={bytesToRead}, volume={fileDescriptor.Volume}, read_bytes={readBytes}");
reader.Dispose();
fs?.Close();
return false;
@@ -454,74 +456,31 @@ namespace SabreTools.Serialization.Wrappers
/// <summary>
/// Uncompress a source byte array to a destination
/// </summary>
private unsafe static int Uncompress(byte[] dest, ref long destLen, byte[] source, ref ulong sourceLen)
private static bool Uncompress(byte[] dest, byte[] source, int sourceLength)
{
fixed (byte* sourcePtr = source)
fixed (byte* destPtr = dest)
try
{
var stream = new ZLib.z_stream_s
// Inflate the data into the buffer
using var ms = new MemoryStream(source, 0, sourceLength);
using var os = new MemoryStream(dest);
#if NET20
using var zs = new ZlibStream(ms, CompressionMode.Decompress);
#else
var options = new CompressionOptions
{
next_in = sourcePtr,
avail_in = (uint)sourceLen,
next_out = destPtr,
avail_out = (uint)destLen,
Type = CompressionType.Decompress,
Dictionary = new CompressionDictionaryOptions { WindowBits = -MAX_WBITS }
};
// make second parameter negative to disable checksum verification
int err = ZLib.inflateInit2_(stream, -MAX_WBITS, ZLib.zlibVersion(), source.Length);
if (err != zlibConst.Z_OK)
return err;
err = ZLib.inflate(stream, 1);
if (err != zlibConst.Z_OK && err != zlibConst.Z_STREAM_END)
{
ZLib.inflateEnd(stream);
return err;
}
destLen = stream.total_out;
sourceLen = stream.total_in;
return ZLib.inflateEnd(stream);
using var zs = new ZLibStream(ms, options);
#endif
zs.CopyTo(os);
os.Flush();
return true;
}
}
/// <summary>
/// Uncompress a source byte array to a destination (old version)
/// </summary>
private unsafe static int UncompressOld(byte[] dest, ref long destLen, byte[] source, ref ulong sourceLen)
{
fixed (byte* sourcePtr = source)
fixed (byte* destPtr = dest)
catch
{
var stream = new ZLib.z_stream_s
{
next_in = sourcePtr,
avail_in = (uint)sourceLen,
next_out = destPtr,
avail_out = (uint)destLen,
};
destLen = 0;
sourceLen = 0;
// make second parameter negative to disable checksum verification
int err = ZLib.inflateInit2_(stream, -MAX_WBITS, ZLib.zlibVersion(), source.Length);
if (err != zlibConst.Z_OK)
return err;
while (stream.avail_in > 1)
{
err = ZLib.inflate(stream, 1);
if (err != zlibConst.Z_OK)
{
ZLib.inflateEnd(stream);
return err;
}
}
destLen = stream.total_out;
sourceLen = stream.total_in;
return ZLib.inflateEnd(stream);
return false;
}
}
@@ -784,7 +743,7 @@ namespace SabreTools.Serialization.Wrappers
ulong volumeBytesLeftCompressed, volumeBytesLeftExpanded;
#if NET20 || NET35
if ((_fileDescriptor.Flags & FileFlags.FILE_SPLIT) != 0)
if ((_fileDescriptor.Flags & FileFlags.FILE_SPLIT) != 0)
#else
if (_fileDescriptor.Flags.HasFlag(FileFlags.FILE_SPLIT))
#endif

View File

@@ -1,9 +1,15 @@
using System;
using System.IO;
using SabreTools.IO.Compression.BZip2;
using SabreTools.IO.Compression.zlib;
#if NET20
using SabreTools.IO.Compression.Deflate;
#else
using Nanook.GrindCore;
using Nanook.GrindCore.ZLib;
#endif
using SabreTools.IO.Extensions;
namespace SabreTools.Serialization.Wrappers
{
public partial class PortableExecutable : IExtractable
@@ -789,36 +795,16 @@ namespace SabreTools.Serialization.Wrappers
try
{
// Inflate the data into the buffer
var zstream = new ZLib.z_stream_s();
byte[] data = new byte[resource.Length * 4];
unsafe
{
fixed (byte* payloadPtr = resource)
fixed (byte* dataPtr = data)
{
zstream.next_in = payloadPtr;
zstream.avail_in = (uint)resource.Length;
zstream.total_in = (uint)resource.Length;
zstream.next_out = dataPtr;
zstream.avail_out = (uint)data.Length;
zstream.total_out = 0;
ZLib.inflateInit_(zstream, ZLib.zlibVersion(), resource.Length);
int zret = ZLib.inflate(zstream, 1);
ZLib.inflateEnd(zstream);
}
}
// Trim the buffer to the proper size
uint read = zstream.total_out;
#if NETFRAMEWORK
var temp = new byte[read];
Array.Copy(data, temp, read);
data = temp;
using var ms = new MemoryStream(resource);
using var os = new MemoryStream();
#if NET20
using var zs = new ZlibStream(ms, CompressionMode.Decompress);
#else
data = new ReadOnlySpan<byte>(data, 0, (int)read).ToArray();
using var zs = new ZLibStream(ms, CompressionOptions.DefaultDecompress());
#endif
return data;
zs.CopyTo(os);
os.Flush();
return os.ToArray();
}
catch
{

View File

@@ -1,7 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using SabreTools.IO.Compression.zlib;
#if NET20
using SabreTools.IO.Compression.Deflate;
#else
using Nanook.GrindCore;
using Nanook.GrindCore.ZLib;
#endif
namespace SabreTools.Serialization.Wrappers
{
@@ -94,25 +99,16 @@ namespace SabreTools.Serialization.Wrappers
else
{
// Inflate the data into the buffer
var zstream = new ZLib.z_stream_s();
data = new byte[outputFileSize];
unsafe
{
fixed (byte* payloadPtr = compressedData)
fixed (byte* dataPtr = data)
{
zstream.next_in = payloadPtr;
zstream.avail_in = (uint)compressedData.Length;
zstream.total_in = (uint)compressedData.Length;
zstream.next_out = dataPtr;
zstream.avail_out = (uint)data.Length;
zstream.total_out = 0;
ZLib.inflateInit_(zstream, ZLib.zlibVersion(), compressedData.Length);
int zret = ZLib.inflate(zstream, 1);
ZLib.inflateEnd(zstream);
}
}
using var ms = new MemoryStream(compressedData);
using var os = new MemoryStream();
#if NET20
using var zs = new ZlibStream(ms, CompressionMode.Decompress);
#else
using var zs = new ZLibStream(ms, CompressionOptions.DefaultDecompress());
#endif
zs.CopyTo(os);
os.Flush();
data = os.ToArray();
}
// If we have an invalid output directory