// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "build/build_config.h"

#include <stddef.h>
#include <stdint.h>

#include <limits>
#include <memory>
#include <set>

#include "base/run_loop.h"
#include "ipc/attachment_broker.h"
#include "ipc/brokerable_attachment.h"
#include "ipc/ipc_channel_reader.h"
#include "ipc/placeholder_brokerable_attachment.h"
#include "testing/gtest/include/gtest/gtest.h"

// Whether IPC::Message::FindNext() can determine message size for
// partial messages. The condition is from FindNext() implementation.
#if USE_ATTACHMENT_BROKER
#define MESSAGE_FINDNEXT_PARTIAL 0
#else
#define MESSAGE_FINDNEXT_PARTIAL 1
#endif

namespace IPC {
namespace internal {

namespace {

#if USE_ATTACHMENT_BROKER

class MockAttachment : public BrokerableAttachment {
 public:
  MockAttachment() {}
  MockAttachment(BrokerableAttachment::AttachmentId id)
      : BrokerableAttachment(id) {}

#if defined(OS_POSIX)
  base::PlatformFile TakePlatformFile() override {
    return base::PlatformFile();
  }
#endif  // OS_POSIX

  BrokerableType GetBrokerableType() const override { return WIN_HANDLE; }

 private:
  ~MockAttachment() override {}
};

class MockAttachmentBroker : public AttachmentBroker {
 public:
  typedef std::set<scoped_refptr<BrokerableAttachment>> AttachmentSet;

  bool SendAttachmentToProcess(
      const scoped_refptr<BrokerableAttachment>& attachment,
      base::ProcessId destination_process) override {
    return false;
  }

  bool OnMessageReceived(const Message& message) override { return false; }

  void AddAttachment(scoped_refptr<BrokerableAttachment> attachment) {
    get_attachments()->push_back(attachment);
    NotifyObservers(attachment->GetIdentifier());
  }
};

#endif  // USE_ATTACHMENT_BROKER

class MockChannelReader : public ChannelReader {
 public:
  MockChannelReader()
      : ChannelReader(nullptr), last_dispatched_message_(nullptr) {}

  ReadState ReadData(char* buffer, int buffer_len, int* bytes_read) override {
    if (data_.empty())
      return READ_PENDING;

    size_t read_len = std::min(static_cast<size_t>(buffer_len), data_.size());
    memcpy(buffer, data_.data(), read_len);
    *bytes_read = static_cast<int>(read_len);
    data_.erase(0, read_len);
    return READ_SUCCEEDED;
  }

  bool ShouldDispatchInputMessage(Message* msg) override { return true; }

  bool GetNonBrokeredAttachments(Message* msg) override { return true; }

  bool DidEmptyInputBuffers() override { return true; }

  void HandleInternalMessage(const Message& msg) override {}

  void DispatchMessage(Message* m) override { last_dispatched_message_ = m; }

  base::ProcessId GetSenderPID() override { return base::kNullProcessId; }

  bool IsAttachmentBrokerEndpoint() override { return false; }

  AttachmentBroker* GetAttachmentBroker() override { return broker_; }

  // This instance takes ownership of |m|.
  void AddMessageForDispatch(Message* m) {
    get_queued_messages()->push_back(m);
  }

  Message* get_last_dispatched_message() { return last_dispatched_message_; }

  void set_broker(AttachmentBroker* broker) { broker_ = broker; }

  void AppendData(const void* data, size_t size) {
    data_.append(static_cast<const char*>(data), size);
  }

  void AppendMessageData(const Message& message) {
    AppendData(message.data(), message.size());
  }

 private:
  Message* last_dispatched_message_;
  AttachmentBroker* broker_;
  std::string data_;
};

class ExposedMessage: public Message {
 public:
  using Message::Header;
  using Message::header;
};

// Payload that makes messages large
const size_t LargePayloadSize = Channel::kMaximumReadBufferSize * 3 / 2;

}  // namespace

#if USE_ATTACHMENT_BROKER

TEST(ChannelReaderTest, AttachmentAlreadyBrokered) {
  MockAttachmentBroker broker;
  MockChannelReader reader;
  reader.set_broker(&broker);
  scoped_refptr<MockAttachment> attachment(new MockAttachment);
  broker.AddAttachment(attachment);

  Message* m = new Message;
  PlaceholderBrokerableAttachment* needs_brokering_attachment =
      new PlaceholderBrokerableAttachment(attachment->GetIdentifier());
  EXPECT_TRUE(m->WriteAttachment(needs_brokering_attachment));
  reader.AddMessageForDispatch(m);
  EXPECT_EQ(ChannelReader::DISPATCH_FINISHED, reader.DispatchMessages());
  EXPECT_EQ(m, reader.get_last_dispatched_message());
}

TEST(ChannelReaderTest, AttachmentNotYetBrokered) {
  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoopForIO());

