OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/spdy/hpack/hpack_huffman_decoder.h" | 5 #include "net/spdy/hpack/hpack_huffman_decoder.h" |
6 | 6 |
7 #include <bitset> | 7 #include <bitset> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 HuffmanWord canonical = | 65 HuffmanWord canonical = |
66 HpackHuffmanDecoderPeer::DecodeToCanonical(code_length, bits); | 66 HpackHuffmanDecoderPeer::DecodeToCanonical(code_length, bits); |
67 EXPECT_LE(canonical, 256u); | 67 EXPECT_LE(canonical, 256u); |
68 if (canonical == 256u) { | 68 if (canonical == 256u) { |
69 return canonical; | 69 return canonical; |
70 } | 70 } |
71 return static_cast<unsigned char>( | 71 return static_cast<unsigned char>( |
72 HpackHuffmanDecoderPeer::CanonicalToSource(canonical)); | 72 HpackHuffmanDecoderPeer::CanonicalToSource(canonical)); |
73 } | 73 } |
74 | 74 |
75 void EncodeString(SpdyStringPiece input, std::string* encoded) { | 75 void EncodeString(SpdyStringPiece input, SpdyString* encoded) { |
76 HpackOutputStream output_stream; | 76 HpackOutputStream output_stream; |
77 table_.EncodeString(input, &output_stream); | 77 table_.EncodeString(input, &output_stream); |
78 encoded->clear(); | 78 encoded->clear(); |
79 output_stream.TakeString(encoded); | 79 output_stream.TakeString(encoded); |
80 // Verify EncodedSize() agrees with EncodeString(). | 80 // Verify EncodedSize() agrees with EncodeString(). |
81 EXPECT_EQ(encoded->size(), table_.EncodedSize(input)); | 81 EXPECT_EQ(encoded->size(), table_.EncodedSize(input)); |
82 } | 82 } |
83 | 83 |
84 std::string EncodeString(SpdyStringPiece input) { | 84 SpdyString EncodeString(SpdyStringPiece input) { |
85 std::string result; | 85 SpdyString result; |
86 EncodeString(input, &result); | 86 EncodeString(input, &result); |
87 return result; | 87 return result; |
88 } | 88 } |
89 | 89 |
90 const HpackHuffmanTable& table_; | 90 const HpackHuffmanTable& table_; |
91 }; | 91 }; |
92 | 92 |
93 TEST_F(HpackHuffmanDecoderTest, CodeLengthOfPrefix) { | 93 TEST_F(HpackHuffmanDecoderTest, CodeLengthOfPrefix) { |
94 for (const HpackHuffmanSymbol& entry : HpackHuffmanCode()) { | 94 for (const HpackHuffmanSymbol& entry : HpackHuffmanCode()) { |
95 // First confirm our assumption that the low order bits of entry.code | 95 // First confirm our assumption that the low order bits of entry.code |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 bits = entry.code | rand; | 155 bits = entry.code | rand; |
156 EXPECT_EQ(entry.id, DecodeToSource(entry.length, bits)) | 156 EXPECT_EQ(entry.id, DecodeToSource(entry.length, bits)) |
157 << " Length: " << entry.length << "\n" | 157 << " Length: " << entry.length << "\n" |
158 << "Full code: " << Bits(entry.code) << "\n" | 158 << "Full code: " << Bits(entry.code) << "\n" |
159 << " rand: " << Bits(rand) << "\n" | 159 << " rand: " << Bits(rand) << "\n" |
160 << " bits: " << Bits(bits); | 160 << " bits: " << Bits(bits); |
161 } | 161 } |
162 } | 162 } |
163 | 163 |
164 TEST_F(HpackHuffmanDecoderTest, SpecRequestExamples) { | 164 TEST_F(HpackHuffmanDecoderTest, SpecRequestExamples) { |
165 std::string buffer; | 165 SpdyString buffer; |
166 std::string test_table[] = { | 166 SpdyString test_table[] = { |
167 a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"), | 167 a2b_hex("f1e3c2e5f23a6ba0ab90f4ff"), |
168 "www.example.com", | 168 "www.example.com", |
169 a2b_hex("a8eb10649cbf"), | 169 a2b_hex("a8eb10649cbf"), |
170 "no-cache", | 170 "no-cache", |
171 a2b_hex("25a849e95ba97d7f"), | 171 a2b_hex("25a849e95ba97d7f"), |
172 "custom-key", | 172 "custom-key", |
173 a2b_hex("25a849e95bb8e8b4bf"), | 173 a2b_hex("25a849e95bb8e8b4bf"), |
174 "custom-value", | 174 "custom-value", |
175 }; | 175 }; |
176 // Round-trip each test example. | 176 // Round-trip each test example. |
177 for (size_t i = 0; i != arraysize(test_table); i += 2) { | 177 for (size_t i = 0; i != arraysize(test_table); i += 2) { |
178 const std::string& encodedFixture(test_table[i]); | 178 const SpdyString& encodedFixture(test_table[i]); |
179 const std::string& decodedFixture(test_table[i + 1]); | 179 const SpdyString& decodedFixture(test_table[i + 1]); |
180 HpackInputStream input_stream(encodedFixture); | 180 HpackInputStream input_stream(encodedFixture); |
181 EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, &buffer)); | 181 EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, &buffer)); |
182 EXPECT_EQ(decodedFixture, buffer); | 182 EXPECT_EQ(decodedFixture, buffer); |
183 buffer = EncodeString(decodedFixture); | 183 buffer = EncodeString(decodedFixture); |
184 EXPECT_EQ(encodedFixture, buffer); | 184 EXPECT_EQ(encodedFixture, buffer); |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 TEST_F(HpackHuffmanDecoderTest, SpecResponseExamples) { | 188 TEST_F(HpackHuffmanDecoderTest, SpecResponseExamples) { |
189 std::string buffer; | 189 SpdyString buffer; |
190 // clang-format off | 190 // clang-format off |
191 std::string test_table[] = { | 191 SpdyString test_table[] = { |
192 a2b_hex("6402"), | 192 a2b_hex("6402"), |
193 "302", | 193 "302", |
194 a2b_hex("aec3771a4b"), | 194 a2b_hex("aec3771a4b"), |
195 "private", | 195 "private", |
196 a2b_hex("d07abe941054d444a8200595040b8166" | 196 a2b_hex("d07abe941054d444a8200595040b8166" |
197 "e082a62d1bff"), | 197 "e082a62d1bff"), |
198 "Mon, 21 Oct 2013 20:13:21 GMT", | 198 "Mon, 21 Oct 2013 20:13:21 GMT", |
199 a2b_hex("9d29ad171863c78f0b97c8e9ae82ae43" | 199 a2b_hex("9d29ad171863c78f0b97c8e9ae82ae43" |
200 "d3"), | 200 "d3"), |
201 "https://www.example.com", | 201 "https://www.example.com", |
202 a2b_hex("94e7821dd7f2e6c7b335dfdfcd5b3960" | 202 a2b_hex("94e7821dd7f2e6c7b335dfdfcd5b3960" |
203 "d5af27087f3672c1ab270fb5291f9587" | 203 "d5af27087f3672c1ab270fb5291f9587" |
204 "316065c003ed4ee5b1063d5007"), | 204 "316065c003ed4ee5b1063d5007"), |
205 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", | 205 "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", |
206 }; | 206 }; |
207 // clang-format on | 207 // clang-format on |
208 // Round-trip each test example. | 208 // Round-trip each test example. |
209 for (size_t i = 0; i != arraysize(test_table); i += 2) { | 209 for (size_t i = 0; i != arraysize(test_table); i += 2) { |
210 const std::string& encodedFixture(test_table[i]); | 210 const SpdyString& encodedFixture(test_table[i]); |
211 const std::string& decodedFixture(test_table[i + 1]); | 211 const SpdyString& decodedFixture(test_table[i + 1]); |
212 HpackInputStream input_stream(encodedFixture); | 212 HpackInputStream input_stream(encodedFixture); |
213 EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, &buffer)); | 213 EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, &buffer)); |
214 EXPECT_EQ(decodedFixture, buffer); | 214 EXPECT_EQ(decodedFixture, buffer); |
215 buffer = EncodeString(decodedFixture); | 215 buffer = EncodeString(decodedFixture); |
216 EXPECT_EQ(encodedFixture, buffer); | 216 EXPECT_EQ(encodedFixture, buffer); |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
220 TEST_F(HpackHuffmanDecoderTest, RoundTripIndividualSymbols) { | 220 TEST_F(HpackHuffmanDecoderTest, RoundTripIndividualSymbols) { |
221 for (size_t i = 0; i != 256; i++) { | 221 for (size_t i = 0; i != 256; i++) { |
222 char c = static_cast<char>(i); | 222 char c = static_cast<char>(i); |
223 char storage[3] = {c, c, c}; | 223 char storage[3] = {c, c, c}; |
224 SpdyStringPiece input(storage, arraysize(storage)); | 224 SpdyStringPiece input(storage, arraysize(storage)); |
225 std::string buffer_in = EncodeString(input); | 225 SpdyString buffer_in = EncodeString(input); |
226 std::string buffer_out; | 226 SpdyString buffer_out; |
227 HpackInputStream input_stream(buffer_in); | 227 HpackInputStream input_stream(buffer_in); |
228 EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, &buffer_out)); | 228 EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, &buffer_out)); |
229 EXPECT_EQ(input, buffer_out); | 229 EXPECT_EQ(input, buffer_out); |
230 } | 230 } |
231 } | 231 } |
232 | 232 |
233 // Creates 256 input strings, each with a unique byte value i used to sandwich | 233 // Creates 256 input strings, each with a unique byte value i used to sandwich |
234 // all the other higher byte values. | 234 // all the other higher byte values. |
235 TEST_F(HpackHuffmanDecoderTest, RoundTripSymbolSequences) { | 235 TEST_F(HpackHuffmanDecoderTest, RoundTripSymbolSequences) { |
236 std::string input; | 236 SpdyString input; |
237 std::string encoded; | 237 SpdyString encoded; |
238 std::string decoded; | 238 SpdyString decoded; |
239 for (size_t i = 0; i != 256; i++) { | 239 for (size_t i = 0; i != 256; i++) { |
240 input.clear(); | 240 input.clear(); |
241 auto ic = static_cast<char>(i); | 241 auto ic = static_cast<char>(i); |
242 input.push_back(ic); | 242 input.push_back(ic); |
243 for (size_t j = i; j != 256; j++) { | 243 for (size_t j = i; j != 256; j++) { |
244 input.push_back(static_cast<char>(j)); | 244 input.push_back(static_cast<char>(j)); |
245 input.push_back(ic); | 245 input.push_back(ic); |
246 } | 246 } |
247 EncodeString(input, &encoded); | 247 EncodeString(input, &encoded); |
248 HpackInputStream input_stream(encoded); | 248 HpackInputStream input_stream(encoded); |
249 EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, &decoded)); | 249 EXPECT_TRUE(HpackHuffmanDecoder::DecodeString(&input_stream, &decoded)); |
250 EXPECT_EQ(input, decoded); | 250 EXPECT_EQ(input, decoded); |
251 } | 251 } |
252 } | 252 } |
253 | 253 |
254 } // namespace test | 254 } // namespace test |
255 } // namespace net | 255 } // namespace net |
OLD | NEW |