Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Side by Side Diff: tools/ipc_fuzzer/message_lib/message_file_writer.cc

Issue 105083002: IPC fuzzer: create message_lib library. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <limits.h>
6 #include <set>
7
8 #include "base/logging.h"
9 #include "base/platform_file.h"
10 #include "tools/ipc_fuzzer/message_lib/message_file.h"
11 #include "tools/ipc_fuzzer/message_lib/message_file_format.h"
12 #include "tools/ipc_fuzzer/message_lib/message_names.h"
13
14 namespace ipc_fuzzer {
15
16 namespace {
17
18 // Helper class to write a MessageVector + message names to a file.
19 class Writer {
20 public:
21 Writer(const base::FilePath& path);
22 ~Writer();
23 bool Write(const MessageVector& messages);
24
25 private:
26 bool OpenFile();
27
28 // Helper to append data to file_.
29 bool WriteBlob(const void *buffer, size_t size);
30
31 // Collects a set of MessageVector message types. Corresponding message
32 // names need to be included in the file.
33 bool CollectMessageTypes();
34
35 bool WriteHeader();
36 bool WriteMessages();
37
38 // Each name table entry is a message type + string table offset.
39 bool WriteNameTable();
40
41 // String table contains the actual message names.
42 bool WriteStringTable();
43
44 typedef std::set<uint32> TypesSet;
45 base::FilePath path_;
46 base::PlatformFile file_;
47 const MessageVector* messages_;
48 TypesSet types_;
49
50 DISALLOW_COPY_AND_ASSIGN(Writer);
51 };
52
53 Writer::Writer(const base::FilePath& path)
54 : path_(path),
55 file_(base::kInvalidPlatformFileValue),
56 messages_(NULL) {
57 }
58
59 Writer::~Writer() {
60 if (file_ != base::kInvalidPlatformFileValue)
61 base::ClosePlatformFile(file_);
62 }
63
64 bool Writer::OpenFile() {
65 file_ = base::CreatePlatformFile(
66 path_,
67 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE,
68 NULL,
69 NULL);
70 if (file_ == base::kInvalidPlatformFileValue) {
71 LOG(ERROR) << "Failed to create IPC message file: " << path_.value();
72 return false;
73 }
74 return true;
75 }
76
77 bool Writer::WriteBlob(const void *buffer, size_t size) {
78 if (size > INT_MAX)
79 return false;
80 const char* char_buffer = static_cast<const char*>(buffer);
81 int ret = base::WritePlatformFileAtCurrentPos(file_, char_buffer, size);
82 if (ret != size) {
83 LOG(ERROR) << "Failed to write " << size << " bytes.";
84 return false;
85 }
86 return true;
87 }
88
89 bool Writer::CollectMessageTypes() {
90 for (size_t i = 0; i < messages_->size(); ++i) {
91 uint32_t type = (*messages_)[i]->type();
92 if (!MessageNames::GetInstance()->TypeExists(type)) {
93 LOG(ERROR) << "Unknown message type: " << type;
94 return false;
95 }
96 types_.insert(type);
97 }
98 return true;
99 }
100
101 bool Writer::WriteHeader() {
102 FileHeader header;
103 if (messages_->size() > UINT_MAX)
104 return false;
105 header.magic = FileHeader::kMagicValue;
106 header.version = FileHeader::kCurrentVersion;
107 header.message_count = messages_->size();
108 header.name_count = types_.size();
109 if (!WriteBlob(&header, sizeof(FileHeader)))
110 return false;
111 return true;
112 }
113
114 bool Writer::WriteMessages() {
115 for (size_t i = 0; i < messages_->size(); ++i) {
116 IPC::Message* message = (*messages_)[i];
117 if (!WriteBlob(message->data(), message->size()))
118 return false;
119 }
120 return true;
121 }
122
123 bool Writer::WriteNameTable() {
124 size_t string_table_offset = 0;
125 NameTableEntry entry;
126
127 for (TypesSet::iterator it = types_.begin(); it != types_.end(); ++it) {
128 if (string_table_offset > UINT_MAX)
129 return false;
130 entry.type = *it;
131 entry.string_table_offset = string_table_offset;
132 if (!WriteBlob(&entry, sizeof(NameTableEntry)))
133 return false;
134 const std::string& name = MessageNames::GetInstance()->TypeToName(*it);
135 string_table_offset += name.length() + 1;
136 }
137 return true;
138 }
139
140 bool Writer::WriteStringTable() {
141 for (TypesSet::iterator it = types_.begin(); it != types_.end(); ++it) {
142 const std::string& name = MessageNames::GetInstance()->TypeToName(*it);
143 if (!WriteBlob(name.c_str(), name.length() + 1))
144 return false;
145 }
146 return true;
147 }
148
149 bool Writer::Write(const MessageVector& messages) {
150 messages_ = &messages;
151
152 if (!OpenFile())
153 return false;
154 if (!CollectMessageTypes())
155 return false;
156 if (!WriteHeader())
157 return false;
158 if (!WriteMessages())
159 return false;
160 if (!WriteNameTable())
161 return false;
162 if (!WriteStringTable())
163 return false;
164
165 return true;
166 }
167
168 } // namespace
169
170 bool MessageFile::Write(const base::FilePath& path,
171 const MessageVector& messages) {
172 Writer writer(path);
173 return writer.Write(messages);
174 }
175
176 } // namespace ipc_fuzzer
OLDNEW
« no previous file with comments | « tools/ipc_fuzzer/message_lib/message_file_reader.cc ('k') | tools/ipc_fuzzer/message_lib/message_lib.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698