1 // Copyright 2016 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
5 #include "quiche/http2/hpack/varint/hpack_varint_encoder.h"
6
7 #include <cstddef>
8 #include <string>
9
10 #include "absl/base/macros.h"
11 #include "absl/strings/escaping.h"
12 #include "quiche/common/platform/api/quiche_test.h"
13
14 namespace http2 {
15 namespace test {
16 namespace {
17
18 struct {
19 uint8_t high_bits;
20 uint8_t prefix_length;
21 uint64_t value;
22 uint8_t expected_encoding;
23 } kShortTestData[] = {{0b10110010, 1, 0, 0b10110010},
24 {0b10101100, 2, 2, 0b10101110},
25 {0b10100000, 3, 6, 0b10100110},
26 {0b10110000, 4, 13, 0b10111101},
27 {0b10100000, 5, 8, 0b10101000},
28 {0b11000000, 6, 48, 0b11110000},
29 {0b10000000, 7, 99, 0b11100011},
30 // Example from RFC7541 C.1.
31 {0b00000000, 5, 10, 0b00001010}};
32
33 // Encode integers that fit in the prefix.
TEST(HpackVarintEncoderTest,Short)34 TEST(HpackVarintEncoderTest, Short) {
35 for (size_t i = 0; i < ABSL_ARRAYSIZE(kShortTestData); ++i) {
36 std::string output;
37 HpackVarintEncoder::Encode(kShortTestData[i].high_bits,
38 kShortTestData[i].prefix_length,
39 kShortTestData[i].value, &output);
40 ASSERT_EQ(1u, output.size());
41 EXPECT_EQ(kShortTestData[i].expected_encoding,
42 static_cast<uint8_t>(output[0]));
43 }
44 }
45
46 struct {
47 uint8_t high_bits;
48 uint8_t prefix_length;
49 uint64_t value;
50 const char* expected_encoding;
51 } kLongTestData[] = {
52 // One extension byte.
53 {0b10011000, 3, 103, "9f60"},
54 {0b10010000, 4, 57, "9f2a"},
55 {0b11000000, 5, 158, "df7f"},
56 {0b01000000, 6, 65, "7f02"},
57 {0b00000000, 7, 200, "7f49"},
58 // Two extension bytes.
59 {0b10011000, 3, 12345, "9fb260"},
60 {0b10010000, 4, 5401, "9f8a2a"},
61 {0b11000000, 5, 16327, "dfa87f"},
62 {0b01000000, 6, 399, "7fd002"},
63 {0b00000000, 7, 9598, "7fff49"},
64 // Three extension bytes.
65 {0b10011000, 3, 1579281, "9f8ab260"},
66 {0b10010000, 4, 689488, "9fc18a2a"},
67 {0b11000000, 5, 2085964, "dfada87f"},
68 {0b01000000, 6, 43103, "7fa0d002"},
69 {0b00000000, 7, 1212541, "7ffeff49"},
70 // Four extension bytes.
71 {0b10011000, 3, 202147110, "9f9f8ab260"},
72 {0b10010000, 4, 88252593, "9fa2c18a2a"},
73 {0b11000000, 5, 266999535, "dfd0ada87f"},
74 {0b01000000, 6, 5509304, "7ff9a0d002"},
75 {0b00000000, 7, 155189149, "7f9efeff49"},
76 // Six extension bytes.
77 {0b10011000, 3, 3311978140938, "9f83aa9f8ab260"},
78 {0b10010000, 4, 1445930244223, "9ff0b0a2c18a2a"},
79 {0b11000000, 5, 4374519874169, "dfda84d0ada87f"},
80 {0b01000000, 6, 90263420404, "7fb5fbf9a0d002"},
81 {0b00000000, 7, 2542616951118, "7fcff19efeff49"},
82 // Eight extension bytes.
83 {0b10011000, 3, 54263449861016696, "9ff19883aa9f8ab260"},
84 {0b10010000, 4, 23690121121119891, "9f84fdf0b0a2c18a2a"},
85 {0b11000000, 5, 71672133617889215, "dfa0dfda84d0ada87f"},
86 {0b01000000, 6, 1478875878881374, "7f9ff0b5fbf9a0d002"},
87 {0b00000000, 7, 41658236125045114, "7ffbc1cff19efeff49"},
88 // Ten extension bytes.
89 {0b10011000, 3, 12832019021693745307u, "9f94f1f19883aa9f8ab201"},
90 {0b10010000, 4, 9980690937382242223u, "9fa08f84fdf0b0a2c18a01"},
91 {0b11000000, 5, 12131360551794650846u, "dfbfdda0dfda84d0ada801"},
92 {0b01000000, 6, 15006530362736632796u, "7f9dc79ff0b5fbf9a0d001"},
93 {0b00000000, 7, 18445754019193211014u, "7f8790fbc1cff19efeff01"},
94 // Maximum value: 2^64-1.
95 {0b10011000, 3, 18446744073709551615u, "9ff8ffffffffffffffff01"},
96 {0b10010000, 4, 18446744073709551615u, "9ff0ffffffffffffffff01"},
97 {0b11000000, 5, 18446744073709551615u, "dfe0ffffffffffffffff01"},
98 {0b01000000, 6, 18446744073709551615u, "7fc0ffffffffffffffff01"},
99 {0b00000000, 7, 18446744073709551615u, "7f80ffffffffffffffff01"},
100 // Example from RFC7541 C.1.
101 {0b00000000, 5, 1337, "1f9a0a"},
102 };
103
104 // Encode integers that do not fit in the prefix.
TEST(HpackVarintEncoderTest,Long)105 TEST(HpackVarintEncoderTest, Long) {
106 // Test encoding byte by byte, also test encoding in
107 // a single ResumeEncoding() call.
108 for (size_t i = 0; i < ABSL_ARRAYSIZE(kLongTestData); ++i) {
109 std::string expected_encoding;
110 ASSERT_TRUE(absl::HexStringToBytes(kLongTestData[i].expected_encoding,
111 &expected_encoding));
112
113 std::string output;
114 HpackVarintEncoder::Encode(kLongTestData[i].high_bits,
115 kLongTestData[i].prefix_length,
116 kLongTestData[i].value, &output);
117
118 EXPECT_EQ(expected_encoding, output);
119 }
120 }
121
122 struct {
123 uint8_t high_bits;
124 uint8_t prefix_length;
125 uint64_t value;
126 uint8_t expected_encoding_first_byte;
127 } kLastByteIsZeroTestData[] = {
128 {0b10110010, 1, 1, 0b10110011}, {0b10101100, 2, 3, 0b10101111},
129 {0b10101000, 3, 7, 0b10101111}, {0b10110000, 4, 15, 0b10111111},
130 {0b10100000, 5, 31, 0b10111111}, {0b11000000, 6, 63, 0b11111111},
131 {0b10000000, 7, 127, 0b11111111}, {0b00000000, 8, 255, 0b11111111}};
132
133 // Make sure that the encoder outputs the last byte even when it is zero. This
134 // happens exactly when encoding the value 2^prefix_length - 1.
TEST(HpackVarintEncoderTest,LastByteIsZero)135 TEST(HpackVarintEncoderTest, LastByteIsZero) {
136 for (size_t i = 0; i < ABSL_ARRAYSIZE(kLastByteIsZeroTestData); ++i) {
137 std::string output;
138 HpackVarintEncoder::Encode(kLastByteIsZeroTestData[i].high_bits,
139 kLastByteIsZeroTestData[i].prefix_length,
140 kLastByteIsZeroTestData[i].value, &output);
141 ASSERT_EQ(2u, output.size());
142 EXPECT_EQ(kLastByteIsZeroTestData[i].expected_encoding_first_byte,
143 static_cast<uint8_t>(output[0]));
144 EXPECT_EQ(0b00000000, output[1]);
145 }
146 }
147
148 // Test that encoder appends correctly to non-empty string.
TEST(HpackVarintEncoderTest,Append)149 TEST(HpackVarintEncoderTest, Append) {
150 std::string output("foo");
151 std::string expected_encoding;
152 ASSERT_TRUE(absl::HexStringToBytes("666f6f", &expected_encoding));
153 EXPECT_EQ(expected_encoding, output);
154
155 HpackVarintEncoder::Encode(0b10011000, 3, 103, &output);
156 ASSERT_TRUE(absl::HexStringToBytes("666f6f9f60", &expected_encoding));
157 EXPECT_EQ(expected_encoding, output);
158
159 HpackVarintEncoder::Encode(0b10100000, 5, 8, &output);
160 ASSERT_TRUE(absl::HexStringToBytes("666f6f9f60a8", &expected_encoding));
161 EXPECT_EQ(expected_encoding, output);
162
163 HpackVarintEncoder::Encode(0b10011000, 3, 202147110, &output);
164 ASSERT_TRUE(
165 absl::HexStringToBytes("666f6f9f60a89f9f8ab260", &expected_encoding));
166 EXPECT_EQ(expected_encoding, output);
167 }
168
169 } // namespace
170 } // namespace test
171 } // namespace http2
172