diff --git a/src/NwcIO/Internal/Container/NwcContainerReader.cs b/src/NwcIO/Internal/Container/NwcContainerReader.cs index a880130..ae87d25 100644 --- a/src/NwcIO/Internal/Container/NwcContainerReader.cs +++ b/src/NwcIO/Internal/Container/NwcContainerReader.cs @@ -11,9 +11,6 @@ public static class NwcContainerReader { private const string SectionMarker = "#LcUStream"; - /// Largest run of unrecognized non-zlib bytes tolerated while re-syncing between streams. - private const int MaxResyncGap = 4096; - public static NwcContainer Read(byte[] data) { if (data.Length < 16 || !StartsWithAscii(data, 0, SectionMarker)) @@ -57,9 +54,8 @@ public static NwcContainer Read(byte[] data) // Non-zlib bytes: framing blocks (hash + size words), section padding, tail. // Scan forward to the next zlib signature or section header. int scan = pos + 1; - int limit = Math.Min(data.Length, pos + MaxResyncGap); int gapEnd = -1; - while (scan < limit) + while (scan < data.Length) { if (IsZlibSignature(data, scan) || StartsWithAscii(data, scan, SectionMarker)) { diff --git a/tests/NwcIO.Tests/ContainerReaderTests.cs b/tests/NwcIO.Tests/ContainerReaderTests.cs index dcadcfd..27b6f56 100644 --- a/tests/NwcIO.Tests/ContainerReaderTests.cs +++ b/tests/NwcIO.Tests/ContainerReaderTests.cs @@ -35,6 +35,43 @@ public void Read_SyntheticBackToBackStreams_InflatesAndPreservesLengths() Assert.Equal(comp2.Length, container.Streams[1].CompressedLength); } + [Theory] + [InlineData(0)] + [InlineData(7)] + public void Read_LargeGaps_PreservesLaterStreamsSectionsAndGapAccounting(int trailingGap) + { + using var ms = new MemoryStream(); + var headerBytes = System.Text.Encoding.ASCII.GetBytes("#LcUStream-V1.1 binary double release C lichunk-008\n"); + var payload1 = new byte[100]; + var payload2 = new byte[200]; + var payload3 = new byte[50]; + var gap = new byte[5000]; + + ms.Write(headerBytes); + ms.Write(CompressZlib(payload1)); + ms.Write(gap); + ms.Write(CompressZlib(payload2)); + ms.Write(gap); + ms.Write(headerBytes); + ms.Write(CompressZlib(payload3)); + ms.Write(new byte[trailingGap]); + + var container = NwcContainerReader.Read(ms.ToArray()); + + Assert.Equal(2, container.Sections.Count); + Assert.Equal(3, container.Streams.Count); + Assert.Equal(payload1, container.Streams[0].Data); + Assert.Equal(payload2, container.Streams[1].Data); + Assert.Equal(payload3, container.Streams[2].Data); + Assert.Equal(0, container.Streams[0].SectionIndex); + Assert.Equal(0, container.Streams[1].SectionIndex); + Assert.Equal(1, container.Streams[2].SectionIndex); + Assert.Equal(0, container.Streams[0].GapBefore); + Assert.Equal(gap.Length, container.Streams[1].GapBefore); + Assert.Equal(0, container.Streams[2].GapBefore); + Assert.Equal(trailingGap, container.TrailingGap); + } + [Fact] public void Read_InvalidHeader_ThrowsInvalidDataException() {