xref: /aosp_15_r20/external/libprotobuf-mutator/examples/xml/xml_converter.cc (revision fd525a9c096e28cf6f8d8719388df0568a611e7b)
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