Skip to content

Commit b6d9dcd

Browse files
committed
Fix MS-ZIP, working
1 parent 0d94215 commit b6d9dcd

File tree

6 files changed

+55
-69
lines changed

6 files changed

+55
-69
lines changed

SabreTools.Compression/Deflate/DeflateManager.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,13 +1649,21 @@ internal int SetParams(CompressionLevel level, CompressionStrategy strategy)
16491649
}
16501650

16511651

1652-
internal int SetDictionary(byte[] dictionary)
1652+
internal int SetDictionary(byte[] dictionary, bool check = true)
16531653
{
16541654
int length = dictionary.Length;
16551655
int index = 0;
16561656

1657-
if (dictionary == null || status != INIT_STATE)
1658-
throw new ZlibException("Stream error.");
1657+
if (check)
1658+
{
1659+
if (dictionary == null || status != INIT_STATE)
1660+
throw new ZlibException("Stream error.");
1661+
}
1662+
else
1663+
{
1664+
if (dictionary == null)
1665+
throw new ZlibException("Stream error.");
1666+
}
16591667

16601668
_codec._Adler32 = Adler.Adler32(_codec._Adler32, dictionary, 0, dictionary.Length);
16611669

SabreTools.Compression/Deflate/DeflateStream.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -620,10 +620,11 @@ public override void Write(byte[] buffer, int offset, int count)
620620
/// Set the dictionary to be used for either Inflation or Deflation.
621621
/// </summary>
622622
/// <param name="dictionary">The dictionary bytes to use.</param>
623+
/// <param name="check">Determines if dictionary checks are run</param>
623624
/// <returns>Z_OK if all goes well.</returns>
624-
public int SetDictionary(byte[] dictionary)
625+
public int SetDictionary(byte[] dictionary, bool check = true)
625626
{
626-
return _baseStream.SetDictionary(dictionary);
627+
return _baseStream.SetDictionary(dictionary, check);
627628
}
628629

629630
#endregion

SabreTools.Compression/Deflate/InflateManager.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -363,16 +363,20 @@ internal int Inflate(FlushType flush)
363363

364364

365365

366-
internal int SetDictionary(byte[] dictionary)
366+
internal int SetDictionary(byte[] dictionary, bool check = true)
367367
{
368368
int index = 0;
369369
int length = dictionary.Length;
370-
if (mode != InflateManagerMode.DICT0)
371-
throw new ZlibException("Stream error.");
372370

373-
if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32)
371+
if (check)
374372
{
375-
return ZlibConstants.Z_DATA_ERROR;
373+
if (mode != InflateManagerMode.DICT0)
374+
throw new ZlibException("Stream error.");
375+
376+
if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32)
377+
{
378+
return ZlibConstants.Z_DATA_ERROR;
379+
}
376380
}
377381

378382
_codec._Adler32 = Adler.Adler32(0, null, 0, 0);

SabreTools.Compression/Deflate/ZlibBaseStream.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,10 +624,11 @@ public static byte[] UncompressBuffer(byte[] compressed, Stream decompressor)
624624
/// Set the dictionary to be used for either Inflation or Deflation.
625625
/// </summary>
626626
/// <param name="dictionary">The dictionary bytes to use.</param>
627+
/// <param name="check">Determines if dictionary checks are run</param>
627628
/// <returns>Z_OK if all goes well.</returns>
628-
public int SetDictionary(byte[] dictionary)
629+
public int SetDictionary(byte[] dictionary, bool check = true)
629630
{
630-
return z.SetDictionary(dictionary);
631+
return z.SetDictionary(dictionary, check);
631632
}
632633

633634
}

