| 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 |