| // 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; |
| } |