  MockAttachmentBroker broker;
  MockChannelReader reader;
  reader.set_broker(&broker);
  scoped_refptr<MockAttachment> attachment(new MockAttachment);

  Message* m = new Message;
  PlaceholderBrokerableAttachment* needs_brokering_attachment =
      new PlaceholderBrokerableAttachment(attachment->GetIdentifier());
  EXPECT_TRUE(m->WriteAttachment(needs_brokering_attachment));
  reader.AddMessageForDispatch(m);
  EXPECT_EQ(ChannelReader::DISPATCH_WAITING_ON_BROKER,
            reader.DispatchMessages());
  EXPECT_EQ(nullptr, reader.get_last_dispatched_message());

  broker.AddAttachment(attachment);
  base::RunLoop run_loop;
  run_loop.RunUntilIdle();

  EXPECT_EQ(m, reader.get_last_dispatched_message());
}

#endif  // USE_ATTACHMENT_BROKER

#if !USE_ATTACHMENT_BROKER

// We can determine message size from its header (and hence resize the buffer)
// only when attachment broker is not used, see IPC::Message::FindNext().

TEST(ChannelReaderTest, ResizeOverflowBuffer) {
  MockChannelReader reader;

  ExposedMessage::Header header = {};

  header.payload_size = 128 * 1024;
  EXPECT_LT(reader.input_overflow_buf_.capacity(), header.payload_size);
  EXPECT_TRUE(reader.TranslateInputData(
      reinterpret_cast<const char*>(&header), sizeof(header)));

  // Once message header is available we resize overflow buffer to
  // fit the entire message.
  EXPECT_GE(reader.input_overflow_buf_.capacity(), header.payload_size);
}

TEST(ChannelReaderTest, InvalidMessageSize) {
  MockChannelReader reader;

  ExposedMessage::Header header = {};

  size_t capacity_before = reader.input_overflow_buf_.capacity();

  // Message is slightly larger than maximum allowed size
  header.payload_size = Channel::kMaximumMessageSize + 1;
  EXPECT_FALSE(reader.TranslateInputData(
      reinterpret_cast<const char*>(&header), sizeof(header)));
  EXPECT_LE(reader.input_overflow_buf_.capacity(), capacity_before);

  // Payload size is negative, overflow is detected by Pickle::PeekNext()
  header.payload_size = static_cast<uint32_t>(-1);
  EXPECT_FALSE(reader.TranslateInputData(
      reinterpret_cast<const char*>(&header), sizeof(header)));
  EXPECT_LE(reader.input_overflow_buf_.capacity(), capacity_before);

  // Payload size is maximum int32_t value
  header.payload_size = std::numeric_limits<int32_t>::max();
  EXPECT_FALSE(reader.TranslateInputData(
      reinterpret_cast<const char*>(&header), sizeof(header)));
  EXPECT_LE(reader.input_overflow_buf_.capacity(), capacity_before);
}

#endif  // !USE_ATTACHMENT_BROKER

TEST(ChannelReaderTest, TrimBuffer) {
  // ChannelReader uses std::string as a buffer, and calls reserve()
  // to trim it to kMaximumReadBufferSize. However, an implementation
  // is free to actually reserve a larger amount.
  size_t trimmed_buffer_size;
  {
    std::string buf;
    buf.reserve(Channel::kMaximumReadBufferSize);
    trimmed_buffer_size = buf.capacity();
  }

  // Buffer is trimmed after message is processed.
  {
    MockChannelReader reader;

    Message message;
    message.WriteString(std::string(LargePayloadSize, 'X'));

    // Sanity check
    EXPECT_TRUE(message.size() > trimmed_buffer_size);

    // Initially buffer is small
    EXPECT_LE(reader.input_overflow_buf_.capacity(), trimmed_buffer_size);

    // Write and process large message
    reader.AppendMessageData(message);
    EXPECT_EQ(ChannelReader::DISPATCH_FINISHED,
              reader.ProcessIncomingMessages());

    // After processing large message buffer is trimmed
    EXPECT_EQ(reader.input_overflow_buf_.capacity(), trimmed_buffer_size);
  }

  // Buffer is trimmed only after entire message is processed.
  {
    MockChannelReader reader;

    ExposedMessage message;
    message.WriteString(std::string(LargePayloadSize, 'X'));

    // Write and process message header
    reader.AppendData(message.header(), sizeof(ExposedMessage::Header));
    EXPECT_EQ(ChannelReader::DISPATCH_FINISHED,
              reader.ProcessIncomingMessages());

#if MESSAGE_FINDNEXT_PARTIAL
    // We determined message size for the message from its header, so
    // we resized the buffer to fit.
    EXPECT_GE(reader.input_overflow_buf_.capacity(), message.size());
#else
    // We couldn't determine message size, so we didn't resize the buffer.
#endif

    // Write and process payload
    reader.AppendData(message.payload(), message.payload_size());
    EXPECT_EQ(ChannelReader::DISPATCH_FINISHED,
              reader.ProcessIncomingMessages());

    // But once we process the message, we trim the buffer
    EXPECT_EQ(reader.input_overflow_buf_.capacity(), trimmed_buffer_size);
  }

  // Buffer is not trimmed if the next message is also large.
  {
    MockChannelReader reader;

    // Write large message
    Message message1;
    message1.WriteString(std::string(LargePayloadSize * 2, 'X'));
    reader.AppendMessageData(message1);

    // Write header for the next large message
    ExposedMessage message2;
    message2.WriteString(std::string(LargePayloadSize, 'Y'));
    reader.AppendData(message2.header(), sizeof(ExposedMessage::Header));

    // Process messages
    EXPECT_EQ(ChannelReader::DISPATCH_FINISHED,
              reader.ProcessIncomingMessages());

#if MESSAGE_FINDNEXT_PARTIAL
    // We determined message size for the second (partial) message, so
    // we resized the buffer to fit.
    EXPECT_GE(reader.input_overflow_buf_.capacity(), message1.size());
#else
    // We couldn't determine message size for the second (partial) message,
    // so we trimmed the buffer.
    EXPECT_EQ(reader.input_overflow_buf_.capacity(), trimmed_buffer_size);
#endif
  }

  // Buffer resized appropriately if next message is larger than the first.
  // (Similar to the test above except for the order of messages.)
  {
    MockChannelReader reader;

    // Write large message
    Message message1;
    message1.WriteString(std::string(LargePayloadSize, 'Y'));
    reader.AppendMessageData(message1);

    // Write header for the next even larger message
    ExposedMessage message2;
    message2.WriteString(std::string(LargePayloadSize * 2, 'X'));
    reader.AppendData(message2.header(), sizeof(ExposedMessage::Header));

    // Process messages
    EXPECT_EQ(ChannelReader::DISPATCH_FINISHED,
              reader.ProcessIncomingMessages());

#if MESSAGE_FINDNEXT_PARTIAL
    // We determined message size for the second (partial) message, and
    // resized the buffer to fit it.
    EXPECT_GE(reader.input_overflow_buf_.capacity(), message2.size());
#else
    // We couldn't determine message size for the second (partial) message,
    // so we trimmed the buffer.
    EXPECT_EQ(reader.input_overflow_buf_.capacity(), trimmed_buffer_size);
#endif
  }

  // Buffer is not trimmed if we've just resized it to accommodate large
  // incoming message.
  {
    MockChannelReader reader;

    // Write small message
    Message message1;
    message1.WriteString(std::string(11, 'X'));
    reader.AppendMessageData(message1);

    // Write header for the next large message
    ExposedMessage message2;
    message2.WriteString(std::string(LargePayloadSize, 'Y'));
    reader.AppendData(message2.header(), sizeof(ExposedMessage::Header));

    EXPECT_EQ(ChannelReader::DISPATCH_FINISHED,
              reader.ProcessIncomingMessages());

#if MESSAGE_FINDNEXT_PARTIAL
    // We determined message size for the second (partial) message, so
    // we resized the buffer to fit.
    EXPECT_GE(reader.input_overflow_buf_.capacity(), message2.size());
#else
    // We couldn't determine size for the second (partial) message, and
    // first message was small, so we did nothing.
#endif
  }
}

}  // namespace internal
}  // namespace IPC
