From ab3a1109d4c3310ef70f0fa20e78459e6c0564df Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 4 Apr 2020 19:25:42 +0000 Subject: [PATCH 1/3] Handle short read in crypto stream This implements the TODO to handle the short read. recv_into should be a bit more efficient as well. --- pyhap/hap_server.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/pyhap/hap_server.py b/pyhap/hap_server.py index d1dc896a..2c8a4002 100644 --- a/pyhap/hap_server.py +++ b/pyhap/hap_server.py @@ -709,11 +709,10 @@ def _wrapper(self, *args, **kwargs): return func(self, *args, **kwargs) return _wrapper - def recv_into(self, buffer, nbytes=1042, flags=0): + def recv_into(self, buffer, nbytes=None, flags=0): """Receive and decrypt up to nbytes in the given buffer.""" - data = self.recv(nbytes, flags) - for i, b in enumerate(data): - buffer[i] = b + data = self.recv(nbytes or len(buffer), flags) + buffer[:len(data)] = data return len(data) def recv(self, buflen=1042, flags=0): @@ -737,8 +736,16 @@ def recv(self, buflen=1042, flags=0): block_length_bytes = self.socket.recv(self.LENGTH_LENGTH) if not block_length_bytes: return result - # TODO: handle this - assert len(block_length_bytes) == self.LENGTH_LENGTH + if len(block_length_bytes) != self.LENGTH_LENGTH: + # Handle a short read where we only get + # one bytes. This should be very rare, but it happens. + block_length_bytes_remainder = self.socket.recv( + self.LENGTH_LENGTH - len(block_length_bytes) + ) + if not block_length_bytes_remainder: + return result + block_length_bytes += block_length_bytes_remainder + assert len(block_length_bytes) == self.LENGTH_LENGTH # Init. info about the block we just started. # Note we are setting the total length to block_length + mac length self.curr_in_total = \ From 7c870a9ca130d1d1b105dd09a6c5567be3ef1374 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 5 Apr 2020 13:52:34 +0000 Subject: [PATCH 2/3] Wait for a full block --- pyhap/hap_server.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/pyhap/hap_server.py b/pyhap/hap_server.py index 2c8a4002..220ca6fd 100644 --- a/pyhap/hap_server.py +++ b/pyhap/hap_server.py @@ -733,19 +733,12 @@ def recv(self, buflen=1042, flags=0): # It may be that we already read some data and we have # 1 byte left, return whatever we have. return result - block_length_bytes = self.socket.recv(self.LENGTH_LENGTH) + # Always wait for a full block to arrive + block_length_bytes = self.socket.recv( + self.LENGTH_LENGTH, flags=socket.MSG_WAITALL + ) if not block_length_bytes: return result - if len(block_length_bytes) != self.LENGTH_LENGTH: - # Handle a short read where we only get - # one bytes. This should be very rare, but it happens. - block_length_bytes_remainder = self.socket.recv( - self.LENGTH_LENGTH - len(block_length_bytes) - ) - if not block_length_bytes_remainder: - return result - block_length_bytes += block_length_bytes_remainder - assert len(block_length_bytes) == self.LENGTH_LENGTH # Init. info about the block we just started. # Note we are setting the total length to block_length + mac length self.curr_in_total = \ From 35995b1e46b85f60768d28f6a484937cae8ba89e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 5 Apr 2020 14:02:56 +0000 Subject: [PATCH 3/3] not keyword --- pyhap/hap_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyhap/hap_server.py b/pyhap/hap_server.py index 220ca6fd..ae863e57 100644 --- a/pyhap/hap_server.py +++ b/pyhap/hap_server.py @@ -735,7 +735,7 @@ def recv(self, buflen=1042, flags=0): return result # Always wait for a full block to arrive block_length_bytes = self.socket.recv( - self.LENGTH_LENGTH, flags=socket.MSG_WAITALL + self.LENGTH_LENGTH, socket.MSG_WAITALL ) if not block_length_bytes: return result