Skip to content

Commit 02bf89f

Browse files
authored
Merge pull request #140 from CCSDSPy/issue-139
Improve robustness of parsing when garbage data exists at the end of a file
2 parents be2a957 + 7e70370 commit 02bf89f

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

ccsdspy/decode.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,11 @@ def _decode_variable_length(file_bytes, fields):
305305
offset = 0
306306

307307
while offset < len(file_bytes):
308-
packet_starts.append(offset)
309-
offset += int(file_bytes[offset + 4]) * 256 + int(file_bytes[offset + 5]) + 7
308+
if offset + 5 < len(file_bytes):
309+
packet_starts.append(offset)
310+
offset += int(file_bytes[offset + 4]) * 256 + int(file_bytes[offset + 5]) + 7
311+
else:
312+
break
310313

311314
if offset != len(file_bytes):
312315
missing_bytes = offset - len(file_bytes)
@@ -328,6 +331,9 @@ def _decode_variable_length(file_bytes, fields):
328331
packet_nbytes = (
329332
int(file_bytes[packet_start + 4]) * 256 + int(file_bytes[packet_start + 5]) + 7
330333
)
334+
if packet_start + packet_nbytes > len(file_bytes):
335+
continue
336+
331337
bit_offsets_cur = bit_offsets.copy()
332338
bit_lengths_cur = {}
333339

ccsdspy/tests/test_regression.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io
44
import os
5+
import shutil
56

67
import numpy as np
78
import pytest
@@ -247,3 +248,35 @@ def test_numpy2_dtype_poly_and_linear():
247248
# test linearconverter (no exception)
248249
converter = converters.LinearConverter(*coeffs)
249250
converted = converter.convert(field_array)
251+
252+
253+
@pytest.mark.parametrize("pkt_class", [FixedLength, VariableLength])
254+
@pytest.mark.parametrize("num_garbage_bytes", list(range(1, 11)))
255+
def test_readahead_primary_header_IndexError(pkt_class, num_garbage_bytes):
256+
"""Fixes IndexError from reading primary header in packet iteration when
257+
file ends abruptly.
258+
259+
See: https://github.com/CCSDSPy/ccsdspy/issues/139
260+
"""
261+
pkt = VariableLength(
262+
[
263+
PacketArray(
264+
name="data",
265+
data_type="uint",
266+
bit_length=16,
267+
array_shape="expand",
268+
),
269+
PacketField(name="footer", data_type="uint", bit_length=16),
270+
]
271+
)
272+
273+
dir_path = os.path.dirname(os.path.realpath(__file__))
274+
bin_path = os.path.join(dir_path, "data", "var_length", "var_length_packets_with_footer.bin")
275+
new_path = os.path.join(dir_path, "data", "garbage_at_end.bin")
276+
shutil.copy(bin_path, new_path)
277+
278+
with open(new_path, "ab") as fh:
279+
fh.write(b"a" * num_garbage_bytes)
280+
281+
with pytest.warns(UserWarning, match="File appears truncated"):
282+
result = pkt.load(new_path)

0 commit comments

Comments
 (0)