Checkpoint (nw)

This commit is contained in:
Matt Nadareski
2023-09-20 11:50:12 -04:00
parent 67d49ac4c0
commit a69d3a5bb2
10 changed files with 119 additions and 74 deletions

View File

@@ -1,3 +1,4 @@
using static SabreTools.Compression.libmspack.macros;
using static SabreTools.Compression.libmspack.CAB.Constants;
namespace SabreTools.Compression.libmspack.CAB
@@ -103,17 +104,17 @@ namespace SabreTools.Compression.libmspack.CAB
/// </summary>
private static MSPACK_ERR ReadBlock(mspack_system sys, mscabd_decompress_state d, ref int @out, int ignore_cksum, int ignore_blocksize)
{
byte[] hdr = new byte[cfdata_SIZEOF];
FixedArray<byte> hdr = new FixedArray<byte>(cfdata_SIZEOF);
uint cksum;
int len, full_len;
// Reset the input block pointer and end of block pointer
d.i_ptr = d.i_end = &d.input[0];
d.i_ptr = d.i_end = (byte*)d.input.Pointer;
do
{
// Read the block header
if (sys.read(d.infh, &hdr[0], cfdata_SIZEOF) != cfdata_SIZEOF)
if (sys.read(d.infh, (byte*)hdr.Pointer, cfdata_SIZEOF) != cfdata_SIZEOF)
{
return MSPACK_ERR.MSPACK_ERR_READ;
}
@@ -126,7 +127,7 @@ namespace SabreTools.Compression.libmspack.CAB
}
// Blocks must not be over CAB_INPUTMAX in size
len = System.BitConverter.ToUInt16(hdr, cfdata_CompressedSize);
len = EndGetI16(hdr, cfdata_CompressedSize);
full_len = (int)(d.i_end - d.i_ptr + len); // Include cab-spanning blocks */
if (full_len > CAB_INPUTMAX)
{
@@ -139,7 +140,7 @@ namespace SabreTools.Compression.libmspack.CAB
}
// Blocks must not expand to more than CAB_BLOCKMAX
if (System.BitConverter.ToUInt16(hdr, cfdata_UncompressedSize) > CAB_BLOCKMAX)
if (EndGetI16(hdr, cfdata_UncompressedSize) > CAB_BLOCKMAX)
{
System.Console.Error.WriteLine("block size > CAB_BLOCKMAX");
if (ignore_blocksize == 0) return MSPACK_ERR.MSPACK_ERR_DATAFORMAT;
@@ -152,10 +153,10 @@ namespace SabreTools.Compression.libmspack.CAB
}
// Perform checksum test on the block (if one is stored)
if ((cksum = System.BitConverter.ToUInt32(hdr, cfdata_CheckSum)) != 0)
if ((cksum = EndGetI32(hdr, cfdata_CheckSum)) != 0)
{
uint sum2 = Checksum(d.i_end, (uint)len, 0);
if (Checksum(&hdr[4], 4, sum2) != cksum)
if (Checksum(hdr, 4, 4, sum2) != cksum)
{
if (ignore_cksum == 0) return MSPACK_ERR.MSPACK_ERR_CHECKSUM;
sys.message(d.infh, "WARNING; bad block checksum found");
@@ -171,7 +172,7 @@ namespace SabreTools.Compression.libmspack.CAB
// reading needs to be done.
// EXIT POINT OF LOOP -- uncompressed size != 0
if ((@out = System.BitConverter.ToInt16(hdr, cfdata_UncompressedSize)) != 0)
if ((@out = EndGetI16(hdr, cfdata_UncompressedSize)) != 0)
{
return MSPACK_ERR.MSPACK_ERR_OK;
}
@@ -207,20 +208,20 @@ namespace SabreTools.Compression.libmspack.CAB
return MSPACK_ERR.MSPACK_ERR_OK;
}
private static uint Checksum(byte* data, uint bytes, uint cksum)
private static uint Checksum(FixedArray<byte> data, int ptr, uint bytes, uint cksum)
{
uint len, ul = 0;
for (len = bytes >> 2; len-- > 0; data += 4)
for (len = bytes >> 2; len-- > 0; ptr += 4)
{
cksum ^= System.BitConverter.ToInt32(data, 0);
cksum ^= EndGetI32(data, ptr);
}
switch (bytes & 3)
{
case 3: ul |= (uint)(*data++ << 16); goto case 2;
case 2: ul |= (uint)(*data++ << 8); goto case 1;
case 1: ul |= *data; break;
case 3: ul |= (uint)(data[ptr++] << 16); goto case 2;
case 2: ul |= (uint)(data[ptr++] << 8); goto case 1;
case 1: ul |= data[ptr]; break;
}
cksum ^= ul;

View File

@@ -1,4 +1,5 @@
using static SabreTools.Compression.libmspack.cab;
using static SabreTools.Compression.libmspack.macros;
using static SabreTools.Compression.libmspack.CAB.Constants;
namespace SabreTools.Compression.libmspack.CAB
@@ -216,7 +217,7 @@ namespace SabreTools.Compression.libmspack.CAB
MSPACK_ERR err;
mscabd_folder fol, linkfol = null;
mscabd_file file, linkfile = null;
byte[] buf = new byte[64];
FixedArray<byte> buf = new FixedArray<byte>(64);
// Initialise pointers
cab.next = null;
@@ -235,24 +236,24 @@ namespace SabreTools.Compression.libmspack.CAB
}
// Read in the CFHEADER
if (sys.read(fh, &buf[0], cfhead_SIZEOF) != cfhead_SIZEOF)
if (sys.read(fh, (byte*)buf.Pointer, cfhead_SIZEOF) != cfhead_SIZEOF)
{
return MSPACK_ERR.MSPACK_ERR_READ;
}
// Check for "MSCF" signature
if (System.BitConverter.ToInt32(buf, cfhead_Signature) != 0x4643534D)
if (EndGetI32(buf, cfhead_Signature) != 0x4643534D)
{
return MSPACK_ERR.MSPACK_ERR_SIGNATURE;
}
// Some basic header fields
cab.length = System.BitConverter.ToUInt32(buf, cfhead_CabinetSize);
cab.set_id = System.BitConverter.ToUInt16(buf, cfhead_SetID);
cab.set_index = System.BitConverter.ToUInt16(buf, cfhead_CabinetIndex);
cab.length = EndGetI32(buf, cfhead_CabinetSize);
cab.set_id = EndGetI16(buf, cfhead_SetID);
cab.set_index = EndGetI16(buf, cfhead_CabinetIndex);
// Get the number of folders
num_folders = System.BitConverter.ToInt16(buf, cfhead_NumFolders);
num_folders = EndGetI16(buf, cfhead_NumFolders);
if (num_folders == 0)
{
if (quiet == 0) sys.message(fh, "No folders in cabinet.");
@@ -260,7 +261,7 @@ namespace SabreTools.Compression.libmspack.CAB
}
// Get the number of files
num_files = System.BitConverter.ToInt16(buf, cfhead_NumFiles);
num_files = EndGetI16(buf, cfhead_NumFiles);
if (num_files == 0)
{
if (quiet == 0) sys.message(fh, "no files in cabinet.");
@@ -274,15 +275,15 @@ namespace SabreTools.Compression.libmspack.CAB
}
// Read the reserved-sizes part of header, if present
cab.flags = (MSCAB_HDR)System.BitConverter.ToInt16(buf, cfhead_Flags);
cab.flags = (MSCAB_HDR)EndGetI16(buf, cfhead_Flags);
if (cab.flags.HasFlag(MSCAB_HDR.MSCAB_HDR_RESV))
{
if (sys.read(fh, &buf[0], cfheadext_SIZEOF) != cfheadext_SIZEOF)
if (sys.read(fh, (byte*)buf.Pointer, cfheadext_SIZEOF) != cfheadext_SIZEOF)
{
return MSPACK_ERR.MSPACK_ERR_READ;
}
cab.header_resv = System.BitConverter.ToUInt16(buf, cfheadext_HeaderReserved);
cab.header_resv = EndGetI16(buf, cfheadext_HeaderReserved);
folder_resv = buf[cfheadext_FolderReserved];
cab.block_resv = buf[cfheadext_DataReserved];
@@ -328,7 +329,7 @@ namespace SabreTools.Compression.libmspack.CAB
// Read folders
for (i = 0; i < num_folders; i++)
{
if (sys.read(fh, &buf[0], cffold_SIZEOF) != cffold_SIZEOF)
if (sys.read(fh, (byte*)buf.Pointer, cffold_SIZEOF) != cffold_SIZEOF)
{
return MSPACK_ERR.MSPACK_ERR_READ;
}
@@ -343,11 +344,11 @@ namespace SabreTools.Compression.libmspack.CAB
fol = new mscabd_folder();
fol.next = null;
fol.comp_type = (MSCAB_COMP)System.BitConverter.ToInt16(buf, cffold_CompType);
fol.num_blocks = (uint)System.BitConverter.ToInt16(buf, cffold_NumBlocks);
fol.comp_type = (MSCAB_COMP)EndGetI16(buf, cffold_CompType);
fol.num_blocks = (uint)EndGetI16(buf, cffold_NumBlocks);
fol.data.next = null;
fol.data.cab = cab;
fol.data.offset = offset + (long)((uint)System.BitConverter.ToInt32(buf, cffold_DataOffset));
fol.data.offset = offset + (long)((uint)EndGetI32(buf, cffold_DataOffset));
fol.merge_prev = null;
fol.merge_next = null;
@@ -360,7 +361,7 @@ namespace SabreTools.Compression.libmspack.CAB
// Read files
for (i = 0; i < num_files; i++)
{
if (sys.read(fh, &buf[0], cffile_SIZEOF) != cffile_SIZEOF)
if (sys.read(fh, (byte*)buf.Pointer, cffile_SIZEOF) != cffile_SIZEOF)
{
return MSPACK_ERR.MSPACK_ERR_READ;
}
@@ -368,12 +369,12 @@ namespace SabreTools.Compression.libmspack.CAB
file = new mscabd_file();
file.next = null;
file.length = System.BitConverter.ToUInt32(buf, cffile_UncompressedSize);
file.attribs = (MSCAB_ATTRIB)System.BitConverter.ToInt16(buf, cffile_Attribs);
file.offset = System.BitConverter.ToUInt32(buf, cffile_FolderOffset);
file.length = EndGetI32(buf, cffile_UncompressedSize);
file.attribs = (MSCAB_ATTRIB)EndGetI16(buf, cffile_Attribs);
file.offset = EndGetI32(buf, cffile_FolderOffset);
// Set folder pointer
fidx = System.BitConverter.ToInt16(buf, cffile_FolderIndex);
fidx = EndGetI16(buf, cffile_FolderIndex);
if (fidx < cffileCONTINUED_FROM_PREV)
{
/* normal folder index; count up to the correct folder */
@@ -416,13 +417,13 @@ namespace SabreTools.Compression.libmspack.CAB
}
// Get time
x = System.BitConverter.ToInt16(buf, cffile_Time);
x = EndGetI16(buf, cffile_Time);
file.time_h = (char)(x >> 11);
file.time_m = (char)((x >> 5) & 0x3F);
file.time_s = (char)((x << 1) & 0x3E);
// Get date
x = System.BitConverter.ToInt16(buf, cffile_Date);
x = EndGetI16(buf, cffile_Date);
file.date_d = (char)(x & 0x1F);
file.date_m = (char)((x >> 5) & 0xF);
file.date_y = (x >> 9) + 1980;
@@ -465,7 +466,7 @@ namespace SabreTools.Compression.libmspack.CAB
int len, i, ok;
// Read up to 256 bytes */
if ((len = sys.read(fh, &buf[0], 256)) <= 0)
if ((len = sys.read(fh, (byte*)buf.Pointer, 256)) <= 0)
{
error = MSPACK_ERR.MSPACK_ERR_READ;
return null;
@@ -492,7 +493,7 @@ namespace SabreTools.Compression.libmspack.CAB
}
char[] strchr = new char[len];
sys.copy(&buf[0], &strchr[0], len);
sys.copy((byte*)buf.Pointer, &strchr[0], len);
str = new string(strchr);
error = MSPACK_ERR.MSPACK_ERR_OK;
return str;
@@ -617,13 +618,13 @@ namespace SabreTools.Compression.libmspack.CAB
}
// FAQ avoidance strategy
if ((offset == 0) && (System.BitConverter.ToInt32(buf, 0) == 0x28635349))
if ((offset == 0) && (EndGetI32(buf, 0) == 0x28635349))
{
sys.message(fh, "WARNING; found InstallShield header. Use unshield (https://github.com/twogood/unshield) to unpack this file");
}
// Read through the entire buffer.
for (p = &buf[0], pend = &buf[length]; p < pend;)
for (p = (byte*)buf.Pointer, pend = &buf[length]; p < pend;)
{
switch (state)
{
@@ -659,7 +660,7 @@ namespace SabreTools.Compression.libmspack.CAB
foffset_u32 |= (uint)(*p++ << 24);
// Now we have recieved 20 bytes of potential cab header. work out
// the offset in the file of this potential cabinet */
caboff = offset + (p - &buf[0]) - 20;
caboff = offset + (p - (byte*)buf.Pointer) - 20;
// Should reading cabinet fail, restart search just after 'MSCF'
offset = caboff + 4;

View File

@@ -73,7 +73,7 @@ namespace SabreTools.Compression.libmspack
/// <summary>
/// One input block of data
/// </summary>
public byte[] input { get; set; } = new byte[CAB_INPUTBUF];
public FixedArray<byte> input { get; set; } = new FixedArray<byte>(CAB_INPUTBUF);
/// <summary>
/// Decompressor code

View File

@@ -30,5 +30,17 @@ namespace SabreTools.Compression.libmspack
{
Marshal.FreeHGlobal(Pointer);
}
/// <inheritdoc cref="System.Linq.Enumerable.SequenceEqual{TSource}(System.Collections.Generic.IEnumerable{TSource}, System.Collections.Generic.IEnumerable{TSource})"/>
public bool SequenceEqual(T[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
if (!this[i].Equals(arr[i]))
return false;
}
return true;
}
}
}

View File

@@ -20,7 +20,7 @@ namespace SabreTools.Compression.libmspack.None
this.InternalSystem = sys;
this.Input = infh;
this.Output = outfh;
this.Buffer = system.CreateArray<byte>(bufsize);
this.Buffer = (byte*)new FixedArray<byte>(bufsize).Pointer;
this.BufferSize = bufsize;
}

View File

@@ -1,3 +1,4 @@
using static SabreTools.Compression.libmspack.macros;
using static SabreTools.Compression.libmspack.oab;
namespace SabreTools.Compression.libmspack.OAB
@@ -67,15 +68,15 @@ namespace SabreTools.Compression.libmspack.OAB
goto outlbl;
}
if (System.BitConverter.ToInt32(hdrbuf, oabhead_VersionHi) != 3 ||
System.BitConverter.ToInt32(hdrbuf, oabhead_VersionLo) != 1)
if (EndGetI32(hdrbuf, oabhead_VersionHi) != 3 ||
EndGetI32(hdrbuf, oabhead_VersionLo) != 1)
{
ret = MSPACK_ERR.MSPACK_ERR_SIGNATURE;
goto outlbl;
}
block_max = System.BitConverter.ToUInt32(hdrbuf, oabhead_BlockMax);
target_size = System.BitConverter.ToUInt32(hdrbuf, oabhead_TargetSize);
block_max = EndGetI32(hdrbuf, oabhead_BlockMax);
target_size = EndGetI32(hdrbuf, oabhead_TargetSize);
outfh = sys.open(output, MSPACK_SYS_OPEN.MSPACK_SYS_OPEN_WRITE);
if (outfh == null)
@@ -110,10 +111,10 @@ namespace SabreTools.Compression.libmspack.OAB
ret = MSPACK_ERR.MSPACK_ERR_READ;
goto outlbl;
}
blk_flags = System.BitConverter.ToInt32(buf, oabblk_Flags);
blk_csize = System.BitConverter.ToInt32(buf, oabblk_CompSize);
blk_dsize = System.BitConverter.ToInt32(buf, oabblk_UncompSize);
blk_crc = System.BitConverter.ToInt32(buf, oabblk_CRC);
blk_flags = EndGetI32(buf, oabblk_Flags);
blk_csize = EndGetI32(buf, oabblk_CompSize);
blk_dsize = EndGetI32(buf, oabblk_UncompSize);
blk_crc = EndGetI32(buf, oabblk_CRC);
if (blk_dsize > block_max || blk_dsize > target_size || blk_flags > 1)
{
@@ -224,22 +225,22 @@ namespace SabreTools.Compression.libmspack.OAB
goto outlbl;
}
byte[] hdrbuf = new byte[patchhead_SIZEOF];
if (sys.read(infh, &hdrbuf[0], patchhead_SIZEOF) != patchhead_SIZEOF)
FixedArray<byte> hdrbuf = new FixedArray<byte>(patchhead_SIZEOF);
if (sys.read(infh, (byte*)hdrbuf.Pointer, patchhead_SIZEOF) != patchhead_SIZEOF)
{
ret = MSPACK_ERR.MSPACK_ERR_READ;
goto outlbl;
}
if (System.BitConverter.ToInt32(hdrbuf, patchhead_VersionHi) != 3 ||
System.BitConverter.ToInt32(hdrbuf, patchhead_VersionLo) != 2)
if (EndGetI32(hdrbuf, patchhead_VersionHi) != 3 ||
EndGetI32(hdrbuf, patchhead_VersionLo) != 2)
{
ret = MSPACK_ERR.MSPACK_ERR_SIGNATURE;
goto outlbl;
}
uint block_max = System.BitConverter.ToUInt32(hdrbuf, patchhead_BlockMax);
uint target_size = System.BitConverter.ToUInt32(hdrbuf, patchhead_TargetSize);
uint block_max = EndGetI32(hdrbuf, patchhead_BlockMax);
uint target_size = EndGetI32(hdrbuf, patchhead_TargetSize);
// We use it for reading block headers too
if (block_max < patchblk_SIZEOF)
@@ -284,10 +285,10 @@ namespace SabreTools.Compression.libmspack.OAB
goto outlbl;
}
uint blk_csize = System.BitConverter.ToInt32(buf, patchblk_PatchSize);
uint blk_dsize = System.BitConverter.ToInt32(buf, patchblk_TargetSize);
uint blk_ssize = System.BitConverter.ToInt32(buf, patchblk_SourceSize);
uint blk_crc = System.BitConverter.ToInt32(buf, patchblk_CRC);
uint blk_csize = EndGetI32(buf, patchblk_PatchSize);
uint blk_dsize = EndGetI32(buf, patchblk_TargetSize);
uint blk_ssize = EndGetI32(buf, patchblk_SourceSize);
uint blk_crc = EndGetI32(buf, patchblk_CRC);
if (blk_dsize > block_max || blk_dsize > target_size ||
blk_ssize > block_max)

