diff options
Diffstat (limited to 'chromium/tools/ipc_fuzzer/message_lib/message_file_reader.cc')
-rw-r--r-- | chromium/tools/ipc_fuzzer/message_lib/message_file_reader.cc | 230 |
1 files changed, 0 insertions, 230 deletions
diff --git a/chromium/tools/ipc_fuzzer/message_lib/message_file_reader.cc b/chromium/tools/ipc_fuzzer/message_lib/message_file_reader.cc deleted file mode 100644 index e93c460b7e2..00000000000 --- a/chromium/tools/ipc_fuzzer/message_lib/message_file_reader.cc +++ /dev/null @@ -1,230 +0,0 @@ -// 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 "base/files/file_path.h" -#include "base/files/memory_mapped_file.h" -#include "base/logging.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(); - const char* message_tail = IPC::Message::FindNext(begin, end); - if (!message_tail) { - LOG(ERROR) << "Failed to parse message."; - return false; - } - - size_t msglen = message_tail - 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); - IPC::Message* message = new IPC::Message(const_message); - messages_->push_back(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, std::string(string_table_.data() + offset)); - } - return true; -} - -bool Reader::RemoveUnknownMessages() { - MessageVector::iterator it = messages_->begin(); - while (it != messages_->end()) { - uint32 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 (MessageVector::iterator it = messages_->begin(); - it != messages_->end(); ++it) { - uint32 type = (*it)->type(); - const std::string& name = name_map_.TypeToName(type); - uint32 correct_type = MessageNames::GetInstance()->NameToType(name); - if (type != correct_type) - MessageCracker::SetMessageType(*it, 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 |