Skip to content

Commit

Permalink
Merge pull request #42 from burninrubber0/fix-invalid-bundles
Browse files Browse the repository at this point in the history
Handle checksum corruption from <v0.3.0
  • Loading branch information
burninrubber0 authored Jun 30, 2023
2 parents 968b013 + f272a5d commit 8f99930
Showing 1 changed file with 38 additions and 0 deletions.
38 changes: 38 additions & 0 deletions BundleFormat/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,50 @@ public static byte[] Decompress(this byte[] self, int uncompressedSize)
}
catch (Exception e)
{
if (self[self.Length - 1] == 0
&& e.Message == "Bad state (incorrect data check)") // Likely a bugged resource
{
uncompressedData = GetDataFromBadAlignedResource(self, uncompressedSize);
if (uncompressedData != null)
return uncompressedData;
}
MessageBox.Show(e.ToString(), e.Source, MessageBoxButtons.OK);
return null;
}
return uncompressedData;
}

// Validate resources from BM versions <0.3.0 where alignment corrupted the checksum
public static byte[] GetDataFromBadAlignedResource(byte[] original, int uncompressedSize)
{
// For some reason, the data validates when length is 1 less than it should be.
// Use this to get the correct uncompressed data.
byte[] uncompressedData = new byte[uncompressedSize];
ZlibStream zlibStream = new ZlibStream(new MemoryStream(uncompressedData), CompressionMode.Decompress);
byte[] trimmed = new ArraySegment<byte>(original, 0, original.Length - 1).ToArray();
try
{
zlibStream.Write(trimmed, 0, trimmed.Length);
}
catch (Exception)
{
return null;
}

byte[] compressed = Compress(uncompressedData);

// Test first three checksum bytes
if (original[original.Length - 4] == compressed[compressed.Length - 4]
&& original[original.Length - 3] == compressed[compressed.Length - 3]
&& original[original.Length - 2] == compressed[compressed.Length - 2])
{
// Testing of data not necessary, likelihood of 24 bits matching without data matching is negligible
return uncompressedData;
}

return null;
}

public static bool Matches(this byte[] self, byte[] other)
{
if (self == null || other == null)
Expand Down

0 comments on commit 8f99930

Please sign in to comment.