hpack_fuzz_util_test.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. #include "net/spdy/fuzzing/hpack_fuzz_util.h"
  5. #include <map>
  6. #include "base/base_paths.h"
  7. #include "base/files/file.h"
  8. #include "base/files/file_util.h"
  9. #include "base/path_service.h"
  10. #include "net/base/hex_utils.h"
  11. #include "testing/gmock/include/gmock/gmock.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. namespace spdy::test {
  14. using std::map;
  15. TEST(HpackFuzzUtilTest, GeneratorContextInitialization) {
  16. HpackFuzzUtil::GeneratorContext context;
  17. HpackFuzzUtil::InitializeGeneratorContext(&context);
  18. // Context was seeded with initial name & value fixtures.
  19. EXPECT_LT(0u, context.names.size());
  20. EXPECT_LT(0u, context.values.size());
  21. }
  22. TEST(HpackFuzzUtil, GeneratorContextExpansion) {
  23. HpackFuzzUtil::GeneratorContext context;
  24. Http2HeaderBlock headers = HpackFuzzUtil::NextGeneratedHeaderSet(&context);
  25. // Headers were generated, and the generator context was expanded.
  26. EXPECT_LT(0u, headers.size());
  27. EXPECT_LT(0u, context.names.size());
  28. EXPECT_LT(0u, context.values.size());
  29. }
  30. // TODO(jgraettinger): A better test would mock a random generator and
  31. // evaluate SampleExponential along fixed points of the [0,1] domain.
  32. TEST(HpackFuzzUtilTest, SampleExponentialRegression) {
  33. // TODO(jgraettinger): Upstream uses a seeded random generator here to pin
  34. // the behavior of SampleExponential. Chromium's random generation utilities
  35. // are strongly secure, but provide no way to seed the generator.
  36. for (size_t i = 0; i != 100; ++i) {
  37. EXPECT_GE(30u, HpackFuzzUtil::SampleExponential(10, 30));
  38. }
  39. }
  40. TEST(HpackFuzzUtilTest, ParsesSequenceOfHeaderBlocks) {
  41. char fixture[] =
  42. "\x00\x00\x00\x05"
  43. "aaaaa"
  44. "\x00\x00\x00\x04"
  45. "bbbb"
  46. "\x00\x00\x00\x03"
  47. "ccc"
  48. "\x00\x00\x00\x02"
  49. "dd"
  50. "\x00\x00\x00\x01"
  51. "e"
  52. "\x00\x00\x00\x00"
  53. ""
  54. "\x00\x00\x00\x03"
  55. "fin";
  56. HpackFuzzUtil::Input input;
  57. input.input.assign(fixture, std::size(fixture) - 1);
  58. absl::string_view block;
  59. EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block));
  60. EXPECT_EQ("aaaaa", block);
  61. EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block));
  62. EXPECT_EQ("bbbb", block);
  63. EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block));
  64. EXPECT_EQ("ccc", block);
  65. EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block));
  66. EXPECT_EQ("dd", block);
  67. EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block));
  68. EXPECT_EQ("e", block);
  69. EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block));
  70. EXPECT_EQ("", block);
  71. EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block));
  72. EXPECT_EQ("fin", block);
  73. EXPECT_FALSE(HpackFuzzUtil::NextHeaderBlock(&input, &block));
  74. }
  75. TEST(HpackFuzzUtilTest, SerializedHeaderBlockPrefixes) {
  76. EXPECT_EQ(std::string("\x00\x00\x00\x00", 4),
  77. HpackFuzzUtil::HeaderBlockPrefix(0));
  78. EXPECT_EQ(std::string("\x00\x00\x00\x05", 4),
  79. HpackFuzzUtil::HeaderBlockPrefix(5));
  80. EXPECT_EQ("\x4f\xb3\x0a\x91", HpackFuzzUtil::HeaderBlockPrefix(1337133713));
  81. }
  82. TEST(HpackFuzzUtilTest, PassValidInputThroughAllStages) {
  83. // Example lifted from HpackDecoderTest.SectionD4RequestHuffmanExamples.
  84. std::string input = net::HexDecode("828684418cf1e3c2e5f23a6ba0ab90f4ff");
  85. HpackFuzzUtil::FuzzerContext context;
  86. HpackFuzzUtil::InitializeFuzzerContext(&context);
  87. EXPECT_TRUE(
  88. HpackFuzzUtil::RunHeaderBlockThroughFuzzerStages(&context, input));
  89. Http2HeaderBlock expect;
  90. expect[":method"] = "GET";
  91. expect[":scheme"] = "http";
  92. expect[":path"] = "/";
  93. expect[":authority"] = "www.example.com";
  94. EXPECT_EQ(expect, context.third_stage->decoded_block());
  95. }
  96. TEST(HpackFuzzUtilTest, ValidFuzzExamplesRegressionTest) {
  97. base::FilePath source_root;
  98. ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root));
  99. // Load the example fixtures versioned with the source tree.
  100. HpackFuzzUtil::Input input;
  101. ASSERT_TRUE(base::ReadFileToString(
  102. source_root.Append(FILE_PATH_LITERAL("net"))
  103. .Append(FILE_PATH_LITERAL("data"))
  104. .Append(FILE_PATH_LITERAL("spdy_tests"))
  105. .Append(FILE_PATH_LITERAL("examples_07.hpack")),
  106. &input.input));
  107. HpackFuzzUtil::FuzzerContext context;
  108. HpackFuzzUtil::InitializeFuzzerContext(&context);
  109. absl::string_view block;
  110. while (HpackFuzzUtil::NextHeaderBlock(&input, &block)) {
  111. // As these are valid examples, all fuzz stages should succeed.
  112. EXPECT_TRUE(
  113. HpackFuzzUtil::RunHeaderBlockThroughFuzzerStages(&context, block));
  114. }
  115. }
  116. TEST(HpackFuzzUtilTest, FlipBitsMutatesBuffer) {
  117. char buffer[] = "testbuffer1234567890";
  118. std::string unmodified(buffer, std::size(buffer) - 1);
  119. EXPECT_EQ(unmodified, buffer);
  120. HpackFuzzUtil::FlipBits(reinterpret_cast<uint8_t*>(buffer),
  121. std::size(buffer) - 1, 1);
  122. EXPECT_NE(unmodified, buffer);
  123. }
  124. } // namespace spdy::test