bool Connection::processMessage() { if (m_readBufferSize < sizeof(MessageInfo)) return false; uint8_t* messageData = m_readBuffer.data(); MessageInfo messageInfo; memcpy(&messageInfo, messageData, sizeof(messageInfo)); messageData += sizeof(messageInfo); size_t messageLength = sizeof(MessageInfo) + messageInfo.attachmentCount() * sizeof(AttachmentInfo) + (messageInfo.isMessageBodyIsOutOfLine() ? 0 : messageInfo.bodySize()); if (m_readBufferSize < messageLength) return false; size_t attachmentFileDescriptorCount = 0; size_t attachmentCount = messageInfo.attachmentCount(); std::unique_ptr<AttachmentInfo[]> attachmentInfo; if (attachmentCount) { attachmentInfo = std::make_unique<AttachmentInfo[]>(attachmentCount); memcpy(attachmentInfo.get(), messageData, sizeof(AttachmentInfo) * attachmentCount); messageData += sizeof(AttachmentInfo) * attachmentCount; for (size_t i = 0; i < attachmentCount; ++i) { switch (attachmentInfo[i].getType()) { case Attachment::MappedMemoryType: case Attachment::SocketType: if (!attachmentInfo[i].isNull()) attachmentFileDescriptorCount++; break; case Attachment::Uninitialized: default: ASSERT_NOT_REACHED(); break; } } if (messageInfo.isMessageBodyIsOutOfLine()) attachmentCount--; } Vector<Attachment> attachments(attachmentCount); AttachmentResourceGuard<Vector<Attachment>, Vector<Attachment>::iterator> attachementDisposer(attachments); RefPtr<WebKit::SharedMemory> oolMessageBody; size_t fdIndex = 0; for (size_t i = 0; i < attachmentCount; ++i) { int fd = -1; switch (attachmentInfo[i].getType()) { case Attachment::MappedMemoryType: if (!attachmentInfo[i].isNull()) fd = m_fileDescriptors[fdIndex++]; attachments[attachmentCount - i - 1] = Attachment(fd, attachmentInfo[i].getSize()); break; case Attachment::SocketType: if (!attachmentInfo[i].isNull()) fd = m_fileDescriptors[fdIndex++]; attachments[attachmentCount - i - 1] = Attachment(fd); break; case Attachment::Uninitialized: attachments[attachmentCount - i - 1] = Attachment(); default: break; } } if (messageInfo.isMessageBodyIsOutOfLine()) { ASSERT(messageInfo.bodySize()); if (attachmentInfo[attachmentCount].isNull()) { ASSERT_NOT_REACHED(); return false; } WebKit::SharedMemory::Handle handle; handle.adoptFromAttachment(m_fileDescriptors[attachmentFileDescriptorCount - 1], attachmentInfo[attachmentCount].getSize()); oolMessageBody = WebKit::SharedMemory::create(handle, WebKit::SharedMemory::ReadOnly); if (!oolMessageBody) { ASSERT_NOT_REACHED(); return false; } } ASSERT(attachments.size() == (messageInfo.isMessageBodyIsOutOfLine() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount())); uint8_t* messageBody = messageData; if (messageInfo.isMessageBodyIsOutOfLine()) messageBody = reinterpret_cast<uint8_t*>(oolMessageBody->data()); auto decoder = std::make_unique<MessageDecoder>(DataReference(messageBody, messageInfo.bodySize()), std::move(attachments)); processIncomingMessage(std::move(decoder)); if (m_readBufferSize > messageLength) { memmove(m_readBuffer.data(), m_readBuffer.data() + messageLength, m_readBufferSize - messageLength); m_readBufferSize -= messageLength; } else m_readBufferSize = 0; if (attachmentFileDescriptorCount) { if (m_fileDescriptorsSize > attachmentFileDescriptorCount) { size_t fileDescriptorsLength = attachmentFileDescriptorCount * sizeof(int); memmove(m_fileDescriptors.data(), m_fileDescriptors.data() + fileDescriptorsLength, m_fileDescriptorsSize - fileDescriptorsLength); m_fileDescriptorsSize -= fileDescriptorsLength; } else m_fileDescriptorsSize = 0; } return true; }