From e8ba6fa59353b033a3c146481b9a190c1c332372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20M=C3=BCller?= Date: Fri, 3 Apr 2026 13:45:16 +0200 Subject: [PATCH 1/4] MAIT: Required buffer length for frame --- pyACS/acs.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pyACS/acs.py b/pyACS/acs.py index 1cd3817..4247f6e 100644 --- a/pyACS/acs.py +++ b/pyACS/acs.py @@ -390,14 +390,12 @@ def find_frame(self, buffer): # Get Length of frame (following 2 bytes, already know it from device file) # frame_length = unpack_from('!H', buffer, offset=i + self.REGISTRATION_BYTES_LENGTH) frame_end_index = i + self.frame_length - # Get frame + # Make sure buffer is long enough (incl. 2-byte checksum) + if len(buffer) < frame_end_index + 2: + return bytearray(), False, buffer, bytearray() + # Get frame and checksum frame = buffer[i:frame_end_index] - if len(frame) != self.frame_length: - return bytearray(), None, buffer, bytearray() - # Get Checksum checksum = buffer[frame_end_index:frame_end_index + 2] - if len(checksum) != 2: - return bytearray(), None, buffer, bytearray() # Check checksum if not self.valid_frame(frame, checksum): # Error in frame, remove registration bytes and attempt again From cd6c0a2e0ab5508f4addb538f82288aafbe0249b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20M=C3=BCller?= Date: Fri, 3 Apr 2026 13:50:42 +0200 Subject: [PATCH 2/4] MAIT: Use buffer.find and check explicitly for match --- pyACS/acs.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyACS/acs.py b/pyACS/acs.py index 4247f6e..013f1d1 100644 --- a/pyACS/acs.py +++ b/pyACS/acs.py @@ -382,7 +382,10 @@ def find_frame(self, buffer): """ try: # Look for registration bytes - i = buffer.index(self.REGISTRATION_BYTES) + i = buffer.find(self.REGISTRATION_BYTES) + if i == -1: + # No registration byte found + return bytearray(), False, buffer, bytearray() # Take care of special case when checksum + pad byte or just checksum = \xff\x00 # It's unlikely that the full packet length is equal to \xff\x00 = 65280 while buffer.find(self.REGISTRATION_BYTES, i + 2, i + 2 + self.REGISTRATION_BYTES_LENGTH) != -1: @@ -403,9 +406,6 @@ def find_frame(self, buffer): buffer[:i+self.REGISTRATION_BYTES_LENGTH] # Pad byte is not always present... (only +2 for checksum) return frame, True, buffer[frame_end_index + 2:], buffer[:i] - except ValueError: - # No registration byte found - return bytearray(), None, buffer, bytearray() except struct_error: # Buffer is too short to unpack packet length return bytearray(), None, buffer, bytearray() From a1932db76d164978eb1fe6d4ca24cd2f3d3d2a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20M=C3=BCller?= Date: Fri, 3 Apr 2026 13:51:27 +0200 Subject: [PATCH 3/4] MAIT: Remove impossible try catch for struct_error Inside ACS.find_frame only ACS.valid_frame uses struct.unpack_from which can never throw struct_error because the bytearray garanteed to have the required length (see acs.py:396). --- pyACS/acs.py | 54 ++++++++++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/pyACS/acs.py b/pyACS/acs.py index 013f1d1..9e81adc 100644 --- a/pyACS/acs.py +++ b/pyACS/acs.py @@ -380,35 +380,31 @@ def find_frame(self, buffer): buffer_post_frame: buffer left after the frame buffer_pre_frame: buffer preceding the first frame returned (likely unknown frame header) """ - try: - # Look for registration bytes - i = buffer.find(self.REGISTRATION_BYTES) - if i == -1: - # No registration byte found - return bytearray(), False, buffer, bytearray() - # Take care of special case when checksum + pad byte or just checksum = \xff\x00 - # It's unlikely that the full packet length is equal to \xff\x00 = 65280 - while buffer.find(self.REGISTRATION_BYTES, i + 2, i + 2 + self.REGISTRATION_BYTES_LENGTH) != -1: - i += 2 - # Get Length of frame (following 2 bytes, already know it from device file) - # frame_length = unpack_from('!H', buffer, offset=i + self.REGISTRATION_BYTES_LENGTH) - frame_end_index = i + self.frame_length - # Make sure buffer is long enough (incl. 2-byte checksum) - if len(buffer) < frame_end_index + 2: - return bytearray(), False, buffer, bytearray() - # Get frame and checksum - frame = buffer[i:frame_end_index] - checksum = buffer[frame_end_index:frame_end_index + 2] - # Check checksum - if not self.valid_frame(frame, checksum): - # Error in frame, remove registration bytes and attempt again - return frame, False, buffer[i+self.REGISTRATION_BYTES_LENGTH:],\ - buffer[:i+self.REGISTRATION_BYTES_LENGTH] - # Pad byte is not always present... (only +2 for checksum) - return frame, True, buffer[frame_end_index + 2:], buffer[:i] - except struct_error: - # Buffer is too short to unpack packet length - return bytearray(), None, buffer, bytearray() + # Look for registration bytes + i = buffer.find(self.REGISTRATION_BYTES) + if i == -1: + # No registration byte found + return bytearray(), False, buffer, bytearray() + # Take care of special case when checksum + pad byte or just checksum = \xff\x00 + # It's unlikely that the full packet length is equal to \xff\x00 = 65280 + while buffer.find(self.REGISTRATION_BYTES, i + 2, i + 2 + self.REGISTRATION_BYTES_LENGTH) != -1: + i += 2 + # Get Length of frame (following 2 bytes, already know it from device file) + # frame_length = unpack_from('!H', buffer, offset=i + self.REGISTRATION_BYTES_LENGTH) + frame_end_index = i + self.frame_length + # Make sure buffer is long enough (incl. 2-byte checksum) + if len(buffer) < frame_end_index + 2: + return bytearray(), False, buffer, bytearray() + # Get frame and checksum + frame = buffer[i:frame_end_index] + checksum = buffer[frame_end_index:frame_end_index + 2] + # Check checksum + if not self.valid_frame(frame, checksum): + # Error in frame, remove registration bytes and attempt again + return frame, False, buffer[i+self.REGISTRATION_BYTES_LENGTH:],\ + buffer[:i+self.REGISTRATION_BYTES_LENGTH] + # Pad byte is not always present... (only +2 for checksum) + return frame, True, buffer[frame_end_index + 2:], buffer[:i] @staticmethod def valid_frame(frame, checksum_received): From 60528586b3882187c7ae26bf7ae6ef3bab95efd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20M=C3=BCller?= Date: Fri, 3 Apr 2026 14:00:03 +0200 Subject: [PATCH 4/4] MAIT: Remove commented-out code --- pyACS/acs.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyACS/acs.py b/pyACS/acs.py index 9e81adc..4b93c96 100644 --- a/pyACS/acs.py +++ b/pyACS/acs.py @@ -389,8 +389,6 @@ def find_frame(self, buffer): # It's unlikely that the full packet length is equal to \xff\x00 = 65280 while buffer.find(self.REGISTRATION_BYTES, i + 2, i + 2 + self.REGISTRATION_BYTES_LENGTH) != -1: i += 2 - # Get Length of frame (following 2 bytes, already know it from device file) - # frame_length = unpack_from('!H', buffer, offset=i + self.REGISTRATION_BYTES_LENGTH) frame_end_index = i + self.frame_length # Make sure buffer is long enough (incl. 2-byte checksum) if len(buffer) < frame_end_index + 2: