1
0
mirror of synced 2024-11-12 01:00:46 +01:00

Fix off-by-one error in LZ77 implementation rarely resulting in truncated files on inflate.

This commit is contained in:
Jennifer Taylor 2020-11-12 05:02:37 +00:00
parent a5966a6382
commit 42c3362a3c
3 changed files with 14 additions and 3 deletions

View File

@ -258,7 +258,7 @@ class Lz77Compress:
# byte and then 8 instructions.
flags = 0x0
flagpos = -1
data: List[bytes] = [b"\x00"] * 8
data: List[bytes] = [b""] * 8
for _ in range(8):
# Track what flag we're generating data for
@ -289,7 +289,7 @@ class Lz77Compress:
backref_amount = min(self.left, 18)
# Iterate over all spots where the first byte equals, and is in range.
earliest = max(0, self.bytes_written - self.ringlength)
earliest = max(0, self.bytes_written - (self.ringlength - 1))
possible_backref_locations: List[int] = [
absolute_pos for absolute_pos in self.starts[self.data[self.read_pos:(self.read_pos + 3)]]
if absolute_pos >= earliest
@ -344,7 +344,7 @@ class Lz77Compress:
self.read_pos += copy_amount
self.left -= copy_amount
yield bytes([flags]) + b"".join(data[:(flagpos + 1)])
yield bytes([flags]) + b"".join(data)
class Lz77:

BIN
bemani/tests/rawdata Normal file

Binary file not shown.

View File

@ -75,6 +75,17 @@ class TestLz77RealCompressor(unittest.TestCase):
decompresseddata = lz77.decompress(compresseddata)
self.assertEqual(data, decompresseddata)
def test_texture(self) -> None:
lz77 = Lz77()
data = get_fixture("rawdata")
compresseddata = lz77.compress(data)
self.assertNotEqual(data, compresseddata)
self.assertTrue(len(compresseddata) < len(data))
decompresseddata = lz77.decompress(compresseddata)
self.assertEqual(data, decompresseddata)
def test_known_compression(self) -> None:
"""
Specifically tests for ability to compress an overlap,