View File

@@ -1,4 +1,5 @@
using System.Linq;
using static SabreTools.Compression.libmspack.macros;
using static SabreTools.Compression.libmspack.SZDD.Constants;
namespace SabreTools.Compression.libmspack.SZDD
@@ -108,10 +109,10 @@ namespace SabreTools.Compression.libmspack.SZDD
/// <returns></returns>
private static MSPACK_ERR ReadHeaders(mspack_system sys, mspack_file fh, msszddd_header hdr)
{
byte[] buf = new byte[8];
FixedArray<byte> buf = new FixedArray<byte>(8);
// Read and check signature
if (sys.read(fh, buffer: &buf[0], 8) != 8) return MSPACK_ERR.MSPACK_ERR_READ;
if (sys.read(fh, (byte*)buf.Pointer, 8) != 8) return MSPACK_ERR.MSPACK_ERR_READ;
if (buf.SequenceEqual(szdd_signature_expand))
{
@@ -119,18 +120,18 @@ namespace SabreTools.Compression.libmspack.SZDD
hdr.format = MSSZDD_FMT.MSSZDD_FMT_NORMAL;
// Read the rest of the header
if (sys.read(fh, &buf[0], 6) != 6) return MSPACK_ERR.MSPACK_ERR_READ;
if (sys.read(fh, (byte*)buf.Pointer, 6) != 6) return MSPACK_ERR.MSPACK_ERR_READ;
if (buf[0] != 0x41) return MSPACK_ERR.MSPACK_ERR_DATAFORMAT;
hdr.missing_char = (char)buf[1];
hdr.length = System.BitConverter.ToInt32(buf, 2);
hdr.length = EndGetI32(buf, 2);
}
else if (buf.SequenceEqual(szdd_signature_qbasic))
{
// Special QBasic SZDD
hdr.format = MSSZDD_FMT.MSSZDD_FMT_QBASIC;
if (sys.read(fh, &buf[0], 4) != 4) return MSPACK_ERR.MSPACK_ERR_READ;
if (sys.read(fh, (byte*)buf.Pointer, 4) != 4) return MSPACK_ERR.MSPACK_ERR_READ;
hdr.missing_char = '\0';
hdr.length = System.BitConverter.ToInt32(buf, 0);
hdr.length = EndGetI32(buf, 0);
}
else
{

35
libmspack/macros.cs Normal file
View File

@@ -0,0 +1,35 @@
namespace SabreTools.Compression.libmspack
{
public static class macros
{
private static uint __egi32(FixedArray<byte> a, int n)
{
return (uint)((a[n + 3] << 24) | (a[n + 2] << 16) | (a[n + 1] << 8) | (a[n + 0]));
}
public static ulong EndGetI64(FixedArray<byte> a, int n)
{
return (__egi32(a, n + 4) << 32) | __egi32(a, n + 0);
}
public static uint EndGetI32(FixedArray<byte> a, int n)
{
return __egi32(a, n + 0);
}
public static ushort EndGetI16(FixedArray<byte> a, int n)
{
return (ushort)((a[n + 1] << 8) | a[n + 0]);
}
public static uint EndGetM32(FixedArray<byte> a, int n)
{
return (uint)((a[n + 0] << 24) | (a[n + 1] << 16) | (a[n + 2] << 8) | (a[n + 3]));
}
public static ushort EndGetM16(FixedArray<byte> a, int n)
{
return (ushort)((a[n + 0] << 8) | a[n + 1]);
}
}
}

View File

@@ -120,7 +120,7 @@ namespace SabreTools.Compression.libmspack
/// <inheritdoc/>
public override unsafe void* alloc(int bytes)
{
return system.CreateArray<byte>(bytes);
return (void*)new FixedArray<byte>(bytes).Pointer;
}
/// <inheritdoc/>

View File

@@ -38,11 +38,5 @@ namespace SabreTools.Compression.libmspack
return MSPACK_ERR.MSPACK_ERR_OK;
}
public static T* CreateArray<T>(int length)
{
T[] buf = new T[length];
return &buf[0];
}
}
}