Skip to content

Commit edd990b

Browse files
committed
Wrap MS-ZIP compression in case of failure
1 parent fb1310a commit edd990b

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

BinaryObjectScanner/FileType/MicrosoftCAB.cs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ private static void ExtractFolder(SabreTools.Serialization.Wrappers.MicrosoftCab
191191
bool includeDebug)
192192
{
193193
// Decompress the blocks, if possible
194-
using var blockStream = DecompressBlocks(cabArchive, filename, folder, folderIndex);
194+
using var blockStream = DecompressBlocks(cabArchive, filename, folder, folderIndex, includeDebug);
195195
if (blockStream == null || blockStream.Length == 0)
196196
return;
197197

@@ -247,9 +247,10 @@ private static void ExtractFile(string outDir, Stream blockStream, CFFILE file,
247247
/// <param name="filename">Filename for one cabinet in the set, if available</param>
248248
/// <param name="folder">Folder containing the blocks to decompress</param>
249249
/// <param name="folderIndex">Index of the folder in the cabinet</param>
250+
/// <param name="includeDebug">True to include debug data, false otherwise</param>
250251
/// <returns>Stream representing the decompressed data on success, null otherwise</returns>
251252
/// TODO: Remove once Serialization is updated
252-
private static Stream? DecompressBlocks(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, string? filename, CFFOLDER? folder, int folderIndex)
253+
private static Stream? DecompressBlocks(SabreTools.Serialization.Wrappers.MicrosoftCabinet cabArchive, string? filename, CFFOLDER? folder, int folderIndex, bool includeDebug)
253254
{
254255
// Ensure data blocks
255256
var dataBlocks = GetDataBlocks(cabArchive, filename, folder, folderIndex);
@@ -275,7 +276,7 @@ private static void ExtractFile(string outDir, Stream blockStream, CFFILE file,
275276
byte[] data = compressionType switch
276277
{
277278
CompressionType.TYPE_NONE => db.CompressedData,
278-
CompressionType.TYPE_MSZIP => DecompressMSZIPBlock(folderIndex, mszip, i, db),
279+
CompressionType.TYPE_MSZIP => DecompressMSZIPBlock(folderIndex, mszip, i, db, includeDebug),
279280

280281
// TODO: Unsupported
281282
CompressionType.TYPE_QUANTUM => [],
@@ -300,28 +301,39 @@ private static void ExtractFile(string outDir, Stream blockStream, CFFILE file,
300301
/// <param name="mszip">MS-ZIP decompressor with persistent state</param>
301302
/// <param name="blockIndex">Index of the block within the folder</param>
302303
/// <param name="block">Block data to be used for decompression</param>
304+
/// <param name="includeDebug">True to include debug data, false otherwise</param>
303305
/// <returns>Byte array representing the decompressed data, empty on error</returns>
304306
/// TODO: Remove once Serialization is updated
305-
private static byte[] DecompressMSZIPBlock(int folderIndex, SabreTools.Compression.MSZIP.Decompressor mszip, int blockIndex, CFDATA block)
307+
private static byte[] DecompressMSZIPBlock(int folderIndex, SabreTools.Compression.MSZIP.Decompressor mszip, int blockIndex, CFDATA block, bool includeDebug)
306308
{
307309
// Ignore invalid blocks
308310
if (block.CompressedData == null)
309311
return [];
310312

311-
// Decompress to a temporary stream
312-
using var stream = new MemoryStream();
313-
mszip.CopyTo(block.CompressedData, stream);
313+
try
314+
{
315+
// Decompress to a temporary stream
316+
using var stream = new MemoryStream();
317+
mszip.CopyTo(block.CompressedData, stream);
314318

315-
// Pad to the correct size but throw a warning about this
316-
if (stream.Length < block.UncompressedSize)
319+
// Pad to the correct size but throw a warning about this
320+
if (stream.Length < block.UncompressedSize)
321+
{
322+
if (includeDebug)
323+
Console.Error.WriteLine($"Data block {blockIndex} in folder {folderIndex} had mismatching sizes. Expected: {block.UncompressedSize}, Got: {stream.Length}");
324+
325+
byte[] padding = new byte[block.UncompressedSize - stream.Length];
326+
stream.Write(padding, 0, padding.Length);
327+
}
328+
329+
// Return the byte array data
330+
return stream.ToArray();
331+
}
332+
catch (Exception ex)
317333
{
318-
Console.Error.WriteLine($"Data block {blockIndex} in folder {folderIndex} had mismatching sizes. Expected: {block.UncompressedSize}, Got: {stream.Length}");
319-
byte[] padding = new byte[block.UncompressedSize - stream.Length];
320-
stream.Write(padding, 0, padding.Length);
334+
if (includeDebug) Console.WriteLine(ex);
335+
return [];
321336
}
322-
323-
// Return the byte array data
324-
return stream.ToArray();
325337
}
326338

327339
/// <summary>

0 commit comments

Comments
 (0)