--- a/src/eric7/DebugClients/Python/AsyncFile.py Fri Feb 02 19:29:29 2024 +0100 +++ b/src/eric7/DebugClients/Python/AsyncFile.py Wed Feb 07 15:28:08 2024 +0100 @@ -10,7 +10,9 @@ import contextlib import socket +import struct import threading +import zlib from DebugUtilities import prepareJsonCommand @@ -109,14 +111,16 @@ self.writeLock.acquire() while self.wpending: try: - buf = self.wpending.pop(0) + data = self.wpending.pop(0) except IndexError: break try: with contextlib.suppress(UnicodeEncodeError, UnicodeDecodeError): - buf = buf.encode("utf-8", "backslashreplace") - self.sock.sendall(buf) + data = data.encode("utf-8", "backslashreplace") + header = struct.pack(b"!II", len(data), zlib.adler32(data) & 0xFFFFFFFF) + self.sock.sendall(header) + self.sock.sendall(data) self.nWriteErrors = 0 except OSError: self.nWriteErrors += 1 @@ -188,24 +192,27 @@ def readCommand(self): """ - Public method to read a length prefixed command string. + Public method to read a command string prefixed by a command header. @return command string @rtype str """ - # The command string is prefixed by a 9 character long length field. - length = self.sock.recv(9) - length = int(length) - data = b"" - while len(data) < length: - remaining = length - len(data) - newBytes = self.sock.recv(min(remaining, AsyncFile.CMD_BUFSIZE)) - data += newBytes - if newBytes[-1] == b"\n": - break + header = self.sock.recv(struct.calcsize(b"!II")) + if header: + length, datahash = struct.unpack(b"!II", header) - # step 2: convert the data - return data.decode("utf8", "backslashreplace") + length = int(length) + data = bytearray() + while len(data) < length: + newData = self.sock.recv(length - len(data)) + data += newData + if not newData: + break + + if data and zlib.adler32(data) & 0xFFFFFFFF == datahash: + return data.decode("utf8", "backslashreplace") + + return "" def readline_p(self, size=-1): """ @@ -348,14 +355,14 @@ # convert to string to send it s = repr(s) - cmd = prepareJsonCommand( + jsonCommand = prepareJsonCommand( "ClientOutput", { "text": s, "debuggerId": "", }, ) - self.wpending.append(cmd) + self.wpending.append(jsonCommand) self.flush() self.writeLock.release()