Coverage Report

Created: 2024-01-24 07:14

/proc/self/cwd/pw_protobuf/encoder_fuzzer.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2019 The Pigweed Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
// use this file except in compliance with the License. You may obtain a copy of
5
// the License at
6
//
7
//     https://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, WITHOUT
11
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
// License for the specific language governing permissions and limitations under
13
// the License.
14
15
#include <cstddef>
16
#include <cstdint>
17
#include <cstring>
18
#include <vector>
19
20
#include "fuzz.h"
21
#include "pw_fuzzer/asan_interface.h"
22
#include "pw_fuzzer/fuzzed_data_provider.h"
23
#include "pw_protobuf/encoder.h"
24
#include "pw_span/span.h"
25
26
namespace pw::protobuf::fuzz {
27
namespace {
28
29
// TODO: b/235289495 - Move this to pw_fuzzer/fuzzed_data_provider.h
30
31
// Uses the given |provider| to pick and return a number between 0 and the
32
// maximum numbers of T that can be generated from the remaining input data.
33
template <typename T>
34
75.6k
size_t ConsumeSize(FuzzedDataProvider& provider) {
35
75.6k
  size_t max = provider.remaining_bytes() / sizeof(T);
36
75.6k
  return provider.ConsumeIntegralInRange<size_t>(0, max);
37
75.6k
}
encoder_fuzzer.cc:unsigned long pw::protobuf::fuzz::(anonymous namespace)::ConsumeSize<unsigned int>(FuzzedDataProvider&)
Line
Count
Source
34
4.57k
size_t ConsumeSize(FuzzedDataProvider& provider) {
35
4.57k
  size_t max = provider.remaining_bytes() / sizeof(T);
36
4.57k
  return provider.ConsumeIntegralInRange<size_t>(0, max);
37
4.57k
}
encoder_fuzzer.cc:unsigned long pw::protobuf::fuzz::(anonymous namespace)::ConsumeSize<unsigned long>(FuzzedDataProvider&)
Line
Count
Source
34
3.40k
size_t ConsumeSize(FuzzedDataProvider& provider) {
35
3.40k
  size_t max = provider.remaining_bytes() / sizeof(T);
36
3.40k
  return provider.ConsumeIntegralInRange<size_t>(0, max);
37
3.40k
}
encoder_fuzzer.cc:unsigned long pw::protobuf::fuzz::(anonymous namespace)::ConsumeSize<int>(FuzzedDataProvider&)
Line
Count
Source
34
7.37k
size_t ConsumeSize(FuzzedDataProvider& provider) {
35
7.37k
  size_t max = provider.remaining_bytes() / sizeof(T);
36
7.37k
  return provider.ConsumeIntegralInRange<size_t>(0, max);
37
7.37k
}
encoder_fuzzer.cc:unsigned long pw::protobuf::fuzz::(anonymous namespace)::ConsumeSize<long>(FuzzedDataProvider&)
Line
Count
Source
34
5.24k
size_t ConsumeSize(FuzzedDataProvider& provider) {
35
5.24k
  size_t max = provider.remaining_bytes() / sizeof(T);
36
5.24k
  return provider.ConsumeIntegralInRange<size_t>(0, max);
37
5.24k
}
encoder_fuzzer.cc:unsigned long pw::protobuf::fuzz::(anonymous namespace)::ConsumeSize<float>(FuzzedDataProvider&)
Line
Count
Source
34
3.29k
size_t ConsumeSize(FuzzedDataProvider& provider) {
35
3.29k
  size_t max = provider.remaining_bytes() / sizeof(T);
36
3.29k
  return provider.ConsumeIntegralInRange<size_t>(0, max);
37
3.29k
}
encoder_fuzzer.cc:unsigned long pw::protobuf::fuzz::(anonymous namespace)::ConsumeSize<double>(FuzzedDataProvider&)
Line
Count
Source
34
3.10k
size_t ConsumeSize(FuzzedDataProvider& provider) {
35
3.10k
  size_t max = provider.remaining_bytes() / sizeof(T);
36
3.10k
  return provider.ConsumeIntegralInRange<size_t>(0, max);
37
3.10k
}
encoder_fuzzer.cc:unsigned long pw::protobuf::fuzz::(anonymous namespace)::ConsumeSize<std::byte>(FuzzedDataProvider&)
Line
Count
Source
34
48.6k
size_t ConsumeSize(FuzzedDataProvider& provider) {
35
48.6k
  size_t max = provider.remaining_bytes() / sizeof(T);
36
48.6k
  return provider.ConsumeIntegralInRange<size_t>(0, max);
37
48.6k
}
38
39
// Uses the given |provider| to generate several instances of T, store them in
40
// |data|, and then return a span to them. It is the caller's responsbility
41
// to ensure |data| remains in scope as long as the returned span.
42
template <typename T>
43
26.9k
span<const T> ConsumeSpan(FuzzedDataProvider& provider, std::vector<T>* data) {
44
26.9k
  size_t num = ConsumeSize<T>(provider);
45
26.9k
  size_t off = data->size();
46
26.9k
  if (num == 0) {
47
15.3k
    return span<const T>();
48
15.3k
  }
49
50
11.6k
  data->reserve(off + num);
51
18.3M
  for (size_t i = 0; i < num; ++i) {
52
18.3M
    if constexpr (std::is_floating_point<T>::value) {
53
15.2M
      data->push_back(provider.ConsumeFloatingPoint<T>());
54
15.2M
    } else {
55
15.2M
      data->push_back(provider.ConsumeIntegral<T>());
56
15.2M
    }
57
18.3M
  }
58
11.6k
  return span(&((*data)[off]), num);
59
26.9k
}
encoder_fuzzer.cc:pw::span<unsigned int const, 18446744073709551615ul> pw::protobuf::fuzz::(anonymous namespace)::ConsumeSpan<unsigned int>(FuzzedDataProvider&, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >*)
Line
Count
Source
43
4.57k
span<const T> ConsumeSpan(FuzzedDataProvider& provider, std::vector<T>* data) {
44
4.57k
  size_t num = ConsumeSize<T>(provider);
45
4.57k
  size_t off = data->size();
46
4.57k
  if (num == 0) {
47
1.89k
    return span<const T>();
48
1.89k
  }
49
50
2.68k
  data->reserve(off + num);
51
4.59M
  for (size_t i = 0; i < num; ++i) {
52
4.59M
    if constexpr (std::is_floating_point<T>::value) {
53
4.59M
      data->push_back(provider.ConsumeFloatingPoint<T>());
54
4.59M
    } else {
55
4.59M
      data->push_back(provider.ConsumeIntegral<T>());
56
4.59M
    }
57
4.59M
  }
58
2.68k
  return span(&((*data)[off]), num);
59
4.57k
}
encoder_fuzzer.cc:pw::span<unsigned long const, 18446744073709551615ul> pw::protobuf::fuzz::(anonymous namespace)::ConsumeSpan<unsigned long>(FuzzedDataProvider&, std::__1::vector<unsigned long, std::__1::allocator<unsigned long> >*)
Line
Count
Source
43
3.40k
span<const T> ConsumeSpan(FuzzedDataProvider& provider, std::vector<T>* data) {
44
3.40k
  size_t num = ConsumeSize<T>(provider);
45
3.40k
  size_t off = data->size();
46
3.40k
  if (num == 0) {
47
1.79k
    return span<const T>();
48
1.79k
  }
49
50
1.60k
  data->reserve(off + num);
51
3.74M
  for (size_t i = 0; i < num; ++i) {
52
3.74M
    if constexpr (std::is_floating_point<T>::value) {
53
3.74M
      data->push_back(provider.ConsumeFloatingPoint<T>());
54
3.74M
    } else {
55
3.74M
      data->push_back(provider.ConsumeIntegral<T>());
56
3.74M
    }
57
3.74M
  }
58
1.60k
  return span(&((*data)[off]), num);
59
3.40k
}
encoder_fuzzer.cc:pw::span<int const, 18446744073709551615ul> pw::protobuf::fuzz::(anonymous namespace)::ConsumeSpan<int>(FuzzedDataProvider&, std::__1::vector<int, std::__1::allocator<int> >*)
Line
Count
Source
43
7.37k
span<const T> ConsumeSpan(FuzzedDataProvider& provider, std::vector<T>* data) {
44
7.37k
  size_t num = ConsumeSize<T>(provider);
45
7.37k
  size_t off = data->size();
46
7.37k
  if (num == 0) {
47
5.23k
    return span<const T>();
48
5.23k
  }
49
50
2.14k
  data->reserve(off + num);
51
3.97M
  for (size_t i = 0; i < num; ++i) {
52
3.97M
    if constexpr (std::is_floating_point<T>::value) {
53
3.97M
      data->push_back(provider.ConsumeFloatingPoint<T>());
54
3.97M
    } else {
55
3.97M
      data->push_back(provider.ConsumeIntegral<T>());
56
3.97M
    }
57
3.97M
  }
58
2.14k
  return span(&((*data)[off]), num);
59
7.37k
}
encoder_fuzzer.cc:pw::span<long const, 18446744073709551615ul> pw::protobuf::fuzz::(anonymous namespace)::ConsumeSpan<long>(FuzzedDataProvider&, std::__1::vector<long, std::__1::allocator<long> >*)
Line
Count
Source
43
5.24k
span<const T> ConsumeSpan(FuzzedDataProvider& provider, std::vector<T>* data) {
44
5.24k
  size_t num = ConsumeSize<T>(provider);
45
5.24k
  size_t off = data->size();
46
5.24k
  if (num == 0) {
47
3.89k
    return span<const T>();
48
3.89k
  }
49
50
1.34k
  data->reserve(off + num);
51
2.94M
  for (size_t i = 0; i < num; ++i) {
52
2.94M
    if constexpr (std::is_floating_point<T>::value) {
53
2.94M
      data->push_back(provider.ConsumeFloatingPoint<T>());
54
2.94M
    } else {
55
2.94M
      data->push_back(provider.ConsumeIntegral<T>());
56
2.94M
    }
57
2.94M
  }
58
1.34k
  return span(&((*data)[off]), num);
59
5.24k
}
encoder_fuzzer.cc:pw::span<float const, 18446744073709551615ul> pw::protobuf::fuzz::(anonymous namespace)::ConsumeSpan<float>(FuzzedDataProvider&, std::__1::vector<float, std::__1::allocator<float> >*)
Line
Count
Source
43
3.29k
span<const T> ConsumeSpan(FuzzedDataProvider& provider, std::vector<T>* data) {
44
3.29k
  size_t num = ConsumeSize<T>(provider);
45
3.29k
  size_t off = data->size();
46
3.29k
  if (num == 0) {
47
1.42k
    return span<const T>();
48
1.42k
  }
49
50
1.86k
  data->reserve(off + num);
51
1.80M
  for (size_t i = 0; i < num; ++i) {
52
1.80M
    if constexpr (std::is_floating_point<T>::value) {
53
1.80M
      data->push_back(provider.ConsumeFloatingPoint<T>());
54
1.80M
    } else {
55
1.80M
      data->push_back(provider.ConsumeIntegral<T>());
56
1.80M
    }
57
1.80M
  }
58
1.86k
  return span(&((*data)[off]), num);
59
3.29k
}
encoder_fuzzer.cc:pw::span<double const, 18446744073709551615ul> pw::protobuf::fuzz::(anonymous namespace)::ConsumeSpan<double>(FuzzedDataProvider&, std::__1::vector<double, std::__1::allocator<double> >*)
Line
Count
Source
43
3.10k
span<const T> ConsumeSpan(FuzzedDataProvider& provider, std::vector<T>* data) {
44
3.10k
  size_t num = ConsumeSize<T>(provider);
45
3.10k
  size_t off = data->size();
46
3.10k
  if (num == 0) {
47
1.09k
    return span<const T>();
48
1.09k
  }
49
50
2.01k
  data->reserve(off + num);
51
1.29M
  for (size_t i = 0; i < num; ++i) {
52
1.29M
    if constexpr (std::is_floating_point<T>::value) {
53
1.29M
      data->push_back(provider.ConsumeFloatingPoint<T>());
54
1.29M
    } else {
55
1.29M
      data->push_back(provider.ConsumeIntegral<T>());
56
1.29M
    }
57
1.29M
  }
58
2.01k
  return span(&((*data)[off]), num);
59
3.10k
}
60
61
// Uses the given |provider| to generate a string, store it in |data|, and
62
// return a C-style representation. It is the caller's responsbility to
63
// ensure |data| remains in scope as long as the returned char*.
64
const char* ConsumeString(FuzzedDataProvider& provider,
65
37.9k
                          std::vector<std::string>* data) {
66
37.9k
  size_t off = data->size();
67
  // OSS-Fuzz's clang doesn't have the zero-parameter version of
68
  // ConsumeRandomLengthString yet.
69
37.9k
  size_t max_length = std::numeric_limits<size_t>::max();
70
37.9k
  data->push_back(provider.ConsumeRandomLengthString(max_length));
71
37.9k
  return (*data)[off].c_str();
72
37.9k
}
73
74
// Uses the given |provider| to generate non-arithmetic bytes, store them in
75
// |data|, and return a span to them. It is the caller's responsbility to
76
// ensure |data| remains in scope as long as the returned span.
77
span<const std::byte> ConsumeBytes(FuzzedDataProvider& provider,
78
48.6k
                                   std::vector<std::byte>* data) {
79
48.6k
  size_t num = ConsumeSize<std::byte>(provider);
80
48.6k
  auto added = provider.ConsumeBytes<std::byte>(num);
81
48.6k
  size_t off = data->size();
82
48.6k
  num = added.size();
83
48.6k
  data->insert(data->end(), added.begin(), added.end());
84
  // It's possible nothing was added, and the vector was empty to begin with.
85
48.6k
  if (data->empty()) {
86
10.0k
    return span<const std::byte>();
87
10.0k
  }
88
38.6k
  return span(&((*data)[off]), num);
89
48.6k
}
90
91
void RecursiveFuzzedEncode(FuzzedDataProvider& provider,
92
                           StreamEncoder& encoder,
93
44.6k
                           uint32_t depth = 0) {
94
44.6k
  constexpr size_t kMaxDepth = 256;
95
44.6k
  if (depth > kMaxDepth) {
96
21.9k
    return;
97
21.9k
  }
98
99
  // Storage for generated spans
100
22.6k
  std::vector<uint32_t> u32s;
101
22.6k
  std::vector<uint64_t> u64s;
102
22.6k
  std::vector<int32_t> s32s;
103
22.6k
  std::vector<int64_t> s64s;
104
22.6k
  std::vector<float> floats;
105
22.6k
  std::vector<double> doubles;
106
22.6k
  std::vector<std::string> strings;
107
22.6k
  std::vector<std::byte> bytes;
108
109
  // Consume the fuzzing input, using it to generate a sequence of fields to
110
  // encode. Both the uint32_t field IDs and the fields values are generated.
111
  // Don't try to detect errors, ensures pushes and pops are balanced, or
112
  // otherwise hold the interface correctly. Instead, fuzz the widest possbile
113
  // set of inputs to the encoder to ensure it doesn't misbehave.
114
1.54M
  while (provider.remaining_bytes() != 0) {
115
1.52M
    switch (provider.ConsumeEnum<FieldType>()) {
116
750k
      case kUint32:
117
750k
        encoder
118
750k
            .WriteUint32(provider.ConsumeIntegral<uint32_t>(),
119
750k
                         provider.ConsumeIntegral<uint32_t>())
120
750k
            .IgnoreError();
121
750k
        break;
122
3.84k
      case kPackedUint32:
123
3.84k
        encoder
124
3.84k
            .WritePackedUint32(provider.ConsumeIntegral<uint32_t>(),
125
3.84k
                               ConsumeSpan<uint32_t>(provider, &u32s))
126
3.84k
            .IgnoreError();
127
3.84k
        break;
128
4.01k
      case kUint64:
129
4.01k
        encoder
130
4.01k
            .WriteUint64(provider.ConsumeIntegral<uint32_t>(),
131
4.01k
                         provider.ConsumeIntegral<uint64_t>())
132
4.01k
            .IgnoreError();
133
4.01k
        break;
134
2.71k
      case kPackedUint64:
135
2.71k
        encoder
136
2.71k
            .WritePackedUint64(provider.ConsumeIntegral<uint32_t>(),
137
2.71k
                               ConsumeSpan<uint64_t>(provider, &u64s))
138
2.71k
            .IgnoreError();
139
2.71k
        break;
140
129k
      case kInt32:
141
129k
        encoder
142
129k
            .WriteInt32(provider.ConsumeIntegral<uint32_t>(),
143
129k
                        provider.ConsumeIntegral<int32_t>())
144
129k
            .IgnoreError();
145
129k
        break;
146
5.15k
      case kPackedInt32:
147
5.15k
        encoder
148
5.15k
            .WritePackedInt32(provider.ConsumeIntegral<uint32_t>(),
149
5.15k
                              ConsumeSpan<int32_t>(provider, &s32s))
150
5.15k
            .IgnoreError();
151
5.15k
        break;
152
47.6k
      case kInt64:
153
47.6k
        encoder
154
47.6k
            .WriteInt64(provider.ConsumeIntegral<uint32_t>(),
155
47.6k
                        provider.ConsumeIntegral<int64_t>())
156
47.6k
            .IgnoreError();
157
47.6k
        break;
158
1.39k
      case kPackedInt64:
159
1.39k
        encoder
160
1.39k
            .WritePackedInt64(provider.ConsumeIntegral<uint32_t>(),
161
1.39k
                              ConsumeSpan<int64_t>(provider, &s64s))
162
1.39k
            .IgnoreError();
163
1.39k
        break;
164
11.0k
      case kSint32:
165
11.0k
        encoder
166
11.0k
            .WriteSint32(provider.ConsumeIntegral<uint32_t>(),
167
11.0k
                         provider.ConsumeIntegral<int32_t>())
168
11.0k
            .IgnoreError();
169
11.0k
        break;
170
1.11k
      case kPackedSint32:
171
1.11k
        encoder
172
1.11k
            .WritePackedSint32(provider.ConsumeIntegral<uint32_t>(),
173
1.11k
                               ConsumeSpan<int32_t>(provider, &s32s))
174
1.11k
            .IgnoreError();
175
1.11k
        break;
176
3.37k
      case kSint64:
177
3.37k
        encoder
178
3.37k
            .WriteSint64(provider.ConsumeIntegral<uint32_t>(),
179
3.37k
                         provider.ConsumeIntegral<int64_t>())
180
3.37k
            .IgnoreError();
181
3.37k
        break;
182
1.10k
      case kPackedSint64:
183
1.10k
        encoder
184
1.10k
            .WritePackedSint64(provider.ConsumeIntegral<uint32_t>(),
185
1.10k
                               ConsumeSpan<int64_t>(provider, &s64s))
186
1.10k
            .IgnoreError();
187
1.10k
        break;
188
12.5k
      case kBool:
189
12.5k
        encoder
190
12.5k
            .WriteBool(provider.ConsumeIntegral<uint32_t>(),
191
12.5k
                       provider.ConsumeBool())
192
12.5k
            .IgnoreError();
193
12.5k
        break;
194
280k
      case kFixed32:
195
280k
        encoder
196
280k
            .WriteFixed32(provider.ConsumeIntegral<uint32_t>(),
197
280k
                          provider.ConsumeIntegral<uint32_t>())
198
280k
            .IgnoreError();
199
280k
        break;
200
731
      case kPackedFixed32:
201
731
        encoder
202
731
            .WritePackedFixed32(provider.ConsumeIntegral<uint32_t>(),
203
731
                                ConsumeSpan<uint32_t>(provider, &u32s))
204
731
            .IgnoreError();
205
731
        break;
206
1.35k
      case kFixed64:
207
1.35k
        encoder
208
1.35k
            .WriteFixed64(provider.ConsumeIntegral<uint32_t>(),
209
1.35k
                          provider.ConsumeIntegral<uint64_t>())
210
1.35k
            .IgnoreError();
211
1.35k
        break;
212
688
      case kPackedFixed64:
213
688
        encoder
214
688
            .WritePackedFixed64(provider.ConsumeIntegral<uint32_t>(),
215
688
                                ConsumeSpan<uint64_t>(provider, &u64s))
216
688
            .IgnoreError();
217
688
        break;
218
116k
      case kSfixed32:
219
116k
        encoder
220
116k
            .WriteSfixed32(provider.ConsumeIntegral<uint32_t>(),
221
116k
                           provider.ConsumeIntegral<int32_t>())
222
116k
            .IgnoreError();
223
116k
        break;
224
1.10k
      case kPackedSfixed32:
225
1.10k
        encoder
226
1.10k
            .WritePackedSfixed32(provider.ConsumeIntegral<uint32_t>(),
227
1.10k
                                 ConsumeSpan<int32_t>(provider, &s32s))
228
1.10k
            .IgnoreError();
229
1.10k
        break;
230
5.04k
      case kSfixed64:
231
5.04k
        encoder
232
5.04k
            .WriteSfixed64(provider.ConsumeIntegral<uint32_t>(),
233
5.04k
                           provider.ConsumeIntegral<int64_t>())
234
5.04k
            .IgnoreError();
235
5.04k
        break;
236
2.74k
      case kPackedSfixed64:
237
2.74k
        encoder
238
2.74k
            .WritePackedSfixed64(provider.ConsumeIntegral<uint32_t>(),
239
2.74k
                                 ConsumeSpan<int64_t>(provider, &s64s))
240
2.74k
            .IgnoreError();
241
2.74k
        break;
242
6.66k
      case kFloat:
243
6.66k
        encoder
244
6.66k
            .WriteFloat(provider.ConsumeIntegral<uint32_t>(),
245
6.66k
                        provider.ConsumeFloatingPoint<float>())
246
6.66k
            .IgnoreError();
247
6.66k
        break;
248
3.29k
      case kPackedFloat:
249
3.29k
        encoder
250
3.29k
            .WritePackedFloat(provider.ConsumeIntegral<uint32_t>(),
251
3.29k
                              ConsumeSpan<float>(provider, &floats))
252
3.29k
            .IgnoreError();
253
3.29k
        break;
254
2.20k
      case kDouble:
255
2.20k
        encoder
256
2.20k
            .WriteDouble(provider.ConsumeIntegral<uint32_t>(),
257
2.20k
                         provider.ConsumeFloatingPoint<double>())
258
2.20k
            .IgnoreError();
259
2.20k
        break;
260
3.10k
      case kPackedDouble:
261
3.10k
        encoder
262
3.10k
            .WritePackedDouble(provider.ConsumeIntegral<uint32_t>(),
263
3.10k
                               ConsumeSpan<double>(provider, &doubles))
264
3.10k
            .IgnoreError();
265
3.10k
        break;
266
48.6k
      case kBytes:
267
48.6k
        encoder
268
48.6k
            .WriteBytes(provider.ConsumeIntegral<uint32_t>(),
269
48.6k
                        ConsumeBytes(provider, &bytes))
270
48.6k
            .IgnoreError();
271
48.6k
        break;
272
37.9k
      case kString:
273
37.9k
        encoder
274
37.9k
            .WriteString(provider.ConsumeIntegral<uint32_t>(),
275
37.9k
                         ConsumeString(provider, &strings))
276
37.9k
            .IgnoreError();
277
37.9k
        break;
278
41.1k
      case kPush: {
279
        // Special "field". The marks the start of a nested message.
280
41.1k
        StreamEncoder nested_encoder =
281
41.1k
            encoder.GetNestedEncoder(provider.ConsumeIntegral<uint32_t>());
282
41.1k
        RecursiveFuzzedEncode(provider, nested_encoder, depth + 1);
283
41.1k
        break;
284
0
      }
285
0
      case kPop:
286
0
        if (depth > 0) {
287
          // Special "field". The marks the end of a nested message.
288
0
          return;
289
0
        }
290
1.52M
    }
291
1.52M
  }
292
22.6k
}
293
294
3.48k
void TestOneInput(FuzzedDataProvider& provider) {
295
3.48k
  static std::byte buffer[65536];
296
297
  // Pick a subset of the buffer that the fuzzer is allowed to use, and poison
298
  // the rest.
299
3.48k
  size_t unpoisoned_length =
300
3.48k
      provider.ConsumeIntegralInRange<size_t>(0, sizeof(buffer));
301
3.48k
  ByteSpan unpoisoned(buffer, unpoisoned_length);
302
3.48k
  void* poisoned = &buffer[unpoisoned_length];
303
3.48k
  size_t poisoned_length = sizeof(buffer) - unpoisoned_length;
304
3.48k
  ASAN_POISON_MEMORY_REGION(poisoned, poisoned_length);
305
306
3.48k
  pw::protobuf::MemoryEncoder encoder(unpoisoned);
307
3.48k
  RecursiveFuzzedEncode(provider, encoder);
308
309
  // Don't forget to unpoison for the next iteration!
310
3.48k
  ASAN_UNPOISON_MEMORY_REGION(poisoned, poisoned_length);
311
3.48k
}
312
313
}  // namespace
314
}  // namespace pw::protobuf::fuzz
315
316
6.07k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
317
6.07k
  FuzzedDataProvider provider(data, size);
318
6.07k
  pw::protobuf::fuzz::TestOneInput(provider);
319
6.07k
  return 0;
320
6.07k
}