Fix for processing packets, where our EOM or EOP is split across buffer reads
This commit is contained in:
parent
ddccc44261
commit
e56ecaa999
@ -250,29 +250,35 @@ class Packet extends FTNBase implements \Iterator, \Countable
|
|||||||
->singleOrFail();
|
->singleOrFail();
|
||||||
}
|
}
|
||||||
|
|
||||||
$buf_ptr = 0;
|
$buf_ptr = 0; // Pointer to the end of the current message
|
||||||
$message = '';
|
$message = ''; // Current message we are building
|
||||||
$readbuf = '';
|
$readbuf = ''; // What we are reading to determine the message contents
|
||||||
$last = '';
|
$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)))) {
|
while ($buf_ptr || (! feof($f) && ($readbuf=fread($f,self::BLOCKSIZE)))) {
|
||||||
if (! $buf_ptr)
|
if (! $buf_ptr)
|
||||||
$read_ptr = ftell($f);
|
$read_ptr = ftell($f);
|
||||||
|
|
||||||
// Packed messages are Message::HEADER_LEN, prefixed with self::PACKED_MSG_LEAD
|
// 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))) {
|
if (strlen($message) < (Message::HEADER_LEN+strlen(self::PACKED_MSG_LEAD))) {
|
||||||
$addchars = (Message::HEADER_LEN+strlen(self::PACKED_MSG_LEAD))-strlen($message);
|
$addchars = (Message::HEADER_LEN+strlen(self::PACKED_MSG_LEAD))-strlen($message);
|
||||||
$message .= substr($readbuf,$buf_ptr,$addchars);
|
$message .= substr($readbuf,$buf_ptr,$addchars);
|
||||||
$buf_ptr += $addchars;
|
$buf_ptr += $addchars;
|
||||||
|
|
||||||
// If our buffer wasnt big enough...
|
// If our buffer wasnt big enough...
|
||||||
|
// @todo can this be true?
|
||||||
if ($buf_ptr >= strlen($readbuf)) {
|
if ($buf_ptr >= strlen($readbuf)) {
|
||||||
|
throw new \Exception('We found a situation that this is true');
|
||||||
$buf_ptr = 0;
|
$buf_ptr = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take 2 chars from the buffer and check if we have our end packet signature
|
// 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)) {
|
if ($last && ($buf_ptr === 0)) {
|
||||||
$last .= substr($readbuf,0,2);
|
$last .= substr($readbuf,0,2);
|
||||||
|
|
||||||
@ -286,21 +292,27 @@ class Packet extends FTNBase implements \Iterator, \Countable
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We didnt have an EOM marker
|
||||||
$last = '';
|
$last = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See if our EOM marker is in the read buffer
|
||||||
if (($end=strpos($readbuf,"\x00".self::PACKED_MSG_LEAD,$buf_ptr)) === FALSE) {
|
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
|
// Just in case our packet break is at the end of the buffer
|
||||||
$last = substr($readbuf,-2);
|
$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);
|
$message .= substr($readbuf,$buf_ptr);
|
||||||
$buf_ptr = 0;
|
$buf_ptr = 0;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No EOM marker
|
||||||
$last = '';
|
$last = '';
|
||||||
|
|
||||||
|
// See if we have an EOP marker
|
||||||
$end = strpos($readbuf,"\x00\x00\x00",$buf_ptr);
|
$end = strpos($readbuf,"\x00\x00\x00",$buf_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,6 +324,7 @@ class Packet extends FTNBase implements \Iterator, \Countable
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// No more to read, so the packet is bad
|
||||||
} else
|
} else
|
||||||
throw new InvalidPacketException(sprintf('Cannot determine END of message/packet: %s|%s',get_class($o),hex_dump($message)));
|
throw new InvalidPacketException(sprintf('Cannot determine END of message/packet: %s|%s',get_class($o),hex_dump($message)));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user