Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions dissect/util/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,15 @@ def _read(self, offset: int, length: int) -> bytes:
overlays = self.overlays
lookup = self._lookup

if length < 0:
# Only happens when reading to EOF on a stream with no size, so determine the end
# from the source file-like object and any overlays that reach past it
fh.seek(0, io.SEEK_END)
end = fh.tell()
for overlay_offset in lookup:
end = max(end, overlay_offset + overlays[overlay_offset][0])
length = max(0, end - offset)

overlay_len = len(overlays)
overlay_idx = bisect_left(lookup, offset)

Expand Down
18 changes: 18 additions & 0 deletions tests/test_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,24 @@ def test_overlay_stream() -> None:
assert fh.read(100) == b"\x04" * 4


def test_overlay_stream_no_size() -> None:
data = b"1234567890"
# Wrap in a BufferedReader, which raises OverflowError on absurdly large reads
overlay = stream.OverlayStream(io.BufferedReader(io.BytesIO(data)))

assert overlay.read(10) == data

overlay.seek(0)
assert overlay.read() == data


def test_overlay_stream_no_size_overlay_past_end() -> None:
overlay = stream.OverlayStream(io.BufferedReader(io.BytesIO(b"1234567890")))
overlay.add(8, b"abcd")

assert overlay.read() == b"12345678abcd"


def test_overlay_stream_add_at_offset_zero() -> None:
buf = io.BytesIO(b"\x00" * 100)
fh = stream.OverlayStream(buf, size=100)
Expand Down