Skip to content

Commit 7fb914a

Browse files
authored
Avoid truncating unknown types in SDO upload (fixes #436) (#591)
When an OD entry is found in SdoClient.upload(), the truncation is currently skipped only for those types explicitly listed as variable length data (domain, strings). That causes unknown types to be truncated to whatever their length indicates, which is usually one byte. Invert the condition to check all types with an explicitly known size, a.k.a. those listed in STRUCT_TYPES where the required length can be deduced from the structure format. Re-enable the unit tests which were skipped based on the previously buggy behavior.
1 parent 7ddb19b commit 7fb914a

File tree

3 files changed

+7
-5
lines changed

3 files changed

+7
-5
lines changed

canopen/objectdictionary/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,12 @@ def add_bit_definition(self, name: str, bits: List[int]) -> None:
419419
"""
420420
self.bit_definitions[name] = bits
421421

422+
@property
423+
def fixed_size(self) -> bool:
424+
"""Indicate whether the amount of needed data is known in advance."""
425+
# Only for types which we parse using a structure.
426+
return self.data_type in self.STRUCT_TYPES
427+
422428
def decode_raw(self, data: bytes) -> Union[int, float, str, bytes, bytearray]:
423429
if self.data_type == VISIBLE_STRING:
424430
# Strip any trailing NUL characters from C-based systems

canopen/sdo/client.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,7 @@ def upload(self, index: int, subindex: int) -> bytes:
126126
var = self.od.get_variable(index, subindex)
127127
if var is not None:
128128
# Found a matching variable in OD
129-
# If this is a data type (string, domain etc) the size is
130-
# unknown anyway so keep the data as is
131-
if var.data_type not in objectdictionary.DATA_TYPES:
129+
if var.fixed_size:
132130
# Get the size in bytes for this variable
133131
var_size = len(var) // 8
134132
if response_size is None or var_size < response_size:

test/test_sdo.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,6 @@ def test_unknown_od_112(self):
814814

815815
def test_unknown_datatype32(self):
816816
"""Test an unknown datatype, but known OD, of 32 bits (4 bytes)."""
817-
return # FIXME: Disabled temporarily until datatype conditionals are fixed, see #436
818817
# Add fake entry 0x2100 to OD, using fake datatype 0xFF
819818
if 0x2100 not in self.node.object_dictionary:
820819
fake_var = ODVariable("Fake", 0x2100)
@@ -829,7 +828,6 @@ def test_unknown_datatype32(self):
829828

830829
def test_unknown_datatype112(self):
831830
"""Test an unknown datatype, but known OD, of 112 bits (14 bytes)."""
832-
return # FIXME: Disabled temporarily until datatype conditionals are fixed, see #436
833831
# Add fake entry 0x2100 to OD, using fake datatype 0xFF
834832
if 0x2100 not in self.node.object_dictionary:
835833
fake_var = ODVariable("Fake", 0x2100)

0 commit comments

Comments
 (0)