Home | History | Annotate | Download | only in fuzzing
      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 
     46     size_t remaining() {
     47       return input.size() - offset;
     48     }
     49     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