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