blob: 7435bd0e5ae2453a2c71d4c78a7837933d932fcb [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// A fuzzer that uses a dictionary finds a divide-by-zero.
#include <stddef.h>
#include <stdint.h>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
// The code under test. Normally this would be in a separate library.
namespace {
// Parses select words into integers.
bool parse_num(const std::string &token, int *out) {
if (token == "zero") {
*out = 0;
} else if (token == "one") {
*out = 1;
} else if (token == "two") {
*out = 2;
} else {
return false;
}
return true;
}
// Calculates a result from a string like "add one to two".
bool calculate(const std::string &input, int *result) {
std::istringstream iss(input);
std::vector<std::string> tokens{std::istream_iterator<std::string>{iss},
std::istream_iterator<std::string>{}};
int op1, op2;
if (tokens.size() != 4 || !parse_num(tokens[1], &op1) || !parse_num(tokens[3], &op2)) {
return false;
}
if (tokens[0] == "add" && tokens[2] == "to") {
*result = op1 + op2;
} else if (tokens[0] == "subtract" && tokens[2] == "from") {
*result = op2 - op1;
} else if (tokens[0] == "multiply" && tokens[2] == "by") {
*result = op1 * op2;
} else if (tokens[0] == "divide" && tokens[2] == "by") {
*result = op1 / op1;
} else {
return false;
}
return true;
}
} // namespace
// The fuzz target function
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
std::string input(reinterpret_cast<const char *>(data), size);
int result;
calculate(input, &result);
return 0;
}