You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.3 KiB
129 lines
3.3 KiB
7 months ago
|
// Copyright 2017 Google Inc. All rights reserved.
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
|
||
|
#include <getopt.h>
|
||
|
|
||
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
|
||
|
#include "examples/xml/xml.pb.h"
|
||
|
#include "examples/xml/xml_writer.h"
|
||
|
#include "port/protobuf.h"
|
||
|
#include "src/text_format.h"
|
||
|
|
||
|
using protobuf_mutator::xml::Input;
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
struct option const kLongOptions[] = {{"reverse", no_argument, NULL, 'r'},
|
||
|
{"verbose", no_argument, NULL, 'v'},
|
||
|
{"help", no_argument, NULL, 'h'},
|
||
|
{NULL, 0, NULL, 0}};
|
||
|
|
||
|
void PrintUsage() {
|
||
|
std::cerr << "Usage: xml_converter [OPTION]... [INFILE [OUTFILE]]\n"
|
||
|
<< "Converts between proto used by fuzzer and XML.\n\n"
|
||
|
<< "\t-h, --help\tPrint this help\n"
|
||
|
<< "\t-r, --reverse\tConverts from XML to proto\n"
|
||
|
<< "\t-v, --verbose\tPrint input\n";
|
||
|
}
|
||
|
|
||
|
struct Options {
|
||
|
bool reverse = false;
|
||
|
bool verbose = false;
|
||
|
std::string in_file;
|
||
|
std::string out_file;
|
||
|
};
|
||
|
|
||
|
bool ParseOptions(int argc, char** argv, Options* options) {
|
||
|
int c = 0;
|
||
|
while ((c = getopt_long(argc, argv, "hrv", kLongOptions, nullptr)) != -1) {
|
||
|
switch (c) {
|
||
|
case 'v':
|
||
|
options->verbose = true;
|
||
|
break;
|
||
|
case 'r':
|
||
|
options->reverse = true;
|
||
|
break;
|
||
|
case 'h':
|
||
|
default:
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int i = optind;
|
||
|
if (i < argc) options->in_file = argv[i++];
|
||
|
if (i < argc) options->out_file = argv[i++];
|
||
|
if (i != argc) return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
int main(int argc, char** argv) {
|
||
|
Options options;
|
||
|
if (!ParseOptions(argc, argv, &options)) {
|
||
|
PrintUsage();
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
std::istream* cin = &std::cin;
|
||
|
std::ostream* cout = &std::cout;
|
||
|
|
||
|
std::ifstream in_file_stream;
|
||
|
if (!options.in_file.empty()) {
|
||
|
in_file_stream.open(options.in_file);
|
||
|
cin = &in_file_stream;
|
||
|
}
|
||
|
|
||
|
std::ofstream out_file_stream;
|
||
|
if (!options.out_file.empty()) {
|
||
|
out_file_stream.open(options.out_file);
|
||
|
cout = &out_file_stream;
|
||
|
}
|
||
|
|
||
|
std::string input;
|
||
|
std::vector<char> buff(1 << 20);
|
||
|
while (auto size = cin->readsome(buff.data(), buff.size())) {
|
||
|
input += std::string(buff.data(), size);
|
||
|
}
|
||
|
std::string output;
|
||
|
|
||
|
int ret = 0;
|
||
|
|
||
|
if (options.reverse) {
|
||
|
Input message;
|
||
|
message.mutable_document()->mutable_element()->add_content()->set_char_data(
|
||
|
input);
|
||
|
output = protobuf_mutator::SaveMessageAsText(message);
|
||
|
} else {
|
||
|
Input message;
|
||
|
bool is_proto = protobuf_mutator::ParseTextMessage(input.data(), &message);
|
||
|
output = MessageToXml(message.document());
|
||
|
if (!is_proto) {
|
||
|
ret = 2;
|
||
|
if (options.verbose) std::cerr << "Input is not proto\n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (options.verbose) {
|
||
|
std::cerr << input << "\n\n";
|
||
|
std::cerr.flush();
|
||
|
}
|
||
|
*cout << output;
|
||
|
|
||
|
return ret;
|
||
|
}
|