• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_
6 #define NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <vector>
13 
14 #include "net/third_party/quiche/src/quiche/spdy/core/hpack/hpack_decoder_adapter.h"
15 #include "net/third_party/quiche/src/quiche/spdy/core/hpack/hpack_encoder.h"
16 
17 namespace spdy {
18 
19 class HpackFuzzUtil {
20  public:
21   // A GeneratorContext holds ordered header names & values which are
22   // initially seeded and then expanded with dynamically generated data.
23   struct GeneratorContext {
24     GeneratorContext();
25     ~GeneratorContext();
26     std::vector<std::string> names;
27     std::vector<std::string> values;
28   };
29 
30   // Initializes a GeneratorContext with a random seed and name/value fixtures.
31   static void InitializeGeneratorContext(GeneratorContext* context);
32 
33   // Generates a header set from the generator context.
34   static Http2HeaderBlock NextGeneratedHeaderSet(GeneratorContext* context);
35 
36   // Samples a size from the exponential distribution with mean |mean|,
37   // upper-bounded by |sanity_bound|.
38   static size_t SampleExponential(size_t mean, size_t sanity_bound);
39 
40   // Holds an input string, and manages an offset into that string.
41   struct Input {
42     Input();  // Initializes |offset| to zero.
43     ~Input();
44 
remainingInput45     size_t remaining() { return input.size() - offset; }
ptrInput46     const char* ptr() { return input.data() + offset; }
47 
48     std::string input;
49     size_t offset = 0;
50   };
51 
52   // Returns true if the next header block was set at |out|. Returns
53   // false if no input header blocks remain.
54   static bool NextHeaderBlock(Input* input, absl::string_view* out);
55 
56   // Returns the serialized header block length prefix for a block of
57   // |block_size| bytes.
58   static std::string HeaderBlockPrefix(size_t block_size);
59 
60   // A FuzzerContext holds fuzzer input, as well as each of the decoder and
61   // encoder stages which fuzzed header blocks are processed through.
62   struct FuzzerContext {
63     FuzzerContext();
64     ~FuzzerContext();
65     std::unique_ptr<HpackDecoderAdapter> first_stage;
66     std::unique_ptr<HpackEncoder> second_stage;
67     std::unique_ptr<HpackDecoderAdapter> third_stage;
68   };
69 
70   static void InitializeFuzzerContext(FuzzerContext* context);
71 
72   // Runs |input_block| through |first_stage| and, iff that succeeds,
73   // |second_stage| and |third_stage| as well. Returns whether all stages
74   // processed the input without error.
75   static bool RunHeaderBlockThroughFuzzerStages(FuzzerContext* context,
76                                                 absl::string_view input_block);
77 
78   // Flips random bits within |buffer|. The total number of flips is
79   // |flip_per_thousand| bits for every 1,024 bytes of |buffer_length|,
80   // rounding up.
81   static void FlipBits(uint8_t* buffer,
82                        size_t buffer_length,
83                        size_t flip_per_thousand);
84 };
85 
86 }  // namespace spdy
87 
88 #endif  // NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_
89