Chromium Code Reviews| 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/http2/decoder/http2_frame_decoder.h" | 5 #include "net/http2/decoder/http2_frame_decoder.h" |
| 6 | 6 |
| 7 // Tests of Http2FrameDecoder. | 7 // Tests of Http2FrameDecoder. |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | |
| 13 #include "base/bind_helpers.h" | |
| 14 #include "base/logging.h" | 12 #include "base/logging.h" |
| 15 #include "net/http2/decoder/frame_parts.h" | 13 #include "net/http2/decoder/frame_parts.h" |
| 16 #include "net/http2/decoder/frame_parts_collector_listener.h" | 14 #include "net/http2/decoder/frame_parts_collector_listener.h" |
| 17 #include "net/http2/http2_constants.h" | 15 #include "net/http2/http2_constants.h" |
| 18 #include "net/http2/tools/failure.h" | 16 #include "net/http2/tools/failure.h" |
| 19 #include "net/http2/tools/http2_random.h" | 17 #include "net/http2/tools/http2_random.h" |
| 20 #include "net/http2/tools/random_decoder_test.h" | 18 #include "net/http2/tools/random_decoder_test.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 20 |
| 23 using base::StringPiece; | 21 using base::StringPiece; |
| 24 using std::string; | 22 using std::string; |
| 25 using ::testing::AssertionResult; | 23 using ::testing::AssertionResult; |
| 26 using ::testing::AssertionSuccess; | 24 using ::testing::AssertionSuccess; |
| 27 | 25 |
| 28 namespace net { | 26 namespace net { |
| 29 namespace test { | 27 namespace test { |
| 30 class Http2FrameDecoderPeer { | 28 class Http2FrameDecoderPeer { |
| 31 public: | 29 public: |
| 32 static size_t remaining_total_payload(Http2FrameDecoder* decoder) { | 30 static size_t remaining_total_payload(Http2FrameDecoder* decoder) { |
| 33 return decoder->frame_decoder_state_.remaining_total_payload(); | 31 return decoder->frame_decoder_state_.remaining_total_payload(); |
| 34 } | 32 } |
| 35 }; | 33 }; |
| 36 | 34 |
| 37 namespace { | 35 namespace { |
| 38 | 36 |
| 39 class Http2FrameDecoderTest : public RandomDecoderTest { | 37 class Http2FrameDecoderTest : public RandomDecoderTest { |
| 40 public: | |
| 41 AssertionResult ValidatorForDecodePayloadExpectingError( | |
| 42 const FrameParts& expected, | |
| 43 const DecodeBuffer& input, | |
| 44 DecodeStatus status) { | |
| 45 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
| 46 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
| 47 } | |
| 48 | |
| 49 AssertionResult ValidatorForBeyondMaximum(const FrameParts& expected, | |
| 50 const DecodeBuffer& input, | |
| 51 DecodeStatus status) { | |
| 52 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
| 53 // The decoder detects this error after decoding the header, and without | |
| 54 // trying to decode the payload. | |
| 55 VERIFY_EQ(input.Offset(), Http2FrameHeader::EncodedSize()); | |
| 56 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
| 57 } | |
| 58 | 38 |
| 59 protected: | 39 protected: |
| 60 void SetUp() override { | 40 void SetUp() override { |
| 61 // On any one run of this suite, we'll always choose the same value for | 41 // On any one run of this suite, we'll always choose the same value for |
| 62 // use_default_reconstruct_ because the random seed is the same for each | 42 // use_default_reconstruct_ because the random seed is the same for each |
| 63 // test case, but across runs the random seed changes. | 43 // test case, but across runs the random seed changes. |
| 64 use_default_reconstruct_ = Random().OneIn(2); | 44 use_default_reconstruct_ = Random().OneIn(2); |
| 65 } | 45 } |
| 66 | 46 |
| 67 DecodeStatus StartDecoding(DecodeBuffer* db) override { | 47 DecodeStatus StartDecoding(DecodeBuffer* db) override { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 } | 124 } |
| 145 | 125 |
| 146 AssertionResult DecodePayloadAndValidateSeveralWays(StringPiece payload, | 126 AssertionResult DecodePayloadAndValidateSeveralWays(StringPiece payload, |
| 147 Validator validator) { | 127 Validator validator) { |
| 148 DecodeBuffer db(payload); | 128 DecodeBuffer db(payload); |
| 149 bool start_decoding_requires_non_empty = false; | 129 bool start_decoding_requires_non_empty = false; |
| 150 return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty, | 130 return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty, |
| 151 validator); | 131 validator); |
| 152 } | 132 } |
| 153 | 133 |
| 154 AssertionResult ValidatorForDecodePayloadAndValidateSeveralWays( | |
| 155 const FrameParts& expected, | |
| 156 const DecodeBuffer& input, | |
| 157 DecodeStatus status) { | |
| 158 VERIFY_EQ(status, DecodeStatus::kDecodeDone); | |
| 159 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
| 160 } | |
| 161 | 134 |
| 162 // Decode one frame's payload and confirm that the listener recorded the | 135 // Decode one frame's payload and confirm that the listener recorded the |
| 163 // expected FrameParts instance, and only one FrameParts instance. The | 136 // expected FrameParts instance, and only one FrameParts instance. The |
| 164 // payload will be decoded several times with different partitionings | 137 // payload will be decoded several times with different partitionings |
| 165 // of the payload, and after each the validator will be called. | 138 // of the payload, and after each the validator will be called. |
| 166 AssertionResult DecodePayloadAndValidateSeveralWays( | 139 AssertionResult DecodePayloadAndValidateSeveralWays( |
| 167 StringPiece payload, | 140 StringPiece payload, |
| 168 const FrameParts& expected) { | 141 const FrameParts& expected) { |
| 169 Validator validator = base::Bind( | 142 Validator validator = [&expected, this]( |
|
James Synge
2017/01/05 21:39:06
I'm curious why "auto validator" became "Validator
Bence
2017/01/06 01:42:40
If I use auto here, I get the compile error below.
| |
| 170 &Http2FrameDecoderTest::ValidatorForDecodePayloadAndValidateSeveralWays, | 143 const DecodeBuffer& input, DecodeStatus status) -> AssertionResult { |
| 171 base::Unretained(this), base::ConstRef(expected)); | 144 VERIFY_EQ(status, DecodeStatus::kDecodeDone); |
| 145 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
| 146 }; | |
| 172 ResetDecodeSpeedCounters(); | 147 ResetDecodeSpeedCounters(); |
| 173 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays( | 148 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays( |
| 174 payload, ValidateDoneAndEmpty(validator))); | 149 payload, ValidateDoneAndEmpty(validator))); |
| 175 VERIFY_GT(fast_decode_count_, 0u); | 150 VERIFY_GT(fast_decode_count_, 0u); |
| 176 VERIFY_GT(slow_decode_count_, 0u); | 151 VERIFY_GT(slow_decode_count_, 0u); |
| 177 | 152 |
| 178 // Repeat with more input; it should stop without reading that input. | 153 // Repeat with more input; it should stop without reading that input. |
| 179 string next_frame = Random().RandString(10); | 154 string next_frame = Random().RandString(10); |
| 180 string input; | 155 string input; |
| 181 payload.AppendToString(&input); | 156 payload.AppendToString(&input); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 201 AssertionResult DecodePayloadAndValidateSeveralWays( | 176 AssertionResult DecodePayloadAndValidateSeveralWays( |
| 202 const char (&buf)[N], | 177 const char (&buf)[N], |
| 203 const Http2FrameHeader& header) { | 178 const Http2FrameHeader& header) { |
| 204 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N), | 179 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N), |
| 205 FrameParts(header)); | 180 FrameParts(header)); |
| 206 } | 181 } |
| 207 | 182 |
| 208 template <size_t N> | 183 template <size_t N> |
| 209 AssertionResult DecodePayloadExpectingError(const char (&buf)[N], | 184 AssertionResult DecodePayloadExpectingError(const char (&buf)[N], |
| 210 const FrameParts& expected) { | 185 const FrameParts& expected) { |
| 186 auto validator = [&expected, this](const DecodeBuffer& input, | |
| 187 DecodeStatus status) -> AssertionResult { | |
| 188 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
| 189 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
| 190 }; | |
| 211 ResetDecodeSpeedCounters(); | 191 ResetDecodeSpeedCounters(); |
| 212 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays( | 192 EXPECT_TRUE( |
| 213 ToStringPiece(buf), | 193 DecodePayloadAndValidateSeveralWays(ToStringPiece(buf), validator)); |
| 214 base::Bind( | |
| 215 &Http2FrameDecoderTest::ValidatorForDecodePayloadExpectingError, | |
| 216 base::Unretained(this), expected))); | |
| 217 EXPECT_GT(fast_decode_count_, 0u); | 194 EXPECT_GT(fast_decode_count_, 0u); |
| 218 EXPECT_GT(slow_decode_count_, 0u); | 195 EXPECT_GT(slow_decode_count_, 0u); |
| 219 return AssertionSuccess(); | 196 return AssertionSuccess(); |
| 220 } | 197 } |
| 221 | 198 |
| 222 template <size_t N> | 199 template <size_t N> |
| 223 AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N], | 200 AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N], |
| 224 FrameParts expected) { | 201 FrameParts expected) { |
| 225 expected.has_frame_size_error = true; | 202 expected.has_frame_size_error = true; |
| 226 VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected)); | 203 VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected)); |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) | 834 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) |
| 858 0x03, // Pad Len | 835 0x03, // Pad Len |
| 859 'a', 'b', 'c', // Data | 836 'a', 'b', 'c', // Data |
| 860 0x00, 0x00, 0x00, // Padding | 837 0x00, 0x00, 0x00, // Padding |
| 861 }; | 838 }; |
| 862 Http2FrameHeader header( | 839 Http2FrameHeader header( |
| 863 7, Http2FrameType::DATA, | 840 7, Http2FrameType::DATA, |
| 864 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2); | 841 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2); |
| 865 FrameParts expected(header); | 842 FrameParts expected(header); |
| 866 expected.has_frame_size_error = true; | 843 expected.has_frame_size_error = true; |
| 844 auto validator = [&expected, this](const DecodeBuffer& input, | |
| 845 DecodeStatus status) -> AssertionResult { | |
| 846 VERIFY_EQ(status, DecodeStatus::kDecodeError); | |
| 847 // The decoder detects this error after decoding the header, and without | |
| 848 // trying to decode the payload. | |
| 849 VERIFY_EQ(input.Offset(), Http2FrameHeader::EncodedSize()); | |
| 850 VERIFY_AND_RETURN_SUCCESS(VerifyCollected(expected)); | |
| 851 }; | |
| 867 ResetDecodeSpeedCounters(); | 852 ResetDecodeSpeedCounters(); |
| 868 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays( | 853 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(ToStringPiece(kFrameData), |
| 869 ToStringPiece(kFrameData), | 854 validator)); |
| 870 base::Bind(&Http2FrameDecoderTest::ValidatorForBeyondMaximum, | |
| 871 base::Unretained(this), expected))); | |
| 872 EXPECT_GT(fast_decode_count_, 0u); | 855 EXPECT_GT(fast_decode_count_, 0u); |
| 873 EXPECT_GT(slow_decode_count_, 0u); | 856 EXPECT_GT(slow_decode_count_, 0u); |
| 874 } | 857 } |
| 875 | 858 |
| 876 TEST_F(Http2FrameDecoderTest, PriorityTooLong) { | 859 TEST_F(Http2FrameDecoderTest, PriorityTooLong) { |
| 877 const char kFrameData[] = { | 860 const char kFrameData[] = { |
| 878 0x00, 0x00, 0x06, // Length: 5 | 861 0x00, 0x00, 0x06, // Length: 5 |
| 879 0x02, // Type: PRIORITY | 862 0x02, // Type: PRIORITY |
| 880 0x00, // Flags: none | 863 0x00, // Flags: none |
| 881 0x00, 0x00, 0x00, 0x02, // Stream: 2 | 864 0x00, 0x00, 0x00, 0x02, // Stream: 2 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 937 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit) | 920 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit) |
| 938 0x00, // Too much | 921 0x00, // Too much |
| 939 }; | 922 }; |
| 940 Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1); | 923 Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1); |
| 941 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | 924 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); |
| 942 } | 925 } |
| 943 | 926 |
| 944 } // namespace | 927 } // namespace |
| 945 } // namespace test | 928 } // namespace test |
| 946 } // namespace net | 929 } // namespace net |
| OLD | NEW |