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 #include "net/http2/decoder/http2_frame_decoder.h" | |
6 | |
7 // Tests of Http2FrameDecoder. | |
8 | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/bind.h" | |
13 #include "base/bind_helpers.h" | |
14 #include "base/logging.h" | |
15 #include "net/http2/decoder/frame_parts.h" | |
16 #include "net/http2/decoder/frame_parts_collector_listener.h" | |
17 #include "net/http2/http2_constants.h" | |
18 #include "net/http2/tools/failure.h" | |
19 #include "net/http2/tools/http2_random.h" | |
20 #include "net/http2/tools/random_decoder_test.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | |
22 | |
23 using base::StringPiece; | |
24 using std::string; | |
25 using ::testing::AssertionResult; | |
26 using ::testing::AssertionSuccess; | |
27 | |
28 namespace net { | |
29 namespace test { | |
30 class Http2FrameDecoderPeer { | |
31 public: | |
32 static size_t remaining_total_payload(Http2FrameDecoder* decoder) { | |
33 return decoder->frame_decoder_state_.remaining_total_payload(); | |
34 } | |
35 }; | |
36 | |
37 namespace { | |
38 | |
39 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 | |
59 protected: | |
60 void SetUp() override { | |
61 // 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 | |
63 // test case, but across runs the random seed changes. | |
64 use_default_reconstruct_ = Random().OneIn(2); | |
65 } | |
66 | |
67 DecodeStatus StartDecoding(DecodeBuffer* db) override { | |
68 DVLOG(2) << "StartDecoding, db->Remaining=" << db->Remaining(); | |
69 collector_.Reset(); | |
70 PrepareDecoder(); | |
71 | |
72 DecodeStatus status = decoder_.DecodeFrame(db); | |
73 if (status != DecodeStatus::kDecodeInProgress) { | |
74 // Keep track of this so that a concrete test can verify that both fast | |
75 // and slow decoding paths have been tested. | |
76 ++fast_decode_count_; | |
77 if (status == DecodeStatus::kDecodeError) { | |
78 ConfirmDiscardsRemainingPayload(); | |
79 } | |
80 } | |
81 return status; | |
82 } | |
83 | |
84 DecodeStatus ResumeDecoding(DecodeBuffer* db) override { | |
85 DVLOG(2) << "ResumeDecoding, db->Remaining=" << db->Remaining(); | |
86 DecodeStatus status = decoder_.DecodeFrame(db); | |
87 if (status != DecodeStatus::kDecodeInProgress) { | |
88 // Keep track of this so that a concrete test can verify that both fast | |
89 // and slow decoding paths have been tested. | |
90 ++slow_decode_count_; | |
91 if (status == DecodeStatus::kDecodeError) { | |
92 ConfirmDiscardsRemainingPayload(); | |
93 } | |
94 } | |
95 return status; | |
96 } | |
97 | |
98 // When an error is returned, the decoder is in state kDiscardPayload, and | |
99 // stays there until the remaining bytes of the frame's payload have been | |
100 // skipped over. There are no callbacks for this situation. | |
101 void ConfirmDiscardsRemainingPayload() { | |
102 ASSERT_TRUE(decoder_.IsDiscardingPayload()); | |
103 size_t remaining = | |
104 Http2FrameDecoderPeer::remaining_total_payload(&decoder_); | |
105 // The decoder will discard the remaining bytes, but not go beyond that, | |
106 // which these conditions verify. | |
107 size_t extra = 10; | |
108 string junk(remaining + extra, '0'); | |
109 DecodeBuffer tmp(junk); | |
110 EXPECT_EQ(DecodeStatus::kDecodeDone, decoder_.DecodeFrame(&tmp)); | |
111 EXPECT_EQ(remaining, tmp.Offset()); | |
112 EXPECT_EQ(extra, tmp.Remaining()); | |
113 EXPECT_FALSE(decoder_.IsDiscardingPayload()); | |
114 } | |
115 | |
116 void PrepareDecoder() { | |
117 // Save and restore the maximum_payload_size when reconstructing | |
118 // the decoder. | |
119 size_t maximum_payload_size = decoder_.maximum_payload_size(); | |
120 | |
121 // Alternate which constructor is used. | |
122 if (use_default_reconstruct_) { | |
123 decoder_.~Http2FrameDecoder(); | |
124 new (&decoder_) Http2FrameDecoder; | |
125 decoder_.set_listener(&collector_); | |
126 } else { | |
127 decoder_.~Http2FrameDecoder(); | |
128 new (&decoder_) Http2FrameDecoder(&collector_); | |
129 } | |
130 decoder_.set_maximum_payload_size(maximum_payload_size); | |
131 | |
132 use_default_reconstruct_ = !use_default_reconstruct_; | |
133 } | |
134 | |
135 void ResetDecodeSpeedCounters() { | |
136 fast_decode_count_ = 0; | |
137 slow_decode_count_ = 0; | |
138 } | |
139 | |
140 AssertionResult VerifyCollected(const FrameParts& expected) { | |
141 VERIFY_FALSE(collector_.IsInProgress()); | |
142 VERIFY_EQ(1u, collector_.size()); | |
143 VERIFY_AND_RETURN_SUCCESS(expected.VerifyEquals(*collector_.frame(0))); | |
144 } | |
145 | |
146 AssertionResult DecodePayloadAndValidateSeveralWays(StringPiece payload, | |
147 Validator validator) { | |
148 DecodeBuffer db(payload); | |
149 bool start_decoding_requires_non_empty = false; | |
150 return DecodeAndValidateSeveralWays(&db, start_decoding_requires_non_empty, | |
151 validator); | |
152 } | |
153 | |
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 | |
162 // Decode one frame's payload and confirm that the listener recorded the | |
163 // expected FrameParts instance, and only one FrameParts instance. The | |
164 // payload will be decoded several times with different partitionings | |
165 // of the payload, and after each the validator will be called. | |
166 AssertionResult DecodePayloadAndValidateSeveralWays( | |
167 StringPiece payload, | |
168 const FrameParts& expected) { | |
169 Validator validator = base::Bind( | |
170 &Http2FrameDecoderTest::ValidatorForDecodePayloadAndValidateSeveralWays, | |
171 base::Unretained(this), base::ConstRef(expected)); | |
172 ResetDecodeSpeedCounters(); | |
173 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays( | |
174 payload, ValidateDoneAndEmpty(validator))); | |
175 VERIFY_GT(fast_decode_count_, 0u); | |
176 VERIFY_GT(slow_decode_count_, 0u); | |
177 | |
178 // Repeat with more input; it should stop without reading that input. | |
179 string next_frame = Random().RandString(10); | |
180 string input; | |
181 payload.AppendToString(&input); | |
182 input += next_frame; | |
183 | |
184 ResetDecodeSpeedCounters(); | |
185 VERIFY_SUCCESS(DecodePayloadAndValidateSeveralWays( | |
186 payload, ValidateDoneAndOffset(payload.size(), validator))); | |
187 VERIFY_GT(fast_decode_count_, 0u); | |
188 VERIFY_GT(slow_decode_count_, 0u); | |
189 | |
190 return AssertionSuccess(); | |
191 } | |
192 | |
193 template <size_t N> | |
194 AssertionResult DecodePayloadAndValidateSeveralWays( | |
195 const char (&buf)[N], | |
196 const FrameParts& expected) { | |
197 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N), expected); | |
198 } | |
199 | |
200 template <size_t N> | |
201 AssertionResult DecodePayloadAndValidateSeveralWays( | |
202 const char (&buf)[N], | |
203 const Http2FrameHeader& header) { | |
204 return DecodePayloadAndValidateSeveralWays(StringPiece(buf, N), | |
205 FrameParts(header)); | |
206 } | |
207 | |
208 template <size_t N> | |
209 AssertionResult DecodePayloadExpectingError(const char (&buf)[N], | |
210 const FrameParts& expected) { | |
211 ResetDecodeSpeedCounters(); | |
212 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays( | |
213 ToStringPiece(buf), | |
214 base::Bind( | |
215 &Http2FrameDecoderTest::ValidatorForDecodePayloadExpectingError, | |
216 base::Unretained(this), expected))); | |
217 EXPECT_GT(fast_decode_count_, 0u); | |
218 EXPECT_GT(slow_decode_count_, 0u); | |
219 return AssertionSuccess(); | |
220 } | |
221 | |
222 template <size_t N> | |
223 AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N], | |
224 FrameParts expected) { | |
225 expected.has_frame_size_error = true; | |
226 VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected)); | |
227 } | |
228 | |
229 template <size_t N> | |
230 AssertionResult DecodePayloadExpectingFrameSizeError( | |
231 const char (&buf)[N], | |
232 const Http2FrameHeader& header) { | |
233 return DecodePayloadExpectingFrameSizeError(buf, FrameParts(header)); | |
234 } | |
235 | |
236 // Count of payloads that are fully decoded by StartDecodingPayload or for | |
237 // which an error was detected by StartDecodingPayload. | |
238 size_t fast_decode_count_ = 0; | |
239 | |
240 // Count of payloads that required calling ResumeDecodingPayload in order to | |
241 // decode completely, or for which an error was detected by | |
242 // ResumeDecodingPayload. | |
243 size_t slow_decode_count_ = 0; | |
244 | |
245 FramePartsCollectorListener collector_; | |
246 Http2FrameDecoder decoder_; | |
247 bool use_default_reconstruct_; | |
248 }; | |
249 | |
250 //////////////////////////////////////////////////////////////////////////////// | |
251 // Tests that pass the minimum allowed size for the frame type, which is often | |
252 // empty. The tests are in order by frame type value (i.e. 0 for DATA frames). | |
253 | |
254 TEST_F(Http2FrameDecoderTest, DataEmpty) { | |
255 const char kFrameData[] = { | |
256 0x00, 0x00, 0x00, // Payload length: 0 | |
257 0x00, // DATA | |
258 0x00, // Flags: none | |
259 0x00, 0x00, 0x00, 0x00, // Stream ID: 0 (invalid but unchecked here) | |
260 }; | |
261 Http2FrameHeader header(0, Http2FrameType::DATA, 0, 0); | |
262 FrameParts expected(header, ""); | |
263 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
264 } | |
265 | |
266 TEST_F(Http2FrameDecoderTest, HeadersEmpty) { | |
267 const char kFrameData[] = { | |
268 0x00, 0x00, 0x00, // Payload length: 0 | |
269 0x01, // HEADERS | |
270 0x00, // Flags: none | |
271 0x00, 0x00, 0x00, 0x01, // Stream ID: 0 (REQUIRES ID) | |
272 }; | |
273 Http2FrameHeader header(0, Http2FrameType::HEADERS, 0, 1); | |
274 FrameParts expected(header, ""); | |
275 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
276 } | |
277 | |
278 TEST_F(Http2FrameDecoderTest, Priority) { | |
279 const char kFrameData[] = { | |
280 0x00, 0x00, 0x05, // Length: 5 | |
281 0x02, // Type: PRIORITY | |
282 0x00, // Flags: none | |
283 0x00, 0x00, 0x00, 0x02, // Stream: 2 | |
284 0x80u, 0x00, 0x00, 0x01, // Parent: 1 (Exclusive) | |
285 0x10, // Weight: 17 | |
286 }; | |
287 Http2FrameHeader header(5, Http2FrameType::PRIORITY, 0, 2); | |
288 FrameParts expected(header); | |
289 expected.opt_priority = Http2PriorityFields(1, 17, true); | |
290 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
291 } | |
292 | |
293 TEST_F(Http2FrameDecoderTest, RstStream) { | |
294 const char kFrameData[] = { | |
295 0x00, 0x00, 0x04, // Length: 4 | |
296 0x03, // Type: RST_STREAM | |
297 0x00, // Flags: none | |
298 0x00, 0x00, 0x00, 0x01, // Stream: 1 | |
299 0x00, 0x00, 0x00, 0x01, // Error: PROTOCOL_ERROR | |
300 }; | |
301 Http2FrameHeader header(4, Http2FrameType::RST_STREAM, 0, 1); | |
302 FrameParts expected(header); | |
303 expected.opt_rst_stream_error_code = Http2ErrorCode::PROTOCOL_ERROR; | |
304 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
305 } | |
306 | |
307 TEST_F(Http2FrameDecoderTest, SettingsEmpty) { | |
308 const char kFrameData[] = { | |
309 0x00, 0x00, 0x00, // Length: 0 | |
310 0x04, // Type: SETTINGS | |
311 0x00, // Flags: none | |
312 0x00, 0x00, 0x00, 0x01, // Stream: 1 (invalid but unchecked here) | |
313 }; | |
314 Http2FrameHeader header(0, Http2FrameType::SETTINGS, 0, 1); | |
315 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, header)); | |
316 } | |
317 | |
318 TEST_F(Http2FrameDecoderTest, SettingsAck) { | |
319 const char kFrameData[] = { | |
320 0x00, 0x00, 0x00, // Length: 6 | |
321 0x04, // Type: SETTINGS | |
322 0x01, // Flags: ACK | |
323 0x00, 0x00, 0x00, 0x00, // Stream: 0 | |
324 }; | |
325 Http2FrameHeader header(0, Http2FrameType::SETTINGS, Http2FrameFlag::FLAG_ACK, | |
326 0); | |
327 FrameParts expected(header); | |
328 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
329 } | |
330 | |
331 TEST_F(Http2FrameDecoderTest, PushPromiseMinimal) { | |
332 const char kFrameData[] = { | |
333 0x00, 0x00, 0x04, // Payload length: 4 | |
334 0x05, // PUSH_PROMISE | |
335 0x04, // Flags: END_HEADERS | |
336 0x00, 0x00, 0x00, 0x02, // Stream: 2 (invalid but unchecked here) | |
337 0x00, 0x00, 0x00, 0x01, // Promised: 1 (invalid but unchecked here) | |
338 }; | |
339 Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE, | |
340 Http2FrameFlag::FLAG_END_HEADERS, 2); | |
341 FrameParts expected(header, ""); | |
342 expected.opt_push_promise = Http2PushPromiseFields{1}; | |
343 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
344 } | |
345 | |
346 TEST_F(Http2FrameDecoderTest, Ping) { | |
347 const char kFrameData[] = { | |
348 0x00, 0x00, 0x08, // Length: 8 | |
349 0x06, // Type: PING | |
350 0xfeu, // Flags: no valid flags | |
351 0x00, 0x00, 0x00, 0x00, // Stream: 0 | |
352 's', 'o', 'm', 'e', // "some" | |
353 'd', 'a', 't', 'a', // "data" | |
354 }; | |
355 Http2FrameHeader header(8, Http2FrameType::PING, 0, 0); | |
356 FrameParts expected(header); | |
357 expected.opt_ping = Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}}; | |
358 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
359 } | |
360 | |
361 TEST_F(Http2FrameDecoderTest, PingAck) { | |
362 const char kFrameData[] = { | |
363 0x00, 0x00, 0x08, // Length: 8 | |
364 0x06, // Type: PING | |
365 0xffu, // Flags: ACK (plus all invalid flags) | |
366 0x00, 0x00, 0x00, 0x00, // Stream: 0 | |
367 's', 'o', 'm', 'e', // "some" | |
368 'd', 'a', 't', 'a', // "data" | |
369 }; | |
370 Http2FrameHeader header(8, Http2FrameType::PING, Http2FrameFlag::FLAG_ACK, 0); | |
371 FrameParts expected(header); | |
372 expected.opt_ping = Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}}; | |
373 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
374 } | |
375 | |
376 TEST_F(Http2FrameDecoderTest, GoAwayMinimal) { | |
377 const char kFrameData[] = { | |
378 0x00, 0x00, 0x08, // Length: 8 (no opaque data) | |
379 0x07, // Type: GOAWAY | |
380 0xffu, // Flags: 0xff (no valid flags) | |
381 0x00, 0x00, 0x00, 0x01, // Stream: 1 (invalid but unchecked here) | |
382 0x80u, 0x00, 0x00, 0xffu, // Last: 255 (plus R bit) | |
383 0x00, 0x00, 0x00, 0x09, // Error: COMPRESSION_ERROR | |
384 }; | |
385 Http2FrameHeader header(8, Http2FrameType::GOAWAY, 0, 1); | |
386 FrameParts expected(header); | |
387 expected.opt_goaway = | |
388 Http2GoAwayFields(255, Http2ErrorCode::COMPRESSION_ERROR); | |
389 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
390 } | |
391 | |
392 TEST_F(Http2FrameDecoderTest, WindowUpdate) { | |
393 const char kFrameData[] = { | |
394 0x00, 0x00, 0x04, // Length: 4 | |
395 0x08, // Type: WINDOW_UPDATE | |
396 0x0f, // Flags: 0xff (no valid flags) | |
397 0x00, 0x00, 0x00, 0x01, // Stream: 1 | |
398 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit) | |
399 }; | |
400 Http2FrameHeader header(4, Http2FrameType::WINDOW_UPDATE, 0, 1); | |
401 FrameParts expected(header); | |
402 expected.opt_window_update_increment = 1024; | |
403 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
404 } | |
405 | |
406 TEST_F(Http2FrameDecoderTest, ContinuationEmpty) { | |
407 const char kFrameData[] = { | |
408 0x00, 0x00, 0x00, // Payload length: 0 | |
409 0x09, // CONTINUATION | |
410 0x00, // Flags: none | |
411 0x00, 0x00, 0x00, 0x00, // Stream ID: 0 (invalid but unchecked here) | |
412 }; | |
413 Http2FrameHeader header(0, Http2FrameType::CONTINUATION, 0, 0); | |
414 FrameParts expected(header); | |
415 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
416 } | |
417 | |
418 TEST_F(Http2FrameDecoderTest, AltSvcMinimal) { | |
419 const char kFrameData[] = { | |
420 0x00, 0x00, 0x02, // Payload length: 2 | |
421 0x0a, // ALTSVC | |
422 0xffu, // Flags: none (plus 0xff) | |
423 0x00, 0x00, 0x00, 0x00, // Stream ID: 0 (invalid but unchecked here) | |
424 0x00, 0x00, // Origin Length: 0 | |
425 }; | |
426 Http2FrameHeader header(2, Http2FrameType::ALTSVC, 0, 0); | |
427 FrameParts expected(header); | |
428 expected.opt_altsvc_origin_length = 0; | |
429 expected.opt_altsvc_value_length = 0; | |
430 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
431 } | |
432 | |
433 TEST_F(Http2FrameDecoderTest, UnknownEmpty) { | |
434 const char kFrameData[] = { | |
435 0x00, 0x00, 0x00, // Payload length: 0 | |
436 0x20, // 32 (unknown) | |
437 0xffu, // Flags: all | |
438 0x00, 0x00, 0x00, 0x00, // Stream ID: 0 | |
439 }; | |
440 Http2FrameHeader header(0, static_cast<Http2FrameType>(32), 0xff, 0); | |
441 FrameParts expected(header); | |
442 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
443 } | |
444 | |
445 //////////////////////////////////////////////////////////////////////////////// | |
446 // Tests of longer payloads, for those frame types that allow longer payloads. | |
447 | |
448 TEST_F(Http2FrameDecoderTest, DataPayload) { | |
449 const char kFrameData[] = { | |
450 0x00, 0x00, 0x03, // Payload length: 7 | |
451 0x00, // DATA | |
452 0x80u, // Flags: 0x80 | |
453 0x00, 0x00, 0x02, 0x02, // Stream ID: 514 | |
454 'a', 'b', 'c', // Data | |
455 }; | |
456 Http2FrameHeader header(3, Http2FrameType::DATA, 0, 514); | |
457 FrameParts expected(header, "abc"); | |
458 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
459 } | |
460 | |
461 TEST_F(Http2FrameDecoderTest, HeadersPayload) { | |
462 const char kFrameData[] = { | |
463 0x00, 0x00, 0x03, // Payload length: 3 | |
464 0x01, // HEADERS | |
465 0x05, // Flags: END_STREAM | END_HEADERS | |
466 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) | |
467 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid) | |
468 }; | |
469 Http2FrameHeader header( | |
470 3, Http2FrameType::HEADERS, | |
471 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_END_HEADERS, 2); | |
472 FrameParts expected(header, "abc"); | |
473 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
474 } | |
475 | |
476 TEST_F(Http2FrameDecoderTest, HeadersPriority) { | |
477 const char kFrameData[] = { | |
478 0x00, 0x00, 0x05, // Payload length: 5 | |
479 0x01, // HEADERS | |
480 0x20, // Flags: PRIORITY | |
481 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) | |
482 0x00, 0x00, 0x00, 0x01, // Parent: 1 (Not Exclusive) | |
483 0xffu, // Weight: 256 | |
484 }; | |
485 Http2FrameHeader header(5, Http2FrameType::HEADERS, | |
486 Http2FrameFlag::FLAG_PRIORITY, 2); | |
487 FrameParts expected(header); | |
488 expected.opt_priority = Http2PriorityFields(1, 256, false); | |
489 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
490 } | |
491 | |
492 TEST_F(Http2FrameDecoderTest, Settings) { | |
493 const char kFrameData[] = { | |
494 0x00, 0x00, 0x0c, // Length: 12 | |
495 0x04, // Type: SETTINGS | |
496 0x00, // Flags: none | |
497 0x00, 0x00, 0x00, 0x00, // Stream: 0 | |
498 0x00, 0x04, // Param: INITIAL_WINDOW_SIZE | |
499 0x0a, 0x0b, 0x0c, 0x0d, // Value: 168496141 | |
500 0x00, 0x02, // Param: ENABLE_PUSH | |
501 0x00, 0x00, 0x00, 0x03, // Value: 3 (invalid but unchecked here) | |
502 }; | |
503 Http2FrameHeader header(12, Http2FrameType::SETTINGS, 0, 0); | |
504 FrameParts expected(header); | |
505 expected.settings.push_back(Http2SettingFields( | |
506 Http2SettingsParameter::INITIAL_WINDOW_SIZE, 168496141)); | |
507 expected.settings.push_back( | |
508 Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3)); | |
509 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
510 } | |
511 | |
512 TEST_F(Http2FrameDecoderTest, PushPromisePayload) { | |
513 const char kFrameData[] = { | |
514 0x00, 0x00, 7, // Payload length: 7 | |
515 0x05, // PUSH_PROMISE | |
516 0x04, // Flags: END_HEADERS | |
517 0x00, 0x00, 0x00, 0xffu, // Stream ID: 255 | |
518 0x00, 0x00, 0x01, 0x00, // Promised: 256 | |
519 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid) | |
520 }; | |
521 Http2FrameHeader header(7, Http2FrameType::PUSH_PROMISE, | |
522 Http2FrameFlag::FLAG_END_HEADERS, 255); | |
523 FrameParts expected(header, "abc"); | |
524 expected.opt_push_promise = Http2PushPromiseFields{256}; | |
525 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
526 } | |
527 | |
528 TEST_F(Http2FrameDecoderTest, GoAwayOpaqueData) { | |
529 const char kFrameData[] = { | |
530 0x00, 0x00, 0x0e, // Length: 14 | |
531 0x07, // Type: GOAWAY | |
532 0xffu, // Flags: 0xff (no valid flags) | |
533 0x80u, 0x00, 0x00, 0x00, // Stream: 0 (plus R bit) | |
534 0x00, 0x00, 0x01, 0x00, // Last: 256 | |
535 0x00, 0x00, 0x00, 0x03, // Error: FLOW_CONTROL_ERROR | |
536 'o', 'p', 'a', 'q', 'u', 'e', | |
537 }; | |
538 Http2FrameHeader header(14, Http2FrameType::GOAWAY, 0, 0); | |
539 FrameParts expected(header, "opaque"); | |
540 expected.opt_goaway = | |
541 Http2GoAwayFields(256, Http2ErrorCode::FLOW_CONTROL_ERROR); | |
542 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
543 } | |
544 | |
545 TEST_F(Http2FrameDecoderTest, ContinuationPayload) { | |
546 const char kFrameData[] = { | |
547 0x00, 0x00, 0x03, // Payload length: 3 | |
548 0x09, // CONTINUATION | |
549 0xffu, // Flags: END_HEADERS | 0xfb | |
550 0x00, 0x00, 0x00, 0x02, // Stream ID: 2 | |
551 'a', 'b', 'c', // Data | |
552 }; | |
553 Http2FrameHeader header(3, Http2FrameType::CONTINUATION, | |
554 Http2FrameFlag::FLAG_END_HEADERS, 2); | |
555 FrameParts expected(header, "abc"); | |
556 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
557 } | |
558 | |
559 TEST_F(Http2FrameDecoderTest, AltSvcPayload) { | |
560 const char kFrameData[] = { | |
561 0x00, 0x00, 0x08, // Payload length: 3 | |
562 0x0a, // ALTSVC | |
563 0x00, // Flags: none | |
564 0x00, 0x00, 0x00, 0x02, // Stream ID: 2 | |
565 0x00, 0x03, // Origin Length: 0 | |
566 'a', 'b', 'c', // Origin | |
567 'd', 'e', 'f', // Value | |
568 }; | |
569 Http2FrameHeader header(8, Http2FrameType::ALTSVC, 0, 2); | |
570 FrameParts expected(header); | |
571 expected.SetAltSvcExpected("abc", "def"); | |
572 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
573 } | |
574 | |
575 TEST_F(Http2FrameDecoderTest, UnknownPayload) { | |
576 const char kFrameData[] = { | |
577 0x00, 0x00, 0x03, // Payload length: 3 | |
578 0x30, // 48 (unknown) | |
579 0x00, // Flags: none | |
580 0x00, 0x00, 0x00, 0x02, // Stream ID: 2 | |
581 'a', 'b', 'c', // Payload | |
582 }; | |
583 Http2FrameHeader header(3, static_cast<Http2FrameType>(48), 0, 2); | |
584 FrameParts expected(header, "abc"); | |
585 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
586 } | |
587 | |
588 //////////////////////////////////////////////////////////////////////////////// | |
589 // Tests of padded payloads, for those frame types that allow padding. | |
590 | |
591 TEST_F(Http2FrameDecoderTest, DataPayloadAndPadding) { | |
592 const char kFrameData[] = { | |
593 0x00, 0x00, 0x07, // Payload length: 7 | |
594 0x00, // DATA | |
595 0x09, // Flags: END_STREAM | PADDED | |
596 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) | |
597 0x03, // Pad Len | |
598 'a', 'b', 'c', // Data | |
599 0x00, 0x00, 0x00, // Padding | |
600 }; | |
601 Http2FrameHeader header( | |
602 7, Http2FrameType::DATA, | |
603 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2); | |
604 size_t total_pad_length = 4; // Including the Pad Length field. | |
605 FrameParts expected(header, "abc", total_pad_length); | |
606 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
607 } | |
608 | |
609 TEST_F(Http2FrameDecoderTest, HeadersPayloadAndPadding) { | |
610 const char kFrameData[] = { | |
611 0x00, 0x00, 0x07, // Payload length: 7 | |
612 0x01, // HEADERS | |
613 0x08, // Flags: PADDED | |
614 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) | |
615 0x03, // Pad Len | |
616 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid) | |
617 0x00, 0x00, 0x00, // Padding | |
618 }; | |
619 Http2FrameHeader header(7, Http2FrameType::HEADERS, | |
620 Http2FrameFlag::FLAG_PADDED, 2); | |
621 size_t total_pad_length = 4; // Including the Pad Length field. | |
622 FrameParts expected(header, "abc", total_pad_length); | |
623 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
624 } | |
625 | |
626 TEST_F(Http2FrameDecoderTest, HeadersPayloadPriorityAndPadding) { | |
627 const char kFrameData[] = { | |
628 0x00, 0x00, 0x0c, // Payload length: 12 | |
629 0x01, // HEADERS | |
630 0xffu, // Flags: all, including undefined | |
631 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) | |
632 0x03, // Pad Len | |
633 0x80u, 0x00, 0x00, 0x01, // Parent: 1 (Exclusive) | |
634 0x10, // Weight: 17 | |
635 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid) | |
636 0x00, 0x00, 0x00, // Padding | |
637 }; | |
638 Http2FrameHeader header( | |
639 12, Http2FrameType::HEADERS, | |
640 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_END_HEADERS | | |
641 Http2FrameFlag::FLAG_PADDED | Http2FrameFlag::FLAG_PRIORITY, | |
642 2); | |
643 size_t total_pad_length = 4; // Including the Pad Length field. | |
644 FrameParts expected(header, "abc", total_pad_length); | |
645 expected.opt_priority = Http2PriorityFields(1, 17, true); | |
646 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
647 } | |
648 | |
649 TEST_F(Http2FrameDecoderTest, PushPromisePayloadAndPadding) { | |
650 const char kFrameData[] = { | |
651 0x00, 0x00, 11, // Payload length: 11 | |
652 0x05, // PUSH_PROMISE | |
653 0xffu, // Flags: END_HEADERS | PADDED | 0xf3 | |
654 0x00, 0x00, 0x00, 0x01, // Stream ID: 1 | |
655 0x03, // Pad Len | |
656 0x00, 0x00, 0x00, 0x02, // Promised: 2 | |
657 'a', 'b', 'c', // HPACK fragment (doesn't have to be valid) | |
658 0x00, 0x00, 0x00, // Padding | |
659 }; | |
660 Http2FrameHeader header( | |
661 11, Http2FrameType::PUSH_PROMISE, | |
662 Http2FrameFlag::FLAG_END_HEADERS | Http2FrameFlag::FLAG_PADDED, 1); | |
663 size_t total_pad_length = 4; // Including the Pad Length field. | |
664 FrameParts expected(header, "abc", total_pad_length); | |
665 expected.opt_push_promise = Http2PushPromiseFields{2}; | |
666 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected)); | |
667 } | |
668 | |
669 //////////////////////////////////////////////////////////////////////////////// | |
670 // Payload too short errors. | |
671 | |
672 TEST_F(Http2FrameDecoderTest, DataMissingPadLengthField) { | |
673 const char kFrameData[] = { | |
674 0x00, 0x00, 0x00, // Payload length: 0 | |
675 0x00, // DATA | |
676 0x08, // Flags: PADDED | |
677 0x00, 0x00, 0x00, 0x01, // Stream ID: 1 | |
678 }; | |
679 Http2FrameHeader header(0, Http2FrameType::DATA, Http2FrameFlag::FLAG_PADDED, | |
680 1); | |
681 FrameParts expected(header); | |
682 expected.opt_missing_length = 1; | |
683 EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected)); | |
684 } | |
685 | |
686 TEST_F(Http2FrameDecoderTest, HeaderPaddingTooLong) { | |
687 const char kFrameData[] = { | |
688 0x00, 0x00, 0x02, // Payload length: 0 | |
689 0x01, // HEADERS | |
690 0x08, // Flags: PADDED | |
691 0x00, 0x01, 0x00, 0x00, // Stream ID: 65536 | |
692 0xffu, // Pad Len: 255 | |
693 0x00, // Only one byte of padding | |
694 }; | |
695 Http2FrameHeader header(2, Http2FrameType::HEADERS, | |
696 Http2FrameFlag::FLAG_PADDED, 65536); | |
697 FrameParts expected(header); | |
698 expected.opt_missing_length = 254; | |
699 EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected)); | |
700 } | |
701 | |
702 TEST_F(Http2FrameDecoderTest, HeaderMissingPriority) { | |
703 const char kFrameData[] = { | |
704 0x00, 0x00, 0x04, // Payload length: 0 | |
705 0x01, // HEADERS | |
706 0x20, // Flags: PRIORITY | |
707 0x00, 0x01, 0x00, 0x00, // Stream ID: 65536 | |
708 0x00, 0x00, 0x00, 0x00, // Priority (truncated) | |
709 }; | |
710 Http2FrameHeader header(4, Http2FrameType::HEADERS, | |
711 Http2FrameFlag::FLAG_PRIORITY, 65536); | |
712 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
713 } | |
714 | |
715 TEST_F(Http2FrameDecoderTest, PriorityTooShort) { | |
716 const char kFrameData[] = { | |
717 0x00, 0x00, 0x04, // Length: 5 | |
718 0x02, // Type: PRIORITY | |
719 0x00, // Flags: none | |
720 0x00, 0x00, 0x00, 0x02, // Stream: 2 | |
721 0x80u, 0x00, 0x00, 0x01, // Parent: 1 (Exclusive) | |
722 }; | |
723 Http2FrameHeader header(4, Http2FrameType::PRIORITY, 0, 2); | |
724 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
725 } | |
726 | |
727 TEST_F(Http2FrameDecoderTest, RstStreamTooShort) { | |
728 const char kFrameData[] = { | |
729 0x00, 0x00, 0x03, // Length: 4 | |
730 0x03, // Type: RST_STREAM | |
731 0x00, // Flags: none | |
732 0x00, 0x00, 0x00, 0x01, // Stream: 1 | |
733 0x00, 0x00, 0x00, // Truncated | |
734 }; | |
735 Http2FrameHeader header(3, Http2FrameType::RST_STREAM, 0, 1); | |
736 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
737 } | |
738 | |
739 // SETTINGS frames must a multiple of 6 bytes long, so an 9 byte payload is | |
740 // invalid. | |
741 TEST_F(Http2FrameDecoderTest, SettingsWrongSize) { | |
742 const char kFrameData[] = { | |
743 0x00, 0x00, 0x09, // Length: 2 | |
744 0x04, // Type: SETTINGS | |
745 0x00, // Flags: none | |
746 0x00, 0x00, 0x00, 0x00, // Stream: 0 | |
747 0x00, 0x02, // Param: ENABLE_PUSH | |
748 0x00, 0x00, 0x00, 0x03, // Value: 1 | |
749 0x00, 0x04, // Param: INITIAL_WINDOW_SIZE | |
750 0x00, // Value: Truncated | |
751 }; | |
752 Http2FrameHeader header(9, Http2FrameType::SETTINGS, 0, 0); | |
753 FrameParts expected(header); | |
754 expected.settings.push_back( | |
755 Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3)); | |
756 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, expected)); | |
757 } | |
758 | |
759 TEST_F(Http2FrameDecoderTest, PushPromiseTooShort) { | |
760 const char kFrameData[] = { | |
761 0x00, 0x00, 3, // Payload length: 3 | |
762 0x05, // PUSH_PROMISE | |
763 0x00, // Flags: none | |
764 0x00, 0x00, 0x00, 0x01, // Stream ID: 1 | |
765 0x00, 0x00, 0x00, // Truncated promise id | |
766 }; | |
767 Http2FrameHeader header(3, Http2FrameType::PUSH_PROMISE, 0, 1); | |
768 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
769 } | |
770 | |
771 TEST_F(Http2FrameDecoderTest, PushPromisePaddedTruncatedPromise) { | |
772 const char kFrameData[] = { | |
773 0x00, 0x00, 4, // Payload length: 4 | |
774 0x05, // PUSH_PROMISE | |
775 0x08, // Flags: PADDED | |
776 0x00, 0x00, 0x00, 0x01, // Stream ID: 1 | |
777 0x00, // Pad Len | |
778 0x00, 0x00, 0x00, // Truncated promise id | |
779 }; | |
780 Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE, | |
781 Http2FrameFlag::FLAG_PADDED, 1); | |
782 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
783 } | |
784 | |
785 TEST_F(Http2FrameDecoderTest, PingTooShort) { | |
786 const char kFrameData[] = { | |
787 0x00, 0x00, 0x07, // Length: 8 | |
788 0x06, // Type: PING | |
789 0xfeu, // Flags: no valid flags | |
790 0x00, 0x00, 0x00, 0x00, // Stream: 0 | |
791 's', 'o', 'm', 'e', // "some" | |
792 'd', 'a', 't', // Too little | |
793 }; | |
794 Http2FrameHeader header(7, Http2FrameType::PING, 0, 0); | |
795 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
796 } | |
797 | |
798 TEST_F(Http2FrameDecoderTest, GoAwayTooShort) { | |
799 const char kFrameData[] = { | |
800 0x00, 0x00, 0x00, // Length: 0 | |
801 0x07, // Type: GOAWAY | |
802 0xffu, // Flags: 0xff (no valid flags) | |
803 0x00, 0x00, 0x00, 0x00, // Stream: 0 | |
804 }; | |
805 Http2FrameHeader header(0, Http2FrameType::GOAWAY, 0, 0); | |
806 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
807 } | |
808 | |
809 TEST_F(Http2FrameDecoderTest, WindowUpdateTooShort) { | |
810 const char kFrameData[] = { | |
811 0x00, 0x00, 0x03, // Length: 3 | |
812 0x08, // Type: WINDOW_UPDATE | |
813 0x0f, // Flags: 0xff (no valid flags) | |
814 0x00, 0x00, 0x00, 0x01, // Stream: 1 | |
815 0x80u, 0x00, 0x04, // Truncated | |
816 }; | |
817 Http2FrameHeader header(3, Http2FrameType::WINDOW_UPDATE, 0, 1); | |
818 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
819 } | |
820 | |
821 TEST_F(Http2FrameDecoderTest, AltSvcTruncatedOriginLength) { | |
822 const char kFrameData[] = { | |
823 0x00, 0x00, 0x01, // Payload length: 3 | |
824 0x0a, // ALTSVC | |
825 0x00, // Flags: none | |
826 0x00, 0x00, 0x00, 0x02, // Stream ID: 2 | |
827 0x00, // Origin Length: truncated | |
828 }; | |
829 Http2FrameHeader header(1, Http2FrameType::ALTSVC, 0, 2); | |
830 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
831 } | |
832 | |
833 TEST_F(Http2FrameDecoderTest, AltSvcTruncatedOrigin) { | |
834 const char kFrameData[] = { | |
835 0x00, 0x00, 0x05, // Payload length: 3 | |
836 0x0a, // ALTSVC | |
837 0x00, // Flags: none | |
838 0x00, 0x00, 0x00, 0x02, // Stream ID: 2 | |
839 0x00, 0x04, // Origin Length: 4 (too long) | |
840 'a', 'b', 'c', // Origin | |
841 }; | |
842 Http2FrameHeader header(5, Http2FrameType::ALTSVC, 0, 2); | |
843 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
844 } | |
845 | |
846 //////////////////////////////////////////////////////////////////////////////// | |
847 // Payload too long errors. | |
848 | |
849 // The decoder calls the listener's OnFrameSizeError method if the frame's | |
850 // payload is longer than the currently configured maximum payload size. | |
851 TEST_F(Http2FrameDecoderTest, BeyondMaximum) { | |
852 decoder_.set_maximum_payload_size(2); | |
853 const char kFrameData[] = { | |
854 0x00, 0x00, 0x07, // Payload length: 7 | |
855 0x00, // DATA | |
856 0x09, // Flags: END_STREAM | PADDED | |
857 0x00, 0x00, 0x00, 0x02, // Stream ID: 0 (REQUIRES ID) | |
858 0x03, // Pad Len | |
859 'a', 'b', 'c', // Data | |
860 0x00, 0x00, 0x00, // Padding | |
861 }; | |
862 Http2FrameHeader header( | |
863 7, Http2FrameType::DATA, | |
864 Http2FrameFlag::FLAG_END_STREAM | Http2FrameFlag::FLAG_PADDED, 2); | |
865 FrameParts expected(header); | |
866 expected.has_frame_size_error = true; | |
867 ResetDecodeSpeedCounters(); | |
868 EXPECT_TRUE(DecodePayloadAndValidateSeveralWays( | |
869 ToStringPiece(kFrameData), | |
870 base::Bind(&Http2FrameDecoderTest::ValidatorForBeyondMaximum, | |
871 base::Unretained(this), expected))); | |
872 EXPECT_GT(fast_decode_count_, 0u); | |
873 EXPECT_GT(slow_decode_count_, 0u); | |
874 } | |
875 | |
876 TEST_F(Http2FrameDecoderTest, PriorityTooLong) { | |
877 const char kFrameData[] = { | |
878 0x00, 0x00, 0x06, // Length: 5 | |
879 0x02, // Type: PRIORITY | |
880 0x00, // Flags: none | |
881 0x00, 0x00, 0x00, 0x02, // Stream: 2 | |
882 0x80u, 0x00, 0x00, 0x01, // Parent: 1 (Exclusive) | |
883 0x10, // Weight: 17 | |
884 0x00, // Too much | |
885 }; | |
886 Http2FrameHeader header(6, Http2FrameType::PRIORITY, 0, 2); | |
887 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
888 } | |
889 | |
890 TEST_F(Http2FrameDecoderTest, RstStreamTooLong) { | |
891 const char kFrameData[] = { | |
892 0x00, 0x00, 0x05, // Length: 4 | |
893 0x03, // Type: RST_STREAM | |
894 0x00, // Flags: none | |
895 0x00, 0x00, 0x00, 0x01, // Stream: 1 | |
896 0x00, 0x00, 0x00, 0x01, // Error: PROTOCOL_ERROR | |
897 0x00, // Too much | |
898 }; | |
899 Http2FrameHeader header(5, Http2FrameType::RST_STREAM, 0, 1); | |
900 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
901 } | |
902 | |
903 TEST_F(Http2FrameDecoderTest, SettingsAckTooLong) { | |
904 const char kFrameData[] = { | |
905 0x00, 0x00, 0x06, // Length: 6 | |
906 0x04, // Type: SETTINGS | |
907 0x01, // Flags: ACK | |
908 0x00, 0x00, 0x00, 0x00, // Stream: 0 | |
909 0x00, 0x00, // Extra | |
910 0x00, 0x00, 0x00, 0x00, // Extra | |
911 }; | |
912 Http2FrameHeader header(6, Http2FrameType::SETTINGS, Http2FrameFlag::FLAG_ACK, | |
913 0); | |
914 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
915 } | |
916 | |
917 TEST_F(Http2FrameDecoderTest, PingAckTooLong) { | |
918 const char kFrameData[] = { | |
919 0x00, 0x00, 0x09, // Length: 8 | |
920 0x06, // Type: PING | |
921 0xffu, // Flags: ACK | 0xfe | |
922 0x00, 0x00, 0x00, 0x00, // Stream: 0 | |
923 's', 'o', 'm', 'e', // "some" | |
924 'd', 'a', 't', 'a', // "data" | |
925 0x00, // Too much | |
926 }; | |
927 Http2FrameHeader header(9, Http2FrameType::PING, Http2FrameFlag::FLAG_ACK, 0); | |
928 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
929 } | |
930 | |
931 TEST_F(Http2FrameDecoderTest, WindowUpdateTooLong) { | |
932 const char kFrameData[] = { | |
933 0x00, 0x00, 0x05, // Length: 5 | |
934 0x08, // Type: WINDOW_UPDATE | |
935 0x0f, // Flags: 0xff (no valid flags) | |
936 0x00, 0x00, 0x00, 0x01, // Stream: 1 | |
937 0x80u, 0x00, 0x04, 0x00, // Incr: 1024 (plus R bit) | |
938 0x00, // Too much | |
939 }; | |
940 Http2FrameHeader header(5, Http2FrameType::WINDOW_UPDATE, 0, 1); | |
941 EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, header)); | |
942 } | |
943 | |
944 } // namespace | |
945 } // namespace test | |
946 } // namespace net | |
OLD | NEW |