From e56ecaa999c065a4bca8b9eb2fd97f8160bff3c0 Mon Sep 17 00:00:00 2001 From: Deon George Date: Thu, 7 Dec 2023 20:19:48 +1100 Subject: [PATCH] Fix for processing packets, where our EOM or EOP is split across buffer reads --- app/Classes/FTN/Packet.php | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/app/Classes/FTN/Packet.php b/app/Classes/FTN/Packet.php index 9457bf7..68fc85e 100644 --- a/app/Classes/FTN/Packet.php +++ b/app/Classes/FTN/Packet.php @@ -250,29 +250,35 @@ class Packet extends FTNBase implements \Iterator, \Countable ->singleOrFail(); } - $buf_ptr = 0; - $message = ''; - $readbuf = ''; - $last = ''; + $buf_ptr = 0; // Pointer to the end of the current message + $message = ''; // Current message we are building + $readbuf = ''; // What we are reading to determine the message contents + $last = ''; // If during buffer reads, the end of the last buffer had our NULL end of message marker + // We loop through reading from the buffer, to find our end of message tag while ($buf_ptr || (! feof($f) && ($readbuf=fread($f,self::BLOCKSIZE)))) { if (! $buf_ptr) $read_ptr = ftell($f); // Packed messages are Message::HEADER_LEN, prefixed with self::PACKED_MSG_LEAD + // If we havent got our header yet if (strlen($message) < (Message::HEADER_LEN+strlen(self::PACKED_MSG_LEAD))) { $addchars = (Message::HEADER_LEN+strlen(self::PACKED_MSG_LEAD))-strlen($message); $message .= substr($readbuf,$buf_ptr,$addchars); $buf_ptr += $addchars; // If our buffer wasnt big enough... + // @todo can this be true? if ($buf_ptr >= strlen($readbuf)) { + throw new \Exception('We found a situation that this is true'); $buf_ptr = 0; continue; } } // Take 2 chars from the buffer and check if we have our end packet signature + // $last is set, because we detected a NULL, so we'll add two more chars and see if we have our EOM + // signature. Some of those chars may belong to the next message, if $last has more than 1 NULL. if ($last && ($buf_ptr === 0)) { $last .= substr($readbuf,0,2); @@ -286,21 +292,27 @@ class Packet extends FTNBase implements \Iterator, \Countable continue; } + // We didnt have an EOM marker $last = ''; } + // See if our EOM marker is in the read buffer if (($end=strpos($readbuf,"\x00".self::PACKED_MSG_LEAD,$buf_ptr)) === FALSE) { // Just in case our packet break is at the end of the buffer $last = substr($readbuf,-2); - if ((str_contains($last,"\x00")) && ($size-$read_ptr > 2)) { + // We have an EOM or EOP marker here, so loop around to get the next read + if (str_contains($last,"\x00")) { $message .= substr($readbuf,$buf_ptr); $buf_ptr = 0; continue; } + // No EOM marker $last = ''; + + // See if we have an EOP marker $end = strpos($readbuf,"\x00\x00\x00",$buf_ptr); } @@ -312,6 +324,7 @@ class Packet extends FTNBase implements \Iterator, \Countable continue; + // No more to read, so the packet is bad } else throw new InvalidPacketException(sprintf('Cannot determine END of message/packet: %s|%s',get_class($o),hex_dump($message)));