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 "quiche/http2/test_tools/payload_decoder_base_test_util.h"
6
7 #include "quiche/http2/test_tools/frame_decoder_state_test_util.h"
8 #include "quiche/http2/test_tools/http2_structures_test_util.h"
9 #include "quiche/common/platform/api/quiche_test.h"
10
11 namespace http2 {
12 namespace test {
PayloadDecoderBaseTest()13 PayloadDecoderBaseTest::PayloadDecoderBaseTest() {
14 // If the test adds more data after the frame payload,
15 // stop as soon as the payload is decoded.
16 stop_decode_on_done_ = true;
17 frame_header_is_set_ = false;
18 Randomize(&frame_header_, RandomPtr());
19 }
20
StartDecoding(DecodeBuffer * db)21 DecodeStatus PayloadDecoderBaseTest::StartDecoding(DecodeBuffer* db) {
22 QUICHE_DVLOG(2) << "StartDecoding, db->Remaining=" << db->Remaining();
23 // Make sure sub-class has set frame_header_ so that we can inject it
24 // into the payload decoder below.
25 if (!frame_header_is_set_) {
26 ADD_FAILURE() << "frame_header_ is not set";
27 return DecodeStatus::kDecodeError;
28 }
29 // The contract with the payload decoders is that they won't receive a
30 // decode buffer that extends beyond the end of the frame.
31 if (db->Remaining() > frame_header_.payload_length) {
32 ADD_FAILURE() << "DecodeBuffer has too much data: " << db->Remaining()
33 << " > " << frame_header_.payload_length;
34 return DecodeStatus::kDecodeError;
35 }
36
37 // Prepare the payload decoder.
38 PreparePayloadDecoder();
39
40 // Reconstruct the FrameDecoderState, prepare the listener, and add it to
41 // the FrameDecoderState.
42 frame_decoder_state_ = std::make_unique<FrameDecoderState>();
43 frame_decoder_state_->set_listener(PrepareListener());
44
45 // Make sure that a listener was provided.
46 if (frame_decoder_state_->listener() == nullptr) {
47 ADD_FAILURE() << "PrepareListener must return a listener.";
48 return DecodeStatus::kDecodeError;
49 }
50
51 // Now that nothing in the payload decoder should be valid, inject the
52 // Http2FrameHeader whose payload we're about to decode. That header is the
53 // only state that a payload decoder should expect is valid when its Start
54 // method is called.
55 FrameDecoderStatePeer::set_frame_header(frame_header_,
56 frame_decoder_state_.get());
57 DecodeStatus status = StartDecodingPayload(db);
58 if (status != DecodeStatus::kDecodeInProgress) {
59 // Keep track of this so that a concrete test can verify that both fast
60 // and slow decoding paths have been tested.
61 ++fast_decode_count_;
62 }
63 return status;
64 }
65
ResumeDecoding(DecodeBuffer * db)66 DecodeStatus PayloadDecoderBaseTest::ResumeDecoding(DecodeBuffer* db) {
67 QUICHE_DVLOG(2) << "ResumeDecoding, db->Remaining=" << db->Remaining();
68 DecodeStatus status = ResumeDecodingPayload(db);
69 if (status != DecodeStatus::kDecodeInProgress) {
70 // Keep track of this so that a concrete test can verify that both fast
71 // and slow decoding paths have been tested.
72 ++slow_decode_count_;
73 }
74 return status;
75 }
76
77 ::testing::AssertionResult
DecodePayloadAndValidateSeveralWays(absl::string_view payload,Validator validator)78 PayloadDecoderBaseTest::DecodePayloadAndValidateSeveralWays(
79 absl::string_view payload, Validator validator) {
80 HTTP2_VERIFY_TRUE(frame_header_is_set_);
81 // Cap the payload to be decoded at the declared payload length. This is
82 // required by the decoders' preconditions; they are designed on the
83 // assumption that they're never passed more than they're permitted to
84 // consume.
85 // Note that it is OK if the payload is too short; the validator may be
86 // designed to check for that.
87 if (payload.size() > frame_header_.payload_length) {
88 payload = absl::string_view(payload.data(), frame_header_.payload_length);
89 }
90 DecodeBuffer db(payload);
91 ResetDecodeSpeedCounters();
92 const bool kMayReturnZeroOnFirst = false;
93 return DecodeAndValidateSeveralWays(&db, kMayReturnZeroOnFirst, validator);
94 }
95
96 } // namespace test
97 } // namespace http2
98