diff --git a/src/Messaging/MessageBuffer.php b/src/Messaging/MessageBuffer.php index e5d197b..317a26a 100644 --- a/src/Messaging/MessageBuffer.php +++ b/src/Messaging/MessageBuffer.php @@ -150,6 +150,7 @@ class MessageBuffer { $payload_length = unpack('C', $data[$frameStart + 1] & "\x7f")[1]; $isMasked = ($data[$frameStart + 1] & "\x80") === "\x80"; $headerSize += $isMasked ? 4 : 0; + $payloadLenOver2GB = false; if ($payload_length > 125 && ($dataLen - $frameStart < $headerSize + 125)) { // no point of checking - this frame is going to be bigger than the buffer is right now break; @@ -158,9 +159,18 @@ class MessageBuffer { $payloadLenBytes = $payload_length === 126 ? 2 : 8; $headerSize += $payloadLenBytes; $bytesToUpack = substr($data, $frameStart + 2, $payloadLenBytes); - $payload_length = $payload_length === 126 - ? unpack('n', $bytesToUpack)[1] - : unpack('J', $bytesToUpack)[1]; + + if ($payload_length === 126){ + $payload_length = unpack('n', $bytesToUpack)[1]; + } else { + $payloadLenOver2GB = unpack('N', $bytesToUpack)[1] > 0; //Decode only the 4 first bytes + if (PHP_INT_SIZE == 4) { // if 32bits PHP + $bytesToUpack = substr($bytesToUpack, 4); //Keep only 4 last bytes + $payload_length = unpack('N', $bytesToUpack)[1]; + } else { + $payload_length = unpack('J', $bytesToUpack)[1]; + } + } } $closeFrame = null; @@ -170,6 +180,10 @@ class MessageBuffer { $closeFrame = $this->newCloseFrame(Frame::CLOSE_PROTOCOL, 'Invalid frame length'); } + if (!$closeFrame && PHP_INT_SIZE == 4 && $payloadLenOver2GB) { + $closeFrame = $this->newCloseFrame(Frame::CLOSE_TOO_BIG, 'Frame over 2GB can\'t be handled on 32bits PHP'); + } + if (!$closeFrame && $this->maxFramePayloadSize > 1 && $payload_length > $this->maxFramePayloadSize) { $closeFrame = $this->newCloseFrame(Frame::CLOSE_TOO_BIG, 'Maximum frame size exceeded'); }