OLD | NEW |
(Empty) | |
| 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 #ifndef NET_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_ |
| 6 #define NET_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_ |
| 7 |
| 8 // Base class for testing concrete payload decoder classes. |
| 9 |
| 10 #include <stddef.h> |
| 11 |
| 12 #include <string> |
| 13 |
| 14 #include "base/bind.h" |
| 15 #include "base/bind_helpers.h" |
| 16 #include "base/callback.h" |
| 17 #include "base/logging.h" |
| 18 #include "base/strings/string_piece.h" |
| 19 #include "net/http2/decoder/decode_buffer.h" |
| 20 #include "net/http2/decoder/decode_status.h" |
| 21 #include "net/http2/decoder/frame_decoder_state.h" |
| 22 #include "net/http2/decoder/frame_parts.h" |
| 23 #include "net/http2/decoder/http2_frame_decoder_listener.h" |
| 24 #include "net/http2/http2_constants.h" |
| 25 #include "net/http2/http2_constants_test_util.h" |
| 26 #include "net/http2/http2_structures.h" |
| 27 #include "net/http2/tools/http2_frame_builder.h" |
| 28 #include "net/http2/tools/random_decoder_test.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" |
| 30 |
| 31 namespace net { |
| 32 namespace test { |
| 33 |
| 34 // Base class for tests of payload decoders. Below this there is a templated |
| 35 // sub-class that adds a bunch of type specific features. |
| 36 class PayloadDecoderBaseTest : public RandomDecoderTest { |
| 37 protected: |
| 38 PayloadDecoderBaseTest(); |
| 39 |
| 40 // Virtual functions to be implemented by the test classes for the individual |
| 41 // payload decoders... |
| 42 |
| 43 // Start decoding the payload. |
| 44 virtual DecodeStatus StartDecodingPayload(DecodeBuffer* db) = 0; |
| 45 |
| 46 // Resume decoding the payload. |
| 47 virtual DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) = 0; |
| 48 |
| 49 // In support of ensuring that we're really accessing and updating the |
| 50 // decoder, prepare the decoder by, for example, overwriting the decoder. |
| 51 virtual void PreparePayloadDecoder() = 0; |
| 52 |
| 53 // Get the listener to be inserted into the FrameDecoderState, ready for |
| 54 // listening (e.g. reset if it is a FramePartsCollector). |
| 55 virtual Http2FrameDecoderListener* PrepareListener() = 0; |
| 56 |
| 57 // Record a frame header for use on each call to StartDecoding. |
| 58 void set_frame_header(const Http2FrameHeader& header) { |
| 59 EXPECT_EQ(0, InvalidFlagMaskForFrameType(header.type) & header.flags); |
| 60 if (!frame_header_is_set_ || frame_header_ != header) { |
| 61 VLOG(2) << "set_frame_header: " << frame_header_; |
| 62 } |
| 63 frame_header_ = header; |
| 64 frame_header_is_set_ = true; |
| 65 } |
| 66 |
| 67 const Http2FrameHeader& frame_header() const { |
| 68 CHECK(frame_header_is_set_); |
| 69 return frame_header_; |
| 70 } |
| 71 |
| 72 FrameDecoderState* mutable_state() { return &frame_decoder_state_; } |
| 73 |
| 74 // Randomize the payload decoder, sets the payload decoder's frame_header_, |
| 75 // then start decoding the payload. Called by RandomDecoderTest. This method |
| 76 // is final so that we can always perform certain actions when |
| 77 // RandomDecoderTest starts the decoding of a payload, such as randomizing the |
| 78 // the payload decoder, injecting the frame header and counting fast decoding |
| 79 // cases. Sub-classes must implement StartDecodingPayload to perform their |
| 80 // initial decoding of a frame's payload. |
| 81 DecodeStatus StartDecoding(DecodeBuffer* db) final; |
| 82 |
| 83 // Called by RandomDecoderTest. This method is final so that we can always |
| 84 // perform certain actions when RandomDecoderTest calls it, such as counting |
| 85 // slow decode cases. Sub-classes must implement ResumeDecodingPayload to |
| 86 // continue decoding the frame's payload, which must not all be in one buffer. |
| 87 DecodeStatus ResumeDecoding(DecodeBuffer* db) final; |
| 88 |
| 89 // Given the specified payload (without the common frame header), decode |
| 90 // it with several partitionings of the payload. |
| 91 ::testing::AssertionResult DecodePayloadAndValidateSeveralWays( |
| 92 base::StringPiece payload, |
| 93 Validator validator); |
| 94 |
| 95 // TODO(jamessynge): Add helper method for verifying these are both non-zero, |
| 96 // and call the new method from tests that expect successful decoding. |
| 97 void ResetDecodeSpeedCounters() { |
| 98 fast_decode_count_ = 0; |
| 99 slow_decode_count_ = 0; |
| 100 } |
| 101 |
| 102 // Count of payloads that are full decoded by StartDecodingPayload, or that |
| 103 // an error was detected by StartDecodingPayload. |
| 104 size_t fast_decode_count_ = 0; |
| 105 |
| 106 // Count of payloads that require calling ResumeDecodingPayload in order to |
| 107 // decode them completely (or to detect an error during decoding). |
| 108 size_t slow_decode_count_ = 0; |
| 109 |
| 110 private: |
| 111 bool frame_header_is_set_ = false; |
| 112 Http2FrameHeader frame_header_; |
| 113 FrameDecoderState frame_decoder_state_; |
| 114 }; |
| 115 |
| 116 // Base class for payload decoders of type Decoder, with corresponding test |
| 117 // peer of type DecoderPeer, and using class Listener as the implementation |
| 118 // of Http2FrameDecoderListenerInterface to be used during decoding. |
| 119 // Typically Listener is a sub-class of FramePartsCollector. |
| 120 // SupportedFrameType is set to false only for UnknownPayloadDecoder. |
| 121 template <class Decoder, |
| 122 class DecoderPeer, |
| 123 class Listener, |
| 124 bool SupportedFrameType = true> |
| 125 class AbstractPayloadDecoderTest : public PayloadDecoderBaseTest { |
| 126 public: |
| 127 static bool SucceedingApproveSize(size_t size) { return true; } |
| 128 |
| 129 protected: |
| 130 // An ApproveSize function returns true to approve decoding the specified |
| 131 // size of payload, else false to skip that size. Typically used for negative |
| 132 // tests; for example, decoding a SETTINGS frame at all sizes except for |
| 133 // multiples of 6. |
| 134 typedef base::Callback<bool(size_t size)> ApproveSize; |
| 135 |
| 136 AbstractPayloadDecoderTest() {} |
| 137 |
| 138 // These tests are in setup rather than the constructor for two reasons: |
| 139 // 1) Constructors are not allowed to fail, so gUnit documents that EXPECT_* |
| 140 // and ASSERT_* are not allowed in constructors, and should instead be in |
| 141 // SetUp if they are needed before the body of the test is executed. |
| 142 // 2) To allow the sub-class constructor to make any desired modifications to |
| 143 // the DecoderPeer before these tests are executed; in particular, |
| 144 // UnknownPayloadDecoderPeer has not got a fixed frame type, but it is |
| 145 // instead set during the test's constructor. |
| 146 void SetUp() override { |
| 147 PayloadDecoderBaseTest::SetUp(); |
| 148 |
| 149 // Confirm that DecoderPeer et al returns sensible values. Using auto as the |
| 150 // variable type so that no (narrowing) conversions take place that hide |
| 151 // problems; i.e. if someone changes KnownFlagsMaskForFrameType so that it |
| 152 // doesn't return a uint8, and has bits above the low-order 8 bits set, this |
| 153 // bit of paranoia should detect the problem before we get too far. |
| 154 auto frame_type = DecoderPeer::FrameType(); |
| 155 if (SupportedFrameType) { |
| 156 EXPECT_TRUE(IsSupportedHttp2FrameType(frame_type)) << frame_type; |
| 157 } else { |
| 158 EXPECT_FALSE(IsSupportedHttp2FrameType(frame_type)) << frame_type; |
| 159 } |
| 160 |
| 161 auto known_flags = KnownFlagsMaskForFrameType(frame_type); |
| 162 EXPECT_EQ(known_flags, known_flags & 0xff); |
| 163 |
| 164 auto flags_to_avoid = DecoderPeer::FlagsAffectingPayloadDecoding(); |
| 165 EXPECT_EQ(flags_to_avoid, flags_to_avoid & known_flags); |
| 166 } |
| 167 |
| 168 void PreparePayloadDecoder() override { |
| 169 payload_decoder_.~Decoder(); |
| 170 new (&payload_decoder_) Decoder; |
| 171 } |
| 172 |
| 173 Http2FrameDecoderListener* PrepareListener() override { |
| 174 listener_.Reset(); |
| 175 return &listener_; |
| 176 } |
| 177 |
| 178 // Returns random flags, but only those valid for the frame type, yet not |
| 179 // those that the DecoderPeer says will affect the decoding of the payload |
| 180 // (e.g. the PRIORTY flag on a HEADERS frame or PADDED on DATA frames). |
| 181 uint8_t RandFlags() { |
| 182 return Random().Rand8() & |
| 183 KnownFlagsMaskForFrameType(DecoderPeer::FrameType()) & |
| 184 ~DecoderPeer::FlagsAffectingPayloadDecoding(); |
| 185 } |
| 186 |
| 187 // Start decoding the payload. |
| 188 DecodeStatus StartDecodingPayload(DecodeBuffer* db) override { |
| 189 DVLOG(2) << "StartDecodingPayload, db->Remaining=" << db->Remaining(); |
| 190 return payload_decoder_.StartDecodingPayload(mutable_state(), db); |
| 191 } |
| 192 |
| 193 // Resume decoding the payload. |
| 194 DecodeStatus ResumeDecodingPayload(DecodeBuffer* db) override { |
| 195 DVLOG(2) << "ResumeDecodingPayload, db->Remaining=" << db->Remaining(); |
| 196 return payload_decoder_.ResumeDecodingPayload(mutable_state(), db); |
| 197 } |
| 198 |
| 199 // Wrap |validator| in another one which will check that we've reached the |
| 200 // expected state of kDecodeError with OnFrameSizeError having been called by |
| 201 AssertionResult ValidatorForDecodePayloadAndValidateSeveralWays( |
| 202 const FrameParts& expected) { |
| 203 VERIFY_FALSE(listener_.IsInProgress()); |
| 204 VERIFY_EQ(1u, listener_.size()); |
| 205 VERIFY_AND_RETURN_SUCCESS(expected.VerifyEquals(*listener_.frame(0))); |
| 206 } |
| 207 |
| 208 // Decode one frame's payload and confirm that the listener recorded the |
| 209 // expected FrameParts instance, and only FrameParts instance. The payload |
| 210 // will be decoded several times with different partitionings of the payload, |
| 211 // and after each the validator will be called. |
| 212 AssertionResult DecodePayloadAndValidateSeveralWays( |
| 213 base::StringPiece payload, |
| 214 const FrameParts& expected) { |
| 215 return PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays( |
| 216 payload, this->ValidateDoneAndEmpty(base::Bind( |
| 217 &AbstractPayloadDecoderTest:: |
| 218 ValidatorForDecodePayloadAndValidateSeveralWays, |
| 219 base::Unretained(this), base::ConstRef(expected)))); |
| 220 } |
| 221 |
| 222 // Wrap |validator| in another one which will check that we've reached the |
| 223 // expected state of kDecodeError with OnFrameSizeError having been called by |
| 224 // the payload decoder. |
| 225 AssertionResult ValidatorForVerifyDetectsFrameSizeError( |
| 226 const Http2FrameHeader& header, |
| 227 const Validator& validator, |
| 228 const DecodeBuffer& input, |
| 229 DecodeStatus status) { |
| 230 DVLOG(2) << "VerifyDetectsFrameSizeError validator; status=" << status |
| 231 << "; input.Remaining=" << input.Remaining(); |
| 232 VERIFY_EQ(DecodeStatus::kDecodeError, status); |
| 233 VERIFY_FALSE(listener_.IsInProgress()); |
| 234 VERIFY_EQ(1u, listener_.size()); |
| 235 const FrameParts* frame = listener_.frame(0); |
| 236 VERIFY_EQ(header, frame->frame_header); |
| 237 VERIFY_TRUE(frame->has_frame_size_error); |
| 238 // Verify did not get OnPaddingTooLong, as we should only ever produce |
| 239 // one of these two errors for a single frame. |
| 240 VERIFY_FALSE(frame->opt_missing_length); |
| 241 return validator.Run(input, status); |
| 242 } |
| 243 |
| 244 // Decode one frame's payload, expecting that the final status will be |
| 245 // kDecodeError, and that OnFrameSizeError will have been called on the |
| 246 // listener. The payload will be decoded several times with different |
| 247 // partitionings of the payload. The type WrappedValidator is either |
| 248 // RandomDecoderTest::Validator, RandomDecoderTest::NoArgValidator or |
| 249 // std::nullptr_t (not extra validation). |
| 250 template <typename WrappedValidator> |
| 251 ::testing::AssertionResult VerifyDetectsFrameSizeError( |
| 252 base::StringPiece payload, |
| 253 const Http2FrameHeader& header, |
| 254 WrappedValidator wrapped_validator) { |
| 255 set_frame_header(header); |
| 256 // If wrapped_validator is not a RandomDecoderTest::Validator, make it so. |
| 257 Validator validator = this->ToValidator(wrapped_validator); |
| 258 VERIFY_AND_RETURN_SUCCESS( |
| 259 PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays( |
| 260 payload, base::Bind(&AbstractPayloadDecoderTest:: |
| 261 ValidatorForVerifyDetectsFrameSizeError, |
| 262 base::Unretained(this), base::ConstRef(header), |
| 263 base::ConstRef(validator)))); |
| 264 } |
| 265 |
| 266 // Confirm that we get OnFrameSizeError when trying to decode unpadded_payload |
| 267 // at all sizes from zero to unpadded_payload.size(), except those sizes not |
| 268 // approved by approve_size. |
| 269 // If total_pad_length is greater than zero, then that amount of padding |
| 270 // is added to the payload (including the Pad Length field). |
| 271 // The flags will be required_flags, PADDED if total_pad_length > 0, and some |
| 272 // randomly selected flag bits not excluded by FlagsAffectingPayloadDecoding. |
| 273 ::testing::AssertionResult VerifyDetectsMultipleFrameSizeErrors( |
| 274 uint8_t required_flags, |
| 275 base::StringPiece unpadded_payload, |
| 276 ApproveSize approve_size, |
| 277 int total_pad_length) { |
| 278 // required_flags should come from those that are defined for the frame |
| 279 // type AND are those that affect the decoding of the payload (otherwise, |
| 280 // the flag shouldn't be required). |
| 281 Http2FrameType frame_type = DecoderPeer::FrameType(); |
| 282 VERIFY_EQ(required_flags, |
| 283 required_flags & KnownFlagsMaskForFrameType(frame_type)); |
| 284 VERIFY_EQ(required_flags, |
| 285 required_flags & DecoderPeer::FlagsAffectingPayloadDecoding()); |
| 286 |
| 287 if (0 != (Http2FrameFlag::FLAG_PADDED & |
| 288 KnownFlagsMaskForFrameType(frame_type))) { |
| 289 // Frame type supports padding. |
| 290 if (total_pad_length == 0) { |
| 291 required_flags &= ~Http2FrameFlag::FLAG_PADDED; |
| 292 } else { |
| 293 required_flags |= Http2FrameFlag::FLAG_PADDED; |
| 294 } |
| 295 } else { |
| 296 VERIFY_EQ(0, total_pad_length); |
| 297 } |
| 298 |
| 299 bool validated = false; |
| 300 for (size_t real_payload_size = 0; |
| 301 real_payload_size <= unpadded_payload.size(); ++real_payload_size) { |
| 302 if (!approve_size.Run(real_payload_size)) { |
| 303 continue; |
| 304 } |
| 305 VLOG(1) << "real_payload_size=" << real_payload_size; |
| 306 uint8_t flags = required_flags | RandFlags(); |
| 307 Http2FrameBuilder fb; |
| 308 if (total_pad_length > 0) { |
| 309 // total_pad_length_ includes the size of the Pad Length field, and thus |
| 310 // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255). |
| 311 fb.AppendUInt8(total_pad_length - 1); |
| 312 } |
| 313 // Append a subset of the unpadded_payload, which the decoder should |
| 314 // determine is not a valid amount. |
| 315 fb.Append(unpadded_payload.substr(0, real_payload_size)); |
| 316 if (total_pad_length > 0) { |
| 317 fb.AppendZeroes(total_pad_length - 1); |
| 318 } |
| 319 // We choose a random stream id because the payload decoders aren't |
| 320 // checking stream ids. |
| 321 uint32_t stream_id = RandStreamId(); |
| 322 Http2FrameHeader header(fb.size(), frame_type, flags, stream_id); |
| 323 VERIFY_SUCCESS(VerifyDetectsFrameSizeError( |
| 324 fb.buffer(), header, base::Bind(&SucceedingValidator))); |
| 325 validated = true; |
| 326 } |
| 327 VERIFY_TRUE(validated); |
| 328 return ::testing::AssertionSuccess(); |
| 329 } |
| 330 |
| 331 // As above, but for frames without padding. |
| 332 ::testing::AssertionResult VerifyDetectsFrameSizeError( |
| 333 uint8_t required_flags, |
| 334 base::StringPiece unpadded_payload, |
| 335 ApproveSize approve_size) { |
| 336 Http2FrameType frame_type = DecoderPeer::FrameType(); |
| 337 uint8_t known_flags = KnownFlagsMaskForFrameType(frame_type); |
| 338 VERIFY_EQ(0, known_flags & Http2FrameFlag::FLAG_PADDED); |
| 339 VERIFY_EQ(0, required_flags & Http2FrameFlag::FLAG_PADDED); |
| 340 VERIFY_AND_RETURN_SUCCESS(VerifyDetectsMultipleFrameSizeErrors( |
| 341 required_flags, unpadded_payload, approve_size, 0)); |
| 342 } |
| 343 |
| 344 Listener listener_; |
| 345 union { |
| 346 // Confirm at compile time that Decoder can be in an anonymous union, |
| 347 // i.e. complain loudly if Decoder has members that prevent this, as it |
| 348 // becomes annoying and possibly difficult to deal with non-anonymous |
| 349 // unions and such union members. |
| 350 Decoder payload_decoder_; |
| 351 }; |
| 352 }; |
| 353 |
| 354 // A base class for tests parameterized by the total number of bytes of |
| 355 // padding, including the Pad Length field (i.e. a total_pad_length of 0 |
| 356 // means unpadded as there is then no room for the Pad Length field). |
| 357 // The frame type must support padding. |
| 358 template <class Decoder, class DecoderPeer, class Listener> |
| 359 class AbstractPaddablePayloadDecoderTest |
| 360 : public AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener>, |
| 361 public ::testing::WithParamInterface<int> { |
| 362 typedef AbstractPayloadDecoderTest<Decoder, DecoderPeer, Listener> Base; |
| 363 |
| 364 protected: |
| 365 using Base::Random; |
| 366 using Base::RandStreamId; |
| 367 using Base::set_frame_header; |
| 368 using Base::listener_; |
| 369 typedef typename Base::Validator Validator; |
| 370 |
| 371 AbstractPaddablePayloadDecoderTest() : total_pad_length_(GetParam()) { |
| 372 LOG(INFO) << "total_pad_length_ = " << total_pad_length_; |
| 373 } |
| 374 |
| 375 // Note that total_pad_length_ includes the size of the Pad Length field, |
| 376 // and thus ranges from 0 (no PADDED flag) to 256 (Pad Length == 255). |
| 377 bool IsPadded() const { return total_pad_length_ > 0; } |
| 378 |
| 379 // Value of the Pad Length field. Only call if IsPadded. |
| 380 size_t pad_length() const { |
| 381 EXPECT_TRUE(IsPadded()); |
| 382 return total_pad_length_ - 1; |
| 383 } |
| 384 |
| 385 // Clear the frame builder and add the Pad Length field if appropriate. |
| 386 void Reset() { |
| 387 frame_builder_ = Http2FrameBuilder(); |
| 388 if (IsPadded()) { |
| 389 frame_builder_.AppendUInt8(pad_length()); |
| 390 } |
| 391 } |
| 392 |
| 393 void MaybeAppendTrailingPadding() { |
| 394 if (IsPadded()) { |
| 395 frame_builder_.AppendZeroes(pad_length()); |
| 396 } |
| 397 } |
| 398 |
| 399 uint8_t RandFlags() { |
| 400 uint8_t flags = Base::RandFlags(); |
| 401 if (IsPadded()) { |
| 402 flags |= Http2FrameFlag::FLAG_PADDED; |
| 403 } else { |
| 404 flags &= ~Http2FrameFlag::FLAG_PADDED; |
| 405 } |
| 406 return flags; |
| 407 } |
| 408 |
| 409 static ::testing::AssertionResult ValidatorForVerifyDetectsPaddingTooLong( |
| 410 const Http2FrameHeader& header, |
| 411 int expected_missing_length, |
| 412 const Listener& listener, |
| 413 const DecodeBuffer& input, |
| 414 DecodeStatus status) { |
| 415 VERIFY_EQ(DecodeStatus::kDecodeError, status); |
| 416 VERIFY_FALSE(listener.IsInProgress()); |
| 417 VERIFY_EQ(1u, listener.size()); |
| 418 const FrameParts* frame = listener.frame(0); |
| 419 VERIFY_EQ(header, frame->frame_header); |
| 420 VERIFY_TRUE(frame->opt_missing_length); |
| 421 VERIFY_EQ(expected_missing_length, frame->opt_missing_length.value()); |
| 422 // Verify did not get OnFrameSizeError. |
| 423 VERIFY_FALSE(frame->has_frame_size_error); |
| 424 return ::testing::AssertionSuccess(); |
| 425 } |
| 426 |
| 427 // Verify that we get OnPaddingTooLong when decoding payload, and that the |
| 428 // amount of missing padding is as specified. header.IsPadded must be true, |
| 429 // and the payload must be empty or the PadLength field must be too large. |
| 430 ::testing::AssertionResult VerifyDetectsPaddingTooLong( |
| 431 base::StringPiece payload, |
| 432 const Http2FrameHeader& header, |
| 433 int expected_missing_length) { |
| 434 set_frame_header(header); |
| 435 auto& listener = listener_; |
| 436 VERIFY_AND_RETURN_SUCCESS( |
| 437 PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays( |
| 438 payload, base::Bind(&AbstractPaddablePayloadDecoderTest:: |
| 439 ValidatorForVerifyDetectsPaddingTooLong, |
| 440 header, expected_missing_length, |
| 441 base::ConstRef(listener)))); |
| 442 } |
| 443 |
| 444 // Verifies that we get OnPaddingTooLong for a padded frame payload whose |
| 445 // (randomly selected) payload length is less than total_pad_length_. |
| 446 // Flags will be selected at random, except PADDED will be set and |
| 447 // flags_to_avoid will not be set. The stream id is selected at random. |
| 448 ::testing::AssertionResult VerifyDetectsPaddingTooLong() { |
| 449 uint8_t flags = RandFlags() | Http2FrameFlag::FLAG_PADDED; |
| 450 |
| 451 // Create an all padding payload for total_pad_length_. |
| 452 int payload_length = 0; |
| 453 Http2FrameBuilder fb; |
| 454 if (IsPadded()) { |
| 455 fb.AppendUInt8(pad_length()); |
| 456 fb.AppendZeroes(pad_length()); |
| 457 VLOG(1) << "fb.size=" << fb.size(); |
| 458 // Pick a random length for the payload that is shorter than neccesary. |
| 459 payload_length = Random().Rand32() % fb.size(); |
| 460 } |
| 461 |
| 462 VLOG(1) << "payload_length=" << payload_length; |
| 463 std::string payload = fb.buffer().substr(0, payload_length); |
| 464 |
| 465 // The missing length is the amount we cut off the end, unless |
| 466 // payload_length is zero, in which case the decoder knows only that 1 |
| 467 // byte, the Pad Length field, is missing. |
| 468 int missing_length = payload_length == 0 ? 1 : fb.size() - payload_length; |
| 469 VLOG(1) << "missing_length=" << missing_length; |
| 470 |
| 471 const Http2FrameHeader header(payload_length, DecoderPeer::FrameType(), |
| 472 flags, RandStreamId()); |
| 473 VERIFY_AND_RETURN_SUCCESS( |
| 474 VerifyDetectsPaddingTooLong(payload, header, missing_length)); |
| 475 } |
| 476 |
| 477 // total_pad_length_ includes the size of the Pad Length field, and thus |
| 478 // ranges from 0 (no PADDED flag) to 256 (Pad Length == 255). |
| 479 const size_t total_pad_length_; |
| 480 Http2FrameBuilder frame_builder_; |
| 481 }; |
| 482 |
| 483 } // namespace test |
| 484 } // namespace net |
| 485 |
| 486 #endif // NET_HTTP2_DECODER_PAYLOAD_DECODERS_PAYLOAD_DECODER_BASE_TEST_UTIL_H_ |
OLD | NEW |