| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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 <stdlib.h> | |
| 7 #include <iostream> | |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/command_line.h" | |
| 12 #include "base/strings/string_split.h" | |
| 13 #include "third_party/re2/re2/re2.h" | |
| 14 #include "tools/ipc_fuzzer/message_lib/message_file.h" | |
| 15 #include "tools/ipc_fuzzer/message_lib/message_names.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 const char kDumpSwitch[] = "dump"; | |
| 20 const char kDumpSwitchHelp[] = | |
| 21 "dump human-readable form to stdout instead of copying."; | |
| 22 | |
| 23 const char kEndSwitch[] = "end"; | |
| 24 const char kEndSwitchHelp[] = | |
| 25 "output messages before |m|th message in file (exclusive)."; | |
| 26 | |
| 27 const char kHelpSwitch[] = "help"; | |
| 28 const char kHelpSwitchHelp[] = | |
| 29 "display this message."; | |
| 30 | |
| 31 const char kInSwitch[] = "in"; | |
| 32 const char kInSwitchHelp[] = | |
| 33 "output only the messages at the specified positions in the file."; | |
| 34 | |
| 35 const char kInvertSwitch[] = "invert"; | |
| 36 const char kInvertSwitchHelp[] = | |
| 37 "output messages NOT meeting above criteria."; | |
| 38 | |
| 39 const char kRegexpSwitch[] = "regexp"; | |
| 40 const char kRegexpSwitchHelp[] = | |
| 41 "output messages matching regular expression |x|."; | |
| 42 | |
| 43 const char kStartSwitch[] = "start"; | |
| 44 const char kStartSwitchHelp[] = | |
| 45 "output messages after |n|th message in file (inclusive)."; | |
| 46 | |
| 47 void usage() { | |
| 48 std::cerr << "ipc_message_util: Concatenate all |infile| message files and " | |
| 49 << "copy a subset of the result to |outfile|.\n"; | |
| 50 | |
| 51 std::cerr << "Usage:\n" | |
| 52 << " ipc_message_util" | |
| 53 << " [--" << kStartSwitch << "=n]" | |
| 54 << " [--" << kEndSwitch << "=m]" | |
| 55 << " [--" << kInSwitch << "=i[,j,...]]" | |
| 56 << " [--" << kRegexpSwitch << "=x]" | |
| 57 << " [--" << kInvertSwitch << "]" | |
| 58 << " [--" << kDumpSwitch << "]" | |
| 59 << " [--" << kHelpSwitch << "]" | |
| 60 << " infile,infile,... [outfile]\n"; | |
| 61 | |
| 62 std::cerr << " --" << kStartSwitch << " - " << kStartSwitchHelp << "\n" | |
| 63 << " --" << kEndSwitch << " - " << kEndSwitchHelp << "\n" | |
| 64 << " --" << kInSwitch << " - " << kInSwitchHelp << "\n" | |
| 65 << " --" << kRegexpSwitch << " - " << kRegexpSwitchHelp << "\n" | |
| 66 << " --" << kInvertSwitch << " - " << kInvertSwitchHelp << "\n" | |
| 67 << " --" << kDumpSwitch << " - " << kDumpSwitchHelp << "\n" | |
| 68 << " --" << kHelpSwitch << " - " << kHelpSwitchHelp << "\n"; | |
| 69 } | |
| 70 | |
| 71 std::string MessageName(const IPC::Message* msg) { | |
| 72 return ipc_fuzzer::MessageNames::GetInstance()->TypeToName(msg->type()); | |
| 73 } | |
| 74 | |
| 75 bool MessageMatches(const IPC::Message* msg, const RE2& pattern) { | |
| 76 return RE2::FullMatch(MessageName(msg), pattern); | |
| 77 } | |
| 78 | |
| 79 } // namespace | |
| 80 | |
| 81 int main(int argc, char** argv) { | |
| 82 base::CommandLine::Init(argc, argv); | |
| 83 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); | |
| 84 base::CommandLine::StringVector args = cmd->GetArgs(); | |
| 85 | |
| 86 if (args.size() < 1 || args.size() > 2 || cmd->HasSwitch(kHelpSwitch)) { | |
| 87 usage(); | |
| 88 return EXIT_FAILURE; | |
| 89 } | |
| 90 | |
| 91 size_t start_index = 0; | |
| 92 if (cmd->HasSwitch(kStartSwitch)) { | |
| 93 int temp = atoi(cmd->GetSwitchValueASCII(kStartSwitch).c_str()); | |
| 94 if (temp > 0) | |
| 95 start_index = static_cast<size_t>(temp); | |
| 96 } | |
| 97 | |
| 98 size_t end_index = INT_MAX; | |
| 99 if (cmd->HasSwitch(kEndSwitch)) { | |
| 100 int temp = atoi(cmd->GetSwitchValueASCII(kEndSwitch).c_str()); | |
| 101 if (temp > 0) | |
| 102 end_index = static_cast<size_t>(temp); | |
| 103 } | |
| 104 | |
| 105 bool has_regexp = cmd->HasSwitch(kRegexpSwitch); | |
| 106 RE2 filter_pattern(cmd->GetSwitchValueASCII(kRegexpSwitch)); | |
| 107 | |
| 108 bool invert = cmd->HasSwitch(kInvertSwitch); | |
| 109 bool perform_dump = cmd->HasSwitch(kDumpSwitch); | |
| 110 | |
| 111 std::vector<base::FilePath::StringType> input_file_names; | |
| 112 base::FilePath::StringType output_file_name; | |
| 113 base::SplitString(args[0], ',', &input_file_names); | |
| 114 | |
| 115 if (!perform_dump) { | |
| 116 if (args.size() < 2) { | |
| 117 usage(); | |
| 118 return EXIT_FAILURE; | |
| 119 } | |
| 120 output_file_name = args[1]; | |
| 121 } | |
| 122 | |
| 123 ipc_fuzzer::MessageVector input_message_vector; | |
| 124 for (std::vector<base::FilePath::StringType>::iterator | |
| 125 it = input_file_names.begin(); it != input_file_names.end(); ++it) { | |
| 126 ipc_fuzzer::MessageVector message_vector; | |
| 127 if (!ipc_fuzzer::MessageFile::Read(base::FilePath(*it), &message_vector)) | |
| 128 return EXIT_FAILURE; | |
| 129 input_message_vector.insert(input_message_vector.end(), | |
| 130 message_vector.begin(), message_vector.end()); | |
| 131 message_vector.weak_clear(); | |
| 132 } | |
| 133 | |
| 134 bool has_indices = cmd->HasSwitch(kInSwitch); | |
| 135 std::vector<bool> indices; | |
| 136 | |
| 137 if (has_indices) { | |
| 138 indices.resize(input_message_vector.size(), false); | |
| 139 std::vector<std::string> index_strings; | |
| 140 base::SplitString(cmd->GetSwitchValueASCII(kInSwitch), ',', &index_strings); | |
| 141 for (std::vector<std::string>::iterator it = index_strings.begin(); | |
| 142 it != index_strings.end(); ++it) { | |
| 143 int index = atoi(it->c_str()); | |
| 144 if (index >= 0 && static_cast<size_t>(index) < indices.size()) | |
| 145 indices[index] = true; | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 ipc_fuzzer::MessageVector output_message_vector; | |
| 150 std::vector<size_t> remap_vector; | |
| 151 | |
| 152 for (size_t i = 0; i < input_message_vector.size(); ++i) { | |
| 153 bool valid = (i >= start_index && i < end_index); | |
| 154 if (valid && has_regexp) { | |
| 155 valid = MessageMatches(input_message_vector[i], filter_pattern); | |
| 156 } | |
| 157 if (valid && has_indices) { | |
| 158 valid = indices[i]; | |
| 159 } | |
| 160 if (valid != invert) { | |
| 161 output_message_vector.push_back(input_message_vector[i]); | |
| 162 remap_vector.push_back(i); | |
| 163 input_message_vector[i] = NULL; | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 if (perform_dump) { | |
| 168 for (size_t i = 0; i < output_message_vector.size(); ++i) { | |
| 169 std::cout << remap_vector[i] << ". " | |
| 170 << MessageName(output_message_vector[i]) << "\n"; | |
| 171 } | |
| 172 } else { | |
| 173 if (!ipc_fuzzer::MessageFile::Write( | |
| 174 base::FilePath(output_file_name), output_message_vector)) { | |
| 175 return EXIT_FAILURE; | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 return EXIT_SUCCESS; | |
| 180 } | |
| OLD | NEW |