SabreTools.Compression/Deflate/ZlibCodec.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -642,14 +642,15 @@ public int SetDeflateParams(CompressionLevel level, CompressionStrategy strategy
642642
/// Set the dictionary to be used for either Inflation or Deflation.
643643
/// </summary>
644644
/// <param name="dictionary">The dictionary bytes to use.</param>
645+
/// <param name="check">Determines if dictionary checks are run</param>
645646
/// <returns>Z_OK if all goes well.</returns>
646-
public int SetDictionary(byte[] dictionary)
647+
public int SetDictionary(byte[] dictionary, bool check = true)
647648
{
648649
if (istate != null)
649-
return istate.SetDictionary(dictionary);
650+
return istate.SetDictionary(dictionary, check);
650651

651652
if (dstate != null)
652-
return dstate.SetDictionary(dictionary);
653+
return dstate.SetDictionary(dictionary, check);
653654

654655
throw new ZlibException("No Inflate or Deflate state!");
655656
}

SabreTools.Compression/MSZIP/Decompressor.cs

Lines changed: 25 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,67 @@
11
using System;
22
using System.IO;
33
using SabreTools.IO.Extensions;
4+
using SabreTools.Models.Compression.MSZIP;
45

56
namespace SabreTools.Compression.MSZIP
67
{
78
/// <see href="https://msopenspecs.azureedge.net/files/MS-MCI/%5bMS-MCI%5d.pdf"/>
89
public class Decompressor
910
{
1011
/// <summary>
11-
/// Source stream for the decompressor
12+
/// Last uncompressed block data
1213
/// </summary>
13-
private readonly Stream _source;
14+
private byte[]? _history = null;
1415

1516
#region Constructors
1617

1718
/// <summary>
1819
/// Create a MS-ZIP decompressor
1920
/// </summary>
20-
private Decompressor(Stream source)
21-
{
22-
// Validate the inputs
23-
if (source.Length == 0)
24-
throw new ArgumentOutOfRangeException(nameof(source));
25-
if (!source.CanRead)
26-
throw new InvalidOperationException(nameof(source));
27-
28-
_source = source;
29-
}
21+
private Decompressor() { }
3022

3123
/// <summary>
3224
/// Create a MS-ZIP decompressor
3325
/// </summary>
34-
public static Decompressor Create(byte[] source)
35-
=> Create(new MemoryStream(source));
26+
public static Decompressor Create() => new();
27+
28+
#endregion
3629

3730
/// <summary>
38-
/// Create a MS-ZIP decompressor
31+
/// Decompress source data to an output stream
3932
/// </summary>
40-
public static Decompressor Create(Stream source)
41-
{
42-
// Create the decompressor
43-
var decompressor = new Decompressor(source);
44-
45-
// Validate the header
46-
var header = new Models.Compression.MSZIP.BlockHeader();
47-
header.Signature = source.ReadUInt16();
48-
if (header.Signature != 0x4B43)
49-
throw new InvalidDataException(nameof(source));
50-
51-
// Return
52-
return decompressor;
53-
}
54-
55-
#endregion
33+
public bool CopyTo(byte[] source, Stream dest)
34+
=> CopyTo(new MemoryStream(source), dest);
5635

5736
/// <summary>
5837
/// Decompress source data to an output stream
5938
/// </summary>
60-
public bool CopyTo(Stream dest)
39+
public bool CopyTo(Stream source, Stream dest)
6140
{
6241
// Ignore unwritable streams
6342
if (!dest.CanWrite)
6443
return false;
6544

66-
byte[]? history = null;
67-
while (true)
68-
{
69-
byte[] buffer = new byte[32 * 1024];
70-
var blockStream = new Deflate.DeflateStream(_source, Deflate.CompressionMode.Decompress);
71-
if (history != null)
72-
blockStream.SetDictionary(history);
45+
// Validate the header
46+
var header = new BlockHeader();
47+
header.Signature = source.ReadUInt16();
48+
if (header.Signature != 0x4B43)
49+
throw new InvalidDataException(nameof(source));
7350

74-
int read = blockStream.Read(buffer, 0, buffer.Length);
75-
if (read <= 0)
76-
break;
51+
byte[] buffer = new byte[32 * 1024];
52+
var blockStream = new Deflate.DeflateStream(source, Deflate.CompressionMode.Decompress);
53+
if (_history != null)
54+
blockStream.SetDictionary(_history, check: false);
7755

56+
int read = blockStream.Read(buffer, 0, buffer.Length);
57+
if (read > 0)
58+
{
7859
// Write to output
7960
dest.Write(buffer, 0, read);
8061

8162
// Save the history for rollover
82-
history = new byte[read];
83-
Array.Copy(buffer, history, read);
84-
85-
// Handle end of stream
86-
if (_source.Position >= _source.Length)
87-
break;
88-
89-
// Validate the header
90-
var header = new Models.Compression.MSZIP.BlockHeader();
91-
header.Signature = _source.ReadUInt16();
92-
if (header.Signature != 0x4B43)
93-
break;
63+
_history = new byte[read];
64+
Array.Copy(buffer, _history, read);
9465
}
9566

9667
// Flush and return

0 commit comments

Comments
 (0)