hpack_fuzz_util.h 3.0 KB

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