Skip to content

Commit 7c0b764

Browse files
scott-phillips-ahpR0Ps
authored andcommitted
Add support for badly terminated files (dtcooper#114)
1 parent 5c0bff1 commit 7c0b764

4 files changed

Lines changed: 16 additions & 5 deletions

File tree

‎fitparse/base.py‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def _read_struct(self, fmt, endian='<', data=None, always_tuple=False):
8080

8181
def _read_and_assert_crc(self, allow_zero=False):
8282
# CRC Calculation is little endian from SDK
83+
# TODO - How to handle the case of unterminated file? Error out and have user retry with check_crc=false?
8384
crc_computed, crc_read = self._crc.value, self._read_struct(Crc.FMT)
8485
if not self.check_crc:
8586
return
@@ -132,7 +133,8 @@ def _parse_file_header(self):
132133
def _parse_message(self):
133134
# When done, calculate the CRC and return None
134135
if self._bytes_left <= 0:
135-
if not self._complete:
136+
# Don't assert CRC if requested not
137+
if not self._complete and self.check_crc:
136138
self._read_and_assert_crc()
137139

138140
if self._file.tell() >= self._filesize:
@@ -245,9 +247,14 @@ def _parse_raw_values_from_data_message(self, def_mesg):
245247
struct_fmt = str(int(field_def.size / base_type.size)) + base_type.fmt
246248

247249
# Extract the raw value, ask for a tuple if it's a byte type
248-
raw_value = self._read_struct(
249-
struct_fmt, endian=def_mesg.endian, always_tuple=is_byte,
250-
)
250+
try:
251+
raw_value = self._read_struct(
252+
struct_fmt, endian=def_mesg.endian, always_tuple=is_byte,
253+
)
254+
except FitEOFError:
255+
# file was suddenly terminated, usually due to
256+
print("File was terminated unexpectedly, some data will not be loaded.")
257+
break
251258

252259
# If the field returns with a tuple of values it's definitely an
253260
# oddball, but we'll parse it on a per-value basis it.

‎scripts/fitdump‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def main(args=None):
9999
fitfile = fitparse.FitFile(
100100
options.infile,
101101
data_processor=fitparse.StandardUnitsDataProcessor(),
102-
check_crc = not(options.ignore_crc),
102+
check_crc=not(options.ignore_crc),
103103
)
104104
records = fitfile.get_messages(
105105
name=options.name,

‎tests/files/nick.fit‎

394 KB
Binary file not shown.

‎tests/test.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,10 @@ def test_mismatched_field_size(self):
420420
assert all("falling back to byte encoding" in str(x) for x in w)
421421
self.assertEqual(len(f.messages), 11293)
422422

423+
def test_unterminated_file(self):
424+
f = FitFile(testfile('nick.fit'), check_crc=False)
425+
f.parse()
426+
423427
# TODO:
424428
# * Test Processors:
425429
# - process_type_<>, process_field_<>, process_units_<>, process_message_<>

0 commit comments

Comments
 (0)