1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <fuzzer/FuzzedDataProvider.h>
6 
7 #include <cstddef>
8 #include <cstdint>
9 #include <limits>
10 #include <string>
11 
12 #include "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
13 #include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
14 
15 namespace quic {
16 namespace test {
17 
18 // This fuzzer exercises QpackEncoderStreamSender.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)19 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
20   FuzzedDataProvider provider(data, size);
21 
22   NoopQpackStreamSenderDelegate delegate;
23   QpackEncoderStreamSender sender(provider.ConsumeBool()
24                                       ? HuffmanEncoding::kEnabled
25                                       : HuffmanEncoding::kDisabled);
26   sender.set_qpack_stream_sender_delegate(&delegate);
27 
28   // Limit string literal length to 2 kB for efficiency.
29   const uint16_t kMaxStringLength = 2048;
30 
31   while (provider.remaining_bytes() != 0) {
32     switch (provider.ConsumeIntegral<uint8_t>() % 5) {
33       case 0: {
34         bool is_static = provider.ConsumeBool();
35         uint64_t name_index = provider.ConsumeIntegral<uint64_t>();
36         uint16_t value_length =
37             provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
38         std::string value = provider.ConsumeRandomLengthString(value_length);
39 
40         sender.SendInsertWithNameReference(is_static, name_index, value);
41         break;
42       }
43       case 1: {
44         uint16_t name_length =
45             provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
46         std::string name = provider.ConsumeRandomLengthString(name_length);
47         uint16_t value_length =
48             provider.ConsumeIntegralInRange<uint16_t>(0, kMaxStringLength);
49         std::string value = provider.ConsumeRandomLengthString(value_length);
50         sender.SendInsertWithoutNameReference(name, value);
51         break;
52       }
53       case 2: {
54         uint64_t index = provider.ConsumeIntegral<uint64_t>();
55         sender.SendDuplicate(index);
56         break;
57       }
58       case 3: {
59         uint64_t capacity = provider.ConsumeIntegral<uint64_t>();
60         sender.SendSetDynamicTableCapacity(capacity);
61         break;
62       }
63       case 4: {
64         sender.Flush();
65         break;
66       }
67     }
68   }
69 
70   sender.Flush();
71   return 0;
72 }
73 
74 }  // namespace test
75 }  // namespace quic
76