1*fd525a9cSAndroid Build Coastguard Worker // Copyright 2017 Google Inc. All rights reserved.
2*fd525a9cSAndroid Build Coastguard Worker //
3*fd525a9cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*fd525a9cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*fd525a9cSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*fd525a9cSAndroid Build Coastguard Worker //
7*fd525a9cSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*fd525a9cSAndroid Build Coastguard Worker //
9*fd525a9cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*fd525a9cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*fd525a9cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*fd525a9cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*fd525a9cSAndroid Build Coastguard Worker // limitations under the License.
14*fd525a9cSAndroid Build Coastguard Worker
15*fd525a9cSAndroid Build Coastguard Worker #include <getopt.h>
16*fd525a9cSAndroid Build Coastguard Worker
17*fd525a9cSAndroid Build Coastguard Worker #include <fstream>
18*fd525a9cSAndroid Build Coastguard Worker #include <iostream>
19*fd525a9cSAndroid Build Coastguard Worker
20*fd525a9cSAndroid Build Coastguard Worker #include "examples/xml/xml.pb.h"
21*fd525a9cSAndroid Build Coastguard Worker #include "examples/xml/xml_writer.h"
22*fd525a9cSAndroid Build Coastguard Worker #include "port/protobuf.h"
23*fd525a9cSAndroid Build Coastguard Worker #include "src/text_format.h"
24*fd525a9cSAndroid Build Coastguard Worker
25*fd525a9cSAndroid Build Coastguard Worker using protobuf_mutator::xml::Input;
26*fd525a9cSAndroid Build Coastguard Worker
27*fd525a9cSAndroid Build Coastguard Worker namespace {
28*fd525a9cSAndroid Build Coastguard Worker
29*fd525a9cSAndroid Build Coastguard Worker struct option const kLongOptions[] = {{"reverse", no_argument, NULL, 'r'},
30*fd525a9cSAndroid Build Coastguard Worker {"verbose", no_argument, NULL, 'v'},
31*fd525a9cSAndroid Build Coastguard Worker {"help", no_argument, NULL, 'h'},
32*fd525a9cSAndroid Build Coastguard Worker {NULL, 0, NULL, 0}};
33*fd525a9cSAndroid Build Coastguard Worker
PrintUsage()34*fd525a9cSAndroid Build Coastguard Worker void PrintUsage() {
35*fd525a9cSAndroid Build Coastguard Worker std::cerr << "Usage: xml_converter [OPTION]... [INFILE [OUTFILE]]\n"
36*fd525a9cSAndroid Build Coastguard Worker << "Converts between proto used by fuzzer and XML.\n\n"
37*fd525a9cSAndroid Build Coastguard Worker << "\t-h, --help\tPrint this help\n"
38*fd525a9cSAndroid Build Coastguard Worker << "\t-r, --reverse\tConverts from XML to proto\n"
39*fd525a9cSAndroid Build Coastguard Worker << "\t-v, --verbose\tPrint input\n";
40*fd525a9cSAndroid Build Coastguard Worker }
41*fd525a9cSAndroid Build Coastguard Worker
42*fd525a9cSAndroid Build Coastguard Worker struct Options {
43*fd525a9cSAndroid Build Coastguard Worker bool reverse = false;
44*fd525a9cSAndroid Build Coastguard Worker bool verbose = false;
45*fd525a9cSAndroid Build Coastguard Worker std::string in_file;
46*fd525a9cSAndroid Build Coastguard Worker std::string out_file;
47*fd525a9cSAndroid Build Coastguard Worker };
48*fd525a9cSAndroid Build Coastguard Worker
ParseOptions(int argc,char ** argv,Options * options)49*fd525a9cSAndroid Build Coastguard Worker bool ParseOptions(int argc, char** argv, Options* options) {
50*fd525a9cSAndroid Build Coastguard Worker int c = 0;
51*fd525a9cSAndroid Build Coastguard Worker while ((c = getopt_long(argc, argv, "hrv", kLongOptions, nullptr)) != -1) {
52*fd525a9cSAndroid Build Coastguard Worker switch (c) {
53*fd525a9cSAndroid Build Coastguard Worker case 'v':
54*fd525a9cSAndroid Build Coastguard Worker options->verbose = true;
55*fd525a9cSAndroid Build Coastguard Worker break;
56*fd525a9cSAndroid Build Coastguard Worker case 'r':
57*fd525a9cSAndroid Build Coastguard Worker options->reverse = true;
58*fd525a9cSAndroid Build Coastguard Worker break;
59*fd525a9cSAndroid Build Coastguard Worker case 'h':
60*fd525a9cSAndroid Build Coastguard Worker default:
61*fd525a9cSAndroid Build Coastguard Worker return false;
62*fd525a9cSAndroid Build Coastguard Worker }
63*fd525a9cSAndroid Build Coastguard Worker }
64*fd525a9cSAndroid Build Coastguard Worker
65*fd525a9cSAndroid Build Coastguard Worker int i = optind;
66*fd525a9cSAndroid Build Coastguard Worker if (i < argc) options->in_file = argv[i++];
67*fd525a9cSAndroid Build Coastguard Worker if (i < argc) options->out_file = argv[i++];
68*fd525a9cSAndroid Build Coastguard Worker if (i != argc) return false;
69*fd525a9cSAndroid Build Coastguard Worker
70*fd525a9cSAndroid Build Coastguard Worker return true;
71*fd525a9cSAndroid Build Coastguard Worker }
72*fd525a9cSAndroid Build Coastguard Worker
73*fd525a9cSAndroid Build Coastguard Worker } // namespace
74*fd525a9cSAndroid Build Coastguard Worker
main(int argc,char ** argv)75*fd525a9cSAndroid Build Coastguard Worker int main(int argc, char** argv) {
76*fd525a9cSAndroid Build Coastguard Worker Options options;
77*fd525a9cSAndroid Build Coastguard Worker if (!ParseOptions(argc, argv, &options)) {
78*fd525a9cSAndroid Build Coastguard Worker PrintUsage();
79*fd525a9cSAndroid Build Coastguard Worker return 1;
80*fd525a9cSAndroid Build Coastguard Worker }
81*fd525a9cSAndroid Build Coastguard Worker
82*fd525a9cSAndroid Build Coastguard Worker std::istream* cin = &std::cin;
83*fd525a9cSAndroid Build Coastguard Worker std::ostream* cout = &std::cout;
84*fd525a9cSAndroid Build Coastguard Worker
85*fd525a9cSAndroid Build Coastguard Worker std::ifstream in_file_stream;
86*fd525a9cSAndroid Build Coastguard Worker if (!options.in_file.empty()) {
87*fd525a9cSAndroid Build Coastguard Worker in_file_stream.open(options.in_file);
88*fd525a9cSAndroid Build Coastguard Worker cin = &in_file_stream;
89*fd525a9cSAndroid Build Coastguard Worker }
90*fd525a9cSAndroid Build Coastguard Worker
91*fd525a9cSAndroid Build Coastguard Worker std::ofstream out_file_stream;
92*fd525a9cSAndroid Build Coastguard Worker if (!options.out_file.empty()) {
93*fd525a9cSAndroid Build Coastguard Worker out_file_stream.open(options.out_file);
94*fd525a9cSAndroid Build Coastguard Worker cout = &out_file_stream;
95*fd525a9cSAndroid Build Coastguard Worker }
96*fd525a9cSAndroid Build Coastguard Worker
97*fd525a9cSAndroid Build Coastguard Worker std::string input;
98*fd525a9cSAndroid Build Coastguard Worker std::vector<char> buff(1 << 20);
99*fd525a9cSAndroid Build Coastguard Worker while (auto size = cin->readsome(buff.data(), buff.size())) {
100*fd525a9cSAndroid Build Coastguard Worker input += std::string(buff.data(), size);
101*fd525a9cSAndroid Build Coastguard Worker }
102*fd525a9cSAndroid Build Coastguard Worker std::string output;
103*fd525a9cSAndroid Build Coastguard Worker
104*fd525a9cSAndroid Build Coastguard Worker int ret = 0;
105*fd525a9cSAndroid Build Coastguard Worker
106*fd525a9cSAndroid Build Coastguard Worker if (options.reverse) {
107*fd525a9cSAndroid Build Coastguard Worker Input message;
108*fd525a9cSAndroid Build Coastguard Worker message.mutable_document()->mutable_element()->add_content()->set_char_data(
109*fd525a9cSAndroid Build Coastguard Worker input);
110*fd525a9cSAndroid Build Coastguard Worker output = protobuf_mutator::SaveMessageAsText(message);
111*fd525a9cSAndroid Build Coastguard Worker } else {
112*fd525a9cSAndroid Build Coastguard Worker Input message;
113*fd525a9cSAndroid Build Coastguard Worker bool is_proto = protobuf_mutator::ParseTextMessage(input.data(), &message);
114*fd525a9cSAndroid Build Coastguard Worker output = MessageToXml(message.document());
115*fd525a9cSAndroid Build Coastguard Worker if (!is_proto) {
116*fd525a9cSAndroid Build Coastguard Worker ret = 2;
117*fd525a9cSAndroid Build Coastguard Worker if (options.verbose) std::cerr << "Input is not proto\n";
118*fd525a9cSAndroid Build Coastguard Worker }
119*fd525a9cSAndroid Build Coastguard Worker }
120*fd525a9cSAndroid Build Coastguard Worker
121*fd525a9cSAndroid Build Coastguard Worker if (options.verbose) {
122*fd525a9cSAndroid Build Coastguard Worker std::cerr << input << "\n\n";
123*fd525a9cSAndroid Build Coastguard Worker std::cerr.flush();
124*fd525a9cSAndroid Build Coastguard Worker }
125*fd525a9cSAndroid Build Coastguard Worker *cout << output;
126*fd525a9cSAndroid Build Coastguard Worker
127*fd525a9cSAndroid Build Coastguard Worker return ret;
128*fd525a9cSAndroid Build Coastguard Worker }
129