|  | // Copyright 2018 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "http2/hpack/varint/hpack_varint_decoder.h" | 
|  |  | 
|  | // Test HpackVarintDecoder against hardcoded data. | 
|  |  | 
|  | #include <stddef.h> | 
|  |  | 
|  | #include "absl/base/macros.h" | 
|  | #include "absl/strings/escaping.h" | 
|  | #include "absl/strings/string_view.h" | 
|  | #include "http2/platform/api/http2_logging.h" | 
|  | #include "http2/tools/random_decoder_test.h" | 
|  | #include "common/platform/api/quiche_test.h" | 
|  |  | 
|  | using ::testing::AssertionFailure; | 
|  | using ::testing::AssertionSuccess; | 
|  |  | 
|  | namespace http2 { | 
|  | namespace test { | 
|  | namespace { | 
|  |  | 
|  | class HpackVarintDecoderTest : public RandomDecoderTest, | 
|  | public ::testing::WithParamInterface< | 
|  | ::testing::tuple<uint8_t, const char*>> { | 
|  | protected: | 
|  | HpackVarintDecoderTest() | 
|  | : high_bits_(::testing::get<0>(GetParam())), | 
|  | suffix_(absl::HexStringToBytes(::testing::get<1>(GetParam()))), | 
|  | prefix_length_(0) {} | 
|  |  | 
|  | void DecodeExpectSuccess(absl::string_view data, | 
|  | uint32_t prefix_length, | 
|  | uint64_t expected_value) { | 
|  | Validator validator = [expected_value, this]( | 
|  | const DecodeBuffer& /*db*/, | 
|  | DecodeStatus /*status*/) -> AssertionResult { | 
|  | VERIFY_EQ(expected_value, decoder_.value()) | 
|  | << "Value doesn't match expected: " << decoder_.value() | 
|  | << " != " << expected_value; | 
|  | return AssertionSuccess(); | 
|  | }; | 
|  |  | 
|  | // First validate that decoding is done and that we've advanced the cursor | 
|  | // the expected amount. | 
|  | validator = ValidateDoneAndOffset(/* offset = */ data.size(), validator); | 
|  |  | 
|  | EXPECT_TRUE(Decode(data, prefix_length, validator)); | 
|  |  | 
|  | EXPECT_EQ(expected_value, decoder_.value()); | 
|  | } | 
|  |  | 
|  | void DecodeExpectError(absl::string_view data, uint32_t prefix_length) { | 
|  | Validator validator = [](const DecodeBuffer& /*db*/, | 
|  | DecodeStatus status) -> AssertionResult { | 
|  | VERIFY_EQ(DecodeStatus::kDecodeError, status); | 
|  | return AssertionSuccess(); | 
|  | }; | 
|  |  | 
|  | EXPECT_TRUE(Decode(data, prefix_length, validator)); | 
|  | } | 
|  |  | 
|  | private: | 
|  | AssertionResult Decode(absl::string_view data, | 
|  | uint32_t prefix_length, | 
|  | const Validator validator) { | 
|  | prefix_length_ = prefix_length; | 
|  |  | 
|  | // Copy |data| so that it can be modified. | 
|  | std::string data_copy(data); | 
|  |  | 
|  | // Bits of the first byte not part of the prefix should be ignored. | 
|  | uint8_t high_bits_mask = 0b11111111 << prefix_length_; | 
|  | data_copy[0] |= (high_bits_mask & high_bits_); | 
|  |  | 
|  | // Extra bytes appended to the input should be ignored. | 
|  | data_copy.append(suffix_); | 
|  |  | 
|  | DecodeBuffer b(data_copy); | 
|  |  | 
|  | // StartDecoding, above, requires the DecodeBuffer be non-empty so that it | 
|  | // can call Start with the prefix byte. | 
|  | bool return_non_zero_on_first = true; | 
|  |  | 
|  | return DecodeAndValidateSeveralWays(&b, return_non_zero_on_first, | 
|  | validator); | 
|  | } | 
|  |  | 
|  | DecodeStatus StartDecoding(DecodeBuffer* b) override { | 
|  | QUICHE_CHECK_LT(0u, b->Remaining()); | 
|  | uint8_t prefix = b->DecodeUInt8(); | 
|  | return decoder_.Start(prefix, prefix_length_, b); | 
|  | } | 
|  |  | 
|  | DecodeStatus ResumeDecoding(DecodeBuffer* b) override { | 
|  | return decoder_.Resume(b); | 
|  | } | 
|  |  | 
|  | // Bits of the first byte not part of the prefix. | 
|  | const uint8_t high_bits_; | 
|  | // Extra bytes appended to the input. | 
|  | const std::string suffix_; | 
|  |  | 
|  | HpackVarintDecoder decoder_; | 
|  | uint8_t prefix_length_; | 
|  | }; | 
|  |  | 
|  | INSTANTIATE_TEST_SUITE_P( | 
|  | HpackVarintDecoderTest, | 
|  | HpackVarintDecoderTest, | 
|  | ::testing::Combine( | 
|  | // Bits of the first byte not part of the prefix should be ignored. | 
|  | ::testing::Values(0b00000000, 0b11111111, 0b10101010), | 
|  | // Extra bytes appended to the input should be ignored. | 
|  | ::testing::Values("", "00", "666f6f"))); | 
|  |  | 
|  | struct { | 
|  | const char* data; | 
|  | uint32_t prefix_length; | 
|  | uint64_t expected_value; | 
|  | } kSuccessTestData[] = { | 
|  | // Zero value with different prefix lengths. | 
|  | {"00", 3, 0}, | 
|  | {"00", 4, 0}, | 
|  | {"00", 5, 0}, | 
|  | {"00", 6, 0}, | 
|  | {"00", 7, 0}, | 
|  | {"00", 8, 0}, | 
|  | // Small values that fit in the prefix. | 
|  | {"06", 3, 6}, | 
|  | {"0d", 4, 13}, | 
|  | {"10", 5, 16}, | 
|  | {"29", 6, 41}, | 
|  | {"56", 7, 86}, | 
|  | {"bf", 8, 191}, | 
|  | // Values of 2^n-1, which have an all-zero extension byte. | 
|  | {"0700", 3, 7}, | 
|  | {"0f00", 4, 15}, | 
|  | {"1f00", 5, 31}, | 
|  | {"3f00", 6, 63}, | 
|  | {"7f00", 7, 127}, | 
|  | {"ff00", 8, 255}, | 
|  | // Values of 2^n-1, plus one extra byte of padding. | 
|  | {"078000", 3, 7}, | 
|  | {"0f8000", 4, 15}, | 
|  | {"1f8000", 5, 31}, | 
|  | {"3f8000", 6, 63}, | 
|  | {"7f8000", 7, 127}, | 
|  | {"ff8000", 8, 255}, | 
|  | // Values requiring one extension byte. | 
|  | {"0760", 3, 103}, | 
|  | {"0f2a", 4, 57}, | 
|  | {"1f7f", 5, 158}, | 
|  | {"3f02", 6, 65}, | 
|  | {"7f49", 7, 200}, | 
|  | {"ff6f", 8, 366}, | 
|  | // Values requiring one extension byte, plus one byte of padding. | 
|  | {"07e000", 3, 103}, | 
|  | {"0faa00", 4, 57}, | 
|  | {"1fff00", 5, 158}, | 
|  | {"3f8200", 6, 65}, | 
|  | {"7fc900", 7, 200}, | 
|  | {"ffef00", 8, 366}, | 
|  | // Values requiring one extension byte, plus two bytes of padding. | 
|  | {"07e08000", 3, 103}, | 
|  | {"0faa8000", 4, 57}, | 
|  | {"1fff8000", 5, 158}, | 
|  | {"3f828000", 6, 65}, | 
|  | {"7fc98000", 7, 200}, | 
|  | {"ffef8000", 8, 366}, | 
|  | // Values requiring one extension byte, plus the maximum amount of padding. | 
|  | {"07e0808080808080808000", 3, 103}, | 
|  | {"0faa808080808080808000", 4, 57}, | 
|  | {"1fff808080808080808000", 5, 158}, | 
|  | {"3f82808080808080808000", 6, 65}, | 
|  | {"7fc9808080808080808000", 7, 200}, | 
|  | {"ffef808080808080808000", 8, 366}, | 
|  | // Values requiring two extension bytes. | 
|  | {"07b260", 3, 12345}, | 
|  | {"0f8a2a", 4, 5401}, | 
|  | {"1fa87f", 5, 16327}, | 
|  | {"3fd002", 6, 399}, | 
|  | {"7fff49", 7, 9598}, | 
|  | {"ffe32f", 8, 6370}, | 
|  | // Values requiring two extension bytes, plus one byte of padding. | 
|  | {"07b2e000", 3, 12345}, | 
|  | {"0f8aaa00", 4, 5401}, | 
|  | {"1fa8ff00", 5, 16327}, | 
|  | {"3fd08200", 6, 399}, | 
|  | {"7fffc900", 7, 9598}, | 
|  | {"ffe3af00", 8, 6370}, | 
|  | // Values requiring two extension bytes, plus the maximum amount of padding. | 
|  | {"07b2e080808080808000", 3, 12345}, | 
|  | {"0f8aaa80808080808000", 4, 5401}, | 
|  | {"1fa8ff80808080808000", 5, 16327}, | 
|  | {"3fd08280808080808000", 6, 399}, | 
|  | {"7fffc980808080808000", 7, 9598}, | 
|  | {"ffe3af80808080808000", 8, 6370}, | 
|  | // Values requiring three extension bytes. | 
|  | {"078ab260", 3, 1579281}, | 
|  | {"0fc18a2a", 4, 689488}, | 
|  | {"1fada87f", 5, 2085964}, | 
|  | {"3fa0d002", 6, 43103}, | 
|  | {"7ffeff49", 7, 1212541}, | 
|  | {"ff93de23", 8, 585746}, | 
|  | // Values requiring three extension bytes, plus one byte of padding. | 
|  | {"078ab2e000", 3, 1579281}, | 
|  | {"0fc18aaa00", 4, 689488}, | 
|  | {"1fada8ff00", 5, 2085964}, | 
|  | {"3fa0d08200", 6, 43103}, | 
|  | {"7ffeffc900", 7, 1212541}, | 
|  | {"ff93dea300", 8, 585746}, | 
|  | // Values requiring four extension bytes. | 
|  | {"079f8ab260", 3, 202147110}, | 
|  | {"0fa2c18a2a", 4, 88252593}, | 
|  | {"1fd0ada87f", 5, 266999535}, | 
|  | {"3ff9a0d002", 6, 5509304}, | 
|  | {"7f9efeff49", 7, 155189149}, | 
|  | {"ffaa82f404", 8, 10289705}, | 
|  | // Values requiring four extension bytes, plus one byte of padding. | 
|  | {"079f8ab2e000", 3, 202147110}, | 
|  | {"0fa2c18aaa00", 4, 88252593}, | 
|  | {"1fd0ada8ff00", 5, 266999535}, | 
|  | {"3ff9a0d08200", 6, 5509304}, | 
|  | {"7f9efeffc900", 7, 155189149}, | 
|  | {"ffaa82f48400", 8, 10289705}, | 
|  | // Values requiring six extension bytes. | 
|  | {"0783aa9f8ab260", 3, 3311978140938}, | 
|  | {"0ff0b0a2c18a2a", 4, 1445930244223}, | 
|  | {"1fda84d0ada87f", 5, 4374519874169}, | 
|  | {"3fb5fbf9a0d002", 6, 90263420404}, | 
|  | {"7fcff19efeff49", 7, 2542616951118}, | 
|  | {"ff9fa486bbc327", 8, 1358138807070}, | 
|  | // Values requiring eight extension bytes. | 
|  | {"07f19883aa9f8ab260", 3, 54263449861016696}, | 
|  | {"0f84fdf0b0a2c18a2a", 4, 23690121121119891}, | 
|  | {"1fa0dfda84d0ada87f", 5, 71672133617889215}, | 
|  | {"3f9ff0b5fbf9a0d002", 6, 1478875878881374}, | 
|  | {"7ffbc1cff19efeff49", 7, 41658236125045114}, | 
|  | {"ff91b6fb85af99c342", 8, 37450237664484368}, | 
|  | // Values requiring ten extension bytes. | 
|  | {"0794f1f19883aa9f8ab201", 3, 12832019021693745307u}, | 
|  | {"0fa08f84fdf0b0a2c18a01", 4, 9980690937382242223u}, | 
|  | {"1fbfdda0dfda84d0ada801", 5, 12131360551794650846u}, | 
|  | {"3f9dc79ff0b5fbf9a0d001", 6, 15006530362736632796u}, | 
|  | {"7f8790fbc1cff19efeff01", 7, 18445754019193211014u}, | 
|  | {"fffba8c5b8d3fe9f8c8401", 8, 9518498503615141242u}, | 
|  | // Maximum value: 2^64-1. | 
|  | {"07f8ffffffffffffffff01", 3, 18446744073709551615u}, | 
|  | {"0ff0ffffffffffffffff01", 4, 18446744073709551615u}, | 
|  | {"1fe0ffffffffffffffff01", 5, 18446744073709551615u}, | 
|  | {"3fc0ffffffffffffffff01", 6, 18446744073709551615u}, | 
|  | {"7f80ffffffffffffffff01", 7, 18446744073709551615u}, | 
|  | {"ff80feffffffffffffff01", 8, 18446744073709551615u}, | 
|  | // Examples from RFC7541 C.1. | 
|  | {"0a", 5, 10}, | 
|  | {"1f9a0a", 5, 1337}, | 
|  | }; | 
|  |  | 
|  | TEST_P(HpackVarintDecoderTest, Success) { | 
|  | for (size_t i = 0; i < ABSL_ARRAYSIZE(kSuccessTestData); ++i) { | 
|  | DecodeExpectSuccess(absl::HexStringToBytes(kSuccessTestData[i].data), | 
|  | kSuccessTestData[i].prefix_length, | 
|  | kSuccessTestData[i].expected_value); | 
|  | } | 
|  | } | 
|  |  | 
|  | struct { | 
|  | const char* data; | 
|  | uint32_t prefix_length; | 
|  | } kErrorTestData[] = { | 
|  | // Too many extension bytes, all 0s (except for extension bit in each byte). | 
|  | {"0780808080808080808080", 3}, | 
|  | {"0f80808080808080808080", 4}, | 
|  | {"1f80808080808080808080", 5}, | 
|  | {"3f80808080808080808080", 6}, | 
|  | {"7f80808080808080808080", 7}, | 
|  | {"ff80808080808080808080", 8}, | 
|  | // Too many extension bytes, all 1s. | 
|  | {"07ffffffffffffffffffff", 3}, | 
|  | {"0fffffffffffffffffffff", 4}, | 
|  | {"1fffffffffffffffffffff", 5}, | 
|  | {"3fffffffffffffffffffff", 6}, | 
|  | {"7fffffffffffffffffffff", 7}, | 
|  | {"ffffffffffffffffffffff", 8}, | 
|  | // Value of 2^64, one higher than maximum of 2^64-1. | 
|  | {"07f9ffffffffffffffff01", 3}, | 
|  | {"0ff1ffffffffffffffff01", 4}, | 
|  | {"1fe1ffffffffffffffff01", 5}, | 
|  | {"3fc1ffffffffffffffff01", 6}, | 
|  | {"7f81ffffffffffffffff01", 7}, | 
|  | {"ff81feffffffffffffff01", 8}, | 
|  | // Maximum value: 2^64-1, with one byte of padding. | 
|  | {"07f8ffffffffffffffff8100", 3}, | 
|  | {"0ff0ffffffffffffffff8100", 4}, | 
|  | {"1fe0ffffffffffffffff8100", 5}, | 
|  | {"3fc0ffffffffffffffff8100", 6}, | 
|  | {"7f80ffffffffffffffff8100", 7}, | 
|  | {"ff80feffffffffffffff8100", 8}}; | 
|  |  | 
|  | TEST_P(HpackVarintDecoderTest, Error) { | 
|  | for (size_t i = 0; i < ABSL_ARRAYSIZE(kErrorTestData); ++i) { | 
|  | DecodeExpectError(absl::HexStringToBytes(kErrorTestData[i].data), | 
|  | kErrorTestData[i].prefix_length); | 
|  | } | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  | }  // namespace test | 
|  | }  // namespace http2 |