1 // Copyright 2014 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 #ifndef NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_ 6 #define NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/memory/scoped_ptr.h" 12 #include "base/strings/string_piece.h" 13 #include "net/base/net_export.h" 14 #include "net/spdy/hpack_decoder.h" 15 #include "net/spdy/hpack_encoder.h" 16 17 namespace net { 18 19 class NET_EXPORT_PRIVATE 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 NET_EXPORT_PRIVATE 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 std::map<std::string, std::string> NextGeneratedHeaderSet( 35 GeneratorContext* context); 36 37 // Samples a size from the exponential distribution with mean |mean|, 38 // upper-bounded by |sanity_bound|. 39 static size_t SampleExponential(size_t mean, size_t sanity_bound); 40 41 // Holds an input string, and manages an offset into that string. 42 struct NET_EXPORT_PRIVATE Input { 43 Input(); // Initializes |offset| to zero. 44 ~Input(); 45 remainingInput46 size_t remaining() { 47 return input.size() - offset; 48 } ptrInput49 const char* ptr() { 50 return input.data() + offset; 51 } 52 53 std::string input; 54 size_t offset; 55 }; 56 57 // Returns true if the next header block was set at |out|. Returns 58 // false if no input header blocks remain. 59 static bool NextHeaderBlock(Input* input, base::StringPiece* out); 60 61 // Returns the serialized header block length prefix for a block of 62 // |block_size| bytes. 63 static std::string HeaderBlockPrefix(size_t block_size); 64 65 // A FuzzerContext holds fuzzer input, as well as each of the decoder and 66 // encoder stages which fuzzed header blocks are processed through. 67 struct NET_EXPORT_PRIVATE FuzzerContext { 68 FuzzerContext(); 69 ~FuzzerContext(); 70 scoped_ptr<HpackDecoder> first_stage; 71 scoped_ptr<HpackEncoder> second_stage; 72 scoped_ptr<HpackDecoder> third_stage; 73 }; 74 75 static void InitializeFuzzerContext(FuzzerContext* context); 76 77 // Runs |input_block| through |first_stage| and, iff that succeeds, 78 // |second_stage| and |third_stage| as well. Returns whether all stages 79 // processed the input without error. 80 static bool RunHeaderBlockThroughFuzzerStages(FuzzerContext* context, 81 base::StringPiece input_block); 82 83 // Flips random bits within |buffer|. The total number of flips is 84 // |flip_per_thousand| bits for every 1,024 bytes of |buffer_length|, 85 // rounding up. 86 static void FlipBits(uint8* buffer, 87 size_t buffer_length, 88 size_t flip_per_thousand); 89 }; 90 91 } // namespace net 92 93 #endif // NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_ 94