// Copyright 2013 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 <limits.h>
#include <stddef.h>
#include <stdint.h>

#include "base/files/file_path.h"
#include "base/files/memory_mapped_file.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_piece.h"
#include "ipc/ipc_message.h"
#include "tools/ipc_fuzzer/message_lib/message_cracker.h"
#include "tools/ipc_fuzzer/message_lib/message_file.h"
#include "tools/ipc_fuzzer/message_lib/message_file_format.h"
#include "tools/ipc_fuzzer/message_lib/message_names.h"

namespace ipc_fuzzer {

namespace {

// Helper class to read IPC message file into a MessageVector and
// fix message types.
class Reader {
 public:
  Reader(const base::FilePath& path);
  bool Read(MessageVector* messages);

 private:
  template <typename T>
  bool CutObject(const T** object);

  // Reads the header, checks magic and version.
  bool ReadHeader();

  bool MapFile();
  bool ReadMessages();

  // Last part of the file is a string table for message names.
  bool ReadStringTable();

  // Reads type <-> name mapping into name_map_. References string table.
  bool ReadNameTable();

  // Removes obsolete messages from the vector.
  bool RemoveUnknownMessages();

  // Does type -> name -> correct_type fixup.
  void FixMessageTypes();

  // Raw data.
  base::FilePath path_;
  base::MemoryMappedFile mapped_file_;
  base::StringPiece file_data_;
  base::StringPiece string_table_;

  // Parsed data.
  const FileHeader* header_;
  MessageVector* messages_;
  MessageNames name_map_;

  DISALLOW_COPY_AND_ASSIGN(Reader);
};

Reader::Reader(const base::FilePath& path)
    : path_(path),
      header_(NULL),
      messages_(NULL) {
}

template <typename T>
bool Reader::CutObject(const T** object) {
  if (file_data_.size() < sizeof(T)) {
    LOG(ERROR) << "Unexpected EOF.";
    return false;
  }
  *object = reinterpret_cast<const T*>(file_data_.data());
  file_data_.remove_prefix(sizeof(T));
  return true;
}

bool Reader::ReadHeader() {
  if (!CutObject<FileHeader>(&header_))
    return false;
  if (header_->magic != FileHeader::kMagicValue) {
    LOG(ERROR) << path_.value() << " is not an IPC message file.";
    return false;
  }
  if (header_->version != FileHeader::kCurrentVersion) {
    LOG(ERROR) << "Wrong version for message file " << path_.value() << ". "
               << "File version is " << header_->version << ", "
               << "current version is " << FileHeader::kCurrentVersion << ".";
    return false;
  }
  return true;
}

bool Reader::MapFile() {
  if (!mapped_file_.Initialize(path_)) {
    LOG(ERROR) << "Failed to map testcase: " << path_.value();
    return false;
  }
  const char* data = reinterpret_cast<const char*>(mapped_file_.data());
  file_data_.set(data, mapped_file_.length());
  return true;
}

bool Reader::ReadMessages() {
  for (size_t i = 0; i < header_->message_count; ++i) {
    const char* begin = file_data_.begin();
    const char* end = file_data_.end();
    IPC::Message::NextMessageInfo info;
    IPC::Message::FindNext(begin, end, &info);
    if (!info.message_found) {
      LOG(ERROR) << "Failed to parse message.";
      return false;
    }

    CHECK_EQ(info.message_end, info.pickle_end);
    size_t msglen = info.message_end - begin;
    if (msglen > INT_MAX) {
      LOG(ERROR) << "Message too large.";
      return false;
    }

    // Copy is necessary to fix message type later.
    IPC::Message const_message(begin, msglen);
    messages_->push_back(std::make_unique<IPC::Message>(const_message));
    file_data_.remove_prefix(msglen);
  }
  return true;
}

bool Reader::ReadStringTable() {
  size_t name_count = header_->name_count;
  if (!name_count)
    return true;
  if (name_count > file_data_.size() / sizeof(NameTableEntry)) {
    LOG(ERROR) << "Invalid name table size: " << name_count;
    return false;
  }

  size_t string_table_offset = name_count * sizeof(NameTableEntry);
  string_table_ = file_data_.substr(string_table_offset);
  if (string_table_.empty()) {
    LOG(ERROR) << "Missing string table.";
    return false;
  }
  if (string_table_.end()[-1] != '\0') {
    LOG(ERROR) << "String table doesn't end with NUL.";
    return false;
  }
  return true;
}

bool Reader::ReadNameTable() {
  for (size_t i = 0; i < header_->name_count; ++i) {
    const NameTableEntry* entry;
    if (!CutObject<NameTableEntry>(&entry))
      return false;
    size_t offset = entry->string_table_offset;
    if (offset >= string_table_.size()) {
      LOG(ERROR) << "Invalid string table offset: " << offset;
      return false;
    }
    name_map_.Add(entry->type, string_table_.data() + offset);
  }
  return true;
}

bool Reader::RemoveUnknownMessages() {
  MessageVector::iterator it = messages_->begin();
  while (it != messages_->end()) {
    uint32_t type = (*it)->type();
    if (!name_map_.TypeExists(type)) {
      LOG(ERROR) << "Missing name table entry for type " << type;
      return false;
    }
    const std::string& name = name_map_.TypeToName(type);
    if (!MessageNames::GetInstance()->NameExists(name)) {
      LOG(WARNING) << "Unknown message " << name;
      it = messages_->erase(it);
    } else {
      ++it;
    }
  }
  return true;
}

// Message types are based on line numbers, so a minor edit of *_messages.h
// changes the types of messages in that file. The types are fixed here to
// increase the lifetime of message files. This is only a partial fix because
// message arguments and structure layouts can change as well.
void Reader::FixMessageTypes() {
  for (const auto& message : *messages_) {
    uint32_t type = message->type();
    const std::string& name = name_map_.TypeToName(type);
    uint32_t correct_type = MessageNames::GetInstance()->NameToType(name);
    if (type != correct_type)
      MessageCracker::SetMessageType(message.get(), correct_type);
  }
}

bool Reader::Read(MessageVector* messages) {
  messages_ = messages;

  if (!MapFile())
    return false;
  if (!ReadHeader())
    return false;
  if (!ReadMessages())
    return false;
  if (!ReadStringTable())
    return false;
  if (!ReadNameTable())
    return false;
  if (!RemoveUnknownMessages())
    return false;
  FixMessageTypes();

  return true;
}

}  // namespace

bool MessageFile::Read(const base::FilePath& path, MessageVector* messages) {
  Reader reader(path);
  return reader.Read(messages);
}

}  // namespace ipc_fuzzer
