blob: d41a759eab16b088d054f5671f0ab03eeb788d72 [file] [log] [blame]
Vitaly Bukab93a1462017-01-07 01:52:581// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <cstddef>
16#include <cstdint>
17
18#include "google/protobuf/text_format.h"
Vitaly Buka9dd2f8e2017-01-13 08:48:3119#include "libfuzzer_example.pb.h" // NOLINT(build/include_subdir)
20#include "src/libfuzzer_protobuf_mutator.h"
Vitaly Bukab93a1462017-01-07 01:52:5821
22using google::protobuf::Message;
23using google::protobuf::TextFormat;
24using protobuf_mutator::LibFuzzerProtobufMutator;
25using libfuzzer_example::Msg;
26
27namespace {
28
29void Parse(const uint8_t* data, size_t size, Message* output) {
30 TextFormat::Parser parser;
31 parser.AllowPartialMessage(true);
32 parser.ParseFromString({data, data + size}, output);
33}
34}
35
36extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
37 size_t max_size, unsigned int seed) {
38 LibFuzzerProtobufMutator mutator(seed);
39 assert(size <= max_size);
40
41 for (int i = 0; i < 100; ++i) {
42 Msg message;
43 Parse(data, size, &message);
44 mutator.Mutate(&message, max_size - size);
45 std::string result;
46 if (TextFormat::PrintToString(message, &result) &&
47 result.size() <= max_size) {
48 memcpy(data, result.data(), result.size());
49 return result.size();
50 }
51 }
52
53 return 0;
54}
55
56extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
57 Msg message;
58 Parse(data, size, &message);
59
60 // Emulate a bug.
61 if (message.optional_uint64() > 100 &&
62 !std::isnan(message.optional_float()) &&
63 fabs(message.optional_float()) > 1000 &&
64 fabs(message.optional_float()) < 1E10) {
65 abort();
66 }
67
68 return 0;
69}