15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_SPDY_FUZZING_HPACK_FUZZ_UTIL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/string_piece.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/hpack_decoder.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/hpack_encoder.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE HpackFuzzUtil {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A GeneratorContext holds ordered header names & values which are
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initially seeded and then expanded with dynamically generated data.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct NET_EXPORT_PRIVATE GeneratorContext {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GeneratorContext();
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~GeneratorContext();
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> names;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> values;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes a GeneratorContext with a random seed and name/value fixtures.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void InitializeGeneratorContext(GeneratorContext* context);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generates a header set from the generator context.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::map<std::string, std::string> NextGeneratedHeaderSet(
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GeneratorContext* context);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Samples a size from the exponential distribution with mean |mean|,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // upper-bounded by |sanity_bound|.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t SampleExponential(size_t mean, size_t sanity_bound);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Holds an input string, and manages an offset into that string.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct NET_EXPORT_PRIVATE Input {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Input();  // Initializes |offset| to zero.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~Input();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t remaining() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return input.size() - offset;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* ptr() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return input.data() + offset;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string input;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t offset;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the next header block was set at |out|. Returns
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // false if no input header blocks remain.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool NextHeaderBlock(Input* input, base::StringPiece* out);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the serialized header block length prefix for a block of
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |block_size| bytes.
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static std::string HeaderBlockPrefix(size_t block_size);
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A FuzzerContext holds fuzzer input, as well as each of the decoder and
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // encoder stages which fuzzed header blocks are processed through.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct NET_EXPORT_PRIVATE FuzzerContext {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FuzzerContext();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~FuzzerContext();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HpackDecoder> first_stage;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HpackEncoder> second_stage;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HpackDecoder> third_stage;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void InitializeFuzzerContext(FuzzerContext* context);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Runs |input_block| through |first_stage| and, iff that succeeds,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |second_stage| and |third_stage| as well. Returns whether all stages
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // processed the input without error.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  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