15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved. 25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be 35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file. 45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/spdy/fuzzing/hpack_fuzz_util.h" 65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <map> 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/base_paths.h" 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/files/file.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/path_service.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/spdy/spdy_test_utils.h" 145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "testing/gmock/include/gmock/gmock.h" 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "testing/gtest/include/gtest/gtest.h" 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace net { 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace { 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing base::StringPiece; 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing std::map; 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing std::string; 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using test::a2b_hex; 255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(HpackFuzzUtilTest, GeneratorContextInitialization) { 275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::GeneratorContext context; 285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::InitializeGeneratorContext(&context); 295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Context was seeded with initial name & value fixtures. 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_LT(0u, context.names.size()); 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_LT(0u, context.values.size()); 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(HpackFuzzUtil, GeneratorContextExpansion) { 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::GeneratorContext context; 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu map<string, string> headers = HpackFuzzUtil::NextGeneratedHeaderSet(&context); 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Headers were generated, and the generator context was expanded. 415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_LT(0u, headers.size()); 425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_LT(0u, context.names.size()); 435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_LT(0u, context.values.size()); 445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// TODO(jgraettinger): A better test would mock a random generator and 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// evaluate SampleExponential along fixed points of the [0,1] domain. 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(HpackFuzzUtilTest, SampleExponentialRegression) { 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // TODO(jgraettinger): Upstream uses a seeded random generator here to pin 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // the behavior of SampleExponential. Chromium's random generation utilities 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // are strongly secure, but provide no way to seed the generator. 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (size_t i = 0; i != 100; ++i) { 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_GE(30u, HpackFuzzUtil::SampleExponential(10, 30)); 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(HpackFuzzUtilTest, ParsesSequenceOfHeaderBlocks) { 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu char fixture[] = 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "\x00\x00\x00\x05""aaaaa" 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "\x00\x00\x00\x04""bbbb" 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "\x00\x00\x00\x03""ccc" 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "\x00\x00\x00\x02""dd" 635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "\x00\x00\x00\x01""e" 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "\x00\x00\x00\x00""" 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "\x00\x00\x00\x03""fin"; 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::Input input; 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu input.input.assign(fixture, arraysize(fixture) - 1); 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu StringPiece block; 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ("aaaaa", block); 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ("bbbb", block); 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ("ccc", block); 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ("dd", block); 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); 815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ("e", block); 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ("", block); 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ("fin", block); 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_FALSE(HpackFuzzUtil::NextHeaderBlock(&input, &block)); 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(HpackFuzzUtilTest, SerializedHeaderBlockPrefixes) { 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(string("\x00\x00\x00\x00", 4), HpackFuzzUtil::HeaderBlockPrefix(0)); 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(string("\x00\x00\x00\x05", 4), HpackFuzzUtil::HeaderBlockPrefix(5)); 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(string("\x4f\xb3\x0a\x91", 4), 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::HeaderBlockPrefix(1337133713)); 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(HpackFuzzUtilTest, PassValidInputThroughAllStages) { 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Example lifted from HpackDecoderTest.SectionD4RequestHuffmanExamples. 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) string input = a2b_hex("828684418cf1e3c2e5f23a6ba0ab90f4" 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "ff"); 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::FuzzerContext context; 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::InitializeFuzzerContext(&context); 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE( 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HpackFuzzUtil::RunHeaderBlockThroughFuzzerStages(&context, input)); 1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::map<string, string> expect; 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu expect[":method"] = "GET"; 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu expect[":scheme"] = "http"; 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu expect[":path"] = "/"; 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu expect[":authority"] = "www.example.com"; 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(expect, context.third_stage->decoded_block()); 1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(HpackFuzzUtilTest, ValidFuzzExamplesRegressionTest) { 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::FilePath source_root; 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_root)); 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Load the example fixtures versioned with the source tree. 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::Input input; 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(base::ReadFileToString( 1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu source_root.Append(FILE_PATH_LITERAL("net")) 1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu .Append(FILE_PATH_LITERAL("data")) 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu .Append(FILE_PATH_LITERAL("spdy_tests")) 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .Append(FILE_PATH_LITERAL("examples_07.hpack")), 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &input.input)); 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::FuzzerContext context; 1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::InitializeFuzzerContext(&context); 1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu StringPiece block; 1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu while (HpackFuzzUtil::NextHeaderBlock(&input, &block)) { 1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // As these are valid examples, all fuzz stages should succeed. 1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(HpackFuzzUtil::RunHeaderBlockThroughFuzzerStages( 1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &context, block)); 1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(HpackFuzzUtilTest, FlipBitsMutatesBuffer) { 1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu char buffer[] = "testbuffer1234567890"; 1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu string unmodified(buffer, arraysize(buffer) - 1); 1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(unmodified, buffer); 1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu HpackFuzzUtil::FlipBits(reinterpret_cast<uint8*>(buffer), 1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu arraysize(buffer) - 1, 1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1); 1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_NE(unmodified, buffer); 1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} // namespace net 153