| Index: net/spdy/hpack/hpack_huffman_table_test.cc
|
| diff --git a/net/spdy/hpack/hpack_huffman_table_test.cc b/net/spdy/hpack/hpack_huffman_table_test.cc
|
| index fe2420ed326cbbdc55671cb9546ac09d3cd3e5db..95ae765d8f8a0dcca923bde57f75815032ab01a2 100644
|
| --- a/net/spdy/hpack/hpack_huffman_table_test.cc
|
| +++ b/net/spdy/hpack/hpack_huffman_table_test.cc
|
| @@ -9,9 +9,12 @@
|
| #include <bitset>
|
| #include <limits>
|
| #include <string>
|
| +#include <utility>
|
|
|
| #include "base/logging.h"
|
| +#include "base/macros.h"
|
| #include "net/spdy/hpack/hpack_constants.h"
|
| +#include "net/spdy/hpack/hpack_huffman_decoder.h"
|
| #include "net/spdy/hpack/hpack_input_stream.h"
|
| #include "net/spdy/hpack/hpack_output_stream.h"
|
| #include "net/spdy/spdy_test_utils.h"
|
| @@ -59,9 +62,11 @@ class HpackHuffmanTablePeer {
|
|
|
| namespace {
|
|
|
| -class HpackHuffmanTableTest : public ::testing::Test {
|
| +// Tests of the ability to decode some canonical Huffman code,
|
| +// not just the one defined in the RFC 7541.
|
| +class GenericHuffmanTableTest : public ::testing::TestWithParam<bool> {
|
| protected:
|
| - HpackHuffmanTableTest() : table_(), peer_(table_) {}
|
| + GenericHuffmanTableTest() : table_(), peer_(table_) {}
|
|
|
| string EncodeString(StringPiece input) {
|
| string result;
|
| @@ -92,14 +97,7 @@ char bits8(const string& bitstring) {
|
| return static_cast<char>(std::bitset<8>(bitstring).to_ulong());
|
| }
|
|
|
| -TEST_F(HpackHuffmanTableTest, InitializeHpackCode) {
|
| - std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
|
| - EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
|
| - EXPECT_TRUE(table_.IsInitialized());
|
| - EXPECT_EQ(peer_.pad_bits(), bits8("11111111")); // First 8 bits of EOS.
|
| -}
|
| -
|
| -TEST_F(HpackHuffmanTableTest, InitializeEdgeCases) {
|
| +TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) {
|
| {
|
| // Verify eight symbols can be encoded with 3 bits per symbol.
|
| HpackHuffmanSymbol code[] = {
|
| @@ -195,7 +193,7 @@ TEST_F(HpackHuffmanTableTest, InitializeEdgeCases) {
|
| }
|
| }
|
|
|
| -TEST_F(HpackHuffmanTableTest, ValidateInternalsWithSmallCode) {
|
| +TEST_F(GenericHuffmanTableTest, ValidateInternalsWithSmallCode) {
|
| HpackHuffmanSymbol code[] = {
|
| {bits32("01100000000000000000000000000000"), 4, 0}, // 3rd.
|
| {bits32("01110000000000000000000000000000"), 4, 1}, // 4th.
|
| @@ -244,11 +242,12 @@ TEST_F(HpackHuffmanTableTest, ValidateInternalsWithSmallCode) {
|
| string buffer_out;
|
| HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
|
| buffer_in);
|
| - EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out));
|
| + EXPECT_TRUE(
|
| + table_.GenericDecodeString(&input_stream, input.size(), &buffer_out));
|
| EXPECT_EQ(buffer_out, input);
|
| }
|
|
|
| -TEST_F(HpackHuffmanTableTest, ValidateMultiLevelDecodeTables) {
|
| +TEST_F(GenericHuffmanTableTest, ValidateMultiLevelDecodeTables) {
|
| HpackHuffmanSymbol code[] = {
|
| {bits32("00000000000000000000000000000000"), 6, 0},
|
| {bits32("00000100000000000000000000000000"), 6, 1},
|
| @@ -288,7 +287,7 @@ TEST_F(HpackHuffmanTableTest, ValidateMultiLevelDecodeTables) {
|
| EXPECT_EQ(bits8("00001000"), peer_.pad_bits());
|
| }
|
|
|
| -TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
|
| +TEST_F(GenericHuffmanTableTest, DecodeWithBadInput) {
|
| HpackHuffmanSymbol code[] = {
|
| {bits32("01100000000000000000000000000000"), 4, 0},
|
| {bits32("01110000000000000000000000000000"), 4, 1},
|
| @@ -309,7 +308,7 @@ TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
|
| StringPiece input(input_storage, arraysize(input_storage));
|
|
|
| HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
|
| - EXPECT_TRUE(table_.DecodeString(&input_stream, capacity, &buffer));
|
| + EXPECT_TRUE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
|
| EXPECT_EQ(buffer, "\x02\x03\x02\x06");
|
| }
|
| {
|
| @@ -319,7 +318,7 @@ TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
|
| StringPiece input(input_storage, arraysize(input_storage));
|
|
|
| HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
|
| - EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer));
|
| + EXPECT_FALSE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
|
| EXPECT_EQ(buffer, "\x02\x03\x02");
|
| }
|
| {
|
| @@ -328,7 +327,7 @@ TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
|
| StringPiece input(&input_storage[0], input_storage.size());
|
|
|
| HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
|
| - EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer));
|
| + EXPECT_FALSE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
|
|
|
| std::vector<char> expected(capacity, '\x02');
|
| EXPECT_THAT(buffer, ElementsAreArray(expected));
|
| @@ -341,15 +340,48 @@ TEST_F(HpackHuffmanTableTest, DecodeWithBadInput) {
|
| StringPiece input(input_storage, arraysize(input_storage));
|
|
|
| HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(), input);
|
| - EXPECT_FALSE(table_.DecodeString(&input_stream, capacity, &buffer));
|
| + EXPECT_FALSE(table_.GenericDecodeString(&input_stream, capacity, &buffer));
|
| EXPECT_EQ(buffer, "\x06");
|
| }
|
| }
|
|
|
| -TEST_F(HpackHuffmanTableTest, SpecRequestExamples) {
|
| - std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
|
| - EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
|
| +// Tests of the ability to decode the HPACK Huffman Code, defined in:
|
| +// https://httpwg.github.io/specs/rfc7541.html#huffman.code
|
| +class HpackHuffmanTableTest : public GenericHuffmanTableTest {
|
| + protected:
|
| + void SetUp() override {
|
| + std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
|
| + EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
|
| + EXPECT_TRUE(table_.IsInitialized());
|
| + }
|
| +
|
| + void DecodeStringTwice(const string& encoded,
|
| + size_t out_capacity,
|
| + string* out) {
|
| + // First decode with HpackHuffmanTable.
|
| + {
|
| + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
|
| + encoded);
|
| + EXPECT_TRUE(table_.GenericDecodeString(&input_stream, out_capacity, out));
|
| + }
|
| + // And decode again with the fixed decoder, confirming that the result is
|
| + // the same.
|
| + {
|
| + HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
|
| + encoded);
|
| + string buf;
|
| + EXPECT_TRUE(
|
| + HpackHuffmanDecoder::DecodeString(&input_stream, out_capacity, &buf));
|
| + EXPECT_EQ(*out, buf);
|
| + }
|
| + }
|
| +};
|
| +
|
| +TEST_F(HpackHuffmanTableTest, InitializeHpackCode) {
|
| + EXPECT_EQ(peer_.pad_bits(), '\xFF'); // First 8 bits of EOS.
|
| +}
|
|
|
| +TEST_F(HpackHuffmanTableTest, SpecRequestExamples) {
|
| string buffer;
|
| string test_table[] = {
|
| a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"),
|
| @@ -365,11 +397,7 @@ TEST_F(HpackHuffmanTableTest, SpecRequestExamples) {
|
| for (size_t i = 0; i != arraysize(test_table); i += 2) {
|
| const string& encodedFixture(test_table[i]);
|
| const string& decodedFixture(test_table[i + 1]);
|
| - HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
|
| - encodedFixture);
|
| -
|
| - EXPECT_TRUE(
|
| - table_.DecodeString(&input_stream, decodedFixture.size(), &buffer));
|
| + DecodeStringTwice(encodedFixture, decodedFixture.size(), &buffer);
|
| EXPECT_EQ(decodedFixture, buffer);
|
| buffer = EncodeString(decodedFixture);
|
| EXPECT_EQ(encodedFixture, buffer);
|
| @@ -377,9 +405,6 @@ TEST_F(HpackHuffmanTableTest, SpecRequestExamples) {
|
| }
|
|
|
| TEST_F(HpackHuffmanTableTest, SpecResponseExamples) {
|
| - std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
|
| - EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
|
| -
|
| string buffer;
|
| string test_table[] = {
|
| a2b_hex("6402"), "302", a2b_hex("aec3771a4b"), "private",
|
| @@ -397,40 +422,27 @@ TEST_F(HpackHuffmanTableTest, SpecResponseExamples) {
|
| for (size_t i = 0; i != arraysize(test_table); i += 2) {
|
| const string& encodedFixture(test_table[i]);
|
| const string& decodedFixture(test_table[i + 1]);
|
| - HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
|
| - encodedFixture);
|
| -
|
| - EXPECT_TRUE(
|
| - table_.DecodeString(&input_stream, decodedFixture.size(), &buffer));
|
| + DecodeStringTwice(encodedFixture, decodedFixture.size(), &buffer);
|
| EXPECT_EQ(decodedFixture, buffer);
|
| buffer = EncodeString(decodedFixture);
|
| EXPECT_EQ(encodedFixture, buffer);
|
| }
|
| }
|
|
|
| -TEST_F(HpackHuffmanTableTest, RoundTripIndvidualSymbols) {
|
| - std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
|
| - EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
|
| -
|
| +TEST_F(HpackHuffmanTableTest, RoundTripIndividualSymbols) {
|
| for (size_t i = 0; i != 256; i++) {
|
| char c = static_cast<char>(i);
|
| char storage[3] = {c, c, c};
|
| StringPiece input(storage, arraysize(storage));
|
| -
|
| string buffer_in = EncodeString(input);
|
| string buffer_out;
|
|
|
| - HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
|
| - buffer_in);
|
| - EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out));
|
| + DecodeStringTwice(buffer_in, input.size(), &buffer_out);
|
| EXPECT_EQ(input, buffer_out);
|
| }
|
| }
|
|
|
| TEST_F(HpackHuffmanTableTest, RoundTripSymbolSequence) {
|
| - std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
|
| - EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
|
| -
|
| char storage[512];
|
| for (size_t i = 0; i != 256; i++) {
|
| storage[i] = static_cast<char>(i);
|
| @@ -440,17 +452,11 @@ TEST_F(HpackHuffmanTableTest, RoundTripSymbolSequence) {
|
|
|
| string buffer_in = EncodeString(input);
|
| string buffer_out;
|
| -
|
| - HpackInputStream input_stream(std::numeric_limits<uint32_t>::max(),
|
| - buffer_in);
|
| - EXPECT_TRUE(table_.DecodeString(&input_stream, input.size(), &buffer_out));
|
| + DecodeStringTwice(buffer_in, input.size(), &buffer_out);
|
| EXPECT_EQ(input, buffer_out);
|
| }
|
|
|
| TEST_F(HpackHuffmanTableTest, EncodedSizeAgreesWithEncodeString) {
|
| - std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode();
|
| - EXPECT_TRUE(table_.Initialize(&code[0], code.size()));
|
| -
|
| string test_table[] = {
|
| "",
|
| "Mon, 21 Oct 2013 20:13:21 GMT",
|
|
|