xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/spdy/core/spdy_framer_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2012 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/spdy/core/spdy_framer.h"
6 
7 #include <stdlib.h>
8 
9 #include <algorithm>
10 #include <cstdint>
11 #include <cstring>
12 #include <ios>
13 #include <limits>
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "absl/base/macros.h"
20 #include "absl/strings/string_view.h"
21 #include "quiche/common/platform/api/quiche_logging.h"
22 #include "quiche/common/platform/api/quiche_test.h"
23 #include "quiche/common/quiche_text_utils.h"
24 #include "quiche/spdy/core/array_output_buffer.h"
25 #include "quiche/spdy/core/hpack/hpack_encoder.h"
26 #include "quiche/spdy/core/http2_frame_decoder_adapter.h"
27 #include "quiche/spdy/core/http2_header_block.h"
28 #include "quiche/spdy/core/recording_headers_handler.h"
29 #include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
30 #include "quiche/spdy/core/spdy_bitmasks.h"
31 #include "quiche/spdy/core/spdy_frame_builder.h"
32 #include "quiche/spdy/core/spdy_headers_handler_interface.h"
33 #include "quiche/spdy/core/spdy_protocol.h"
34 #include "quiche/spdy/test_tools/mock_spdy_framer_visitor.h"
35 #include "quiche/spdy/test_tools/spdy_test_utils.h"
36 
37 using ::http2::Http2DecoderAdapter;
38 using ::testing::_;
39 
40 namespace spdy {
41 
42 namespace test {
43 
44 namespace {
45 
46 const int64_t kSize = 1024 * 1024;
47 char output_buffer[kSize] = "";
48 
49 // frame_list_char is used to hold frames to be compared with output_buffer.
50 const int64_t buffer_size = 64 * 1024;
51 char frame_list_char[buffer_size] = "";
52 }  // namespace
53 
54 class MockDebugVisitor : public SpdyFramerDebugVisitorInterface {
55  public:
56   MOCK_METHOD(void, OnSendCompressedFrame,
57               (SpdyStreamId stream_id, SpdyFrameType type, size_t payload_len,
58                size_t frame_len),
59               (override));
60 
61   MOCK_METHOD(void, OnReceiveCompressedFrame,
62               (SpdyStreamId stream_id, SpdyFrameType type, size_t frame_len),
63               (override));
64 };
65 
66 MATCHER_P(IsFrameUnionOf, frame_list, "") {
67   size_t size_verified = 0;
68   for (const auto& frame : *frame_list) {
69     if (arg.size() < size_verified + frame.size()) {
70       QUICHE_LOG(FATAL)
71           << "Incremental header serialization should not lead to a "
72           << "higher total frame length than non-incremental method.";
73       return false;
74     }
75     if (memcmp(arg.data() + size_verified, frame.data(), frame.size())) {
76       CompareCharArraysWithHexError(
77           "Header serialization methods should be equivalent: ",
78           reinterpret_cast<unsigned char*>(arg.data() + size_verified),
79           frame.size(), reinterpret_cast<unsigned char*>(frame.data()),
80           frame.size());
81       return false;
82     }
83     size_verified += frame.size();
84   }
85   return size_verified == arg.size();
86 }
87 
88 class SpdyFramerPeer {
89  public:
90   // TODO(dahollings): Remove these methods when deprecating non-incremental
91   // header serialization path.
CloneSpdyHeadersIR(const SpdyHeadersIR & headers)92   static std::unique_ptr<SpdyHeadersIR> CloneSpdyHeadersIR(
93       const SpdyHeadersIR& headers) {
94     auto new_headers = std::make_unique<SpdyHeadersIR>(
95         headers.stream_id(), headers.header_block().Clone());
96     new_headers->set_fin(headers.fin());
97     new_headers->set_has_priority(headers.has_priority());
98     new_headers->set_weight(headers.weight());
99     new_headers->set_parent_stream_id(headers.parent_stream_id());
100     new_headers->set_exclusive(headers.exclusive());
101     if (headers.padded()) {
102       new_headers->set_padding_len(headers.padding_payload_len() + 1);
103     }
104     return new_headers;
105   }
106 
SerializeHeaders(SpdyFramer * framer,const SpdyHeadersIR & headers)107   static SpdySerializedFrame SerializeHeaders(SpdyFramer* framer,
108                                               const SpdyHeadersIR& headers) {
109     SpdySerializedFrame serialized_headers_old_version(
110         framer->SerializeHeaders(headers));
111     framer->hpack_encoder_.reset(nullptr);
112     auto* saved_debug_visitor = framer->debug_visitor_;
113     framer->debug_visitor_ = nullptr;
114 
115     std::vector<SpdySerializedFrame> frame_list;
116     ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
117     SpdyFramer::SpdyHeaderFrameIterator it(framer, CloneSpdyHeadersIR(headers));
118     while (it.HasNextFrame()) {
119       size_t size_before = frame_list_buffer.Size();
120       EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
121       frame_list.emplace_back(
122           MakeSerializedFrame(frame_list_buffer.Begin() + size_before,
123                               frame_list_buffer.Size() - size_before));
124     }
125     framer->debug_visitor_ = saved_debug_visitor;
126 
127     EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
128     return serialized_headers_old_version;
129   }
130 
SerializeHeaders(SpdyFramer * framer,const SpdyHeadersIR & headers,ArrayOutputBuffer * output)131   static SpdySerializedFrame SerializeHeaders(SpdyFramer* framer,
132                                               const SpdyHeadersIR& headers,
133                                               ArrayOutputBuffer* output) {
134     if (output == nullptr) {
135       return SerializeHeaders(framer, headers);
136     }
137     output->Reset();
138     EXPECT_TRUE(framer->SerializeHeaders(headers, output));
139     SpdySerializedFrame serialized_headers_old_version =
140         MakeSerializedFrame(output->Begin(), output->Size());
141     framer->hpack_encoder_.reset(nullptr);
142     auto* saved_debug_visitor = framer->debug_visitor_;
143     framer->debug_visitor_ = nullptr;
144 
145     std::vector<SpdySerializedFrame> frame_list;
146     ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
147     SpdyFramer::SpdyHeaderFrameIterator it(framer, CloneSpdyHeadersIR(headers));
148     while (it.HasNextFrame()) {
149       size_t size_before = frame_list_buffer.Size();
150       EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
151       frame_list.emplace_back(
152           MakeSerializedFrame(frame_list_buffer.Begin() + size_before,
153                               frame_list_buffer.Size() - size_before));
154     }
155     framer->debug_visitor_ = saved_debug_visitor;
156 
157     EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
158     return serialized_headers_old_version;
159   }
160 
CloneSpdyPushPromiseIR(const SpdyPushPromiseIR & push_promise)161   static std::unique_ptr<SpdyPushPromiseIR> CloneSpdyPushPromiseIR(
162       const SpdyPushPromiseIR& push_promise) {
163     auto new_push_promise = std::make_unique<SpdyPushPromiseIR>(
164         push_promise.stream_id(), push_promise.promised_stream_id(),
165         push_promise.header_block().Clone());
166     new_push_promise->set_fin(push_promise.fin());
167     if (push_promise.padded()) {
168       new_push_promise->set_padding_len(push_promise.padding_payload_len() + 1);
169     }
170     return new_push_promise;
171   }
172 
SerializePushPromise(SpdyFramer * framer,const SpdyPushPromiseIR & push_promise)173   static SpdySerializedFrame SerializePushPromise(
174       SpdyFramer* framer, const SpdyPushPromiseIR& push_promise) {
175     SpdySerializedFrame serialized_headers_old_version =
176         framer->SerializePushPromise(push_promise);
177     framer->hpack_encoder_.reset(nullptr);
178     auto* saved_debug_visitor = framer->debug_visitor_;
179     framer->debug_visitor_ = nullptr;
180 
181     std::vector<SpdySerializedFrame> frame_list;
182     ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
183     frame_list_buffer.Reset();
184     SpdyFramer::SpdyPushPromiseFrameIterator it(
185         framer, CloneSpdyPushPromiseIR(push_promise));
186     while (it.HasNextFrame()) {
187       size_t size_before = frame_list_buffer.Size();
188       EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
189       frame_list.emplace_back(
190           MakeSerializedFrame(frame_list_buffer.Begin() + size_before,
191                               frame_list_buffer.Size() - size_before));
192     }
193     framer->debug_visitor_ = saved_debug_visitor;
194 
195     EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
196     return serialized_headers_old_version;
197   }
198 
SerializePushPromise(SpdyFramer * framer,const SpdyPushPromiseIR & push_promise,ArrayOutputBuffer * output)199   static SpdySerializedFrame SerializePushPromise(
200       SpdyFramer* framer, const SpdyPushPromiseIR& push_promise,
201       ArrayOutputBuffer* output) {
202     if (output == nullptr) {
203       return SerializePushPromise(framer, push_promise);
204     }
205     output->Reset();
206     EXPECT_TRUE(framer->SerializePushPromise(push_promise, output));
207     SpdySerializedFrame serialized_headers_old_version =
208         MakeSerializedFrame(output->Begin(), output->Size());
209     framer->hpack_encoder_.reset(nullptr);
210     auto* saved_debug_visitor = framer->debug_visitor_;
211     framer->debug_visitor_ = nullptr;
212 
213     std::vector<SpdySerializedFrame> frame_list;
214     ArrayOutputBuffer frame_list_buffer(frame_list_char, buffer_size);
215     frame_list_buffer.Reset();
216     SpdyFramer::SpdyPushPromiseFrameIterator it(
217         framer, CloneSpdyPushPromiseIR(push_promise));
218     while (it.HasNextFrame()) {
219       size_t size_before = frame_list_buffer.Size();
220       EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
221       frame_list.emplace_back(
222           MakeSerializedFrame(frame_list_buffer.Begin() + size_before,
223                               frame_list_buffer.Size() - size_before));
224     }
225     framer->debug_visitor_ = saved_debug_visitor;
226 
227     EXPECT_THAT(serialized_headers_old_version, IsFrameUnionOf(&frame_list));
228     return serialized_headers_old_version;
229   }
230 };
231 
232 class TestSpdyVisitor : public SpdyFramerVisitorInterface,
233                         public SpdyFramerDebugVisitorInterface {
234  public:
235   // This is larger than our max frame size because header blocks that
236   // are too long can spill over into CONTINUATION frames.
237   static constexpr size_t kDefaultHeaderBufferSize = 16 * 1024 * 1024;
238 
TestSpdyVisitor(SpdyFramer::CompressionOption option)239   explicit TestSpdyVisitor(SpdyFramer::CompressionOption option)
240       : framer_(option),
241         error_count_(0),
242         headers_frame_count_(0),
243         push_promise_frame_count_(0),
244         goaway_count_(0),
245         setting_count_(0),
246         settings_ack_sent_(0),
247         settings_ack_received_(0),
248         continuation_count_(0),
249         altsvc_count_(0),
250         priority_count_(0),
251         unknown_frame_count_(0),
252         on_unknown_frame_result_(false),
253         last_window_update_stream_(0),
254         last_window_update_delta_(0),
255         last_push_promise_stream_(0),
256         last_push_promise_promised_stream_(0),
257         data_bytes_(0),
258         fin_frame_count_(0),
259         fin_flag_count_(0),
260         end_of_stream_count_(0),
261         control_frame_header_data_count_(0),
262         zero_length_control_frame_header_data_count_(0),
263         data_frame_count_(0),
264         last_payload_len_(0),
265         last_frame_len_(0),
266         unknown_payload_len_(0),
267         header_buffer_(new char[kDefaultHeaderBufferSize]),
268         header_buffer_length_(0),
269         header_buffer_size_(kDefaultHeaderBufferSize),
270         header_stream_id_(static_cast<SpdyStreamId>(-1)),
271         header_control_type_(SpdyFrameType::DATA),
272         header_buffer_valid_(false) {}
273 
OnError(Http2DecoderAdapter::SpdyFramerError error,std::string)274   void OnError(Http2DecoderAdapter::SpdyFramerError error,
275                std::string /*detailed_error*/) override {
276     QUICHE_VLOG(1) << "SpdyFramer Error: "
277                    << Http2DecoderAdapter::SpdyFramerErrorToString(error);
278     ++error_count_;
279   }
280 
OnDataFrameHeader(SpdyStreamId stream_id,size_t length,bool fin)281   void OnDataFrameHeader(SpdyStreamId stream_id, size_t length,
282                          bool fin) override {
283     QUICHE_VLOG(1) << "OnDataFrameHeader(" << stream_id << ", " << length
284                    << ", " << fin << ")";
285     ++data_frame_count_;
286     header_stream_id_ = stream_id;
287   }
288 
OnStreamFrameData(SpdyStreamId stream_id,const char * data,size_t len)289   void OnStreamFrameData(SpdyStreamId stream_id, const char* data,
290                          size_t len) override {
291     QUICHE_VLOG(1) << "OnStreamFrameData(" << stream_id << ", data, " << len
292                    << ", "
293                    << ")   data:\n"
294                    << quiche::QuicheTextUtils::HexDump(
295                           absl::string_view(data, len));
296     EXPECT_EQ(header_stream_id_, stream_id);
297 
298     data_bytes_ += len;
299   }
300 
OnStreamEnd(SpdyStreamId stream_id)301   void OnStreamEnd(SpdyStreamId stream_id) override {
302     QUICHE_VLOG(1) << "OnStreamEnd(" << stream_id << ")";
303     EXPECT_EQ(header_stream_id_, stream_id);
304     ++end_of_stream_count_;
305   }
306 
OnStreamPadLength(SpdyStreamId stream_id,size_t value)307   void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override {
308     QUICHE_VLOG(1) << "OnStreamPadding(" << stream_id << ", " << value << ")\n";
309     EXPECT_EQ(header_stream_id_, stream_id);
310     // Count the padding length field byte against total data bytes.
311     data_bytes_ += 1;
312   }
313 
OnStreamPadding(SpdyStreamId stream_id,size_t len)314   void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {
315     QUICHE_VLOG(1) << "OnStreamPadding(" << stream_id << ", " << len << ")\n";
316     EXPECT_EQ(header_stream_id_, stream_id);
317     data_bytes_ += len;
318   }
319 
OnHeaderFrameStart(SpdyStreamId)320   SpdyHeadersHandlerInterface* OnHeaderFrameStart(
321       SpdyStreamId /*stream_id*/) override {
322     if (headers_handler_ == nullptr) {
323       headers_handler_ = std::make_unique<RecordingHeadersHandler>();
324     }
325     return headers_handler_.get();
326   }
327 
OnHeaderFrameEnd(SpdyStreamId)328   void OnHeaderFrameEnd(SpdyStreamId /*stream_id*/) override {
329     QUICHE_CHECK(headers_handler_ != nullptr);
330     headers_ = headers_handler_->decoded_block().Clone();
331     header_bytes_received_ = headers_handler_->uncompressed_header_bytes();
332     headers_handler_.reset();
333   }
334 
OnRstStream(SpdyStreamId stream_id,SpdyErrorCode error_code)335   void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override {
336     QUICHE_VLOG(1) << "OnRstStream(" << stream_id << ", " << error_code << ")";
337     ++fin_frame_count_;
338   }
339 
OnSetting(SpdySettingsId id,uint32_t value)340   void OnSetting(SpdySettingsId id, uint32_t value) override {
341     QUICHE_VLOG(1) << "OnSetting(" << id << ", " << std::hex << value << ")";
342     ++setting_count_;
343   }
344 
OnSettingsAck()345   void OnSettingsAck() override {
346     QUICHE_VLOG(1) << "OnSettingsAck";
347     ++settings_ack_received_;
348   }
349 
OnSettingsEnd()350   void OnSettingsEnd() override {
351     QUICHE_VLOG(1) << "OnSettingsEnd";
352     ++settings_ack_sent_;
353   }
354 
OnPing(SpdyPingId unique_id,bool is_ack)355   void OnPing(SpdyPingId unique_id, bool is_ack) override {
356     QUICHE_LOG(DFATAL) << "OnPing(" << unique_id << ", " << (is_ack ? 1 : 0)
357                        << ")";
358   }
359 
OnGoAway(SpdyStreamId last_accepted_stream_id,SpdyErrorCode error_code)360   void OnGoAway(SpdyStreamId last_accepted_stream_id,
361                 SpdyErrorCode error_code) override {
362     QUICHE_VLOG(1) << "OnGoAway(" << last_accepted_stream_id << ", "
363                    << error_code << ")";
364     ++goaway_count_;
365   }
366 
OnHeaders(SpdyStreamId stream_id,size_t payload_length,bool has_priority,int weight,SpdyStreamId parent_stream_id,bool exclusive,bool fin,bool end)367   void OnHeaders(SpdyStreamId stream_id, size_t payload_length,
368                  bool has_priority, int weight, SpdyStreamId parent_stream_id,
369                  bool exclusive, bool fin, bool end) override {
370     QUICHE_VLOG(1) << "OnHeaders(" << stream_id << ", " << payload_length
371                    << ", " << has_priority << ", " << weight << ", "
372                    << parent_stream_id << ", " << exclusive << ", " << fin
373                    << ", " << end << ")";
374     ++headers_frame_count_;
375     InitHeaderStreaming(SpdyFrameType::HEADERS, stream_id);
376     if (fin) {
377       ++fin_flag_count_;
378     }
379     header_has_priority_ = has_priority;
380     header_parent_stream_id_ = parent_stream_id;
381     header_exclusive_ = exclusive;
382   }
383 
OnWindowUpdate(SpdyStreamId stream_id,int delta_window_size)384   void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {
385     QUICHE_VLOG(1) << "OnWindowUpdate(" << stream_id << ", "
386                    << delta_window_size << ")";
387     last_window_update_stream_ = stream_id;
388     last_window_update_delta_ = delta_window_size;
389   }
390 
OnPushPromise(SpdyStreamId stream_id,SpdyStreamId promised_stream_id,bool end)391   void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id,
392                      bool end) override {
393     QUICHE_VLOG(1) << "OnPushPromise(" << stream_id << ", "
394                    << promised_stream_id << ", " << end << ")";
395     ++push_promise_frame_count_;
396     InitHeaderStreaming(SpdyFrameType::PUSH_PROMISE, stream_id);
397     last_push_promise_stream_ = stream_id;
398     last_push_promise_promised_stream_ = promised_stream_id;
399   }
400 
OnContinuation(SpdyStreamId stream_id,size_t payload_size,bool end)401   void OnContinuation(SpdyStreamId stream_id, size_t payload_size,
402                       bool end) override {
403     QUICHE_VLOG(1) << "OnContinuation(" << stream_id << ", " << payload_size
404                    << ", " << end << ")";
405     ++continuation_count_;
406   }
407 
OnAltSvc(SpdyStreamId stream_id,absl::string_view origin,const SpdyAltSvcWireFormat::AlternativeServiceVector & altsvc_vector)408   void OnAltSvc(SpdyStreamId stream_id, absl::string_view origin,
409                 const SpdyAltSvcWireFormat::AlternativeServiceVector&
410                     altsvc_vector) override {
411     QUICHE_VLOG(1) << "OnAltSvc(" << stream_id << ", \"" << origin
412                    << "\", altsvc_vector)";
413     test_altsvc_ir_ = std::make_unique<SpdyAltSvcIR>(stream_id);
414     if (origin.length() > 0) {
415       test_altsvc_ir_->set_origin(std::string(origin));
416     }
417     for (const auto& altsvc : altsvc_vector) {
418       test_altsvc_ir_->add_altsvc(altsvc);
419     }
420     ++altsvc_count_;
421   }
422 
OnPriority(SpdyStreamId stream_id,SpdyStreamId parent_stream_id,int weight,bool exclusive)423   void OnPriority(SpdyStreamId stream_id, SpdyStreamId parent_stream_id,
424                   int weight, bool exclusive) override {
425     QUICHE_VLOG(1) << "OnPriority(" << stream_id << ", " << parent_stream_id
426                    << ", " << weight << ", " << (exclusive ? 1 : 0) << ")";
427     ++priority_count_;
428   }
429 
OnPriorityUpdate(SpdyStreamId prioritized_stream_id,absl::string_view priority_field_value)430   void OnPriorityUpdate(SpdyStreamId prioritized_stream_id,
431                         absl::string_view priority_field_value) override {
432     QUICHE_VLOG(1) << "OnPriorityUpdate(" << prioritized_stream_id << ", "
433                    << priority_field_value << ")";
434   }
435 
OnUnknownFrame(SpdyStreamId stream_id,uint8_t frame_type)436   bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override {
437     QUICHE_VLOG(1) << "OnUnknownFrame(" << stream_id << ", " << frame_type
438                    << ")";
439     return on_unknown_frame_result_;
440   }
441 
OnUnknownFrameStart(SpdyStreamId stream_id,size_t length,uint8_t type,uint8_t flags)442   void OnUnknownFrameStart(SpdyStreamId stream_id, size_t length, uint8_t type,
443                            uint8_t flags) override {
444     QUICHE_VLOG(1) << "OnUnknownFrameStart(" << stream_id << ", " << length
445                    << ", " << static_cast<int>(type) << ", "
446                    << static_cast<int>(flags) << ")";
447     ++unknown_frame_count_;
448   }
449 
OnUnknownFramePayload(SpdyStreamId stream_id,absl::string_view payload)450   void OnUnknownFramePayload(SpdyStreamId stream_id,
451                              absl::string_view payload) override {
452     QUICHE_VLOG(1) << "OnUnknownFramePayload(" << stream_id << ", " << payload
453                    << ")";
454     unknown_payload_len_ += payload.length();
455   }
456 
OnSendCompressedFrame(SpdyStreamId stream_id,SpdyFrameType type,size_t payload_len,size_t frame_len)457   void OnSendCompressedFrame(SpdyStreamId stream_id, SpdyFrameType type,
458                              size_t payload_len, size_t frame_len) override {
459     QUICHE_VLOG(1) << "OnSendCompressedFrame(" << stream_id << ", " << type
460                    << ", " << payload_len << ", " << frame_len << ")";
461     last_payload_len_ = payload_len;
462     last_frame_len_ = frame_len;
463   }
464 
OnReceiveCompressedFrame(SpdyStreamId stream_id,SpdyFrameType type,size_t frame_len)465   void OnReceiveCompressedFrame(SpdyStreamId stream_id, SpdyFrameType type,
466                                 size_t frame_len) override {
467     QUICHE_VLOG(1) << "OnReceiveCompressedFrame(" << stream_id << ", " << type
468                    << ", " << frame_len << ")";
469     last_frame_len_ = frame_len;
470   }
471 
472   // Convenience function which runs a framer simulation with particular input.
SimulateInFramer(const unsigned char * input,size_t size)473   void SimulateInFramer(const unsigned char* input, size_t size) {
474     deframer_.set_visitor(this);
475     size_t input_remaining = size;
476     const char* input_ptr = reinterpret_cast<const char*>(input);
477     while (input_remaining > 0 && deframer_.spdy_framer_error() ==
478                                       Http2DecoderAdapter::SPDY_NO_ERROR) {
479       // To make the tests more interesting, we feed random (and small) chunks
480       // into the framer.  This simulates getting strange-sized reads from
481       // the socket.
482       const size_t kMaxReadSize = 32;
483       size_t bytes_read =
484           (rand() % std::min(input_remaining, kMaxReadSize)) + 1;  // NOLINT
485       size_t bytes_processed = deframer_.ProcessInput(input_ptr, bytes_read);
486       input_remaining -= bytes_processed;
487       input_ptr += bytes_processed;
488     }
489   }
490 
InitHeaderStreaming(SpdyFrameType header_control_type,SpdyStreamId stream_id)491   void InitHeaderStreaming(SpdyFrameType header_control_type,
492                            SpdyStreamId stream_id) {
493     if (!IsDefinedFrameType(SerializeFrameType(header_control_type))) {
494       QUICHE_DLOG(FATAL) << "Attempted to init header streaming with "
495                          << "invalid control frame type: "
496                          << header_control_type;
497     }
498     memset(header_buffer_.get(), 0, header_buffer_size_);
499     header_buffer_length_ = 0;
500     header_stream_id_ = stream_id;
501     header_control_type_ = header_control_type;
502     header_buffer_valid_ = true;
503   }
504 
set_extension_visitor(ExtensionVisitorInterface * extension)505   void set_extension_visitor(ExtensionVisitorInterface* extension) {
506     deframer_.set_extension_visitor(extension);
507   }
508 
509   // Override the default buffer size (16K). Call before using the framer!
set_header_buffer_size(size_t header_buffer_size)510   void set_header_buffer_size(size_t header_buffer_size) {
511     header_buffer_size_ = header_buffer_size;
512     header_buffer_.reset(new char[header_buffer_size]);
513   }
514 
515   SpdyFramer framer_;
516   Http2DecoderAdapter deframer_;
517 
518   // Counters from the visitor callbacks.
519   int error_count_;
520   int headers_frame_count_;
521   int push_promise_frame_count_;
522   int goaway_count_;
523   int setting_count_;
524   int settings_ack_sent_;
525   int settings_ack_received_;
526   int continuation_count_;
527   int altsvc_count_;
528   int priority_count_;
529   std::unique_ptr<SpdyAltSvcIR> test_altsvc_ir_;
530   int unknown_frame_count_;
531   bool on_unknown_frame_result_;
532   SpdyStreamId last_window_update_stream_;
533   int last_window_update_delta_;
534   SpdyStreamId last_push_promise_stream_;
535   SpdyStreamId last_push_promise_promised_stream_;
536   int data_bytes_;
537   int fin_frame_count_;      // The count of RST_STREAM type frames received.
538   int fin_flag_count_;       // The count of frames with the FIN flag set.
539   int end_of_stream_count_;  // The count of zero-length data frames.
540   int control_frame_header_data_count_;  // The count of chunks received.
541   // The count of zero-length control frame header data chunks received.
542   int zero_length_control_frame_header_data_count_;
543   int data_frame_count_;
544   size_t last_payload_len_;
545   size_t last_frame_len_;
546   size_t unknown_payload_len_;
547 
548   // Header block streaming state:
549   std::unique_ptr<char[]> header_buffer_;
550   size_t header_buffer_length_;
551   size_t header_buffer_size_;
552   size_t header_bytes_received_;
553   SpdyStreamId header_stream_id_;
554   SpdyFrameType header_control_type_;
555   bool header_buffer_valid_;
556   std::unique_ptr<RecordingHeadersHandler> headers_handler_;
557   Http2HeaderBlock headers_;
558   bool header_has_priority_;
559   SpdyStreamId header_parent_stream_id_;
560   bool header_exclusive_;
561 };
562 
563 class TestExtension : public ExtensionVisitorInterface {
564  public:
OnSetting(SpdySettingsId id,uint32_t value)565   void OnSetting(SpdySettingsId id, uint32_t value) override {
566     settings_received_.push_back({id, value});
567   }
568 
569   // Called when non-standard frames are received.
OnFrameHeader(SpdyStreamId stream_id,size_t length,uint8_t type,uint8_t flags)570   bool OnFrameHeader(SpdyStreamId stream_id, size_t length, uint8_t type,
571                      uint8_t flags) override {
572     stream_id_ = stream_id;
573     length_ = length;
574     type_ = type;
575     flags_ = flags;
576     return true;
577   }
578 
579   // The payload for a single frame may be delivered as multiple calls to
580   // OnFramePayload.
OnFramePayload(const char * data,size_t len)581   void OnFramePayload(const char* data, size_t len) override {
582     payload_.append(data, len);
583   }
584 
585   std::vector<std::pair<SpdySettingsId, uint32_t>> settings_received_;
586   SpdyStreamId stream_id_ = 0;
587   size_t length_ = 0;
588   uint8_t type_ = 0;
589   uint8_t flags_ = 0;
590   std::string payload_;
591 };
592 
593 // Exposes SpdyUnknownIR::set_length() for testing purposes.
594 class TestSpdyUnknownIR : public SpdyUnknownIR {
595  public:
596   using SpdyUnknownIR::set_length;
597   using SpdyUnknownIR::SpdyUnknownIR;
598 };
599 
600 enum Output { USE, NOT_USE };
601 
602 class SpdyFramerTest : public quiche::test::QuicheTestWithParam<Output> {
603  public:
SpdyFramerTest()604   SpdyFramerTest()
605       : output_(output_buffer, kSize),
606         framer_(SpdyFramer::ENABLE_COMPRESSION),
607         deframer_(std::make_unique<Http2DecoderAdapter>()) {}
608 
609  protected:
SetUp()610   void SetUp() override {
611     switch (GetParam()) {
612       case USE:
613         use_output_ = true;
614         break;
615       case NOT_USE:
616         // TODO(yasong): remove this case after
617         // gfe2_reloadable_flag_write_queue_zero_copy_buffer deprecates.
618         use_output_ = false;
619         break;
620     }
621   }
622 
CompareFrame(const std::string & description,const SpdySerializedFrame & actual_frame,const unsigned char * expected,const int expected_len)623   void CompareFrame(const std::string& description,
624                     const SpdySerializedFrame& actual_frame,
625                     const unsigned char* expected, const int expected_len) {
626     const unsigned char* actual =
627         reinterpret_cast<const unsigned char*>(actual_frame.data());
628     CompareCharArraysWithHexError(description, actual, actual_frame.size(),
629                                   expected, expected_len);
630   }
631 
632   bool use_output_ = false;
633   ArrayOutputBuffer output_;
634   SpdyFramer framer_;
635   std::unique_ptr<Http2DecoderAdapter> deframer_;
636 };
637 
638 INSTANTIATE_TEST_SUITE_P(SpdyFramerTests, SpdyFramerTest,
639                          ::testing::Values(USE, NOT_USE));
640 
641 // Test that we can encode and decode a Http2HeaderBlock in serialized form.
TEST_P(SpdyFramerTest,HeaderBlockInBuffer)642 TEST_P(SpdyFramerTest, HeaderBlockInBuffer) {
643   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
644 
645   // Encode the header block into a Headers frame.
646   SpdyHeadersIR headers(/* stream_id = */ 1);
647   headers.SetHeader("alpha", "beta");
648   headers.SetHeader("gamma", "charlie");
649   headers.SetHeader("cookie", "key1=value1; key2=value2");
650   SpdySerializedFrame frame(
651       SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
652 
653   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
654   visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
655                            frame.size());
656 
657   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
658   EXPECT_EQ(headers.header_block(), visitor.headers_);
659 }
660 
661 // Test that if there's not a full frame, we fail to parse it.
TEST_P(SpdyFramerTest,UndersizedHeaderBlockInBuffer)662 TEST_P(SpdyFramerTest, UndersizedHeaderBlockInBuffer) {
663   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
664 
665   // Encode the header block into a Headers frame.
666   SpdyHeadersIR headers(/* stream_id = */ 1);
667   headers.SetHeader("alpha", "beta");
668   headers.SetHeader("gamma", "charlie");
669   SpdySerializedFrame frame(
670       SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
671 
672   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
673   visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
674                            frame.size() - 2);
675 
676   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
677   EXPECT_THAT(visitor.headers_, testing::IsEmpty());
678 }
679 
680 // Test that we can encode and decode stream dependency values in a header
681 // frame.
TEST_P(SpdyFramerTest,HeaderStreamDependencyValues)682 TEST_P(SpdyFramerTest, HeaderStreamDependencyValues) {
683   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
684 
685   const SpdyStreamId parent_stream_id_test_array[] = {0, 3};
686   for (SpdyStreamId parent_stream_id : parent_stream_id_test_array) {
687     const bool exclusive_test_array[] = {true, false};
688     for (bool exclusive : exclusive_test_array) {
689       SpdyHeadersIR headers(1);
690       headers.set_has_priority(true);
691       headers.set_parent_stream_id(parent_stream_id);
692       headers.set_exclusive(exclusive);
693       SpdySerializedFrame frame(
694           SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
695 
696       TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
697       visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
698                                frame.size());
699 
700       EXPECT_TRUE(visitor.header_has_priority_);
701       EXPECT_EQ(parent_stream_id, visitor.header_parent_stream_id_);
702       EXPECT_EQ(exclusive, visitor.header_exclusive_);
703     }
704   }
705 }
706 
707 // Test that if we receive a frame with a payload length field at the default
708 // max size, we do not set an error in ProcessInput.
TEST_P(SpdyFramerTest,AcceptMaxFrameSizeSetting)709 TEST_P(SpdyFramerTest, AcceptMaxFrameSizeSetting) {
710   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
711   deframer_->set_visitor(&visitor);
712 
713   // DATA frame with maximum allowed payload length.
714   unsigned char kH2FrameData[] = {
715       0x00, 0x40, 0x00,        // Length: 2^14
716       0x00,                    //   Type: DATA
717       0x00,                    //  Flags: None
718       0x00, 0x00, 0x00, 0x01,  // Stream: 1
719       0x00, 0x00, 0x00, 0x00,  // Junk payload
720   };
721 
722   SpdySerializedFrame frame = MakeSerializedFrame(
723       reinterpret_cast<char*>(kH2FrameData), sizeof(kH2FrameData));
724 
725   EXPECT_CALL(visitor, OnCommonHeader(1, 16384, 0x0, 0x0));
726   EXPECT_CALL(visitor, OnDataFrameHeader(1, 1 << 14, false));
727   EXPECT_CALL(visitor, OnStreamFrameData(1, _, 4));
728   deframer_->ProcessInput(frame.data(), frame.size());
729   EXPECT_FALSE(deframer_->HasError());
730 }
731 
732 // Test that if we receive a frame with a payload length larger than the default
733 // max size, we set an error of SPDY_INVALID_CONTROL_FRAME_SIZE.
TEST_P(SpdyFramerTest,ExceedMaxFrameSizeSetting)734 TEST_P(SpdyFramerTest, ExceedMaxFrameSizeSetting) {
735   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
736   deframer_->set_visitor(&visitor);
737 
738   // DATA frame with too large payload length.
739   unsigned char kH2FrameData[] = {
740       0x00, 0x40, 0x01,        // Length: 2^14 + 1
741       0x00,                    //   Type: DATA
742       0x00,                    //  Flags: None
743       0x00, 0x00, 0x00, 0x01,  // Stream: 1
744       0x00, 0x00, 0x00, 0x00,  // Junk payload
745   };
746 
747   SpdySerializedFrame frame = MakeSerializedFrame(
748       reinterpret_cast<char*>(kH2FrameData), sizeof(kH2FrameData));
749 
750   EXPECT_CALL(visitor, OnCommonHeader(1, 16385, 0x0, 0x0));
751   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD, _));
752   deframer_->ProcessInput(frame.data(), frame.size());
753   EXPECT_TRUE(deframer_->HasError());
754   EXPECT_EQ(Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD,
755             deframer_->spdy_framer_error())
756       << Http2DecoderAdapter::SpdyFramerErrorToString(
757              deframer_->spdy_framer_error());
758 }
759 
760 // Test that if we set a larger max frame size and then receive a frame with a
761 // payload length at that larger size, we do not set an error in ProcessInput.
TEST_P(SpdyFramerTest,AcceptLargerMaxFrameSizeSetting)762 TEST_P(SpdyFramerTest, AcceptLargerMaxFrameSizeSetting) {
763   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
764   deframer_->set_visitor(&visitor);
765 
766   const size_t big_frame_size = (1 << 14) + 1;
767   deframer_->SetMaxFrameSize(big_frame_size);
768 
769   // DATA frame with larger-than-default but acceptable payload length.
770   unsigned char kH2FrameData[] = {
771       0x00, 0x40, 0x01,        // Length: 2^14 + 1
772       0x00,                    //   Type: DATA
773       0x00,                    //  Flags: None
774       0x00, 0x00, 0x00, 0x01,  // Stream: 1
775       0x00, 0x00, 0x00, 0x00,  // Junk payload
776   };
777 
778   SpdySerializedFrame frame = MakeSerializedFrame(
779       reinterpret_cast<char*>(kH2FrameData), sizeof(kH2FrameData));
780 
781   EXPECT_CALL(visitor, OnCommonHeader(1, big_frame_size, 0x0, 0x0));
782   EXPECT_CALL(visitor, OnDataFrameHeader(1, big_frame_size, false));
783   EXPECT_CALL(visitor, OnStreamFrameData(1, _, 4));
784   deframer_->ProcessInput(frame.data(), frame.size());
785   EXPECT_FALSE(deframer_->HasError());
786 }
787 
788 // Test that if we receive a DATA frame with padding length larger than the
789 // payload length, we set an error of SPDY_INVALID_PADDING
TEST_P(SpdyFramerTest,OversizedDataPaddingError)790 TEST_P(SpdyFramerTest, OversizedDataPaddingError) {
791   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
792   deframer_->set_visitor(&visitor);
793 
794   // DATA frame with invalid padding length.
795   // |kH2FrameData| has to be |unsigned char|, because Chromium on Windows uses
796   // MSVC, where |char| is signed by default, which would not compile because of
797   // the element exceeding 127.
798   unsigned char kH2FrameData[] = {
799       0x00, 0x00, 0x05,        // Length: 5
800       0x00,                    //   Type: DATA
801       0x09,                    //  Flags: END_STREAM|PADDED
802       0x00, 0x00, 0x00, 0x01,  // Stream: 1
803       0xff,                    // PadLen: 255 trailing bytes (Too Long)
804       0x00, 0x00, 0x00, 0x00,  // Padding
805   };
806 
807   SpdySerializedFrame frame = MakeSerializedFrame(
808       reinterpret_cast<char*>(kH2FrameData), sizeof(kH2FrameData));
809 
810   {
811     testing::InSequence seq;
812     EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x0, 0x9));
813     EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, 1));
814     EXPECT_CALL(visitor, OnStreamPadding(1, 1));
815     EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_PADDING, _));
816   }
817   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
818   EXPECT_TRUE(deframer_->HasError());
819   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_PADDING,
820             deframer_->spdy_framer_error())
821       << Http2DecoderAdapter::SpdyFramerErrorToString(
822              deframer_->spdy_framer_error());
823 }
824 
825 // Test that if we receive a DATA frame with padding length not larger than the
826 // payload length, we do not set an error of SPDY_INVALID_PADDING
TEST_P(SpdyFramerTest,CorrectlySizedDataPaddingNoError)827 TEST_P(SpdyFramerTest, CorrectlySizedDataPaddingNoError) {
828   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
829 
830   deframer_->set_visitor(&visitor);
831 
832   // DATA frame with valid Padding length
833   char kH2FrameData[] = {
834       0x00, 0x00, 0x05,        // Length: 5
835       0x00,                    //   Type: DATA
836       0x08,                    //  Flags: PADDED
837       0x00, 0x00, 0x00, 0x01,  // Stream: 1
838       0x04,                    // PadLen: 4 trailing bytes
839       0x00, 0x00, 0x00, 0x00,  // Padding
840   };
841 
842   SpdySerializedFrame frame =
843       MakeSerializedFrame(kH2FrameData, sizeof(kH2FrameData));
844 
845   {
846     testing::InSequence seq;
847     EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x0, 0x8));
848     EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, false));
849     EXPECT_CALL(visitor, OnStreamPadLength(1, 4));
850     EXPECT_CALL(visitor, OnError(_, _)).Times(0);
851     // Note that OnStreamFrameData(1, _, 1)) is never called
852     // since there is no data, only padding
853     EXPECT_CALL(visitor, OnStreamPadding(1, 4));
854   }
855 
856   EXPECT_EQ(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
857   EXPECT_FALSE(deframer_->HasError());
858   EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
859       << Http2DecoderAdapter::SpdyFramerErrorToString(
860              deframer_->spdy_framer_error());
861 }
862 
863 // Test that if we receive a HEADERS frame with padding length larger than the
864 // payload length, we set an error of SPDY_INVALID_PADDING
TEST_P(SpdyFramerTest,OversizedHeadersPaddingError)865 TEST_P(SpdyFramerTest, OversizedHeadersPaddingError) {
866   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
867 
868   deframer_->set_visitor(&visitor);
869 
870   // HEADERS frame with invalid padding length.
871   // |kH2FrameData| has to be |unsigned char|, because Chromium on Windows uses
872   // MSVC, where |char| is signed by default, which would not compile because of
873   // the element exceeding 127.
874   unsigned char kH2FrameData[] = {
875       0x00, 0x00, 0x05,        // Length: 5
876       0x01,                    //   Type: HEADERS
877       0x08,                    //  Flags: PADDED
878       0x00, 0x00, 0x00, 0x01,  // Stream: 1
879       0xff,                    // PadLen: 255 trailing bytes (Too Long)
880       0x00, 0x00, 0x00, 0x00,  // Padding
881   };
882 
883   SpdySerializedFrame frame = MakeSerializedFrame(
884       reinterpret_cast<char*>(kH2FrameData), sizeof(kH2FrameData));
885 
886   EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x1, 0x8));
887   EXPECT_CALL(visitor, OnHeaders(1, 5, false, 0, 0, false, false, false));
888   EXPECT_CALL(visitor, OnHeaderFrameStart(1)).Times(1);
889   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_PADDING, _));
890   EXPECT_EQ(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
891   EXPECT_TRUE(deframer_->HasError());
892   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_PADDING,
893             deframer_->spdy_framer_error())
894       << Http2DecoderAdapter::SpdyFramerErrorToString(
895              deframer_->spdy_framer_error());
896 }
897 
898 // Test that if we receive a HEADERS frame with padding length not larger
899 // than the payload length, we do not set an error of SPDY_INVALID_PADDING
TEST_P(SpdyFramerTest,CorrectlySizedHeadersPaddingNoError)900 TEST_P(SpdyFramerTest, CorrectlySizedHeadersPaddingNoError) {
901   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
902 
903   deframer_->set_visitor(&visitor);
904 
905   // HEADERS frame with invalid Padding length
906   char kH2FrameData[] = {
907       0x00, 0x00, 0x05,        // Length: 5
908       0x01,                    //   Type: HEADERS
909       0x08,                    //  Flags: PADDED
910       0x00, 0x00, 0x00, 0x01,  // Stream: 1
911       0x04,                    // PadLen: 4 trailing bytes
912       0x00, 0x00, 0x00, 0x00,  // Padding
913   };
914 
915   SpdySerializedFrame frame =
916       MakeSerializedFrame(kH2FrameData, sizeof(kH2FrameData));
917 
918   EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x1, 0x8));
919   EXPECT_CALL(visitor, OnHeaders(1, 5, false, 0, 0, false, false, false));
920   EXPECT_CALL(visitor, OnHeaderFrameStart(1)).Times(1);
921 
922   EXPECT_EQ(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
923   EXPECT_FALSE(deframer_->HasError());
924   EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
925       << Http2DecoderAdapter::SpdyFramerErrorToString(
926              deframer_->spdy_framer_error());
927 }
928 
929 // Test that if we receive a DATA with stream ID zero, we signal an error
930 // (but don't crash).
TEST_P(SpdyFramerTest,DataWithStreamIdZero)931 TEST_P(SpdyFramerTest, DataWithStreamIdZero) {
932   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
933 
934   deframer_->set_visitor(&visitor);
935 
936   const char bytes[] = "hello";
937   SpdyDataIR data_ir(/* stream_id = */ 0, bytes);
938   SpdySerializedFrame frame(framer_.SerializeData(data_ir));
939 
940   // We shouldn't have to read the whole frame before we signal an error.
941   EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x0, _));
942   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
943   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
944   EXPECT_TRUE(deframer_->HasError());
945   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
946             deframer_->spdy_framer_error())
947       << Http2DecoderAdapter::SpdyFramerErrorToString(
948              deframer_->spdy_framer_error());
949 }
950 
951 // Test that if we receive a HEADERS with stream ID zero, we signal an error
952 // (but don't crash).
TEST_P(SpdyFramerTest,HeadersWithStreamIdZero)953 TEST_P(SpdyFramerTest, HeadersWithStreamIdZero) {
954   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
955 
956   deframer_->set_visitor(&visitor);
957 
958   SpdyHeadersIR headers(/* stream_id = */ 0);
959   headers.SetHeader("alpha", "beta");
960   SpdySerializedFrame frame(
961       SpdyFramerPeer::SerializeHeaders(&framer_, headers, &output_));
962 
963   // We shouldn't have to read the whole frame before we signal an error.
964   EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x1, _));
965   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
966   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
967   EXPECT_TRUE(deframer_->HasError());
968   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
969             deframer_->spdy_framer_error())
970       << Http2DecoderAdapter::SpdyFramerErrorToString(
971              deframer_->spdy_framer_error());
972 }
973 
974 // Test that if we receive a PRIORITY with stream ID zero, we signal an error
975 // (but don't crash).
TEST_P(SpdyFramerTest,PriorityWithStreamIdZero)976 TEST_P(SpdyFramerTest, PriorityWithStreamIdZero) {
977   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
978 
979   deframer_->set_visitor(&visitor);
980 
981   SpdyPriorityIR priority_ir(/* stream_id = */ 0,
982                              /* parent_stream_id = */ 1,
983                              /* weight = */ 16,
984                              /* exclusive = */ true);
985   SpdySerializedFrame frame(framer_.SerializeFrame(priority_ir));
986   if (use_output_) {
987     EXPECT_EQ(framer_.SerializeFrame(priority_ir, &output_), frame.size());
988     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
989   }
990 
991   // We shouldn't have to read the whole frame before we signal an error.
992   EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x2, _));
993   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
994   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
995   EXPECT_TRUE(deframer_->HasError());
996   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
997             deframer_->spdy_framer_error())
998       << Http2DecoderAdapter::SpdyFramerErrorToString(
999              deframer_->spdy_framer_error());
1000 }
1001 
1002 // Test that if we receive a RST_STREAM with stream ID zero, we signal an error
1003 // (but don't crash).
TEST_P(SpdyFramerTest,RstStreamWithStreamIdZero)1004 TEST_P(SpdyFramerTest, RstStreamWithStreamIdZero) {
1005   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
1006 
1007   deframer_->set_visitor(&visitor);
1008 
1009   SpdyRstStreamIR rst_stream_ir(/* stream_id = */ 0, ERROR_CODE_PROTOCOL_ERROR);
1010   SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream_ir));
1011   if (use_output_) {
1012     EXPECT_TRUE(framer_.SerializeRstStream(rst_stream_ir, &output_));
1013     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1014   }
1015 
1016   // We shouldn't have to read the whole frame before we signal an error.
1017   EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x3, _));
1018   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
1019   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
1020   EXPECT_TRUE(deframer_->HasError());
1021   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
1022             deframer_->spdy_framer_error())
1023       << Http2DecoderAdapter::SpdyFramerErrorToString(
1024              deframer_->spdy_framer_error());
1025 }
1026 
1027 // Test that if we receive a SETTINGS with stream ID other than zero,
1028 // we signal an error (but don't crash).
TEST_P(SpdyFramerTest,SettingsWithStreamIdNotZero)1029 TEST_P(SpdyFramerTest, SettingsWithStreamIdNotZero) {
1030   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
1031 
1032   deframer_->set_visitor(&visitor);
1033 
1034   // Settings frame with invalid StreamID of 0x01
1035   char kH2FrameData[] = {
1036       0x00, 0x00, 0x06,        // Length: 6
1037       0x04,                    //   Type: SETTINGS
1038       0x00,                    //  Flags: none
1039       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1040       0x00, 0x04,              //  Param: INITIAL_WINDOW_SIZE
1041       0x0a, 0x0b, 0x0c, 0x0d,  //  Value: 168496141
1042   };
1043 
1044   SpdySerializedFrame frame =
1045       MakeSerializedFrame(kH2FrameData, sizeof(kH2FrameData));
1046 
1047   // We shouldn't have to read the whole frame before we signal an error.
1048   EXPECT_CALL(visitor, OnCommonHeader(1, 6, 0x4, 0x0));
1049   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
1050   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
1051   EXPECT_TRUE(deframer_->HasError());
1052   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
1053             deframer_->spdy_framer_error())
1054       << Http2DecoderAdapter::SpdyFramerErrorToString(
1055              deframer_->spdy_framer_error());
1056 }
1057 
1058 // Test that if we receive a GOAWAY with stream ID other than zero,
1059 // we signal an error (but don't crash).
TEST_P(SpdyFramerTest,GoawayWithStreamIdNotZero)1060 TEST_P(SpdyFramerTest, GoawayWithStreamIdNotZero) {
1061   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
1062 
1063   deframer_->set_visitor(&visitor);
1064 
1065   // GOAWAY frame with invalid StreamID of 0x01
1066   char kH2FrameData[] = {
1067       0x00, 0x00, 0x0a,        // Length: 10
1068       0x07,                    //   Type: GOAWAY
1069       0x00,                    //  Flags: none
1070       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1071       0x00, 0x00, 0x00, 0x00,  //   Last: 0
1072       0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
1073       0x47, 0x41,              // Description
1074   };
1075 
1076   SpdySerializedFrame frame =
1077       MakeSerializedFrame(kH2FrameData, sizeof(kH2FrameData));
1078 
1079   // We shouldn't have to read the whole frame before we signal an error.
1080   EXPECT_CALL(visitor, OnCommonHeader(1, 10, 0x7, 0x0));
1081   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
1082   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
1083   EXPECT_TRUE(deframer_->HasError());
1084   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
1085             deframer_->spdy_framer_error())
1086       << Http2DecoderAdapter::SpdyFramerErrorToString(
1087              deframer_->spdy_framer_error());
1088 }
1089 
1090 // Test that if we receive a CONTINUATION with stream ID zero, we signal
1091 // SPDY_INVALID_STREAM_ID.
TEST_P(SpdyFramerTest,ContinuationWithStreamIdZero)1092 TEST_P(SpdyFramerTest, ContinuationWithStreamIdZero) {
1093   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
1094 
1095   deframer_->set_visitor(&visitor);
1096 
1097   SpdyContinuationIR continuation(/* stream_id = */ 0);
1098   std::string some_nonsense_encoding = "some nonsense encoding";
1099   continuation.take_encoding(std::move(some_nonsense_encoding));
1100   continuation.set_end_headers(true);
1101   SpdySerializedFrame frame(framer_.SerializeContinuation(continuation));
1102   if (use_output_) {
1103     ASSERT_TRUE(framer_.SerializeContinuation(continuation, &output_));
1104     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1105   }
1106 
1107   // We shouldn't have to read the whole frame before we signal an error.
1108   EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x9, _));
1109   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
1110   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
1111   EXPECT_TRUE(deframer_->HasError());
1112   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
1113             deframer_->spdy_framer_error())
1114       << Http2DecoderAdapter::SpdyFramerErrorToString(
1115              deframer_->spdy_framer_error());
1116 }
1117 
1118 // Test that if we receive a PUSH_PROMISE with stream ID zero, we signal
1119 // SPDY_INVALID_STREAM_ID.
TEST_P(SpdyFramerTest,PushPromiseWithStreamIdZero)1120 TEST_P(SpdyFramerTest, PushPromiseWithStreamIdZero) {
1121   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
1122 
1123   deframer_->set_visitor(&visitor);
1124 
1125   SpdyPushPromiseIR push_promise(/* stream_id = */ 0,
1126                                  /* promised_stream_id = */ 4);
1127   push_promise.SetHeader("alpha", "beta");
1128   SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
1129       &framer_, push_promise, use_output_ ? &output_ : nullptr));
1130 
1131   // We shouldn't have to read the whole frame before we signal an error.
1132   EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x5, _));
1133   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
1134   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
1135   EXPECT_TRUE(deframer_->HasError());
1136   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID,
1137             deframer_->spdy_framer_error())
1138       << Http2DecoderAdapter::SpdyFramerErrorToString(
1139              deframer_->spdy_framer_error());
1140 }
1141 
1142 // Test that if we receive a PUSH_PROMISE with promised stream ID zero, we
1143 // signal SPDY_INVALID_CONTROL_FRAME.
TEST_P(SpdyFramerTest,PushPromiseWithPromisedStreamIdZero)1144 TEST_P(SpdyFramerTest, PushPromiseWithPromisedStreamIdZero) {
1145   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
1146 
1147   deframer_->set_visitor(&visitor);
1148 
1149   SpdyPushPromiseIR push_promise(/* stream_id = */ 3,
1150                                  /* promised_stream_id = */ 0);
1151   push_promise.SetHeader("alpha", "beta");
1152   SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
1153       &framer_, push_promise, use_output_ ? &output_ : nullptr));
1154 
1155   EXPECT_CALL(visitor, OnCommonHeader(3, _, 0x5, _));
1156   EXPECT_CALL(visitor,
1157               OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME, _));
1158   deframer_->ProcessInput(frame.data(), frame.size());
1159   EXPECT_TRUE(deframer_->HasError());
1160   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
1161             deframer_->spdy_framer_error())
1162       << Http2DecoderAdapter::SpdyFramerErrorToString(
1163              deframer_->spdy_framer_error());
1164 }
1165 
TEST_P(SpdyFramerTest,MultiValueHeader)1166 TEST_P(SpdyFramerTest, MultiValueHeader) {
1167   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
1168   std::string value("value1\0value2", 13);
1169   // TODO(jgraettinger): If this pattern appears again, move to test class.
1170   Http2HeaderBlock header_set;
1171   header_set["name"] = value;
1172   HpackEncoder encoder;
1173   encoder.DisableCompression();
1174   std::string buffer = encoder.EncodeHeaderBlock(header_set);
1175   // Frame builder with plentiful buffer size.
1176   SpdyFrameBuilder frame(1024);
1177   frame.BeginNewFrame(SpdyFrameType::HEADERS,
1178                       HEADERS_FLAG_PRIORITY | HEADERS_FLAG_END_HEADERS, 3,
1179                       buffer.size() + 5 /* priority */);
1180   frame.WriteUInt32(0);   // Priority exclusivity and dependent stream.
1181   frame.WriteUInt8(255);  // Priority weight.
1182   frame.WriteBytes(&buffer[0], buffer.size());
1183 
1184   SpdySerializedFrame control_frame(frame.take());
1185 
1186   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
1187   visitor.SimulateInFramer(
1188       reinterpret_cast<unsigned char*>(control_frame.data()),
1189       control_frame.size());
1190 
1191   EXPECT_THAT(visitor.headers_, testing::ElementsAre(testing::Pair(
1192                                     "name", absl::string_view(value))));
1193 }
1194 
TEST_P(SpdyFramerTest,CompressEmptyHeaders)1195 TEST_P(SpdyFramerTest, CompressEmptyHeaders) {
1196   // See https://crbug.com/172383/
1197   SpdyHeadersIR headers(1);
1198   headers.SetHeader("server", "SpdyServer 1.0");
1199   headers.SetHeader("date", "Mon 12 Jan 2009 12:12:12 PST");
1200   headers.SetHeader("status", "200");
1201   headers.SetHeader("version", "HTTP/1.1");
1202   headers.SetHeader("content-type", "text/html");
1203   headers.SetHeader("content-length", "12");
1204   headers.SetHeader("x-empty-header", "");
1205 
1206   SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
1207   SpdySerializedFrame frame1(
1208       SpdyFramerPeer::SerializeHeaders(&framer, headers, &output_));
1209 }
1210 
TEST_P(SpdyFramerTest,Basic)1211 TEST_P(SpdyFramerTest, Basic) {
1212   // Send HEADERS frames with PRIORITY and END_HEADERS set.
1213   // frame-format off
1214   const unsigned char kH2Input[] = {
1215       0x00, 0x00, 0x05,        // Length: 5
1216       0x01,                    //   Type: HEADERS
1217       0x24,                    //  Flags: END_HEADERS|PRIORITY
1218       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1219       0x00, 0x00, 0x00, 0x00,  // Parent: 0
1220       0x82,                    // Weight: 131
1221 
1222       0x00, 0x00, 0x01,        // Length: 1
1223       0x01,                    //   Type: HEADERS
1224       0x04,                    //  Flags: END_HEADERS
1225       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1226       0x8c,                    // :status: 200
1227 
1228       0x00, 0x00, 0x0c,        // Length: 12
1229       0x00,                    //   Type: DATA
1230       0x00,                    //  Flags: none
1231       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1232       0xde, 0xad, 0xbe, 0xef,  // Payload
1233       0xde, 0xad, 0xbe, 0xef,  //
1234       0xde, 0xad, 0xbe, 0xef,  //
1235 
1236       0x00, 0x00, 0x05,        // Length: 5
1237       0x01,                    //   Type: HEADERS
1238       0x24,                    //  Flags: END_HEADERS|PRIORITY
1239       0x00, 0x00, 0x00, 0x03,  // Stream: 3
1240       0x00, 0x00, 0x00, 0x00,  // Parent: 0
1241       0x82,                    // Weight: 131
1242 
1243       0x00, 0x00, 0x08,        // Length: 8
1244       0x00,                    //   Type: DATA
1245       0x00,                    //  Flags: none
1246       0x00, 0x00, 0x00, 0x03,  // Stream: 3
1247       0xde, 0xad, 0xbe, 0xef,  // Payload
1248       0xde, 0xad, 0xbe, 0xef,  //
1249 
1250       0x00, 0x00, 0x04,        // Length: 4
1251       0x00,                    //   Type: DATA
1252       0x00,                    //  Flags: none
1253       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1254       0xde, 0xad, 0xbe, 0xef,  // Payload
1255 
1256       0x00, 0x00, 0x04,        // Length: 4
1257       0x03,                    //   Type: RST_STREAM
1258       0x00,                    //  Flags: none
1259       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1260       0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
1261 
1262       0x00, 0x00, 0x00,        // Length: 0
1263       0x00,                    //   Type: DATA
1264       0x00,                    //  Flags: none
1265       0x00, 0x00, 0x00, 0x03,  // Stream: 3
1266 
1267       0x00, 0x00, 0x04,        // Length: 4
1268       0x03,                    //   Type: RST_STREAM
1269       0x00,                    //  Flags: none
1270       0x00, 0x00, 0x00, 0x03,  // Stream: 3
1271       0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
1272   };
1273   // frame-format on
1274 
1275   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
1276   visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
1277 
1278   EXPECT_EQ(24, visitor.data_bytes_);
1279   EXPECT_EQ(0, visitor.error_count_);
1280   EXPECT_EQ(2, visitor.fin_frame_count_);
1281 
1282   EXPECT_EQ(3, visitor.headers_frame_count_);
1283 
1284   EXPECT_EQ(0, visitor.fin_flag_count_);
1285   EXPECT_EQ(0, visitor.end_of_stream_count_);
1286   EXPECT_EQ(4, visitor.data_frame_count_);
1287 }
1288 
1289 // Verifies that the decoder stops delivering events after a user error.
TEST_P(SpdyFramerTest,BasicWithError)1290 TEST_P(SpdyFramerTest, BasicWithError) {
1291   // Send HEADERS frames with PRIORITY and END_HEADERS set.
1292   // frame-format off
1293   const unsigned char kH2Input[] = {
1294       0x00, 0x00, 0x01,        // Length: 1
1295       0x01,                    //   Type: HEADERS
1296       0x04,                    //  Flags: END_HEADERS
1297       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1298       0x8c,                    // :status: 200
1299 
1300       0x00, 0x00, 0x0c,        // Length: 12
1301       0x00,                    //   Type: DATA
1302       0x00,                    //  Flags: none
1303       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1304       0xde, 0xad, 0xbe, 0xef,  // Payload
1305       0xde, 0xad, 0xbe, 0xef,  //
1306       0xde, 0xad, 0xbe, 0xef,  //
1307 
1308       0x00, 0x00, 0x06,        // Length: 6
1309       0x01,                    //   Type: HEADERS
1310       0x24,                    //  Flags: END_HEADERS|PRIORITY
1311       0x00, 0x00, 0x00, 0x03,  // Stream: 3
1312       0x00, 0x00, 0x00, 0x00,  // Parent: 0
1313       0x82,                    // Weight: 131
1314       0x8c,                    // :status: 200
1315 
1316       0x00, 0x00, 0x08,        // Length: 8
1317       0x00,                    //   Type: DATA
1318       0x00,                    //  Flags: none
1319       0x00, 0x00, 0x00, 0x03,  // Stream: 3
1320       0xde, 0xad, 0xbe, 0xef,  // Payload
1321       0xde, 0xad, 0xbe, 0xef,  //
1322 
1323       0x00, 0x00, 0x04,        // Length: 4
1324       0x00,                    //   Type: DATA
1325       0x00,                    //  Flags: none
1326       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1327       0xde, 0xad, 0xbe, 0xef,  // Payload
1328 
1329       0x00, 0x00, 0x04,        // Length: 4
1330       0x03,                    //   Type: RST_STREAM
1331       0x00,                    //  Flags: none
1332       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1333       0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
1334 
1335       0x00, 0x00, 0x00,        // Length: 0
1336       0x00,                    //   Type: DATA
1337       0x00,                    //  Flags: none
1338       0x00, 0x00, 0x00, 0x03,  // Stream: 3
1339 
1340       0x00, 0x00, 0x04,        // Length: 4
1341       0x03,                    //   Type: RST_STREAM
1342       0x00,                    //  Flags: none
1343       0x00, 0x00, 0x00, 0x03,  // Stream: 3
1344       0x00, 0x00, 0x00, 0x08,  //  Error: CANCEL
1345   };
1346   // frame-format on
1347 
1348   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
1349 
1350   deframer_->set_visitor(&visitor);
1351 
1352   testing::InSequence s;
1353   EXPECT_CALL(visitor, OnCommonHeader(1, 1, 0x1, 0x4));
1354   EXPECT_CALL(visitor, OnHeaders(1, 1, false, 0, 0, false, false, true));
1355   EXPECT_CALL(visitor, OnHeaderFrameStart(1));
1356   EXPECT_CALL(visitor, OnHeaderFrameEnd(1));
1357   EXPECT_CALL(visitor, OnCommonHeader(1, 12, 0x0, 0x0));
1358   EXPECT_CALL(visitor, OnDataFrameHeader(1, 12, false));
1359   EXPECT_CALL(visitor, OnStreamFrameData(1, _, 12));
1360   EXPECT_CALL(visitor, OnCommonHeader(3, 6, 0x1, 0x24));
1361   EXPECT_CALL(visitor, OnHeaders(3, 6, true, 131, 0, false, false, true));
1362   EXPECT_CALL(visitor, OnHeaderFrameStart(3));
1363   EXPECT_CALL(visitor, OnHeaderFrameEnd(3));
1364   EXPECT_CALL(visitor, OnCommonHeader(3, 8, 0x0, 0x0));
1365   EXPECT_CALL(visitor, OnDataFrameHeader(3, 8, false))
1366       .WillOnce(testing::InvokeWithoutArgs(
1367           [this]() { deframer_->StopProcessing(); }));
1368   // Remaining frames are not processed due to the error.
1369   EXPECT_CALL(
1370       visitor,
1371       OnError(http2::Http2DecoderAdapter::SpdyFramerError::SPDY_STOP_PROCESSING,
1372               "Ignoring further events on this connection."));
1373 
1374   size_t processed = deframer_->ProcessInput(
1375       reinterpret_cast<const char*>(kH2Input), sizeof(kH2Input));
1376   EXPECT_LT(processed, sizeof(kH2Input));
1377 }
1378 
1379 // Test that the FIN flag on a data frame signifies EOF.
TEST_P(SpdyFramerTest,FinOnDataFrame)1380 TEST_P(SpdyFramerTest, FinOnDataFrame) {
1381   // Send HEADERS frames with END_HEADERS set.
1382   // frame-format off
1383   const unsigned char kH2Input[] = {
1384       0x00, 0x00, 0x05,        // Length: 5
1385       0x01,                    //   Type: HEADERS
1386       0x24,                    //  Flags: END_HEADERS|PRIORITY
1387       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1388       0x00, 0x00, 0x00, 0x00,  // Parent: 0
1389       0x82,                    // Weight: 131
1390 
1391       0x00, 0x00, 0x01,        // Length: 1
1392       0x01,                    //   Type: HEADERS
1393       0x04,                    //  Flags: END_HEADERS
1394       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1395       0x8c,                    // :status: 200
1396 
1397       0x00, 0x00, 0x0c,        // Length: 12
1398       0x00,                    //   Type: DATA
1399       0x00,                    //  Flags: none
1400       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1401       0xde, 0xad, 0xbe, 0xef,  // Payload
1402       0xde, 0xad, 0xbe, 0xef,  //
1403       0xde, 0xad, 0xbe, 0xef,  //
1404 
1405       0x00, 0x00, 0x04,        // Length: 4
1406       0x00,                    //   Type: DATA
1407       0x01,                    //  Flags: END_STREAM
1408       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1409       0xde, 0xad, 0xbe, 0xef,  // Payload
1410   };
1411   // frame-format on
1412 
1413   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
1414   visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
1415 
1416   EXPECT_EQ(0, visitor.error_count_);
1417   EXPECT_EQ(2, visitor.headers_frame_count_);
1418   EXPECT_EQ(16, visitor.data_bytes_);
1419   EXPECT_EQ(0, visitor.fin_frame_count_);
1420   EXPECT_EQ(0, visitor.fin_flag_count_);
1421   EXPECT_EQ(1, visitor.end_of_stream_count_);
1422   EXPECT_EQ(2, visitor.data_frame_count_);
1423 }
1424 
TEST_P(SpdyFramerTest,FinOnHeadersFrame)1425 TEST_P(SpdyFramerTest, FinOnHeadersFrame) {
1426   // Send HEADERS frames with END_HEADERS set.
1427   // frame-format off
1428   const unsigned char kH2Input[] = {
1429       0x00, 0x00, 0x05,        // Length: 5
1430       0x01,                    //   Type: HEADERS
1431       0x24,                    //  Flags: END_HEADERS|PRIORITY
1432       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1433       0x00, 0x00, 0x00, 0x00,  // Parent: 0
1434       0x82,                    // Weight: 131
1435 
1436       0x00, 0x00, 0x01,        // Length: 1
1437       0x01,                    //   Type: HEADERS
1438       0x05,                    //  Flags: END_STREAM|END_HEADERS
1439       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1440       0x8c,                    // :status: 200
1441   };
1442   // frame-format on
1443 
1444   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
1445   visitor.SimulateInFramer(kH2Input, sizeof(kH2Input));
1446 
1447   EXPECT_EQ(0, visitor.error_count_);
1448   EXPECT_EQ(2, visitor.headers_frame_count_);
1449   EXPECT_EQ(0, visitor.data_bytes_);
1450   EXPECT_EQ(0, visitor.fin_frame_count_);
1451   EXPECT_EQ(1, visitor.fin_flag_count_);
1452   EXPECT_EQ(1, visitor.end_of_stream_count_);
1453   EXPECT_EQ(0, visitor.data_frame_count_);
1454 }
1455 
1456 // Verify we can decompress the stream even if handed over to the
1457 // framer 1 byte at a time.
TEST_P(SpdyFramerTest,UnclosedStreamDataCompressorsOneByteAtATime)1458 TEST_P(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) {
1459   const char kHeader1[] = "header1";
1460   const char kHeader2[] = "header2";
1461   const char kValue1[] = "value1";
1462   const char kValue2[] = "value2";
1463 
1464   SpdyHeadersIR headers(/* stream_id = */ 1);
1465   headers.SetHeader(kHeader1, kValue1);
1466   headers.SetHeader(kHeader2, kValue2);
1467   SpdySerializedFrame headers_frame(SpdyFramerPeer::SerializeHeaders(
1468       &framer_, headers, use_output_ ? &output_ : nullptr));
1469 
1470   const char bytes[] = "this is a test test test test test!";
1471   SpdyDataIR data_ir(/* stream_id = */ 1,
1472                      absl::string_view(bytes, ABSL_ARRAYSIZE(bytes)));
1473   data_ir.set_fin(true);
1474   SpdySerializedFrame send_frame(framer_.SerializeData(data_ir));
1475 
1476   // Run the inputs through the framer.
1477   TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
1478   const unsigned char* data;
1479   data = reinterpret_cast<const unsigned char*>(headers_frame.data());
1480   for (size_t idx = 0; idx < headers_frame.size(); ++idx) {
1481     visitor.SimulateInFramer(data + idx, 1);
1482     ASSERT_EQ(0, visitor.error_count_);
1483   }
1484   data = reinterpret_cast<const unsigned char*>(send_frame.data());
1485   for (size_t idx = 0; idx < send_frame.size(); ++idx) {
1486     visitor.SimulateInFramer(data + idx, 1);
1487     ASSERT_EQ(0, visitor.error_count_);
1488   }
1489 
1490   EXPECT_EQ(0, visitor.error_count_);
1491   EXPECT_EQ(1, visitor.headers_frame_count_);
1492   EXPECT_EQ(ABSL_ARRAYSIZE(bytes), static_cast<unsigned>(visitor.data_bytes_));
1493   EXPECT_EQ(0, visitor.fin_frame_count_);
1494   EXPECT_EQ(0, visitor.fin_flag_count_);
1495   EXPECT_EQ(1, visitor.end_of_stream_count_);
1496   EXPECT_EQ(1, visitor.data_frame_count_);
1497 }
1498 
TEST_P(SpdyFramerTest,WindowUpdateFrame)1499 TEST_P(SpdyFramerTest, WindowUpdateFrame) {
1500   SpdyWindowUpdateIR window_update(/* stream_id = */ 1,
1501                                    /* delta = */ 0x12345678);
1502   SpdySerializedFrame frame(framer_.SerializeWindowUpdate(window_update));
1503   if (use_output_) {
1504     ASSERT_TRUE(framer_.SerializeWindowUpdate(window_update, &output_));
1505     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1506   }
1507 
1508   const char kDescription[] = "WINDOW_UPDATE frame, stream 1, delta 0x12345678";
1509   const unsigned char kH2FrameData[] = {
1510       0x00, 0x00, 0x04,        // Length: 4
1511       0x08,                    //   Type: WINDOW_UPDATE
1512       0x00,                    //  Flags: none
1513       0x00, 0x00, 0x00, 0x01,  // Stream: 1
1514       0x12, 0x34, 0x56, 0x78,  // Increment: 305419896
1515   };
1516 
1517   CompareFrame(kDescription, frame, kH2FrameData, ABSL_ARRAYSIZE(kH2FrameData));
1518 }
1519 
TEST_P(SpdyFramerTest,CreateDataFrame)1520 TEST_P(SpdyFramerTest, CreateDataFrame) {
1521   {
1522     const char kDescription[] = "'hello' data frame, no FIN";
1523     // frame-format off
1524     const unsigned char kH2FrameData[] = {
1525         0x00, 0x00, 0x05,        // Length: 5
1526         0x00,                    //   Type: DATA
1527         0x00,                    //  Flags: none
1528         0x00, 0x00, 0x00, 0x01,  // Stream: 1
1529         'h',  'e',  'l',  'l',   // Payload
1530         'o',                     //
1531     };
1532     // frame-format on
1533     const char bytes[] = "hello";
1534 
1535     SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
1536     SpdySerializedFrame frame(framer_.SerializeData(data_ir));
1537     CompareFrame(kDescription, frame, kH2FrameData,
1538                  ABSL_ARRAYSIZE(kH2FrameData));
1539 
1540     SpdyDataIR data_header_ir(/* stream_id = */ 1);
1541     data_header_ir.SetDataShallow(bytes);
1542     frame =
1543         framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_header_ir);
1544     CompareCharArraysWithHexError(
1545         kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
1546         kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
1547   }
1548 
1549   {
1550     const char kDescription[] = "'hello' data frame with more padding, no FIN";
1551     // clang-format off
1552     // frame-format off
1553     const unsigned char kH2FrameData[] = {
1554         0x00, 0x00, 0xfd,        // Length: 253
1555         0x00,                    //   Type: DATA
1556         0x08,                    //  Flags: PADDED
1557         0x00, 0x00, 0x00, 0x01,  // Stream: 1
1558         0xf7,                    // PadLen: 247 trailing bytes
1559         'h', 'e', 'l', 'l',      // Payload
1560         'o',                     //
1561         // Padding of 247 0x00(s).
1562         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1563         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1564         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1565         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1566         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1567         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1568         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1569         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1570         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1571         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1572         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1573         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1574         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1575         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1576         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1577         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1578         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1579         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1580         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1581         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1582         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1583     };
1584     // frame-format on
1585     // clang-format on
1586     const char bytes[] = "hello";
1587 
1588     SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
1589     // 247 zeros and the pad length field make the overall padding to be 248
1590     // bytes.
1591     data_ir.set_padding_len(248);
1592     SpdySerializedFrame frame(framer_.SerializeData(data_ir));
1593     CompareFrame(kDescription, frame, kH2FrameData,
1594                  ABSL_ARRAYSIZE(kH2FrameData));
1595 
1596     frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
1597     CompareCharArraysWithHexError(
1598         kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
1599         kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
1600   }
1601 
1602   {
1603     const char kDescription[] = "'hello' data frame with few padding, no FIN";
1604     // frame-format off
1605     const unsigned char kH2FrameData[] = {
1606         0x00, 0x00, 0x0d,        // Length: 13
1607         0x00,                    //   Type: DATA
1608         0x08,                    //  Flags: PADDED
1609         0x00, 0x00, 0x00, 0x01,  // Stream: 1
1610         0x07,                    // PadLen: 7 trailing bytes
1611         'h',  'e',  'l',  'l',   // Payload
1612         'o',                     //
1613         0x00, 0x00, 0x00, 0x00,  // Padding
1614         0x00, 0x00, 0x00,        // Padding
1615     };
1616     // frame-format on
1617     const char bytes[] = "hello";
1618 
1619     SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
1620     // 7 zeros and the pad length field make the overall padding to be 8 bytes.
1621     data_ir.set_padding_len(8);
1622     SpdySerializedFrame frame(framer_.SerializeData(data_ir));
1623     CompareFrame(kDescription, frame, kH2FrameData,
1624                  ABSL_ARRAYSIZE(kH2FrameData));
1625 
1626     frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
1627     CompareCharArraysWithHexError(
1628         kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
1629         kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
1630   }
1631 
1632   {
1633     const char kDescription[] =
1634         "'hello' data frame with 1 byte padding, no FIN";
1635     // frame-format off
1636     const unsigned char kH2FrameData[] = {
1637         0x00, 0x00, 0x06,        // Length: 6
1638         0x00,                    //   Type: DATA
1639         0x08,                    //  Flags: PADDED
1640         0x00, 0x00, 0x00, 0x01,  // Stream: 1
1641         0x00,                    // PadLen: 0 trailing bytes
1642         'h',  'e',  'l',  'l',   // Payload
1643         'o',                     //
1644     };
1645     // frame-format on
1646     const char bytes[] = "hello";
1647 
1648     SpdyDataIR data_ir(/* stream_id = */ 1, bytes);
1649     // The pad length field itself is used for the 1-byte padding and no padding
1650     // payload is needed.
1651     data_ir.set_padding_len(1);
1652     SpdySerializedFrame frame(framer_.SerializeData(data_ir));
1653     CompareFrame(kDescription, frame, kH2FrameData,
1654                  ABSL_ARRAYSIZE(kH2FrameData));
1655 
1656     frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
1657     CompareCharArraysWithHexError(
1658         kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
1659         kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
1660   }
1661 
1662   {
1663     const char kDescription[] = "Data frame with negative data byte, no FIN";
1664     const unsigned char kH2FrameData[] = {
1665         0x00, 0x00, 0x01,        // Length: 1
1666         0x00,                    //   Type: DATA
1667         0x00,                    //  Flags: none
1668         0x00, 0x00, 0x00, 0x01,  // Stream: 1
1669         0xff,                    // Payload
1670     };
1671     SpdyDataIR data_ir(/* stream_id = */ 1, "\xff");
1672     SpdySerializedFrame frame(framer_.SerializeData(data_ir));
1673     CompareFrame(kDescription, frame, kH2FrameData,
1674                  ABSL_ARRAYSIZE(kH2FrameData));
1675   }
1676 
1677   {
1678     const char kDescription[] = "'hello' data frame, with FIN";
1679     const unsigned char kH2FrameData[] = {
1680         0x00, 0x00, 0x05,        // Length: 5
1681         0x00,                    //   Type: DATA
1682         0x01,                    //  Flags: END_STREAM
1683         0x00, 0x00, 0x00, 0x01,  // Stream: 1
1684         0x68, 0x65, 0x6c, 0x6c,  // Payload
1685         0x6f,                    //
1686     };
1687     SpdyDataIR data_ir(/* stream_id = */ 1, "hello");
1688     data_ir.set_fin(true);
1689     SpdySerializedFrame frame(framer_.SerializeData(data_ir));
1690     CompareFrame(kDescription, frame, kH2FrameData,
1691                  ABSL_ARRAYSIZE(kH2FrameData));
1692   }
1693 
1694   {
1695     const char kDescription[] = "Empty data frame";
1696     const unsigned char kH2FrameData[] = {
1697         0x00, 0x00, 0x00,        // Length: 0
1698         0x00,                    //   Type: DATA
1699         0x00,                    //  Flags: none
1700         0x00, 0x00, 0x00, 0x01,  // Stream: 1
1701     };
1702     SpdyDataIR data_ir(/* stream_id = */ 1, "");
1703     SpdySerializedFrame frame(framer_.SerializeData(data_ir));
1704     CompareFrame(kDescription, frame, kH2FrameData,
1705                  ABSL_ARRAYSIZE(kH2FrameData));
1706 
1707     frame = framer_.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
1708     CompareCharArraysWithHexError(
1709         kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
1710         kDataFrameMinimumSize, kH2FrameData, kDataFrameMinimumSize);
1711   }
1712 
1713   {
1714     const char kDescription[] = "Data frame with max stream ID";
1715     const unsigned char kH2FrameData[] = {
1716         0x00, 0x00, 0x05,        // Length: 5
1717         0x00,                    //   Type: DATA
1718         0x01,                    //  Flags: END_STREAM
1719         0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
1720         0x68, 0x65, 0x6c, 0x6c,  // Payload
1721         0x6f,                    //
1722     };
1723     SpdyDataIR data_ir(/* stream_id = */ 0x7fffffff, "hello");
1724     data_ir.set_fin(true);
1725     SpdySerializedFrame frame(framer_.SerializeData(data_ir));
1726     CompareFrame(kDescription, frame, kH2FrameData,
1727                  ABSL_ARRAYSIZE(kH2FrameData));
1728   }
1729 }
1730 
TEST_P(SpdyFramerTest,CreateRstStream)1731 TEST_P(SpdyFramerTest, CreateRstStream) {
1732   {
1733     const char kDescription[] = "RST_STREAM frame";
1734     const unsigned char kH2FrameData[] = {
1735         0x00, 0x00, 0x04,        // Length: 4
1736         0x03,                    //   Type: RST_STREAM
1737         0x00,                    //  Flags: none
1738         0x00, 0x00, 0x00, 0x01,  // Stream: 1
1739         0x00, 0x00, 0x00, 0x01,  //  Error: PROTOCOL_ERROR
1740     };
1741     SpdyRstStreamIR rst_stream(/* stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR);
1742     SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
1743     if (use_output_) {
1744       ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
1745       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1746     }
1747     CompareFrame(kDescription, frame, kH2FrameData,
1748                  ABSL_ARRAYSIZE(kH2FrameData));
1749   }
1750 
1751   {
1752     const char kDescription[] = "RST_STREAM frame with max stream ID";
1753     const unsigned char kH2FrameData[] = {
1754         0x00, 0x00, 0x04,        // Length: 4
1755         0x03,                    //   Type: RST_STREAM
1756         0x00,                    //  Flags: none
1757         0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
1758         0x00, 0x00, 0x00, 0x01,  //  Error: PROTOCOL_ERROR
1759     };
1760     SpdyRstStreamIR rst_stream(/* stream_id = */ 0x7FFFFFFF,
1761                                ERROR_CODE_PROTOCOL_ERROR);
1762     SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
1763     if (use_output_) {
1764       output_.Reset();
1765       ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
1766       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1767     }
1768     CompareFrame(kDescription, frame, kH2FrameData,
1769                  ABSL_ARRAYSIZE(kH2FrameData));
1770   }
1771 
1772   {
1773     const char kDescription[] = "RST_STREAM frame with max status code";
1774     const unsigned char kH2FrameData[] = {
1775         0x00, 0x00, 0x04,        // Length: 4
1776         0x03,                    //   Type: RST_STREAM
1777         0x00,                    //  Flags: none
1778         0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
1779         0x00, 0x00, 0x00, 0x02,  //  Error: INTERNAL_ERROR
1780     };
1781     SpdyRstStreamIR rst_stream(/* stream_id = */ 0x7FFFFFFF,
1782                                ERROR_CODE_INTERNAL_ERROR);
1783     SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
1784     if (use_output_) {
1785       output_.Reset();
1786       ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
1787       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1788     }
1789     CompareFrame(kDescription, frame, kH2FrameData,
1790                  ABSL_ARRAYSIZE(kH2FrameData));
1791   }
1792 }
1793 
TEST_P(SpdyFramerTest,CreateSettings)1794 TEST_P(SpdyFramerTest, CreateSettings) {
1795   {
1796     const char kDescription[] = "Network byte order SETTINGS frame";
1797     const unsigned char kH2FrameData[] = {
1798         0x00, 0x00, 0x06,        // Length: 6
1799         0x04,                    //   Type: SETTINGS
1800         0x00,                    //  Flags: none
1801         0x00, 0x00, 0x00, 0x00,  // Stream: 0
1802         0x00, 0x04,              //  Param: INITIAL_WINDOW_SIZE
1803         0x0a, 0x0b, 0x0c, 0x0d,  //  Value: 168496141
1804     };
1805 
1806     uint32_t kValue = 0x0a0b0c0d;
1807     SpdySettingsIR settings_ir;
1808 
1809     SpdyKnownSettingsId kId = SETTINGS_INITIAL_WINDOW_SIZE;
1810     settings_ir.AddSetting(kId, kValue);
1811 
1812     SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
1813     if (use_output_) {
1814       ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
1815       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1816     }
1817     CompareFrame(kDescription, frame, kH2FrameData,
1818                  ABSL_ARRAYSIZE(kH2FrameData));
1819   }
1820 
1821   {
1822     const char kDescription[] = "Basic SETTINGS frame";
1823     // These end up seemingly out of order because of the way that our internal
1824     // ordering for settings_ir works. HTTP2 has no requirement on ordering on
1825     // the wire.
1826     const unsigned char kH2FrameData[] = {
1827         0x00, 0x00, 0x18,        // Length: 24
1828         0x04,                    //   Type: SETTINGS
1829         0x00,                    //  Flags: none
1830         0x00, 0x00, 0x00, 0x00,  // Stream: 0
1831         0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
1832         0x00, 0x00, 0x00, 0x05,  //  Value: 5
1833         0x00, 0x02,              //  Param: ENABLE_PUSH
1834         0x00, 0x00, 0x00, 0x06,  //  Value: 6
1835         0x00, 0x03,              //  Param: MAX_CONCURRENT_STREAMS
1836         0x00, 0x00, 0x00, 0x07,  //  Value: 7
1837         0x00, 0x04,              //  Param: INITIAL_WINDOW_SIZE
1838         0x00, 0x00, 0x00, 0x08,  //  Value: 8
1839     };
1840 
1841     SpdySettingsIR settings_ir;
1842     settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
1843     settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
1844     settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
1845     settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 8);
1846     SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
1847     if (use_output_) {
1848       output_.Reset();
1849       ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
1850       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1851     }
1852 
1853     CompareFrame(kDescription, frame, kH2FrameData,
1854                  ABSL_ARRAYSIZE(kH2FrameData));
1855   }
1856 
1857   {
1858     const char kDescription[] = "Empty SETTINGS frame";
1859     const unsigned char kH2FrameData[] = {
1860         0x00, 0x00, 0x00,        // Length: 0
1861         0x04,                    //   Type: SETTINGS
1862         0x00,                    //  Flags: none
1863         0x00, 0x00, 0x00, 0x00,  // Stream: 0
1864     };
1865     SpdySettingsIR settings_ir;
1866     SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
1867     if (use_output_) {
1868       output_.Reset();
1869       ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
1870       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1871     }
1872 
1873     CompareFrame(kDescription, frame, kH2FrameData,
1874                  ABSL_ARRAYSIZE(kH2FrameData));
1875   }
1876 }
1877 
TEST_P(SpdyFramerTest,CreatePingFrame)1878 TEST_P(SpdyFramerTest, CreatePingFrame) {
1879   {
1880     const char kDescription[] = "PING frame";
1881     const unsigned char kH2FrameData[] = {
1882         0x00, 0x00, 0x08,        // Length: 8
1883         0x06,                    //   Type: PING
1884         0x00,                    //  Flags: none
1885         0x00, 0x00, 0x00, 0x00,  // Stream: 0
1886         0x12, 0x34, 0x56, 0x78,  // Opaque
1887         0x9a, 0xbc, 0xde, 0xff,  //     Data
1888     };
1889     const unsigned char kH2FrameDataWithAck[] = {
1890         0x00, 0x00, 0x08,        // Length: 8
1891         0x06,                    //   Type: PING
1892         0x01,                    //  Flags: ACK
1893         0x00, 0x00, 0x00, 0x00,  // Stream: 0
1894         0x12, 0x34, 0x56, 0x78,  // Opaque
1895         0x9a, 0xbc, 0xde, 0xff,  //     Data
1896     };
1897     const SpdyPingId kPingId = 0x123456789abcdeffULL;
1898     SpdyPingIR ping_ir(kPingId);
1899     // Tests SpdyPingIR when the ping is not an ack.
1900     ASSERT_FALSE(ping_ir.is_ack());
1901     SpdySerializedFrame frame(framer_.SerializePing(ping_ir));
1902     if (use_output_) {
1903       ASSERT_TRUE(framer_.SerializePing(ping_ir, &output_));
1904       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1905     }
1906     CompareFrame(kDescription, frame, kH2FrameData,
1907                  ABSL_ARRAYSIZE(kH2FrameData));
1908 
1909     // Tests SpdyPingIR when the ping is an ack.
1910     ping_ir.set_is_ack(true);
1911     frame = framer_.SerializePing(ping_ir);
1912     if (use_output_) {
1913       output_.Reset();
1914       ASSERT_TRUE(framer_.SerializePing(ping_ir, &output_));
1915       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1916     }
1917     CompareFrame(kDescription, frame, kH2FrameDataWithAck,
1918                  ABSL_ARRAYSIZE(kH2FrameDataWithAck));
1919   }
1920 }
1921 
TEST_P(SpdyFramerTest,CreateGoAway)1922 TEST_P(SpdyFramerTest, CreateGoAway) {
1923   {
1924     const char kDescription[] = "GOAWAY frame";
1925     const unsigned char kH2FrameData[] = {
1926         0x00, 0x00, 0x0a,        // Length: 10
1927         0x07,                    //   Type: GOAWAY
1928         0x00,                    //  Flags: none
1929         0x00, 0x00, 0x00, 0x00,  // Stream: 0
1930         0x00, 0x00, 0x00, 0x00,  //   Last: 0
1931         0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
1932         0x47, 0x41,              // Description
1933     };
1934     SpdyGoAwayIR goaway_ir(/* last_good_stream_id = */ 0, ERROR_CODE_NO_ERROR,
1935                            "GA");
1936     SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
1937     if (use_output_) {
1938       ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
1939       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1940     }
1941     CompareFrame(kDescription, frame, kH2FrameData,
1942                  ABSL_ARRAYSIZE(kH2FrameData));
1943   }
1944 
1945   {
1946     const char kDescription[] = "GOAWAY frame with max stream ID, status";
1947     const unsigned char kH2FrameData[] = {
1948         0x00, 0x00, 0x0a,        // Length: 10
1949         0x07,                    //   Type: GOAWAY
1950         0x00,                    //  Flags: none
1951         0x00, 0x00, 0x00, 0x00,  // Stream: 0
1952         0x7f, 0xff, 0xff, 0xff,  //   Last: 0x7fffffff
1953         0x00, 0x00, 0x00, 0x02,  //  Error: INTERNAL_ERROR
1954         0x47, 0x41,              // Description
1955     };
1956     SpdyGoAwayIR goaway_ir(/* last_good_stream_id = */ 0x7FFFFFFF,
1957                            ERROR_CODE_INTERNAL_ERROR, "GA");
1958     SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
1959     if (use_output_) {
1960       output_.Reset();
1961       ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
1962       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
1963     }
1964     CompareFrame(kDescription, frame, kH2FrameData,
1965                  ABSL_ARRAYSIZE(kH2FrameData));
1966   }
1967 }
1968 
TEST_P(SpdyFramerTest,CreateHeadersUncompressed)1969 TEST_P(SpdyFramerTest, CreateHeadersUncompressed) {
1970   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
1971 
1972   {
1973     const char kDescription[] = "HEADERS frame, no FIN";
1974     // frame-format off
1975     const unsigned char kH2FrameData[] = {
1976         0x00, 0x00, 0x12,        // Length: 18
1977         0x01,                    //   Type: HEADERS
1978         0x04,                    //  Flags: END_HEADERS
1979         0x00, 0x00, 0x00, 0x01,  // Stream: 1
1980 
1981         0x00,              // Unindexed Entry
1982         0x03,              // Name Len: 3
1983         0x62, 0x61, 0x72,  // bar
1984         0x03,              // Value Len: 3
1985         0x66, 0x6f, 0x6f,  // foo
1986 
1987         0x00,              // Unindexed Entry
1988         0x03,              // Name Len: 3
1989         0x66, 0x6f, 0x6f,  // foo
1990         0x03,              // Value Len: 3
1991         0x62, 0x61, 0x72,  // bar
1992     };
1993     // frame-format on
1994     SpdyHeadersIR headers(/* stream_id = */ 1);
1995     headers.SetHeader("bar", "foo");
1996     headers.SetHeader("foo", "bar");
1997     SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
1998         &framer, headers, use_output_ ? &output_ : nullptr));
1999     CompareFrame(kDescription, frame, kH2FrameData,
2000                  ABSL_ARRAYSIZE(kH2FrameData));
2001   }
2002 
2003   {
2004     const char kDescription[] =
2005         "HEADERS frame with a 0-length header name, FIN, max stream ID";
2006     // frame-format off
2007     const unsigned char kH2FrameData[] = {
2008         0x00, 0x00, 0x0f,        // Length: 15
2009         0x01,                    //   Type: HEADERS
2010         0x05,                    //  Flags: END_STREAM|END_HEADERS
2011         0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
2012 
2013         0x00,              // Unindexed Entry
2014         0x00,              // Name Len: 0
2015         0x03,              // Value Len: 3
2016         0x66, 0x6f, 0x6f,  // foo
2017 
2018         0x00,              // Unindexed Entry
2019         0x03,              // Name Len: 3
2020         0x66, 0x6f, 0x6f,  // foo
2021         0x03,              // Value Len: 3
2022         0x62, 0x61, 0x72,  // bar
2023     };
2024     // frame-format on
2025     SpdyHeadersIR headers(/* stream_id = */ 0x7fffffff);
2026     headers.set_fin(true);
2027     headers.SetHeader("", "foo");
2028     headers.SetHeader("foo", "bar");
2029     SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
2030         &framer, headers, use_output_ ? &output_ : nullptr));
2031     CompareFrame(kDescription, frame, kH2FrameData,
2032                  ABSL_ARRAYSIZE(kH2FrameData));
2033   }
2034 
2035   {
2036     const char kDescription[] =
2037         "HEADERS frame with a 0-length header val, FIN, max stream ID";
2038     // frame-format off
2039     const unsigned char kH2FrameData[] = {
2040         0x00, 0x00, 0x0f,        // Length: 15
2041         0x01,                    //   Type: HEADERS
2042         0x05,                    //  Flags: END_STREAM|END_HEADERS
2043         0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
2044 
2045         0x00,              // Unindexed Entry
2046         0x03,              // Name Len: 3
2047         0x62, 0x61, 0x72,  // bar
2048         0x03,              // Value Len: 3
2049         0x66, 0x6f, 0x6f,  // foo
2050 
2051         0x00,              // Unindexed Entry
2052         0x03,              // Name Len: 3
2053         0x66, 0x6f, 0x6f,  // foo
2054         0x00,              // Value Len: 0
2055     };
2056     // frame-format on
2057     SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
2058     headers_ir.set_fin(true);
2059     headers_ir.SetHeader("bar", "foo");
2060     headers_ir.SetHeader("foo", "");
2061     SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
2062         &framer, headers_ir, use_output_ ? &output_ : nullptr));
2063     CompareFrame(kDescription, frame, kH2FrameData,
2064                  ABSL_ARRAYSIZE(kH2FrameData));
2065   }
2066 
2067   {
2068     const char kDescription[] =
2069         "HEADERS frame with a 0-length header val, FIN, max stream ID, pri";
2070 
2071     // frame-format off
2072     const unsigned char kH2FrameData[] = {
2073         0x00, 0x00, 0x14,        // Length: 20
2074         0x01,                    //   Type: HEADERS
2075         0x25,                    //  Flags: END_STREAM|END_HEADERS|PRIORITY
2076         0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
2077         0x00, 0x00, 0x00, 0x00,  // Parent: 0
2078         0xdb,                    // Weight: 220
2079 
2080         0x00,              // Unindexed Entry
2081         0x03,              // Name Len: 3
2082         0x62, 0x61, 0x72,  // bar
2083         0x03,              // Value Len: 3
2084         0x66, 0x6f, 0x6f,  // foo
2085 
2086         0x00,              // Unindexed Entry
2087         0x03,              // Name Len: 3
2088         0x66, 0x6f, 0x6f,  // foo
2089         0x00,              // Value Len: 0
2090     };
2091     // frame-format on
2092     SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
2093     headers_ir.set_fin(true);
2094     headers_ir.set_has_priority(true);
2095     headers_ir.set_weight(220);
2096     headers_ir.SetHeader("bar", "foo");
2097     headers_ir.SetHeader("foo", "");
2098     SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
2099         &framer, headers_ir, use_output_ ? &output_ : nullptr));
2100     CompareFrame(kDescription, frame, kH2FrameData,
2101                  ABSL_ARRAYSIZE(kH2FrameData));
2102   }
2103 
2104   {
2105     const char kDescription[] =
2106         "HEADERS frame with a 0-length header val, FIN, max stream ID, pri, "
2107         "exclusive=true, parent_stream=0";
2108 
2109     // frame-format off
2110     const unsigned char kV4FrameData[] = {
2111         0x00, 0x00, 0x14,        // Length: 20
2112         0x01,                    //   Type: HEADERS
2113         0x25,                    //  Flags: END_STREAM|END_HEADERS|PRIORITY
2114         0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
2115         0x80, 0x00, 0x00, 0x00,  // Parent: 0 (Exclusive)
2116         0xdb,                    // Weight: 220
2117 
2118         0x00,              // Unindexed Entry
2119         0x03,              // Name Len: 3
2120         0x62, 0x61, 0x72,  // bar
2121         0x03,              // Value Len: 3
2122         0x66, 0x6f, 0x6f,  // foo
2123 
2124         0x00,              // Unindexed Entry
2125         0x03,              // Name Len: 3
2126         0x66, 0x6f, 0x6f,  // foo
2127         0x00,              // Value Len: 0
2128     };
2129     // frame-format on
2130     SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
2131     headers_ir.set_fin(true);
2132     headers_ir.set_has_priority(true);
2133     headers_ir.set_weight(220);
2134     headers_ir.set_exclusive(true);
2135     headers_ir.set_parent_stream_id(0);
2136     headers_ir.SetHeader("bar", "foo");
2137     headers_ir.SetHeader("foo", "");
2138     SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
2139         &framer, headers_ir, use_output_ ? &output_ : nullptr));
2140     CompareFrame(kDescription, frame, kV4FrameData,
2141                  ABSL_ARRAYSIZE(kV4FrameData));
2142   }
2143 
2144   {
2145     const char kDescription[] =
2146         "HEADERS frame with a 0-length header val, FIN, max stream ID, pri, "
2147         "exclusive=false, parent_stream=max stream ID";
2148 
2149     // frame-format off
2150     const unsigned char kV4FrameData[] = {
2151         0x00, 0x00, 0x14,        // Length: 20
2152         0x01,                    //   Type: HEADERS
2153         0x25,                    //  Flags: END_STREAM|END_HEADERS|PRIORITY
2154         0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
2155         0x7f, 0xff, 0xff, 0xff,  // Parent: 2147483647
2156         0xdb,                    // Weight: 220
2157 
2158         0x00,              // Unindexed Entry
2159         0x03,              // Name Len: 3
2160         0x62, 0x61, 0x72,  // bar
2161         0x03,              // Value Len: 3
2162         0x66, 0x6f, 0x6f,  // foo
2163 
2164         0x00,              // Unindexed Entry
2165         0x03,              // Name Len: 3
2166         0x66, 0x6f, 0x6f,  // foo
2167         0x00,              // Value Len: 0
2168     };
2169     // frame-format on
2170     SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
2171     headers_ir.set_fin(true);
2172     headers_ir.set_has_priority(true);
2173     headers_ir.set_weight(220);
2174     headers_ir.set_exclusive(false);
2175     headers_ir.set_parent_stream_id(0x7fffffff);
2176     headers_ir.SetHeader("bar", "foo");
2177     headers_ir.SetHeader("foo", "");
2178     SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
2179         &framer, headers_ir, use_output_ ? &output_ : nullptr));
2180     CompareFrame(kDescription, frame, kV4FrameData,
2181                  ABSL_ARRAYSIZE(kV4FrameData));
2182   }
2183 
2184   {
2185     const char kDescription[] =
2186         "HEADERS frame with a 0-length header name, FIN, max stream ID, padded";
2187 
2188     // frame-format off
2189     const unsigned char kH2FrameData[] = {
2190         0x00, 0x00, 0x15,        // Length: 21
2191         0x01,                    //   Type: HEADERS
2192         0x0d,                    //  Flags: END_STREAM|END_HEADERS|PADDED
2193         0x7f, 0xff, 0xff, 0xff,  // Stream: 2147483647
2194         0x05,                    // PadLen: 5 trailing bytes
2195 
2196         0x00,              // Unindexed Entry
2197         0x00,              // Name Len: 0
2198         0x03,              // Value Len: 3
2199         0x66, 0x6f, 0x6f,  // foo
2200 
2201         0x00,              // Unindexed Entry
2202         0x03,              // Name Len: 3
2203         0x66, 0x6f, 0x6f,  // foo
2204         0x03,              // Value Len: 3
2205         0x62, 0x61, 0x72,  // bar
2206 
2207         0x00, 0x00, 0x00, 0x00,  // Padding
2208         0x00,                    // Padding
2209     };
2210     // frame-format on
2211     SpdyHeadersIR headers_ir(/* stream_id = */ 0x7fffffff);
2212     headers_ir.set_fin(true);
2213     headers_ir.SetHeader("", "foo");
2214     headers_ir.SetHeader("foo", "bar");
2215     headers_ir.set_padding_len(6);
2216     SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
2217         &framer, headers_ir, use_output_ ? &output_ : nullptr));
2218     CompareFrame(kDescription, frame, kH2FrameData,
2219                  ABSL_ARRAYSIZE(kH2FrameData));
2220   }
2221 }
2222 
TEST_P(SpdyFramerTest,CreateWindowUpdate)2223 TEST_P(SpdyFramerTest, CreateWindowUpdate) {
2224   {
2225     const char kDescription[] = "WINDOW_UPDATE frame";
2226     const unsigned char kH2FrameData[] = {
2227         0x00, 0x00, 0x04,        // Length: 4
2228         0x08,                    //   Type: WINDOW_UPDATE
2229         0x00,                    //  Flags: none
2230         0x00, 0x00, 0x00, 0x01,  // Stream: 1
2231         0x00, 0x00, 0x00, 0x01,  // Increment: 1
2232     };
2233     SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
2234         SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 1)));
2235     if (use_output_) {
2236       output_.Reset();
2237       ASSERT_TRUE(framer_.SerializeWindowUpdate(
2238           SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 1), &output_));
2239       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2240     }
2241     CompareFrame(kDescription, frame, kH2FrameData,
2242                  ABSL_ARRAYSIZE(kH2FrameData));
2243   }
2244 
2245   {
2246     const char kDescription[] = "WINDOW_UPDATE frame with max stream ID";
2247     const unsigned char kH2FrameData[] = {
2248         0x00, 0x00, 0x04,        // Length: 4
2249         0x08,                    //   Type: WINDOW_UPDATE
2250         0x00,                    //  Flags: none
2251         0x7f, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff
2252         0x00, 0x00, 0x00, 0x01,  // Increment: 1
2253     };
2254     SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
2255         SpdyWindowUpdateIR(/* stream_id = */ 0x7FFFFFFF, /* delta = */ 1)));
2256     if (use_output_) {
2257       output_.Reset();
2258       ASSERT_TRUE(framer_.SerializeWindowUpdate(
2259           SpdyWindowUpdateIR(/* stream_id = */ 0x7FFFFFFF, /* delta = */ 1),
2260           &output_));
2261       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2262     }
2263     CompareFrame(kDescription, frame, kH2FrameData,
2264                  ABSL_ARRAYSIZE(kH2FrameData));
2265   }
2266 
2267   {
2268     const char kDescription[] = "WINDOW_UPDATE frame with max window delta";
2269     const unsigned char kH2FrameData[] = {
2270         0x00, 0x00, 0x04,        // Length: 4
2271         0x08,                    //   Type: WINDOW_UPDATE
2272         0x00,                    //  Flags: none
2273         0x00, 0x00, 0x00, 0x01,  // Stream: 1
2274         0x7f, 0xff, 0xff, 0xff,  // Increment: 0x7fffffff
2275     };
2276     SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
2277         SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 0x7FFFFFFF)));
2278     if (use_output_) {
2279       output_.Reset();
2280       ASSERT_TRUE(framer_.SerializeWindowUpdate(
2281           SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 0x7FFFFFFF),
2282           &output_));
2283       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2284     }
2285     CompareFrame(kDescription, frame, kH2FrameData,
2286                  ABSL_ARRAYSIZE(kH2FrameData));
2287   }
2288 }
2289 
TEST_P(SpdyFramerTest,CreatePushPromiseUncompressed)2290 TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) {
2291   {
2292     // Test framing PUSH_PROMISE without padding.
2293     SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
2294     const char kDescription[] = "PUSH_PROMISE frame without padding";
2295 
2296     // frame-format off
2297     const unsigned char kFrameData[] = {
2298         0x00, 0x00, 0x16,        // Length: 22
2299         0x05,                    //   Type: PUSH_PROMISE
2300         0x04,                    //  Flags: END_HEADERS
2301         0x00, 0x00, 0x00, 0x29,  // Stream: 41
2302         0x00, 0x00, 0x00, 0x3a,  // Promise: 58
2303 
2304         0x00,              // Unindexed Entry
2305         0x03,              // Name Len: 3
2306         0x62, 0x61, 0x72,  // bar
2307         0x03,              // Value Len: 3
2308         0x66, 0x6f, 0x6f,  // foo
2309 
2310         0x00,              // Unindexed Entry
2311         0x03,              // Name Len: 3
2312         0x66, 0x6f, 0x6f,  // foo
2313         0x03,              // Value Len: 3
2314         0x62, 0x61, 0x72,  // bar
2315     };
2316     // frame-format on
2317 
2318     SpdyPushPromiseIR push_promise(/* stream_id = */ 41,
2319                                    /* promised_stream_id = */ 58);
2320     push_promise.SetHeader("bar", "foo");
2321     push_promise.SetHeader("foo", "bar");
2322     SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
2323         &framer, push_promise, use_output_ ? &output_ : nullptr));
2324     CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2325   }
2326 
2327   {
2328     // Test framing PUSH_PROMISE with one byte of padding.
2329     SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
2330     const char kDescription[] = "PUSH_PROMISE frame with one byte of padding";
2331 
2332     // frame-format off
2333     const unsigned char kFrameData[] = {
2334         0x00, 0x00, 0x17,        // Length: 23
2335         0x05,                    //   Type: PUSH_PROMISE
2336         0x0c,                    //  Flags: END_HEADERS|PADDED
2337         0x00, 0x00, 0x00, 0x29,  // Stream: 41
2338         0x00,                    // PadLen: 0 trailing bytes
2339         0x00, 0x00, 0x00, 0x3a,  // Promise: 58
2340 
2341         0x00,              // Unindexed Entry
2342         0x03,              // Name Len: 3
2343         0x62, 0x61, 0x72,  // bar
2344         0x03,              // Value Len: 3
2345         0x66, 0x6f, 0x6f,  // foo
2346 
2347         0x00,              // Unindexed Entry
2348         0x03,              // Name Len: 3
2349         0x66, 0x6f, 0x6f,  // foo
2350         0x03,              // Value Len: 3
2351         0x62, 0x61, 0x72,  // bar
2352     };
2353     // frame-format on
2354 
2355     SpdyPushPromiseIR push_promise(/* stream_id = */ 41,
2356                                    /* promised_stream_id = */ 58);
2357     push_promise.set_padding_len(1);
2358     push_promise.SetHeader("bar", "foo");
2359     push_promise.SetHeader("foo", "bar");
2360     output_.Reset();
2361     SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
2362         &framer, push_promise, use_output_ ? &output_ : nullptr));
2363 
2364     CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2365   }
2366 
2367   {
2368     // Test framing PUSH_PROMISE with 177 bytes of padding.
2369     SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
2370     const char kDescription[] = "PUSH_PROMISE frame with 177 bytes of padding";
2371 
2372     // frame-format off
2373     // clang-format off
2374     const unsigned char kFrameData[] = {
2375         0x00, 0x00, 0xc7,        // Length: 199
2376         0x05,                    //   Type: PUSH_PROMISE
2377         0x0c,                    //  Flags: END_HEADERS|PADDED
2378         0x00, 0x00, 0x00, 0x2a,  // Stream: 42
2379         0xb0,                    // PadLen: 176 trailing bytes
2380         0x00, 0x00, 0x00, 0x39,  // Promise: 57
2381 
2382         0x00,                    // Unindexed Entry
2383         0x03,                    // Name Len: 3
2384         0x62, 0x61, 0x72,        // bar
2385         0x03,                    // Value Len: 3
2386         0x66, 0x6f, 0x6f,        // foo
2387 
2388         0x00,                    // Unindexed Entry
2389         0x03,                    // Name Len: 3
2390         0x66, 0x6f, 0x6f,        // foo
2391         0x03,                    // Value Len: 3
2392         0x62, 0x61, 0x72,        // bar
2393 
2394       // Padding of 176 0x00(s).
2395       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2396       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2397       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2398       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2399       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2400       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2401       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2402       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2403       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2404       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2405       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2406       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2407       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2408       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2409       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2410       0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00,  0x00,
2411     };
2412     // clang-format on
2413     // frame-format on
2414 
2415     SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
2416                                    /* promised_stream_id = */ 57);
2417     push_promise.set_padding_len(177);
2418     push_promise.SetHeader("bar", "foo");
2419     push_promise.SetHeader("foo", "bar");
2420     output_.Reset();
2421     SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
2422         &framer, push_promise, use_output_ ? &output_ : nullptr));
2423 
2424     CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2425   }
2426 }
2427 
2428 // Regression test for https://crbug.com/464748.
TEST_P(SpdyFramerTest,GetNumberRequiredContinuationFrames)2429 TEST_P(SpdyFramerTest, GetNumberRequiredContinuationFrames) {
2430   EXPECT_EQ(1u, GetNumberRequiredContinuationFrames(16383 + 16374));
2431   EXPECT_EQ(2u, GetNumberRequiredContinuationFrames(16383 + 16374 + 1));
2432   EXPECT_EQ(2u, GetNumberRequiredContinuationFrames(16383 + 2 * 16374));
2433   EXPECT_EQ(3u, GetNumberRequiredContinuationFrames(16383 + 2 * 16374 + 1));
2434 }
2435 
TEST_P(SpdyFramerTest,CreateContinuationUncompressed)2436 TEST_P(SpdyFramerTest, CreateContinuationUncompressed) {
2437   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
2438   const char kDescription[] = "CONTINUATION frame";
2439 
2440   // frame-format off
2441   const unsigned char kFrameData[] = {
2442       0x00, 0x00, 0x12,        // Length: 18
2443       0x09,                    //   Type: CONTINUATION
2444       0x04,                    //  Flags: END_HEADERS
2445       0x00, 0x00, 0x00, 0x2a,  // Stream: 42
2446 
2447       0x00,              // Unindexed Entry
2448       0x03,              // Name Len: 3
2449       0x62, 0x61, 0x72,  // bar
2450       0x03,              // Value Len: 3
2451       0x66, 0x6f, 0x6f,  // foo
2452 
2453       0x00,              // Unindexed Entry
2454       0x03,              // Name Len: 3
2455       0x66, 0x6f, 0x6f,  // foo
2456       0x03,              // Value Len: 3
2457       0x62, 0x61, 0x72,  // bar
2458   };
2459   // frame-format on
2460 
2461   Http2HeaderBlock header_block;
2462   header_block["bar"] = "foo";
2463   header_block["foo"] = "bar";
2464   HpackEncoder encoder;
2465   encoder.DisableCompression();
2466   std::string buffer = encoder.EncodeHeaderBlock(header_block);
2467 
2468   SpdyContinuationIR continuation(/* stream_id = */ 42);
2469   continuation.take_encoding(std::move(buffer));
2470   continuation.set_end_headers(true);
2471 
2472   SpdySerializedFrame frame(framer.SerializeContinuation(continuation));
2473   if (use_output_) {
2474     ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_));
2475     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2476   }
2477   CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2478 }
2479 
2480 // Test that if we send an unexpected CONTINUATION
2481 // we signal an error (but don't crash).
TEST_P(SpdyFramerTest,SendUnexpectedContinuation)2482 TEST_P(SpdyFramerTest, SendUnexpectedContinuation) {
2483   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
2484 
2485   deframer_->set_visitor(&visitor);
2486 
2487   // frame-format off
2488   char kH2FrameData[] = {
2489       0x00, 0x00, 0x12,        // Length: 18
2490       0x09,                    //   Type: CONTINUATION
2491       0x04,                    //  Flags: END_HEADERS
2492       0x00, 0x00, 0x00, 0x2a,  // Stream: 42
2493 
2494       0x00,              // Unindexed Entry
2495       0x03,              // Name Len: 3
2496       0x62, 0x61, 0x72,  // bar
2497       0x03,              // Value Len: 3
2498       0x66, 0x6f, 0x6f,  // foo
2499 
2500       0x00,              // Unindexed Entry
2501       0x03,              // Name Len: 3
2502       0x66, 0x6f, 0x6f,  // foo
2503       0x03,              // Value Len: 3
2504       0x62, 0x61, 0x72,  // bar
2505   };
2506   // frame-format on
2507 
2508   SpdySerializedFrame frame =
2509       MakeSerializedFrame(kH2FrameData, sizeof(kH2FrameData));
2510 
2511   // We shouldn't have to read the whole frame before we signal an error.
2512   EXPECT_CALL(visitor, OnCommonHeader(42, 18, 0x9, 0x4));
2513   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME, _));
2514   EXPECT_GT(frame.size(), deframer_->ProcessInput(frame.data(), frame.size()));
2515   EXPECT_TRUE(deframer_->HasError());
2516   EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
2517             deframer_->spdy_framer_error())
2518       << Http2DecoderAdapter::SpdyFramerErrorToString(
2519              deframer_->spdy_framer_error());
2520 }
2521 
TEST_P(SpdyFramerTest,CreatePushPromiseThenContinuationUncompressed)2522 TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) {
2523   {
2524     // Test framing in a case such that a PUSH_PROMISE frame, with one byte of
2525     // padding, cannot hold all the data payload, which is overflowed to the
2526     // consecutive CONTINUATION frame.
2527     SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
2528     const char kDescription[] =
2529         "PUSH_PROMISE and CONTINUATION frames with one byte of padding";
2530 
2531     // frame-format off
2532     const unsigned char kPartialPushPromiseFrameData[] = {
2533         0x00, 0x3f, 0xf6,        // Length: 16374
2534         0x05,                    //   Type: PUSH_PROMISE
2535         0x08,                    //  Flags: PADDED
2536         0x00, 0x00, 0x00, 0x2a,  // Stream: 42
2537         0x00,                    // PadLen: 0 trailing bytes
2538         0x00, 0x00, 0x00, 0x39,  // Promise: 57
2539 
2540         0x00,                    // Unindexed Entry
2541         0x03,                    // Name Len: 3
2542         0x78, 0x78, 0x78,        // xxx
2543         0x7f, 0x80, 0x7f,        // Value Len: 16361
2544         0x78, 0x78, 0x78, 0x78,  // xxxx
2545         0x78, 0x78, 0x78, 0x78,  // xxxx
2546         0x78, 0x78, 0x78, 0x78,  // xxxx
2547         0x78, 0x78, 0x78, 0x78,  // xxxx
2548         0x78, 0x78, 0x78, 0x78,  // xxxx
2549         0x78, 0x78, 0x78, 0x78,  // xxxx
2550         0x78, 0x78, 0x78, 0x78,  // xxxx
2551         0x78, 0x78, 0x78, 0x78,  // xxxx
2552         0x78, 0x78, 0x78, 0x78,  // xxxx
2553         0x78, 0x78, 0x78, 0x78,  // xxxx
2554         0x78, 0x78, 0x78, 0x78,  // xxxx
2555         0x78, 0x78, 0x78, 0x78,  // xxxx
2556         0x78, 0x78, 0x78, 0x78,  // xxxx
2557         0x78, 0x78, 0x78, 0x78,  // xxxx
2558         0x78, 0x78, 0x78, 0x78,  // xxxx
2559         0x78, 0x78, 0x78, 0x78,  // xxxx
2560         0x78, 0x78, 0x78, 0x78,  // xxxx
2561         0x78, 0x78, 0x78, 0x78,  // xxxx
2562         0x78, 0x78, 0x78, 0x78,  // xxxx
2563         0x78, 0x78, 0x78, 0x78,  // xxxx
2564         0x78, 0x78, 0x78, 0x78,  // xxxx
2565     };
2566     const unsigned char kContinuationFrameData[] = {
2567         0x00, 0x00, 0x16,        // Length: 22
2568         0x09,                    //   Type: CONTINUATION
2569         0x04,                    //  Flags: END_HEADERS
2570         0x00, 0x00, 0x00, 0x2a,  // Stream: 42
2571         0x78, 0x78, 0x78, 0x78,  // xxxx
2572         0x78, 0x78, 0x78, 0x78,  // xxxx
2573         0x78, 0x78, 0x78, 0x78,  // xxxx
2574         0x78, 0x78, 0x78, 0x78,  // xxxx
2575         0x78, 0x78, 0x78, 0x78,  // xxxx
2576         0x78,                    // x
2577     };
2578     // frame-format on
2579 
2580     SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
2581                                    /* promised_stream_id = */ 57);
2582     push_promise.set_padding_len(1);
2583     std::string big_value(kHttp2MaxControlFrameSendSize, 'x');
2584     push_promise.SetHeader("xxx", big_value);
2585     SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
2586         &framer, push_promise, use_output_ ? &output_ : nullptr));
2587 
2588     // The entire frame should look like below:
2589     // Name                     Length in Byte
2590     // ------------------------------------------- Begin of PUSH_PROMISE frame
2591     // PUSH_PROMISE header      9
2592     // Pad length field         1
2593     // Promised stream          4
2594     // Length field of key      2
2595     // Content of key           3
2596     // Length field of value    3
2597     // Part of big_value        16361
2598     // ------------------------------------------- Begin of CONTINUATION frame
2599     // CONTINUATION header      9
2600     // Remaining of big_value   22
2601     // ------------------------------------------- End
2602 
2603     // Length of everything listed above except big_value.
2604     int len_non_data_payload = 31;
2605     EXPECT_EQ(kHttp2MaxControlFrameSendSize + len_non_data_payload,
2606               frame.size());
2607 
2608     // Partially compare the PUSH_PROMISE frame against the template.
2609     const unsigned char* frame_data =
2610         reinterpret_cast<const unsigned char*>(frame.data());
2611     CompareCharArraysWithHexError(kDescription, frame_data,
2612                                   ABSL_ARRAYSIZE(kPartialPushPromiseFrameData),
2613                                   kPartialPushPromiseFrameData,
2614                                   ABSL_ARRAYSIZE(kPartialPushPromiseFrameData));
2615 
2616     // Compare the CONTINUATION frame against the template.
2617     frame_data += kHttp2MaxControlFrameSendSize;
2618     CompareCharArraysWithHexError(
2619         kDescription, frame_data, ABSL_ARRAYSIZE(kContinuationFrameData),
2620         kContinuationFrameData, ABSL_ARRAYSIZE(kContinuationFrameData));
2621   }
2622 }
2623 
TEST_P(SpdyFramerTest,CreateAltSvc)2624 TEST_P(SpdyFramerTest, CreateAltSvc) {
2625   const char kDescription[] = "ALTSVC frame";
2626   const unsigned char kType = SerializeFrameType(SpdyFrameType::ALTSVC);
2627   const unsigned char kFrameData[] = {
2628       0x00, 0x00, 0x49, kType, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 'o',
2629       'r',  'i',  'g',  'i',   'n',  'p',  'i',  'd',  '1',  '=',  '"',  'h',
2630       'o',  's',  't',  ':',   '4',  '4',  '3',  '"',  ';',  ' ',  'm',  'a',
2631       '=',  '5',  ',',  'p',   '%',  '2',  '2',  '%',  '3',  'D',  'i',  '%',
2632       '3',  'A',  'd',  '=',   '"',  'h',  '_',  '\\', '\\', 'o',  '\\', '"',
2633       's',  't',  ':',  '1',   '2',  '3',  '"',  ';',  ' ',  'm',  'a',  '=',
2634       '4',  '2',  ';',  ' ',   'v',  '=',  '"',  '2',  '4',  '"'};
2635   SpdyAltSvcIR altsvc_ir(/* stream_id = */ 3);
2636   altsvc_ir.set_origin("origin");
2637   altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
2638       "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()));
2639   altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
2640       "p\"=i:d", "h_\\o\"st", 123, 42,
2641       SpdyAltSvcWireFormat::VersionVector{24}));
2642   SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
2643   if (use_output_) {
2644     EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
2645     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2646   }
2647   CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2648 }
2649 
TEST_P(SpdyFramerTest,CreatePriority)2650 TEST_P(SpdyFramerTest, CreatePriority) {
2651   const char kDescription[] = "PRIORITY frame";
2652   const unsigned char kFrameData[] = {
2653       0x00, 0x00, 0x05,        // Length: 5
2654       0x02,                    //   Type: PRIORITY
2655       0x00,                    //  Flags: none
2656       0x00, 0x00, 0x00, 0x02,  // Stream: 2
2657       0x80, 0x00, 0x00, 0x01,  // Parent: 1 (Exclusive)
2658       0x10,                    // Weight: 17
2659   };
2660   SpdyPriorityIR priority_ir(/* stream_id = */ 2,
2661                              /* parent_stream_id = */ 1,
2662                              /* weight = */ 17,
2663                              /* exclusive = */ true);
2664   SpdySerializedFrame frame(framer_.SerializeFrame(priority_ir));
2665   if (use_output_) {
2666     EXPECT_EQ(framer_.SerializeFrame(priority_ir, &output_), frame.size());
2667     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2668   }
2669   CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2670 }
2671 
TEST_P(SpdyFramerTest,CreatePriorityUpdate)2672 TEST_P(SpdyFramerTest, CreatePriorityUpdate) {
2673   const char kDescription[] = "PRIORITY_UPDATE frame";
2674   const unsigned char kType =
2675       SerializeFrameType(SpdyFrameType::PRIORITY_UPDATE);
2676   const unsigned char kFrameData[] = {
2677       0x00,  0x00, 0x07,        // frame length
2678       kType,                    // frame type
2679       0x00,                     // flags
2680       0x00,  0x00, 0x00, 0x00,  // stream ID, must be 0 for PRIORITY_UPDATE
2681       0x00,  0x00, 0x00, 0x03,  // prioritized stream ID
2682       'u',   '=',  '0'};        // priority field value
2683   SpdyPriorityUpdateIR priority_update_ir(/* stream_id = */ 0,
2684                                           /* prioritized_stream_id = */ 3,
2685                                           /* priority_field_value = */ "u=0");
2686   SpdySerializedFrame frame(framer_.SerializeFrame(priority_update_ir));
2687   if (use_output_) {
2688     EXPECT_EQ(framer_.SerializeFrame(priority_update_ir, &output_),
2689               frame.size());
2690     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2691   }
2692   CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2693 }
2694 
TEST_P(SpdyFramerTest,CreateAcceptCh)2695 TEST_P(SpdyFramerTest, CreateAcceptCh) {
2696   const char kDescription[] = "ACCEPT_CH frame";
2697   const unsigned char kType = SerializeFrameType(SpdyFrameType::ACCEPT_CH);
2698   const unsigned char kFrameData[] = {
2699       0x00,  0x00, 0x2d,                  // frame length
2700       kType,                              // frame type
2701       0x00,                               // flags
2702       0x00,  0x00, 0x00, 0x00,            // stream ID, must be 0 for ACCEPT_CH
2703       0x00,  0x0f,                        // origin length
2704       'w',   'w',  'w',  '.',  'e', 'x',  // origin
2705       'a',   'm',  'p',  'l',  'e', '.',  //
2706       'c',   'o',  'm',                   //
2707       0x00,  0x03,                        // value length
2708       'f',   'o',  'o',                   // value
2709       0x00,  0x10,                        // origin length
2710       'm',   'a',  'i',  'l',  '.', 'e',  //
2711       'x',   'a',  'm',  'p',  'l', 'e',  //
2712       '.',   'c',  'o',  'm',             //
2713       0x00,  0x03,                        // value length
2714       'b',   'a',  'r'};                  // value
2715   SpdyAcceptChIR accept_ch_ir(
2716       {{"www.example.com", "foo"}, {"mail.example.com", "bar"}});
2717   SpdySerializedFrame frame(framer_.SerializeFrame(accept_ch_ir));
2718   if (use_output_) {
2719     EXPECT_EQ(framer_.SerializeFrame(accept_ch_ir, &output_), frame.size());
2720     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2721   }
2722   CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2723 }
2724 
TEST_P(SpdyFramerTest,CreateUnknown)2725 TEST_P(SpdyFramerTest, CreateUnknown) {
2726   const char kDescription[] = "Unknown frame";
2727   const uint8_t kType = 0xaf;
2728   const uint8_t kFlags = 0x11;
2729   const uint8_t kLength = strlen(kDescription);
2730   const unsigned char kFrameData[] = {
2731       0x00,   0x00, kLength,        // Length: 13
2732       kType,                        //   Type: undefined
2733       kFlags,                       //  Flags: arbitrary, undefined
2734       0x00,   0x00, 0x00,    0x02,  // Stream: 2
2735       0x55,   0x6e, 0x6b,    0x6e,  // "Unkn"
2736       0x6f,   0x77, 0x6e,    0x20,  // "own "
2737       0x66,   0x72, 0x61,    0x6d,  // "fram"
2738       0x65,                         // "e"
2739   };
2740   SpdyUnknownIR unknown_ir(/* stream_id = */ 2,
2741                            /* type = */ kType,
2742                            /* flags = */ kFlags,
2743                            /* payload = */ kDescription);
2744   SpdySerializedFrame frame(framer_.SerializeFrame(unknown_ir));
2745   if (use_output_) {
2746     EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size());
2747     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2748   }
2749   CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2750 }
2751 
2752 // Test serialization of a SpdyUnknownIR with a defined type, a length field
2753 // that does not match the payload size and in fact exceeds framer limits, and a
2754 // stream ID that effectively flips the reserved bit.
TEST_P(SpdyFramerTest,CreateUnknownUnchecked)2755 TEST_P(SpdyFramerTest, CreateUnknownUnchecked) {
2756   const char kDescription[] = "Unknown frame";
2757   const uint8_t kType = 0x00;
2758   const uint8_t kFlags = 0x11;
2759   const uint8_t kLength = std::numeric_limits<uint8_t>::max();
2760   const unsigned int kStreamId = kStreamIdMask + 42;
2761   const unsigned char kFrameData[] = {
2762       0x00,   0x00, kLength,        // Length: 16426
2763       kType,                        //   Type: DATA, defined
2764       kFlags,                       //  Flags: arbitrary, undefined
2765       0x80,   0x00, 0x00,    0x29,  // Stream: 2147483689
2766       0x55,   0x6e, 0x6b,    0x6e,  // "Unkn"
2767       0x6f,   0x77, 0x6e,    0x20,  // "own "
2768       0x66,   0x72, 0x61,    0x6d,  // "fram"
2769       0x65,                         // "e"
2770   };
2771   TestSpdyUnknownIR unknown_ir(/* stream_id = */ kStreamId,
2772                                /* type = */ kType,
2773                                /* flags = */ kFlags,
2774                                /* payload = */ kDescription);
2775   unknown_ir.set_length(kLength);
2776   SpdySerializedFrame frame(framer_.SerializeFrame(unknown_ir));
2777   if (use_output_) {
2778     EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size());
2779     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
2780   }
2781   CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
2782 }
2783 
TEST_P(SpdyFramerTest,ReadCompressedHeadersHeaderBlock)2784 TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) {
2785   SpdyHeadersIR headers_ir(/* stream_id = */ 1);
2786   headers_ir.SetHeader("alpha", "beta");
2787   headers_ir.SetHeader("gamma", "delta");
2788   SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
2789       &framer_, headers_ir, use_output_ ? &output_ : nullptr));
2790   TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
2791   visitor.SimulateInFramer(
2792       reinterpret_cast<unsigned char*>(control_frame.data()),
2793       control_frame.size());
2794   EXPECT_EQ(1, visitor.headers_frame_count_);
2795   EXPECT_EQ(0, visitor.control_frame_header_data_count_);
2796   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2797   EXPECT_EQ(0, visitor.end_of_stream_count_);
2798   EXPECT_EQ(headers_ir.header_block(), visitor.headers_);
2799 }
2800 
TEST_P(SpdyFramerTest,ReadCompressedHeadersHeaderBlockWithHalfClose)2801 TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
2802   SpdyHeadersIR headers_ir(/* stream_id = */ 1);
2803   headers_ir.set_fin(true);
2804   headers_ir.SetHeader("alpha", "beta");
2805   headers_ir.SetHeader("gamma", "delta");
2806   SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
2807       &framer_, headers_ir, use_output_ ? &output_ : nullptr));
2808   TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
2809   visitor.SimulateInFramer(
2810       reinterpret_cast<unsigned char*>(control_frame.data()),
2811       control_frame.size());
2812   EXPECT_EQ(1, visitor.headers_frame_count_);
2813   EXPECT_EQ(0, visitor.control_frame_header_data_count_);
2814   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2815   EXPECT_EQ(1, visitor.end_of_stream_count_);
2816   EXPECT_EQ(headers_ir.header_block(), visitor.headers_);
2817 }
2818 
TEST_P(SpdyFramerTest,TooLargeHeadersFrameUsesContinuation)2819 TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) {
2820   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
2821   SpdyHeadersIR headers(/* stream_id = */ 1);
2822   headers.set_padding_len(256);
2823 
2824   // Exact payload length will change with HPACK, but this should be long
2825   // enough to cause an overflow.
2826   const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
2827   std::string big_value(kBigValueSize, 'x');
2828   headers.SetHeader("aa", big_value);
2829   SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
2830       &framer, headers, use_output_ ? &output_ : nullptr));
2831   EXPECT_GT(control_frame.size(), kHttp2MaxControlFrameSendSize);
2832 
2833   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
2834   visitor.SimulateInFramer(
2835       reinterpret_cast<unsigned char*>(control_frame.data()),
2836       control_frame.size());
2837   EXPECT_TRUE(visitor.header_buffer_valid_);
2838   EXPECT_EQ(0, visitor.error_count_);
2839   EXPECT_EQ(1, visitor.headers_frame_count_);
2840   EXPECT_EQ(1, visitor.continuation_count_);
2841   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2842 }
2843 
TEST_P(SpdyFramerTest,MultipleContinuationFramesWithIterator)2844 TEST_P(SpdyFramerTest, MultipleContinuationFramesWithIterator) {
2845   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
2846   auto headers = std::make_unique<SpdyHeadersIR>(/* stream_id = */ 1);
2847   headers->set_padding_len(256);
2848 
2849   // Exact payload length will change with HPACK, but this should be long
2850   // enough to cause an overflow.
2851   const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
2852   std::string big_valuex(kBigValueSize, 'x');
2853   headers->SetHeader("aa", big_valuex);
2854   std::string big_valuez(kBigValueSize, 'z');
2855   headers->SetHeader("bb", big_valuez);
2856 
2857   SpdyFramer::SpdyHeaderFrameIterator frame_it(&framer, std::move(headers));
2858 
2859   EXPECT_TRUE(frame_it.HasNextFrame());
2860   EXPECT_GT(frame_it.NextFrame(&output_), 0u);
2861   SpdySerializedFrame headers_frame =
2862       MakeSerializedFrame(output_.Begin(), output_.Size());
2863   EXPECT_EQ(headers_frame.size(), kHttp2MaxControlFrameSendSize);
2864 
2865   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
2866   visitor.SimulateInFramer(
2867       reinterpret_cast<unsigned char*>(headers_frame.data()),
2868       headers_frame.size());
2869   EXPECT_TRUE(visitor.header_buffer_valid_);
2870   EXPECT_EQ(0, visitor.error_count_);
2871   EXPECT_EQ(1, visitor.headers_frame_count_);
2872   EXPECT_EQ(0, visitor.continuation_count_);
2873   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2874 
2875   output_.Reset();
2876   EXPECT_TRUE(frame_it.HasNextFrame());
2877   EXPECT_GT(frame_it.NextFrame(&output_), 0u);
2878   SpdySerializedFrame first_cont_frame =
2879       MakeSerializedFrame(output_.Begin(), output_.Size());
2880   EXPECT_EQ(first_cont_frame.size(), kHttp2MaxControlFrameSendSize);
2881 
2882   visitor.SimulateInFramer(
2883       reinterpret_cast<unsigned char*>(first_cont_frame.data()),
2884       first_cont_frame.size());
2885   EXPECT_TRUE(visitor.header_buffer_valid_);
2886   EXPECT_EQ(0, visitor.error_count_);
2887   EXPECT_EQ(1, visitor.headers_frame_count_);
2888   EXPECT_EQ(1, visitor.continuation_count_);
2889   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2890 
2891   output_.Reset();
2892   EXPECT_TRUE(frame_it.HasNextFrame());
2893   EXPECT_GT(frame_it.NextFrame(&output_), 0u);
2894   SpdySerializedFrame second_cont_frame =
2895       MakeSerializedFrame(output_.Begin(), output_.Size());
2896   EXPECT_LT(second_cont_frame.size(), kHttp2MaxControlFrameSendSize);
2897 
2898   visitor.SimulateInFramer(
2899       reinterpret_cast<unsigned char*>(second_cont_frame.data()),
2900       second_cont_frame.size());
2901   EXPECT_TRUE(visitor.header_buffer_valid_);
2902   EXPECT_EQ(0, visitor.error_count_);
2903   EXPECT_EQ(1, visitor.headers_frame_count_);
2904   EXPECT_EQ(2, visitor.continuation_count_);
2905   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2906 
2907   EXPECT_FALSE(frame_it.HasNextFrame());
2908 }
2909 
TEST_P(SpdyFramerTest,PushPromiseFramesWithIterator)2910 TEST_P(SpdyFramerTest, PushPromiseFramesWithIterator) {
2911   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
2912   auto push_promise =
2913       std::make_unique<SpdyPushPromiseIR>(/* stream_id = */ 1,
2914                                           /* promised_stream_id = */ 2);
2915   push_promise->set_padding_len(256);
2916 
2917   // Exact payload length will change with HPACK, but this should be long
2918   // enough to cause an overflow.
2919   const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
2920   std::string big_valuex(kBigValueSize, 'x');
2921   push_promise->SetHeader("aa", big_valuex);
2922   std::string big_valuez(kBigValueSize, 'z');
2923   push_promise->SetHeader("bb", big_valuez);
2924 
2925   SpdyFramer::SpdyPushPromiseFrameIterator frame_it(&framer,
2926                                                     std::move(push_promise));
2927 
2928   EXPECT_TRUE(frame_it.HasNextFrame());
2929   EXPECT_GT(frame_it.NextFrame(&output_), 0u);
2930   SpdySerializedFrame push_promise_frame =
2931       MakeSerializedFrame(output_.Begin(), output_.Size());
2932   EXPECT_EQ(push_promise_frame.size(), kHttp2MaxControlFrameSendSize);
2933 
2934   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
2935   visitor.SimulateInFramer(
2936       reinterpret_cast<unsigned char*>(push_promise_frame.data()),
2937       push_promise_frame.size());
2938   EXPECT_TRUE(visitor.header_buffer_valid_);
2939   EXPECT_EQ(0, visitor.error_count_);
2940   EXPECT_EQ(1, visitor.push_promise_frame_count_);
2941   EXPECT_EQ(0, visitor.continuation_count_);
2942   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2943 
2944   EXPECT_TRUE(frame_it.HasNextFrame());
2945   output_.Reset();
2946   EXPECT_GT(frame_it.NextFrame(&output_), 0u);
2947   SpdySerializedFrame first_cont_frame =
2948       MakeSerializedFrame(output_.Begin(), output_.Size());
2949 
2950   EXPECT_EQ(first_cont_frame.size(), kHttp2MaxControlFrameSendSize);
2951   visitor.SimulateInFramer(
2952       reinterpret_cast<unsigned char*>(first_cont_frame.data()),
2953       first_cont_frame.size());
2954   EXPECT_TRUE(visitor.header_buffer_valid_);
2955   EXPECT_EQ(0, visitor.error_count_);
2956   EXPECT_EQ(1, visitor.push_promise_frame_count_);
2957   EXPECT_EQ(1, visitor.continuation_count_);
2958   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2959 
2960   EXPECT_TRUE(frame_it.HasNextFrame());
2961   output_.Reset();
2962   EXPECT_GT(frame_it.NextFrame(&output_), 0u);
2963   SpdySerializedFrame second_cont_frame =
2964       MakeSerializedFrame(output_.Begin(), output_.Size());
2965   EXPECT_LT(second_cont_frame.size(), kHttp2MaxControlFrameSendSize);
2966 
2967   visitor.SimulateInFramer(
2968       reinterpret_cast<unsigned char*>(second_cont_frame.data()),
2969       second_cont_frame.size());
2970   EXPECT_TRUE(visitor.header_buffer_valid_);
2971   EXPECT_EQ(0, visitor.error_count_);
2972   EXPECT_EQ(1, visitor.push_promise_frame_count_);
2973   EXPECT_EQ(2, visitor.continuation_count_);
2974   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2975 
2976   EXPECT_FALSE(frame_it.HasNextFrame());
2977 }
2978 
2979 class SpdyControlFrameIteratorTest : public quiche::test::QuicheTest {
2980  public:
SpdyControlFrameIteratorTest()2981   SpdyControlFrameIteratorTest() : output_(output_buffer, kSize) {}
2982 
RunTest(std::unique_ptr<SpdyFrameIR> ir)2983   void RunTest(std::unique_ptr<SpdyFrameIR> ir) {
2984     SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
2985     SpdySerializedFrame frame(framer.SerializeFrame(*ir));
2986     std::unique_ptr<SpdyFrameSequence> it =
2987         SpdyFramer::CreateIterator(&framer, std::move(ir));
2988     EXPECT_TRUE(it->HasNextFrame());
2989     EXPECT_EQ(it->NextFrame(&output_), frame.size());
2990     EXPECT_FALSE(it->HasNextFrame());
2991   }
2992 
2993  private:
2994   ArrayOutputBuffer output_;
2995 };
2996 
TEST_F(SpdyControlFrameIteratorTest,RstStreamFrameWithIterator)2997 TEST_F(SpdyControlFrameIteratorTest, RstStreamFrameWithIterator) {
2998   auto ir = std::make_unique<SpdyRstStreamIR>(0, ERROR_CODE_PROTOCOL_ERROR);
2999   RunTest(std::move(ir));
3000 }
3001 
TEST_F(SpdyControlFrameIteratorTest,SettingsFrameWithIterator)3002 TEST_F(SpdyControlFrameIteratorTest, SettingsFrameWithIterator) {
3003   auto ir = std::make_unique<SpdySettingsIR>();
3004   uint32_t kValue = 0x0a0b0c0d;
3005   SpdyKnownSettingsId kId = SETTINGS_INITIAL_WINDOW_SIZE;
3006   ir->AddSetting(kId, kValue);
3007   RunTest(std::move(ir));
3008 }
3009 
TEST_F(SpdyControlFrameIteratorTest,PingFrameWithIterator)3010 TEST_F(SpdyControlFrameIteratorTest, PingFrameWithIterator) {
3011   const SpdyPingId kPingId = 0x123456789abcdeffULL;
3012   auto ir = std::make_unique<SpdyPingIR>(kPingId);
3013   RunTest(std::move(ir));
3014 }
3015 
TEST_F(SpdyControlFrameIteratorTest,GoAwayFrameWithIterator)3016 TEST_F(SpdyControlFrameIteratorTest, GoAwayFrameWithIterator) {
3017   auto ir = std::make_unique<SpdyGoAwayIR>(0, ERROR_CODE_NO_ERROR, "GA");
3018   RunTest(std::move(ir));
3019 }
3020 
TEST_F(SpdyControlFrameIteratorTest,WindowUpdateFrameWithIterator)3021 TEST_F(SpdyControlFrameIteratorTest, WindowUpdateFrameWithIterator) {
3022   auto ir = std::make_unique<SpdyWindowUpdateIR>(1, 1);
3023   RunTest(std::move(ir));
3024 }
3025 
TEST_F(SpdyControlFrameIteratorTest,AtlSvcFrameWithIterator)3026 TEST_F(SpdyControlFrameIteratorTest, AtlSvcFrameWithIterator) {
3027   auto ir = std::make_unique<SpdyAltSvcIR>(3);
3028   ir->set_origin("origin");
3029   ir->add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
3030       "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()));
3031   ir->add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
3032       "p\"=i:d", "h_\\o\"st", 123, 42,
3033       SpdyAltSvcWireFormat::VersionVector{24}));
3034   RunTest(std::move(ir));
3035 }
3036 
TEST_F(SpdyControlFrameIteratorTest,PriorityFrameWithIterator)3037 TEST_F(SpdyControlFrameIteratorTest, PriorityFrameWithIterator) {
3038   auto ir = std::make_unique<SpdyPriorityIR>(2, 1, 17, true);
3039   RunTest(std::move(ir));
3040 }
3041 
TEST_P(SpdyFramerTest,TooLargePushPromiseFrameUsesContinuation)3042 TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) {
3043   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
3044   SpdyPushPromiseIR push_promise(/* stream_id = */ 1,
3045                                  /* promised_stream_id = */ 2);
3046   push_promise.set_padding_len(256);
3047 
3048   // Exact payload length will change with HPACK, but this should be long
3049   // enough to cause an overflow.
3050   const size_t kBigValueSize = kHttp2MaxControlFrameSendSize;
3051   std::string big_value(kBigValueSize, 'x');
3052   push_promise.SetHeader("aa", big_value);
3053   SpdySerializedFrame control_frame(SpdyFramerPeer::SerializePushPromise(
3054       &framer, push_promise, use_output_ ? &output_ : nullptr));
3055   EXPECT_GT(control_frame.size(), kHttp2MaxControlFrameSendSize);
3056 
3057   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3058   visitor.SimulateInFramer(
3059       reinterpret_cast<unsigned char*>(control_frame.data()),
3060       control_frame.size());
3061   EXPECT_TRUE(visitor.header_buffer_valid_);
3062   EXPECT_EQ(0, visitor.error_count_);
3063   EXPECT_EQ(1, visitor.push_promise_frame_count_);
3064   EXPECT_EQ(1, visitor.continuation_count_);
3065   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
3066 }
3067 
3068 // Check that the framer stops delivering header data chunks once the visitor
3069 // declares it doesn't want any more. This is important to guard against
3070 // "zip bomb" types of attacks.
TEST_P(SpdyFramerTest,ControlFrameMuchTooLarge)3071 TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) {
3072   const size_t kHeaderBufferChunks = 4;
3073   const size_t kHeaderBufferSize =
3074       kHttp2DefaultFramePayloadLimit / kHeaderBufferChunks;
3075   const size_t kBigValueSize = kHeaderBufferSize * 2;
3076   std::string big_value(kBigValueSize, 'x');
3077   SpdyHeadersIR headers(/* stream_id = */ 1);
3078   headers.set_fin(true);
3079   headers.SetHeader("aa", big_value);
3080   SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders(
3081       &framer_, headers, use_output_ ? &output_ : nullptr));
3082   TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
3083   visitor.set_header_buffer_size(kHeaderBufferSize);
3084   visitor.SimulateInFramer(
3085       reinterpret_cast<unsigned char*>(control_frame.data()),
3086       control_frame.size());
3087   // It's up to the visitor to ignore extraneous header data; the framer
3088   // won't throw an error.
3089   EXPECT_GT(visitor.header_bytes_received_, visitor.header_buffer_size_);
3090   EXPECT_EQ(1, visitor.end_of_stream_count_);
3091 }
3092 
TEST_P(SpdyFramerTest,ControlFrameSizesAreValidated)3093 TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) {
3094   // Create a GoAway frame that has a few extra bytes at the end.
3095   const size_t length = 20;
3096 
3097   // HTTP/2 GOAWAY frames are only bound by a minimal length, since they may
3098   // carry opaque data. Verify that minimal length is tested.
3099   ASSERT_GT(kGoawayFrameMinimumSize, kFrameHeaderSize);
3100   const size_t less_than_min_length =
3101       kGoawayFrameMinimumSize - kFrameHeaderSize - 1;
3102   ASSERT_LE(less_than_min_length, std::numeric_limits<unsigned char>::max());
3103   const unsigned char kH2Len = static_cast<unsigned char>(less_than_min_length);
3104   const unsigned char kH2FrameData[] = {
3105       0x00, 0x00, kH2Len,        // Length: min length - 1
3106       0x07,                      //   Type: GOAWAY
3107       0x00,                      //  Flags: none
3108       0x00, 0x00, 0x00,   0x00,  // Stream: 0
3109       0x00, 0x00, 0x00,   0x00,  //   Last: 0
3110       0x00, 0x00, 0x00,          // Truncated Status Field
3111   };
3112   const size_t pad_length = length + kFrameHeaderSize - sizeof(kH2FrameData);
3113   std::string pad(pad_length, 'A');
3114   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3115 
3116   visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
3117   visitor.SimulateInFramer(reinterpret_cast<const unsigned char*>(pad.c_str()),
3118                            pad.length());
3119 
3120   EXPECT_EQ(1, visitor.error_count_);  // This generated an error.
3121   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
3122             visitor.deframer_.spdy_framer_error())
3123       << Http2DecoderAdapter::SpdyFramerErrorToString(
3124              visitor.deframer_.spdy_framer_error());
3125   EXPECT_EQ(0, visitor.goaway_count_);  // Frame not parsed.
3126 }
3127 
TEST_P(SpdyFramerTest,ReadZeroLenSettingsFrame)3128 TEST_P(SpdyFramerTest, ReadZeroLenSettingsFrame) {
3129   SpdySettingsIR settings_ir;
3130   SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
3131   if (use_output_) {
3132     ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
3133     control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
3134   }
3135   SetFrameLength(&control_frame, 0);
3136   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3137   visitor.SimulateInFramer(
3138       reinterpret_cast<unsigned char*>(control_frame.data()), kFrameHeaderSize);
3139   // Zero-len settings frames are permitted as of HTTP/2.
3140   EXPECT_EQ(0, visitor.error_count_);
3141 }
3142 
3143 // Tests handling of SETTINGS frames with invalid length.
TEST_P(SpdyFramerTest,ReadBogusLenSettingsFrame)3144 TEST_P(SpdyFramerTest, ReadBogusLenSettingsFrame) {
3145   SpdySettingsIR settings_ir;
3146 
3147   // Add settings to more than fill the frame so that we don't get a buffer
3148   // overflow when calling SimulateInFramer() below. These settings must be
3149   // distinct parameters because SpdySettingsIR has a map for settings, and
3150   // will collapse multiple copies of the same parameter.
3151   settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 0x00000002);
3152   settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 0x00000002);
3153   SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
3154   if (use_output_) {
3155     ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
3156     control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
3157   }
3158   const size_t kNewLength = 8;
3159   SetFrameLength(&control_frame, kNewLength);
3160   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3161   visitor.SimulateInFramer(
3162       reinterpret_cast<unsigned char*>(control_frame.data()),
3163       kFrameHeaderSize + kNewLength);
3164   // Should generate an error, since its not possible to have a
3165   // settings frame of length kNewLength.
3166   EXPECT_EQ(1, visitor.error_count_);
3167   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
3168             visitor.deframer_.spdy_framer_error())
3169       << Http2DecoderAdapter::SpdyFramerErrorToString(
3170              visitor.deframer_.spdy_framer_error());
3171 }
3172 
3173 // Tests handling of larger SETTINGS frames.
TEST_P(SpdyFramerTest,ReadLargeSettingsFrame)3174 TEST_P(SpdyFramerTest, ReadLargeSettingsFrame) {
3175   SpdySettingsIR settings_ir;
3176   settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
3177   settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
3178   settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
3179 
3180   SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
3181   if (use_output_) {
3182     ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
3183     control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
3184   }
3185 
3186   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3187 
3188   // Read all at once.
3189   visitor.SimulateInFramer(
3190       reinterpret_cast<unsigned char*>(control_frame.data()),
3191       control_frame.size());
3192   EXPECT_EQ(0, visitor.error_count_);
3193   EXPECT_EQ(3, visitor.setting_count_);
3194   EXPECT_EQ(1, visitor.settings_ack_sent_);
3195 
3196   // Read data in small chunks.
3197   size_t framed_data = 0;
3198   size_t unframed_data = control_frame.size();
3199   size_t kReadChunkSize = 5;  // Read five bytes at a time.
3200   while (unframed_data > 0) {
3201     size_t to_read = std::min(kReadChunkSize, unframed_data);
3202     visitor.SimulateInFramer(
3203         reinterpret_cast<unsigned char*>(control_frame.data() + framed_data),
3204         to_read);
3205     unframed_data -= to_read;
3206     framed_data += to_read;
3207   }
3208   EXPECT_EQ(0, visitor.error_count_);
3209   EXPECT_EQ(3 * 2, visitor.setting_count_);
3210   EXPECT_EQ(2, visitor.settings_ack_sent_);
3211 }
3212 
3213 // Tests handling of SETTINGS frame with duplicate entries.
TEST_P(SpdyFramerTest,ReadDuplicateSettings)3214 TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
3215   const unsigned char kH2FrameData[] = {
3216       0x00, 0x00, 0x12,        // Length: 18
3217       0x04,                    //   Type: SETTINGS
3218       0x00,                    //  Flags: none
3219       0x00, 0x00, 0x00, 0x00,  // Stream: 0
3220       0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
3221       0x00, 0x00, 0x00, 0x02,  //  Value: 2
3222       0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
3223       0x00, 0x00, 0x00, 0x03,  //  Value: 3
3224       0x00, 0x03,              //  Param: MAX_CONCURRENT_STREAMS
3225       0x00, 0x00, 0x00, 0x03,  //  Value: 3
3226   };
3227 
3228   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3229   visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
3230 
3231   // In HTTP/2, duplicate settings are allowed;
3232   // each setting replaces the previous value for that setting.
3233   EXPECT_EQ(3, visitor.setting_count_);
3234   EXPECT_EQ(0, visitor.error_count_);
3235   EXPECT_EQ(1, visitor.settings_ack_sent_);
3236 }
3237 
3238 // Tests handling of SETTINGS frame with a setting we don't recognize.
TEST_P(SpdyFramerTest,ReadUnknownSettingsId)3239 TEST_P(SpdyFramerTest, ReadUnknownSettingsId) {
3240   const unsigned char kH2FrameData[] = {
3241       0x00, 0x00, 0x06,        // Length: 6
3242       0x04,                    //   Type: SETTINGS
3243       0x00,                    //  Flags: none
3244       0x00, 0x00, 0x00, 0x00,  // Stream: 0
3245       0x00, 0x10,              //  Param: 16
3246       0x00, 0x00, 0x00, 0x02,  //  Value: 2
3247   };
3248 
3249   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3250   visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
3251 
3252   // In HTTP/2, we ignore unknown settings because of extensions. However, we
3253   // pass the SETTINGS to the visitor, which can decide how to handle them.
3254   EXPECT_EQ(1, visitor.setting_count_);
3255   EXPECT_EQ(0, visitor.error_count_);
3256 }
3257 
TEST_P(SpdyFramerTest,ReadKnownAndUnknownSettingsWithExtension)3258 TEST_P(SpdyFramerTest, ReadKnownAndUnknownSettingsWithExtension) {
3259   const unsigned char kH2FrameData[] = {
3260       0x00, 0x00, 0x18,        // Length: 24
3261       0x04,                    //   Type: SETTINGS
3262       0x00,                    //  Flags: none
3263       0x00, 0x00, 0x00, 0x00,  // Stream: 0
3264       0x00, 0x10,              //  Param: 16
3265       0x00, 0x00, 0x00, 0x02,  //  Value: 2
3266       0x00, 0x5f,              //  Param: 95
3267       0x00, 0x01, 0x00, 0x02,  //  Value: 65538
3268       0x00, 0x02,              //  Param: ENABLE_PUSH
3269       0x00, 0x00, 0x00, 0x01,  //  Value: 1
3270       0x00, 0x08,              //  Param: ENABLE_CONNECT_PROTOCOL
3271       0x00, 0x00, 0x00, 0x01,  //  Value: 1
3272   };
3273 
3274   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3275   TestExtension extension;
3276   visitor.set_extension_visitor(&extension);
3277   visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
3278 
3279   // In HTTP/2, we ignore unknown settings because of extensions. However, we
3280   // pass the SETTINGS to the visitor, which can decide how to handle them.
3281   EXPECT_EQ(4, visitor.setting_count_);
3282   EXPECT_EQ(0, visitor.error_count_);
3283 
3284   // The extension receives only the non-standard SETTINGS.
3285   EXPECT_THAT(
3286       extension.settings_received_,
3287       testing::ElementsAre(testing::Pair(16, 2), testing::Pair(95, 65538)));
3288 }
3289 
3290 // Tests handling of SETTINGS frame with entries out of order.
TEST_P(SpdyFramerTest,ReadOutOfOrderSettings)3291 TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
3292   const unsigned char kH2FrameData[] = {
3293       0x00, 0x00, 0x12,        // Length: 18
3294       0x04,                    //   Type: SETTINGS
3295       0x00,                    //  Flags: none
3296       0x00, 0x00, 0x00, 0x00,  // Stream: 0
3297       0x00, 0x02,              //  Param: ENABLE_PUSH
3298       0x00, 0x00, 0x00, 0x02,  //  Value: 2
3299       0x00, 0x01,              //  Param: HEADER_TABLE_SIZE
3300       0x00, 0x00, 0x00, 0x03,  //  Value: 3
3301       0x00, 0x03,              //  Param: MAX_CONCURRENT_STREAMS
3302       0x00, 0x00, 0x00, 0x03,  //  Value: 3
3303   };
3304 
3305   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3306   visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
3307 
3308   // In HTTP/2, settings are allowed in any order.
3309   EXPECT_EQ(3, visitor.setting_count_);
3310   EXPECT_EQ(0, visitor.error_count_);
3311 }
3312 
TEST_P(SpdyFramerTest,ProcessSettingsAckFrame)3313 TEST_P(SpdyFramerTest, ProcessSettingsAckFrame) {
3314   const unsigned char kFrameData[] = {
3315       0x00, 0x00, 0x00,        // Length: 0
3316       0x04,                    //   Type: SETTINGS
3317       0x01,                    //  Flags: ACK
3318       0x00, 0x00, 0x00, 0x00,  // Stream: 0
3319   };
3320 
3321   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3322   visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
3323 
3324   EXPECT_EQ(0, visitor.error_count_);
3325   EXPECT_EQ(0, visitor.setting_count_);
3326   EXPECT_EQ(1, visitor.settings_ack_received_);
3327 }
3328 
TEST_P(SpdyFramerTest,ProcessDataFrameWithPadding)3329 TEST_P(SpdyFramerTest, ProcessDataFrameWithPadding) {
3330   const int kPaddingLen = 119;
3331   const char data_payload[] = "hello";
3332 
3333   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
3334   deframer_->set_visitor(&visitor);
3335 
3336   SpdyDataIR data_ir(/* stream_id = */ 1, data_payload);
3337   data_ir.set_padding_len(kPaddingLen);
3338   SpdySerializedFrame frame(framer_.SerializeData(data_ir));
3339 
3340   int bytes_consumed = 0;
3341 
3342   // Send the frame header.
3343   EXPECT_CALL(visitor,
3344               OnCommonHeader(1, kPaddingLen + strlen(data_payload), 0x0, 0x8));
3345   EXPECT_CALL(visitor,
3346               OnDataFrameHeader(1, kPaddingLen + strlen(data_payload), false));
3347   QUICHE_CHECK_EQ(kDataFrameMinimumSize,
3348                   deframer_->ProcessInput(frame.data(), kDataFrameMinimumSize));
3349   QUICHE_CHECK_EQ(deframer_->state(),
3350                   Http2DecoderAdapter::SPDY_READ_DATA_FRAME_PADDING_LENGTH);
3351   QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
3352                   Http2DecoderAdapter::SPDY_NO_ERROR);
3353   bytes_consumed += kDataFrameMinimumSize;
3354 
3355   // Send the padding length field.
3356   EXPECT_CALL(visitor, OnStreamPadLength(1, kPaddingLen - 1));
3357   QUICHE_CHECK_EQ(1u,
3358                   deframer_->ProcessInput(frame.data() + bytes_consumed, 1));
3359   QUICHE_CHECK_EQ(deframer_->state(),
3360                   Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME);
3361   QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
3362                   Http2DecoderAdapter::SPDY_NO_ERROR);
3363   bytes_consumed += 1;
3364 
3365   // Send the first two bytes of the data payload, i.e., "he".
3366   EXPECT_CALL(visitor, OnStreamFrameData(1, _, 2));
3367   QUICHE_CHECK_EQ(2u,
3368                   deframer_->ProcessInput(frame.data() + bytes_consumed, 2));
3369   QUICHE_CHECK_EQ(deframer_->state(),
3370                   Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME);
3371   QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
3372                   Http2DecoderAdapter::SPDY_NO_ERROR);
3373   bytes_consumed += 2;
3374 
3375   // Send the rest three bytes of the data payload, i.e., "llo".
3376   EXPECT_CALL(visitor, OnStreamFrameData(1, _, 3));
3377   QUICHE_CHECK_EQ(3u,
3378                   deframer_->ProcessInput(frame.data() + bytes_consumed, 3));
3379   QUICHE_CHECK_EQ(deframer_->state(),
3380                   Http2DecoderAdapter::SPDY_CONSUME_PADDING);
3381   QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
3382                   Http2DecoderAdapter::SPDY_NO_ERROR);
3383   bytes_consumed += 3;
3384 
3385   // Send the first 100 bytes of the padding payload.
3386   EXPECT_CALL(visitor, OnStreamPadding(1, 100));
3387   QUICHE_CHECK_EQ(100u,
3388                   deframer_->ProcessInput(frame.data() + bytes_consumed, 100));
3389   QUICHE_CHECK_EQ(deframer_->state(),
3390                   Http2DecoderAdapter::SPDY_CONSUME_PADDING);
3391   QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
3392                   Http2DecoderAdapter::SPDY_NO_ERROR);
3393   bytes_consumed += 100;
3394 
3395   // Send rest of the padding payload.
3396   EXPECT_CALL(visitor, OnStreamPadding(1, 18));
3397   QUICHE_CHECK_EQ(18u,
3398                   deframer_->ProcessInput(frame.data() + bytes_consumed, 18));
3399   QUICHE_CHECK_EQ(deframer_->state(),
3400                   Http2DecoderAdapter::SPDY_READY_FOR_FRAME);
3401   QUICHE_CHECK_EQ(deframer_->spdy_framer_error(),
3402                   Http2DecoderAdapter::SPDY_NO_ERROR);
3403 }
3404 
TEST_P(SpdyFramerTest,ReadWindowUpdate)3405 TEST_P(SpdyFramerTest, ReadWindowUpdate) {
3406   SpdySerializedFrame control_frame(framer_.SerializeWindowUpdate(
3407       SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 2)));
3408   if (use_output_) {
3409     ASSERT_TRUE(framer_.SerializeWindowUpdate(
3410         SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 2), &output_));
3411     control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
3412   }
3413   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3414   visitor.SimulateInFramer(
3415       reinterpret_cast<unsigned char*>(control_frame.data()),
3416       control_frame.size());
3417   EXPECT_EQ(1u, visitor.last_window_update_stream_);
3418   EXPECT_EQ(2, visitor.last_window_update_delta_);
3419 }
3420 
TEST_P(SpdyFramerTest,ReadCompressedPushPromise)3421 TEST_P(SpdyFramerTest, ReadCompressedPushPromise) {
3422   SpdyPushPromiseIR push_promise(/* stream_id = */ 42,
3423                                  /* promised_stream_id = */ 57);
3424   push_promise.SetHeader("foo", "bar");
3425   push_promise.SetHeader("bar", "foofoo");
3426   SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
3427       &framer_, push_promise, use_output_ ? &output_ : nullptr));
3428   TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
3429   visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
3430                            frame.size());
3431   EXPECT_EQ(42u, visitor.last_push_promise_stream_);
3432   EXPECT_EQ(57u, visitor.last_push_promise_promised_stream_);
3433   EXPECT_EQ(push_promise.header_block(), visitor.headers_);
3434 }
3435 
TEST_P(SpdyFramerTest,ReadHeadersWithContinuation)3436 TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) {
3437   // frame-format off
3438   const unsigned char kInput[] = {
3439       0x00, 0x00, 0x14,                       // Length: 20
3440       0x01,                                   //   Type: HEADERS
3441       0x08,                                   //  Flags: PADDED
3442       0x00, 0x00, 0x00, 0x01,                 // Stream: 1
3443       0x03,                                   // PadLen: 3 trailing bytes
3444       0x00,                                   // Unindexed Entry
3445       0x06,                                   // Name Len: 6
3446       'c',  'o',  'o',  'k',  'i', 'e',       // Name
3447       0x07,                                   // Value Len: 7
3448       'f',  'o',  'o',  '=',  'b', 'a', 'r',  // Value
3449       0x00, 0x00, 0x00,                       // Padding
3450 
3451       0x00, 0x00, 0x14,                            // Length: 20
3452       0x09,                                        //   Type: CONTINUATION
3453       0x00,                                        //  Flags: none
3454       0x00, 0x00, 0x00, 0x01,                      // Stream: 1
3455       0x00,                                        // Unindexed Entry
3456       0x06,                                        // Name Len: 6
3457       'c',  'o',  'o',  'k',  'i', 'e',            // Name
3458       0x08,                                        // Value Len: 7
3459       'b',  'a',  'z',  '=',  'b', 'i', 'n', 'g',  // Value
3460       0x00,                                        // Unindexed Entry
3461       0x06,                                        // Name Len: 6
3462       'c',                                         // Name (split)
3463 
3464       0x00, 0x00, 0x12,             // Length: 18
3465       0x09,                         //   Type: CONTINUATION
3466       0x04,                         //  Flags: END_HEADERS
3467       0x00, 0x00, 0x00, 0x01,       // Stream: 1
3468       'o',  'o',  'k',  'i',  'e',  // Name (continued)
3469       0x00,                         // Value Len: 0
3470       0x00,                         // Unindexed Entry
3471       0x04,                         // Name Len: 4
3472       'n',  'a',  'm',  'e',        // Name
3473       0x05,                         // Value Len: 5
3474       'v',  'a',  'l',  'u',  'e',  // Value
3475   };
3476   // frame-format on
3477 
3478   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3479   visitor.SimulateInFramer(kInput, sizeof(kInput));
3480 
3481   EXPECT_EQ(0, visitor.error_count_);
3482   EXPECT_EQ(1, visitor.headers_frame_count_);
3483   EXPECT_EQ(2, visitor.continuation_count_);
3484   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
3485   EXPECT_EQ(0, visitor.end_of_stream_count_);
3486 
3487   EXPECT_THAT(
3488       visitor.headers_,
3489       testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "),
3490                            testing::Pair("name", "value")));
3491 }
3492 
TEST_P(SpdyFramerTest,ReadHeadersWithContinuationAndFin)3493 TEST_P(SpdyFramerTest, ReadHeadersWithContinuationAndFin) {
3494   // frame-format off
3495   const unsigned char kInput[] = {
3496       0x00, 0x00, 0x10,                       // Length: 20
3497       0x01,                                   //   Type: HEADERS
3498       0x01,                                   //  Flags: END_STREAM
3499       0x00, 0x00, 0x00, 0x01,                 // Stream: 1
3500       0x00,                                   // Unindexed Entry
3501       0x06,                                   // Name Len: 6
3502       'c',  'o',  'o',  'k',  'i', 'e',       // Name
3503       0x07,                                   // Value Len: 7
3504       'f',  'o',  'o',  '=',  'b', 'a', 'r',  // Value
3505 
3506       0x00, 0x00, 0x14,                            // Length: 20
3507       0x09,                                        //   Type: CONTINUATION
3508       0x00,                                        //  Flags: none
3509       0x00, 0x00, 0x00, 0x01,                      // Stream: 1
3510       0x00,                                        // Unindexed Entry
3511       0x06,                                        // Name Len: 6
3512       'c',  'o',  'o',  'k',  'i', 'e',            // Name
3513       0x08,                                        // Value Len: 7
3514       'b',  'a',  'z',  '=',  'b', 'i', 'n', 'g',  // Value
3515       0x00,                                        // Unindexed Entry
3516       0x06,                                        // Name Len: 6
3517       'c',                                         // Name (split)
3518 
3519       0x00, 0x00, 0x12,             // Length: 18
3520       0x09,                         //   Type: CONTINUATION
3521       0x04,                         //  Flags: END_HEADERS
3522       0x00, 0x00, 0x00, 0x01,       // Stream: 1
3523       'o',  'o',  'k',  'i',  'e',  // Name (continued)
3524       0x00,                         // Value Len: 0
3525       0x00,                         // Unindexed Entry
3526       0x04,                         // Name Len: 4
3527       'n',  'a',  'm',  'e',        // Name
3528       0x05,                         // Value Len: 5
3529       'v',  'a',  'l',  'u',  'e',  // Value
3530   };
3531   // frame-format on
3532 
3533   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3534   visitor.SimulateInFramer(kInput, sizeof(kInput));
3535 
3536   EXPECT_EQ(0, visitor.error_count_);
3537   EXPECT_EQ(1, visitor.headers_frame_count_);
3538   EXPECT_EQ(2, visitor.continuation_count_);
3539   EXPECT_EQ(1, visitor.fin_flag_count_);
3540   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
3541   EXPECT_EQ(1, visitor.end_of_stream_count_);
3542 
3543   EXPECT_THAT(
3544       visitor.headers_,
3545       testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "),
3546                            testing::Pair("name", "value")));
3547 }
3548 
TEST_P(SpdyFramerTest,ReadPushPromiseWithContinuation)3549 TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) {
3550   // frame-format off
3551   const unsigned char kInput[] = {
3552       0x00, 0x00, 0x17,                       // Length: 23
3553       0x05,                                   //   Type: PUSH_PROMISE
3554       0x08,                                   //  Flags: PADDED
3555       0x00, 0x00, 0x00, 0x01,                 // Stream: 1
3556       0x02,                                   // PadLen: 2 trailing bytes
3557       0x00, 0x00, 0x00, 0x2a,                 // Promise: 42
3558       0x00,                                   // Unindexed Entry
3559       0x06,                                   // Name Len: 6
3560       'c',  'o',  'o',  'k',  'i', 'e',       // Name
3561       0x07,                                   // Value Len: 7
3562       'f',  'o',  'o',  '=',  'b', 'a', 'r',  // Value
3563       0x00, 0x00,                             // Padding
3564 
3565       0x00, 0x00, 0x14,                            // Length: 20
3566       0x09,                                        //   Type: CONTINUATION
3567       0x00,                                        //  Flags: none
3568       0x00, 0x00, 0x00, 0x01,                      // Stream: 1
3569       0x00,                                        // Unindexed Entry
3570       0x06,                                        // Name Len: 6
3571       'c',  'o',  'o',  'k',  'i', 'e',            // Name
3572       0x08,                                        // Value Len: 7
3573       'b',  'a',  'z',  '=',  'b', 'i', 'n', 'g',  // Value
3574       0x00,                                        // Unindexed Entry
3575       0x06,                                        // Name Len: 6
3576       'c',                                         // Name (split)
3577 
3578       0x00, 0x00, 0x12,             // Length: 18
3579       0x09,                         //   Type: CONTINUATION
3580       0x04,                         //  Flags: END_HEADERS
3581       0x00, 0x00, 0x00, 0x01,       // Stream: 1
3582       'o',  'o',  'k',  'i',  'e',  // Name (continued)
3583       0x00,                         // Value Len: 0
3584       0x00,                         // Unindexed Entry
3585       0x04,                         // Name Len: 4
3586       'n',  'a',  'm',  'e',        // Name
3587       0x05,                         // Value Len: 5
3588       'v',  'a',  'l',  'u',  'e',  // Value
3589   };
3590   // frame-format on
3591 
3592   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3593   visitor.SimulateInFramer(kInput, sizeof(kInput));
3594 
3595   EXPECT_EQ(0, visitor.error_count_);
3596   EXPECT_EQ(1u, visitor.last_push_promise_stream_);
3597   EXPECT_EQ(42u, visitor.last_push_promise_promised_stream_);
3598   EXPECT_EQ(2, visitor.continuation_count_);
3599   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
3600   EXPECT_EQ(0, visitor.end_of_stream_count_);
3601 
3602   EXPECT_THAT(
3603       visitor.headers_,
3604       testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "),
3605                            testing::Pair("name", "value")));
3606 }
3607 
3608 // Receiving an unknown frame when a continuation is expected should
3609 // result in a SPDY_UNEXPECTED_FRAME error
TEST_P(SpdyFramerTest,ReceiveUnknownMidContinuation)3610 TEST_P(SpdyFramerTest, ReceiveUnknownMidContinuation) {
3611   const unsigned char kInput[] = {
3612       0x00, 0x00, 0x10,        // Length: 16
3613       0x01,                    //   Type: HEADERS
3614       0x00,                    //  Flags: none
3615       0x00, 0x00, 0x00, 0x01,  // Stream: 1
3616       0x00, 0x06, 0x63, 0x6f,  // HPACK
3617       0x6f, 0x6b, 0x69, 0x65,  //
3618       0x07, 0x66, 0x6f, 0x6f,  //
3619       0x3d, 0x62, 0x61, 0x72,  //
3620 
3621       0x00, 0x00, 0x14,        // Length: 20
3622       0xa9,                    //   Type: UnknownFrameType(169)
3623       0x00,                    //  Flags: none
3624       0x00, 0x00, 0x00, 0x01,  // Stream: 1
3625       0x00, 0x06, 0x63, 0x6f,  // Payload
3626       0x6f, 0x6b, 0x69, 0x65,  //
3627       0x08, 0x62, 0x61, 0x7a,  //
3628       0x3d, 0x62, 0x69, 0x6e,  //
3629       0x67, 0x00, 0x06, 0x63,  //
3630   };
3631 
3632   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3633   // Assume the unknown frame is allowed
3634   visitor.on_unknown_frame_result_ = true;
3635   deframer_->set_visitor(&visitor);
3636   visitor.SimulateInFramer(kInput, sizeof(kInput));
3637 
3638   EXPECT_EQ(1, visitor.error_count_);
3639   EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
3640             visitor.deframer_.spdy_framer_error())
3641       << Http2DecoderAdapter::SpdyFramerErrorToString(
3642              visitor.deframer_.spdy_framer_error());
3643   EXPECT_EQ(1, visitor.headers_frame_count_);
3644   EXPECT_EQ(0, visitor.continuation_count_);
3645   EXPECT_EQ(0u, visitor.header_buffer_length_);
3646 }
3647 
3648 // Receiving an unknown frame when a continuation is expected should
3649 // result in a SPDY_UNEXPECTED_FRAME error
TEST_P(SpdyFramerTest,ReceiveUnknownMidContinuationWithExtension)3650 TEST_P(SpdyFramerTest, ReceiveUnknownMidContinuationWithExtension) {
3651   const unsigned char kInput[] = {
3652       0x00, 0x00, 0x10,        // Length: 16
3653       0x01,                    //   Type: HEADERS
3654       0x00,                    //  Flags: none
3655       0x00, 0x00, 0x00, 0x01,  // Stream: 1
3656       0x00, 0x06, 0x63, 0x6f,  // HPACK
3657       0x6f, 0x6b, 0x69, 0x65,  //
3658       0x07, 0x66, 0x6f, 0x6f,  //
3659       0x3d, 0x62, 0x61, 0x72,  //
3660 
3661       0x00, 0x00, 0x14,        // Length: 20
3662       0xa9,                    //   Type: UnknownFrameType(169)
3663       0x00,                    //  Flags: none
3664       0x00, 0x00, 0x00, 0x01,  // Stream: 1
3665       0x00, 0x06, 0x63, 0x6f,  // Payload
3666       0x6f, 0x6b, 0x69, 0x65,  //
3667       0x08, 0x62, 0x61, 0x7a,  //
3668       0x3d, 0x62, 0x69, 0x6e,  //
3669       0x67, 0x00, 0x06, 0x63,  //
3670   };
3671 
3672   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3673   TestExtension extension;
3674   visitor.set_extension_visitor(&extension);
3675   deframer_->set_visitor(&visitor);
3676   visitor.SimulateInFramer(kInput, sizeof(kInput));
3677 
3678   EXPECT_EQ(1, visitor.error_count_);
3679   EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
3680             visitor.deframer_.spdy_framer_error())
3681       << Http2DecoderAdapter::SpdyFramerErrorToString(
3682              visitor.deframer_.spdy_framer_error());
3683   EXPECT_EQ(1, visitor.headers_frame_count_);
3684   EXPECT_EQ(0, visitor.continuation_count_);
3685   EXPECT_EQ(0u, visitor.header_buffer_length_);
3686 }
3687 
TEST_P(SpdyFramerTest,ReceiveContinuationOnWrongStream)3688 TEST_P(SpdyFramerTest, ReceiveContinuationOnWrongStream) {
3689   const unsigned char kInput[] = {
3690       0x00, 0x00, 0x10,        // Length: 16
3691       0x01,                    //   Type: HEADERS
3692       0x00,                    //  Flags: none
3693       0x00, 0x00, 0x00, 0x01,  // Stream: 1
3694       0x00, 0x06, 0x63, 0x6f,  // HPACK
3695       0x6f, 0x6b, 0x69, 0x65,  //
3696       0x07, 0x66, 0x6f, 0x6f,  //
3697       0x3d, 0x62, 0x61, 0x72,  //
3698 
3699       0x00, 0x00, 0x14,        // Length: 20
3700       0x09,                    //   Type: CONTINUATION
3701       0x00,                    //  Flags: none
3702       0x00, 0x00, 0x00, 0x02,  // Stream: 2
3703       0x00, 0x06, 0x63, 0x6f,  // HPACK
3704       0x6f, 0x6b, 0x69, 0x65,  //
3705       0x08, 0x62, 0x61, 0x7a,  //
3706       0x3d, 0x62, 0x69, 0x6e,  //
3707       0x67, 0x00, 0x06, 0x63,  //
3708   };
3709 
3710   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3711   deframer_->set_visitor(&visitor);
3712   visitor.SimulateInFramer(kInput, sizeof(kInput));
3713 
3714   EXPECT_EQ(1, visitor.error_count_);
3715   EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
3716             visitor.deframer_.spdy_framer_error())
3717       << Http2DecoderAdapter::SpdyFramerErrorToString(
3718              visitor.deframer_.spdy_framer_error());
3719   EXPECT_EQ(1, visitor.headers_frame_count_);
3720   EXPECT_EQ(0, visitor.continuation_count_);
3721   EXPECT_EQ(0u, visitor.header_buffer_length_);
3722 }
3723 
TEST_P(SpdyFramerTest,ReadContinuationOutOfOrder)3724 TEST_P(SpdyFramerTest, ReadContinuationOutOfOrder) {
3725   const unsigned char kInput[] = {
3726       0x00, 0x00, 0x18,        // Length: 24
3727       0x09,                    //   Type: CONTINUATION
3728       0x00,                    //  Flags: none
3729       0x00, 0x00, 0x00, 0x01,  // Stream: 1
3730       0x00, 0x06, 0x63, 0x6f,  // HPACK
3731       0x6f, 0x6b, 0x69, 0x65,  //
3732       0x07, 0x66, 0x6f, 0x6f,  //
3733       0x3d, 0x62, 0x61, 0x72,  //
3734   };
3735 
3736   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3737   deframer_->set_visitor(&visitor);
3738   visitor.SimulateInFramer(kInput, sizeof(kInput));
3739 
3740   EXPECT_EQ(1, visitor.error_count_);
3741   EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
3742             visitor.deframer_.spdy_framer_error())
3743       << Http2DecoderAdapter::SpdyFramerErrorToString(
3744              visitor.deframer_.spdy_framer_error());
3745   EXPECT_EQ(0, visitor.continuation_count_);
3746   EXPECT_EQ(0u, visitor.header_buffer_length_);
3747 }
3748 
TEST_P(SpdyFramerTest,ExpectContinuationReceiveData)3749 TEST_P(SpdyFramerTest, ExpectContinuationReceiveData) {
3750   const unsigned char kInput[] = {
3751       0x00, 0x00, 0x10,        // Length: 16
3752       0x01,                    //   Type: HEADERS
3753       0x00,                    //  Flags: none
3754       0x00, 0x00, 0x00, 0x01,  // Stream: 1
3755       0x00, 0x06, 0x63, 0x6f,  // HPACK
3756       0x6f, 0x6b, 0x69, 0x65,  //
3757       0x07, 0x66, 0x6f, 0x6f,  //
3758       0x3d, 0x62, 0x61, 0x72,  //
3759 
3760       0x00, 0x00, 0x00,        // Length: 0
3761       0x00,                    //   Type: DATA
3762       0x01,                    //  Flags: END_STREAM
3763       0x00, 0x00, 0x00, 0x04,  // Stream: 4
3764 
3765       0xde, 0xad, 0xbe, 0xef,  // Truncated Frame Header
3766   };
3767 
3768   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3769   deframer_->set_visitor(&visitor);
3770   visitor.SimulateInFramer(kInput, sizeof(kInput));
3771 
3772   EXPECT_EQ(1, visitor.error_count_);
3773   EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
3774             visitor.deframer_.spdy_framer_error())
3775       << Http2DecoderAdapter::SpdyFramerErrorToString(
3776              visitor.deframer_.spdy_framer_error());
3777   EXPECT_EQ(1, visitor.headers_frame_count_);
3778   EXPECT_EQ(0, visitor.continuation_count_);
3779   EXPECT_EQ(0u, visitor.header_buffer_length_);
3780   EXPECT_EQ(0, visitor.data_frame_count_);
3781 }
3782 
TEST_P(SpdyFramerTest,ExpectContinuationReceiveControlFrame)3783 TEST_P(SpdyFramerTest, ExpectContinuationReceiveControlFrame) {
3784   const unsigned char kInput[] = {
3785       0x00, 0x00, 0x10,        // Length: 16
3786       0x01,                    //   Type: HEADERS
3787       0x00,                    //  Flags: none
3788       0x00, 0x00, 0x00, 0x01,  // Stream: 1
3789       0x00, 0x06, 0x63, 0x6f,  // HPACK
3790       0x6f, 0x6b, 0x69, 0x65,  //
3791       0x07, 0x66, 0x6f, 0x6f,  //
3792       0x3d, 0x62, 0x61, 0x72,  //
3793 
3794       0x00, 0x00, 0x10,        // Length: 16
3795       0x01,                    //   Type: HEADERS
3796       0x00,                    //  Flags: none
3797       0x00, 0x00, 0x00, 0x01,  // Stream: 1
3798       0x00, 0x06, 0x63, 0x6f,  // HPACK
3799       0x6f, 0x6b, 0x69, 0x65,  //
3800       0x07, 0x66, 0x6f, 0x6f,  //
3801       0x3d, 0x62, 0x61, 0x72,  //
3802   };
3803 
3804   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3805   deframer_->set_visitor(&visitor);
3806   visitor.SimulateInFramer(kInput, sizeof(kInput));
3807 
3808   EXPECT_EQ(1, visitor.error_count_);
3809   EXPECT_EQ(Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME,
3810             visitor.deframer_.spdy_framer_error())
3811       << Http2DecoderAdapter::SpdyFramerErrorToString(
3812              visitor.deframer_.spdy_framer_error());
3813   EXPECT_EQ(1, visitor.headers_frame_count_);
3814   EXPECT_EQ(0, visitor.continuation_count_);
3815   EXPECT_EQ(0u, visitor.header_buffer_length_);
3816   EXPECT_EQ(0, visitor.data_frame_count_);
3817 }
3818 
TEST_P(SpdyFramerTest,ReadGarbage)3819 TEST_P(SpdyFramerTest, ReadGarbage) {
3820   unsigned char garbage_frame[256];
3821   memset(garbage_frame, ~0, sizeof(garbage_frame));
3822   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3823   visitor.SimulateInFramer(garbage_frame, sizeof(garbage_frame));
3824   EXPECT_EQ(1, visitor.error_count_);
3825 }
3826 
TEST_P(SpdyFramerTest,ReadUnknownExtensionFrame)3827 TEST_P(SpdyFramerTest, ReadUnknownExtensionFrame) {
3828   // The unrecognized frame type should still have a valid length.
3829   const unsigned char unknown_frame[] = {
3830       0x00, 0x00, 0x08,        // Length: 8
3831       0xff,                    //   Type: UnknownFrameType(255)
3832       0xff,                    //  Flags: 0xff
3833       0xff, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff (R-bit set)
3834       0xff, 0xff, 0xff, 0xff,  // Payload
3835       0xff, 0xff, 0xff, 0xff,  //
3836   };
3837   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3838 
3839   // Simulate the case where the stream id validation checks out.
3840   visitor.on_unknown_frame_result_ = true;
3841   visitor.SimulateInFramer(unknown_frame, ABSL_ARRAYSIZE(unknown_frame));
3842   EXPECT_EQ(0, visitor.error_count_);
3843   EXPECT_EQ(1, visitor.unknown_frame_count_);
3844   EXPECT_EQ(8, visitor.unknown_payload_len_);
3845 
3846   // Follow it up with a valid control frame to make sure we handle
3847   // subsequent frames correctly.
3848   SpdySettingsIR settings_ir;
3849   settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 10);
3850   SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
3851   if (use_output_) {
3852     ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
3853     control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
3854   }
3855   visitor.SimulateInFramer(
3856       reinterpret_cast<unsigned char*>(control_frame.data()),
3857       control_frame.size());
3858   EXPECT_EQ(0, visitor.error_count_);
3859   EXPECT_EQ(1, visitor.setting_count_);
3860   EXPECT_EQ(1, visitor.settings_ack_sent_);
3861 }
3862 
TEST_P(SpdyFramerTest,ReadUnknownExtensionFrameWithExtension)3863 TEST_P(SpdyFramerTest, ReadUnknownExtensionFrameWithExtension) {
3864   // The unrecognized frame type should still have a valid length.
3865   const unsigned char unknown_frame[] = {
3866       0x00, 0x00, 0x14,        // Length: 20
3867       0xff,                    //   Type: UnknownFrameType(255)
3868       0xff,                    //  Flags: 0xff
3869       0xff, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff (R-bit set)
3870       0xff, 0xff, 0xff, 0xff,  // Payload
3871       0xff, 0xff, 0xff, 0xff,  //
3872       0xff, 0xff, 0xff, 0xff,  //
3873       0xff, 0xff, 0xff, 0xff,  //
3874       0xff, 0xff, 0xff, 0xff,  //
3875   };
3876   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3877   TestExtension extension;
3878   visitor.set_extension_visitor(&extension);
3879   visitor.SimulateInFramer(unknown_frame, ABSL_ARRAYSIZE(unknown_frame));
3880   EXPECT_EQ(0, visitor.error_count_);
3881   EXPECT_EQ(0x7fffffffu, extension.stream_id_);
3882   EXPECT_EQ(20u, extension.length_);
3883   EXPECT_EQ(255, extension.type_);
3884   EXPECT_EQ(0xff, extension.flags_);
3885   EXPECT_EQ(std::string(20, '\xff'), extension.payload_);
3886 
3887   // Follow it up with a valid control frame to make sure we handle
3888   // subsequent frames correctly.
3889   SpdySettingsIR settings_ir;
3890   settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 10);
3891   SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
3892   visitor.SimulateInFramer(
3893       reinterpret_cast<unsigned char*>(control_frame.data()),
3894       control_frame.size());
3895   EXPECT_EQ(0, visitor.error_count_);
3896   EXPECT_EQ(1, visitor.setting_count_);
3897   EXPECT_EQ(1, visitor.settings_ack_sent_);
3898 }
3899 
TEST_P(SpdyFramerTest,ReadGarbageWithValidLength)3900 TEST_P(SpdyFramerTest, ReadGarbageWithValidLength) {
3901   const unsigned char kFrameData[] = {
3902       0x00, 0x00, 0x08,        // Length: 8
3903       0xff,                    //   Type: UnknownFrameType(255)
3904       0xff,                    //  Flags: 0xff
3905       0xff, 0xff, 0xff, 0xff,  // Stream: 0x7fffffff (R-bit set)
3906       0xff, 0xff, 0xff, 0xff,  // Payload
3907       0xff, 0xff, 0xff, 0xff,  //
3908   };
3909   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3910   visitor.SimulateInFramer(kFrameData, ABSL_ARRAYSIZE(kFrameData));
3911   EXPECT_EQ(1, visitor.error_count_);
3912 }
3913 
TEST_P(SpdyFramerTest,ReadGarbageHPACKEncoding)3914 TEST_P(SpdyFramerTest, ReadGarbageHPACKEncoding) {
3915   const unsigned char kInput[] = {
3916       0x00, 0x12, 0x01,        // Length: 4609
3917       0x04,                    //   Type: SETTINGS
3918       0x00,                    //  Flags: none
3919       0x00, 0x00, 0x01, 0xef,  // Stream: 495
3920       0xef, 0xff,              //  Param: 61439
3921       0xff, 0xff, 0xff, 0xff,  //  Value: 4294967295
3922       0xff, 0xff,              //  Param: 0xffff
3923       0xff, 0xff, 0xff, 0xff,  //  Value: 4294967295
3924       0xff, 0xff, 0xff, 0xff,  // Settings (Truncated)
3925       0xff,                    //
3926   };
3927 
3928   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
3929   visitor.SimulateInFramer(kInput, ABSL_ARRAYSIZE(kInput));
3930   EXPECT_EQ(1, visitor.error_count_);
3931 }
3932 
TEST_P(SpdyFramerTest,SizesTest)3933 TEST_P(SpdyFramerTest, SizesTest) {
3934   EXPECT_EQ(9u, kFrameHeaderSize);
3935   EXPECT_EQ(9u, kDataFrameMinimumSize);
3936   EXPECT_EQ(9u, kHeadersFrameMinimumSize);
3937   EXPECT_EQ(14u, kPriorityFrameSize);
3938   EXPECT_EQ(13u, kRstStreamFrameSize);
3939   EXPECT_EQ(9u, kSettingsFrameMinimumSize);
3940   EXPECT_EQ(13u, kPushPromiseFrameMinimumSize);
3941   EXPECT_EQ(17u, kPingFrameSize);
3942   EXPECT_EQ(17u, kGoawayFrameMinimumSize);
3943   EXPECT_EQ(13u, kWindowUpdateFrameSize);
3944   EXPECT_EQ(9u, kContinuationFrameMinimumSize);
3945   EXPECT_EQ(11u, kGetAltSvcFrameMinimumSize);
3946   EXPECT_EQ(9u, kFrameMinimumSize);
3947 
3948   EXPECT_EQ(16384u, kHttp2DefaultFramePayloadLimit);
3949   EXPECT_EQ(16393u, kHttp2DefaultFrameSizeLimit);
3950 }
3951 
TEST_P(SpdyFramerTest,StateToStringTest)3952 TEST_P(SpdyFramerTest, StateToStringTest) {
3953   EXPECT_STREQ("ERROR", Http2DecoderAdapter::StateToString(
3954                             Http2DecoderAdapter::SPDY_ERROR));
3955   EXPECT_STREQ("FRAME_COMPLETE", Http2DecoderAdapter::StateToString(
3956                                      Http2DecoderAdapter::SPDY_FRAME_COMPLETE));
3957   EXPECT_STREQ("READY_FOR_FRAME",
3958                Http2DecoderAdapter::StateToString(
3959                    Http2DecoderAdapter::SPDY_READY_FOR_FRAME));
3960   EXPECT_STREQ("READING_COMMON_HEADER",
3961                Http2DecoderAdapter::StateToString(
3962                    Http2DecoderAdapter::SPDY_READING_COMMON_HEADER));
3963   EXPECT_STREQ("CONTROL_FRAME_PAYLOAD",
3964                Http2DecoderAdapter::StateToString(
3965                    Http2DecoderAdapter::SPDY_CONTROL_FRAME_PAYLOAD));
3966   EXPECT_STREQ("IGNORE_REMAINING_PAYLOAD",
3967                Http2DecoderAdapter::StateToString(
3968                    Http2DecoderAdapter::SPDY_IGNORE_REMAINING_PAYLOAD));
3969   EXPECT_STREQ("FORWARD_STREAM_FRAME",
3970                Http2DecoderAdapter::StateToString(
3971                    Http2DecoderAdapter::SPDY_FORWARD_STREAM_FRAME));
3972   EXPECT_STREQ(
3973       "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK",
3974       Http2DecoderAdapter::StateToString(
3975           Http2DecoderAdapter::SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK));
3976   EXPECT_STREQ("SPDY_CONTROL_FRAME_HEADER_BLOCK",
3977                Http2DecoderAdapter::StateToString(
3978                    Http2DecoderAdapter::SPDY_CONTROL_FRAME_HEADER_BLOCK));
3979   EXPECT_STREQ("SPDY_SETTINGS_FRAME_PAYLOAD",
3980                Http2DecoderAdapter::StateToString(
3981                    Http2DecoderAdapter::SPDY_SETTINGS_FRAME_PAYLOAD));
3982   EXPECT_STREQ("SPDY_ALTSVC_FRAME_PAYLOAD",
3983                Http2DecoderAdapter::StateToString(
3984                    Http2DecoderAdapter::SPDY_ALTSVC_FRAME_PAYLOAD));
3985   EXPECT_STREQ("UNKNOWN_STATE",
3986                Http2DecoderAdapter::StateToString(
3987                    Http2DecoderAdapter::SPDY_ALTSVC_FRAME_PAYLOAD + 1));
3988 }
3989 
TEST_P(SpdyFramerTest,SpdyFramerErrorToStringTest)3990 TEST_P(SpdyFramerTest, SpdyFramerErrorToStringTest) {
3991   EXPECT_STREQ("NO_ERROR", Http2DecoderAdapter::SpdyFramerErrorToString(
3992                                Http2DecoderAdapter::SPDY_NO_ERROR));
3993   EXPECT_STREQ("INVALID_STREAM_ID",
3994                Http2DecoderAdapter::SpdyFramerErrorToString(
3995                    Http2DecoderAdapter::SPDY_INVALID_STREAM_ID));
3996   EXPECT_STREQ("INVALID_CONTROL_FRAME",
3997                Http2DecoderAdapter::SpdyFramerErrorToString(
3998                    Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME));
3999   EXPECT_STREQ("CONTROL_PAYLOAD_TOO_LARGE",
4000                Http2DecoderAdapter::SpdyFramerErrorToString(
4001                    Http2DecoderAdapter::SPDY_CONTROL_PAYLOAD_TOO_LARGE));
4002   EXPECT_STREQ("DECOMPRESS_FAILURE",
4003                Http2DecoderAdapter::SpdyFramerErrorToString(
4004                    Http2DecoderAdapter::SPDY_DECOMPRESS_FAILURE));
4005   EXPECT_STREQ("INVALID_PADDING",
4006                Http2DecoderAdapter::SpdyFramerErrorToString(
4007                    Http2DecoderAdapter::SPDY_INVALID_PADDING));
4008   EXPECT_STREQ("INVALID_DATA_FRAME_FLAGS",
4009                Http2DecoderAdapter::SpdyFramerErrorToString(
4010                    Http2DecoderAdapter::SPDY_INVALID_DATA_FRAME_FLAGS));
4011   EXPECT_STREQ("UNEXPECTED_FRAME",
4012                Http2DecoderAdapter::SpdyFramerErrorToString(
4013                    Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME));
4014   EXPECT_STREQ("INTERNAL_FRAMER_ERROR",
4015                Http2DecoderAdapter::SpdyFramerErrorToString(
4016                    Http2DecoderAdapter::SPDY_INTERNAL_FRAMER_ERROR));
4017   EXPECT_STREQ("INVALID_CONTROL_FRAME_SIZE",
4018                Http2DecoderAdapter::SpdyFramerErrorToString(
4019                    Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE));
4020   EXPECT_STREQ("OVERSIZED_PAYLOAD",
4021                Http2DecoderAdapter::SpdyFramerErrorToString(
4022                    Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD));
4023   EXPECT_STREQ("UNKNOWN_ERROR", Http2DecoderAdapter::SpdyFramerErrorToString(
4024                                     Http2DecoderAdapter::LAST_ERROR));
4025   EXPECT_STREQ("UNKNOWN_ERROR",
4026                Http2DecoderAdapter::SpdyFramerErrorToString(
4027                    static_cast<Http2DecoderAdapter::SpdyFramerError>(
4028                        Http2DecoderAdapter::LAST_ERROR + 1)));
4029 }
4030 
TEST_P(SpdyFramerTest,DataFrameFlagsV4)4031 TEST_P(SpdyFramerTest, DataFrameFlagsV4) {
4032   uint8_t valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_PADDED;
4033 
4034   uint8_t flags = 0;
4035   do {
4036     SCOPED_TRACE(testing::Message()
4037                  << "Flags " << std::hex << static_cast<int>(flags));
4038 
4039     testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4040 
4041     deframer_->set_visitor(&visitor);
4042 
4043     SpdyDataIR data_ir(/* stream_id = */ 1, "hello");
4044     SpdySerializedFrame frame(framer_.SerializeData(data_ir));
4045     SetFrameFlags(&frame, flags);
4046 
4047     EXPECT_CALL(visitor, OnCommonHeader(1, 5, 0x0, flags));
4048     if (flags & ~valid_data_flags) {
4049       EXPECT_CALL(visitor, OnError(_, _));
4050     } else {
4051       EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN));
4052       if (flags & DATA_FLAG_PADDED) {
4053         // The first byte of payload is parsed as padding length, but 'h'
4054         // (0x68) is too large a padding length for a 5 byte payload.
4055         EXPECT_CALL(visitor, OnStreamPadding(_, 1));
4056         // Expect Error since the frame ends prematurely.
4057         EXPECT_CALL(visitor, OnError(_, _));
4058       } else {
4059         EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5));
4060         if (flags & DATA_FLAG_FIN) {
4061           EXPECT_CALL(visitor, OnStreamEnd(_));
4062         }
4063       }
4064     }
4065 
4066     deframer_->ProcessInput(frame.data(), frame.size());
4067     if (flags & ~valid_data_flags) {
4068       EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
4069       EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_DATA_FRAME_FLAGS,
4070                 deframer_->spdy_framer_error())
4071           << Http2DecoderAdapter::SpdyFramerErrorToString(
4072                  deframer_->spdy_framer_error());
4073     } else if (flags & DATA_FLAG_PADDED) {
4074       EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
4075       EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_PADDING,
4076                 deframer_->spdy_framer_error())
4077           << Http2DecoderAdapter::SpdyFramerErrorToString(
4078                  deframer_->spdy_framer_error());
4079     } else {
4080       EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4081       EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
4082                 deframer_->spdy_framer_error())
4083           << Http2DecoderAdapter::SpdyFramerErrorToString(
4084                  deframer_->spdy_framer_error());
4085     }
4086     deframer_ = std::make_unique<Http2DecoderAdapter>();
4087   } while (++flags != 0);
4088 }
4089 
TEST_P(SpdyFramerTest,RstStreamFrameFlags)4090 TEST_P(SpdyFramerTest, RstStreamFrameFlags) {
4091   uint8_t flags = 0;
4092   do {
4093     SCOPED_TRACE(testing::Message()
4094                  << "Flags " << std::hex << static_cast<int>(flags));
4095 
4096     testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4097     deframer_->set_visitor(&visitor);
4098 
4099     SpdyRstStreamIR rst_stream(/* stream_id = */ 13, ERROR_CODE_CANCEL);
4100     SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
4101     if (use_output_) {
4102       output_.Reset();
4103       ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
4104       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
4105     }
4106     SetFrameFlags(&frame, flags);
4107 
4108     EXPECT_CALL(visitor, OnCommonHeader(13, 4, 0x3, flags));
4109     EXPECT_CALL(visitor, OnRstStream(13, ERROR_CODE_CANCEL));
4110 
4111     deframer_->ProcessInput(frame.data(), frame.size());
4112     EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4113     EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
4114               deframer_->spdy_framer_error())
4115         << Http2DecoderAdapter::SpdyFramerErrorToString(
4116                deframer_->spdy_framer_error());
4117     deframer_ = std::make_unique<Http2DecoderAdapter>();
4118   } while (++flags != 0);
4119 }
4120 
TEST_P(SpdyFramerTest,SettingsFrameFlags)4121 TEST_P(SpdyFramerTest, SettingsFrameFlags) {
4122   uint8_t flags = 0;
4123   do {
4124     SCOPED_TRACE(testing::Message()
4125                  << "Flags " << std::hex << static_cast<int>(flags));
4126 
4127     testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4128     deframer_->set_visitor(&visitor);
4129 
4130     SpdySettingsIR settings_ir;
4131     settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 16);
4132     SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
4133     if (use_output_) {
4134       output_.Reset();
4135       ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
4136       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
4137     }
4138     SetFrameFlags(&frame, flags);
4139 
4140     EXPECT_CALL(visitor, OnCommonHeader(0, 6, 0x4, flags));
4141     if (flags & SETTINGS_FLAG_ACK) {
4142       EXPECT_CALL(visitor, OnError(_, _));
4143     } else {
4144       EXPECT_CALL(visitor, OnSettings());
4145       EXPECT_CALL(visitor, OnSetting(SETTINGS_INITIAL_WINDOW_SIZE, 16));
4146       EXPECT_CALL(visitor, OnSettingsEnd());
4147     }
4148 
4149     deframer_->ProcessInput(frame.data(), frame.size());
4150     if (flags & SETTINGS_FLAG_ACK) {
4151       // The frame is invalid because ACK frames should have no payload.
4152       EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
4153       EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
4154                 deframer_->spdy_framer_error())
4155           << Http2DecoderAdapter::SpdyFramerErrorToString(
4156                  deframer_->spdy_framer_error());
4157     } else {
4158       EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4159       EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
4160                 deframer_->spdy_framer_error())
4161           << Http2DecoderAdapter::SpdyFramerErrorToString(
4162                  deframer_->spdy_framer_error());
4163     }
4164     deframer_ = std::make_unique<Http2DecoderAdapter>();
4165   } while (++flags != 0);
4166 }
4167 
TEST_P(SpdyFramerTest,GoawayFrameFlags)4168 TEST_P(SpdyFramerTest, GoawayFrameFlags) {
4169   uint8_t flags = 0;
4170   do {
4171     SCOPED_TRACE(testing::Message()
4172                  << "Flags " << std::hex << static_cast<int>(flags));
4173 
4174     testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4175 
4176     deframer_->set_visitor(&visitor);
4177 
4178     SpdyGoAwayIR goaway_ir(/* last_good_stream_id = */ 97, ERROR_CODE_NO_ERROR,
4179                            "test");
4180     SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
4181     if (use_output_) {
4182       output_.Reset();
4183       ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
4184       frame = MakeSerializedFrame(output_.Begin(), output_.Size());
4185     }
4186     SetFrameFlags(&frame, flags);
4187 
4188     EXPECT_CALL(visitor, OnCommonHeader(0, _, 0x7, flags));
4189     EXPECT_CALL(visitor, OnGoAway(97, ERROR_CODE_NO_ERROR));
4190     EXPECT_CALL(visitor, OnGoAwayFrameData)
4191         .WillRepeatedly(testing::Return(true));
4192 
4193     deframer_->ProcessInput(frame.data(), frame.size());
4194     EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4195     EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
4196               deframer_->spdy_framer_error())
4197         << Http2DecoderAdapter::SpdyFramerErrorToString(
4198                deframer_->spdy_framer_error());
4199     deframer_ = std::make_unique<Http2DecoderAdapter>();
4200   } while (++flags != 0);
4201 }
4202 
TEST_P(SpdyFramerTest,HeadersFrameFlags)4203 TEST_P(SpdyFramerTest, HeadersFrameFlags) {
4204   uint8_t flags = 0;
4205   do {
4206     SCOPED_TRACE(testing::Message()
4207                  << "Flags " << std::hex << static_cast<int>(flags));
4208 
4209     testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4210     SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
4211     Http2DecoderAdapter deframer;
4212     deframer.set_visitor(&visitor);
4213 
4214     SpdyHeadersIR headers_ir(/* stream_id = */ 57);
4215     if (flags & HEADERS_FLAG_PRIORITY) {
4216       headers_ir.set_weight(3);
4217       headers_ir.set_has_priority(true);
4218       headers_ir.set_parent_stream_id(5);
4219       headers_ir.set_exclusive(true);
4220     }
4221     headers_ir.SetHeader("foo", "bar");
4222     SpdySerializedFrame frame(SpdyFramerPeer::SerializeHeaders(
4223         &framer, headers_ir, use_output_ ? &output_ : nullptr));
4224     uint8_t set_flags = flags & ~HEADERS_FLAG_PADDED;
4225     SetFrameFlags(&frame, set_flags);
4226 
4227     // Expected callback values
4228     SpdyStreamId stream_id = 57;
4229     bool has_priority = false;
4230     int weight = 0;
4231     SpdyStreamId parent_stream_id = 0;
4232     bool exclusive = false;
4233     bool fin = flags & CONTROL_FLAG_FIN;
4234     bool end = flags & HEADERS_FLAG_END_HEADERS;
4235     if (flags & HEADERS_FLAG_PRIORITY) {
4236       has_priority = true;
4237       weight = 3;
4238       parent_stream_id = 5;
4239       exclusive = true;
4240     }
4241     EXPECT_CALL(visitor, OnCommonHeader(stream_id, _, 0x1, set_flags));
4242     EXPECT_CALL(visitor, OnHeaders(stream_id, _, has_priority, weight,
4243                                    parent_stream_id, exclusive, fin, end));
4244     EXPECT_CALL(visitor, OnHeaderFrameStart(57)).Times(1);
4245     if (end) {
4246       EXPECT_CALL(visitor, OnHeaderFrameEnd(57)).Times(1);
4247     }
4248     if (flags & DATA_FLAG_FIN && end) {
4249       EXPECT_CALL(visitor, OnStreamEnd(_));
4250     } else {
4251       // Do not close the stream if we are expecting a CONTINUATION frame.
4252       EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0);
4253     }
4254 
4255     deframer.ProcessInput(frame.data(), frame.size());
4256     EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer.state());
4257     EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer.spdy_framer_error())
4258         << Http2DecoderAdapter::SpdyFramerErrorToString(
4259                deframer.spdy_framer_error());
4260   } while (++flags != 0);
4261 }
4262 
TEST_P(SpdyFramerTest,PingFrameFlags)4263 TEST_P(SpdyFramerTest, PingFrameFlags) {
4264   uint8_t flags = 0;
4265   do {
4266     SCOPED_TRACE(testing::Message()
4267                  << "Flags " << std::hex << static_cast<int>(flags));
4268 
4269     testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4270     deframer_->set_visitor(&visitor);
4271 
4272     SpdySerializedFrame frame(framer_.SerializePing(SpdyPingIR(42)));
4273     SetFrameFlags(&frame, flags);
4274 
4275     EXPECT_CALL(visitor, OnCommonHeader(0, 8, 0x6, flags));
4276     EXPECT_CALL(visitor, OnPing(42, flags & PING_FLAG_ACK));
4277 
4278     deframer_->ProcessInput(frame.data(), frame.size());
4279     EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4280     EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
4281               deframer_->spdy_framer_error())
4282         << Http2DecoderAdapter::SpdyFramerErrorToString(
4283                deframer_->spdy_framer_error());
4284     deframer_ = std::make_unique<Http2DecoderAdapter>();
4285   } while (++flags != 0);
4286 }
4287 
TEST_P(SpdyFramerTest,WindowUpdateFrameFlags)4288 TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) {
4289   uint8_t flags = 0;
4290   do {
4291     SCOPED_TRACE(testing::Message()
4292                  << "Flags " << std::hex << static_cast<int>(flags));
4293 
4294     testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4295 
4296     deframer_->set_visitor(&visitor);
4297 
4298     SpdySerializedFrame frame(framer_.SerializeWindowUpdate(
4299         SpdyWindowUpdateIR(/* stream_id = */ 4, /* delta = */ 1024)));
4300     SetFrameFlags(&frame, flags);
4301 
4302     EXPECT_CALL(visitor, OnCommonHeader(4, 4, 0x8, flags));
4303     EXPECT_CALL(visitor, OnWindowUpdate(4, 1024));
4304 
4305     deframer_->ProcessInput(frame.data(), frame.size());
4306     EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4307     EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
4308               deframer_->spdy_framer_error())
4309         << Http2DecoderAdapter::SpdyFramerErrorToString(
4310                deframer_->spdy_framer_error());
4311     deframer_ = std::make_unique<Http2DecoderAdapter>();
4312   } while (++flags != 0);
4313 }
4314 
TEST_P(SpdyFramerTest,PushPromiseFrameFlags)4315 TEST_P(SpdyFramerTest, PushPromiseFrameFlags) {
4316   const SpdyStreamId client_id = 123;   // Must be odd.
4317   const SpdyStreamId promised_id = 22;  // Must be even.
4318   uint8_t flags = 0;
4319   do {
4320     SCOPED_TRACE(testing::Message()
4321                  << "Flags " << std::hex << static_cast<int>(flags));
4322 
4323     testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4324     testing::StrictMock<test::MockDebugVisitor> debug_visitor;
4325     SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
4326     Http2DecoderAdapter deframer;
4327     deframer.set_visitor(&visitor);
4328     deframer.set_debug_visitor(&debug_visitor);
4329     framer.set_debug_visitor(&debug_visitor);
4330 
4331     EXPECT_CALL(
4332         debug_visitor,
4333         OnSendCompressedFrame(client_id, SpdyFrameType::PUSH_PROMISE, _, _));
4334 
4335     SpdyPushPromiseIR push_promise(client_id, promised_id);
4336     push_promise.SetHeader("foo", "bar");
4337     SpdySerializedFrame frame(SpdyFramerPeer::SerializePushPromise(
4338         &framer, push_promise, use_output_ ? &output_ : nullptr));
4339     // TODO(jgraettinger): Add padding to SpdyPushPromiseIR,
4340     // and implement framing.
4341     SetFrameFlags(&frame, flags & ~HEADERS_FLAG_PADDED);
4342 
4343     bool end = flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
4344     EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(
4345                                    client_id, SpdyFrameType::PUSH_PROMISE, _));
4346     EXPECT_CALL(visitor, OnCommonHeader(client_id, _, 0x5,
4347                                         flags & ~HEADERS_FLAG_PADDED));
4348     EXPECT_CALL(visitor, OnPushPromise(client_id, promised_id, end));
4349     EXPECT_CALL(visitor, OnHeaderFrameStart(client_id)).Times(1);
4350     if (end) {
4351       EXPECT_CALL(visitor, OnHeaderFrameEnd(client_id)).Times(1);
4352     }
4353 
4354     deframer.ProcessInput(frame.data(), frame.size());
4355     EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer.state());
4356     EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer.spdy_framer_error())
4357         << Http2DecoderAdapter::SpdyFramerErrorToString(
4358                deframer.spdy_framer_error());
4359   } while (++flags != 0);
4360 }
4361 
TEST_P(SpdyFramerTest,ContinuationFrameFlags)4362 TEST_P(SpdyFramerTest, ContinuationFrameFlags) {
4363   uint8_t flags = 0;
4364   do {
4365     if (use_output_) {
4366       output_.Reset();
4367     }
4368     SCOPED_TRACE(testing::Message()
4369                  << "Flags " << std::hex << static_cast<int>(flags));
4370 
4371     testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4372     testing::StrictMock<test::MockDebugVisitor> debug_visitor;
4373     SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
4374     Http2DecoderAdapter deframer;
4375     deframer.set_visitor(&visitor);
4376     deframer.set_debug_visitor(&debug_visitor);
4377     framer.set_debug_visitor(&debug_visitor);
4378 
4379     EXPECT_CALL(debug_visitor,
4380                 OnSendCompressedFrame(42, SpdyFrameType::HEADERS, _, _));
4381     EXPECT_CALL(debug_visitor,
4382                 OnReceiveCompressedFrame(42, SpdyFrameType::HEADERS, _));
4383     EXPECT_CALL(visitor, OnCommonHeader(42, _, 0x1, 0));
4384     EXPECT_CALL(visitor, OnHeaders(42, _, false, 0, 0, false, false, false));
4385     EXPECT_CALL(visitor, OnHeaderFrameStart(42)).Times(1);
4386 
4387     SpdyHeadersIR headers_ir(/* stream_id = */ 42);
4388     headers_ir.SetHeader("foo", "bar");
4389     SpdySerializedFrame frame0;
4390     if (use_output_) {
4391       EXPECT_TRUE(framer.SerializeHeaders(headers_ir, &output_));
4392       frame0 = MakeSerializedFrame(output_.Begin(), output_.Size());
4393     } else {
4394       frame0 = framer.SerializeHeaders(headers_ir);
4395     }
4396     SetFrameFlags(&frame0, 0);
4397 
4398     SpdyContinuationIR continuation(/* stream_id = */ 42);
4399     SpdySerializedFrame frame1;
4400     if (use_output_) {
4401       char* begin = output_.Begin() + output_.Size();
4402       ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_));
4403       frame1 = MakeSerializedFrame(begin, output_.Size() - frame0.size());
4404     } else {
4405       frame1 = framer.SerializeContinuation(continuation);
4406     }
4407     SetFrameFlags(&frame1, flags);
4408 
4409     EXPECT_CALL(debug_visitor,
4410                 OnReceiveCompressedFrame(42, SpdyFrameType::CONTINUATION, _));
4411     EXPECT_CALL(visitor, OnCommonHeader(42, _, 0x9, flags));
4412     EXPECT_CALL(visitor,
4413                 OnContinuation(42, _, flags & HEADERS_FLAG_END_HEADERS));
4414     bool end = flags & HEADERS_FLAG_END_HEADERS;
4415     if (end) {
4416       EXPECT_CALL(visitor, OnHeaderFrameEnd(42)).Times(1);
4417     }
4418 
4419     deframer.ProcessInput(frame0.data(), frame0.size());
4420     deframer.ProcessInput(frame1.data(), frame1.size());
4421     EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer.state());
4422     EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer.spdy_framer_error())
4423         << Http2DecoderAdapter::SpdyFramerErrorToString(
4424                deframer.spdy_framer_error());
4425   } while (++flags != 0);
4426 }
4427 
4428 // TODO(mlavan): Add TEST_P(SpdyFramerTest, AltSvcFrameFlags)
4429 
4430 // Test handling of a RST_STREAM with out-of-bounds status codes.
TEST_P(SpdyFramerTest,RstStreamStatusBounds)4431 TEST_P(SpdyFramerTest, RstStreamStatusBounds) {
4432   const unsigned char kH2RstStreamInvalid[] = {
4433       0x00, 0x00, 0x04,        // Length: 4
4434       0x03,                    //   Type: RST_STREAM
4435       0x00,                    //  Flags: none
4436       0x00, 0x00, 0x00, 0x01,  // Stream: 1
4437       0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
4438   };
4439   const unsigned char kH2RstStreamNumStatusCodes[] = {
4440       0x00, 0x00, 0x04,        // Length: 4
4441       0x03,                    //   Type: RST_STREAM
4442       0x00,                    //  Flags: none
4443       0x00, 0x00, 0x00, 0x01,  // Stream: 1
4444       0x00, 0x00, 0x00, 0xff,  //  Error: 255
4445   };
4446 
4447   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4448   deframer_->set_visitor(&visitor);
4449 
4450   EXPECT_CALL(visitor, OnCommonHeader(1, 4, 0x3, 0x0));
4451   EXPECT_CALL(visitor, OnRstStream(1, ERROR_CODE_NO_ERROR));
4452   deframer_->ProcessInput(reinterpret_cast<const char*>(kH2RstStreamInvalid),
4453                           ABSL_ARRAYSIZE(kH2RstStreamInvalid));
4454   EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4455   EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
4456       << Http2DecoderAdapter::SpdyFramerErrorToString(
4457              deframer_->spdy_framer_error());
4458   deframer_ = std::make_unique<Http2DecoderAdapter>();
4459   deframer_->set_visitor(&visitor);
4460 
4461   EXPECT_CALL(visitor, OnCommonHeader(1, 4, 0x3, 0x0));
4462   EXPECT_CALL(visitor, OnRstStream(1, ERROR_CODE_INTERNAL_ERROR));
4463   deframer_->ProcessInput(
4464       reinterpret_cast<const char*>(kH2RstStreamNumStatusCodes),
4465       ABSL_ARRAYSIZE(kH2RstStreamNumStatusCodes));
4466   EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4467   EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
4468       << Http2DecoderAdapter::SpdyFramerErrorToString(
4469              deframer_->spdy_framer_error());
4470 }
4471 
4472 // Test handling of GOAWAY frames with out-of-bounds status code.
TEST_P(SpdyFramerTest,GoAwayStatusBounds)4473 TEST_P(SpdyFramerTest, GoAwayStatusBounds) {
4474   const unsigned char kH2FrameData[] = {
4475       0x00, 0x00, 0x0a,        // Length: 10
4476       0x07,                    //   Type: GOAWAY
4477       0x00,                    //  Flags: none
4478       0x00, 0x00, 0x00, 0x00,  // Stream: 0
4479       0x00, 0x00, 0x00, 0x01,  //   Last: 1
4480       0xff, 0xff, 0xff, 0xff,  //  Error: 0xffffffff
4481       0x47, 0x41,              // Description
4482   };
4483   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4484   deframer_->set_visitor(&visitor);
4485 
4486   EXPECT_CALL(visitor, OnCommonHeader(0, 10, 0x7, 0x0));
4487   EXPECT_CALL(visitor, OnGoAway(1, ERROR_CODE_INTERNAL_ERROR));
4488   EXPECT_CALL(visitor, OnGoAwayFrameData).WillRepeatedly(testing::Return(true));
4489   deframer_->ProcessInput(reinterpret_cast<const char*>(kH2FrameData),
4490                           ABSL_ARRAYSIZE(kH2FrameData));
4491   EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4492   EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
4493       << Http2DecoderAdapter::SpdyFramerErrorToString(
4494              deframer_->spdy_framer_error());
4495 }
4496 
4497 // Tests handling of a GOAWAY frame with out-of-bounds stream ID.
TEST_P(SpdyFramerTest,GoAwayStreamIdBounds)4498 TEST_P(SpdyFramerTest, GoAwayStreamIdBounds) {
4499   const unsigned char kH2FrameData[] = {
4500       0x00, 0x00, 0x08,        // Length: 8
4501       0x07,                    //   Type: GOAWAY
4502       0x00,                    //  Flags: none
4503       0x00, 0x00, 0x00, 0x00,  // Stream: 0
4504       0xff, 0xff, 0xff, 0xff,  //   Last: 0x7fffffff (R-bit set)
4505       0x00, 0x00, 0x00, 0x00,  //  Error: NO_ERROR
4506   };
4507 
4508   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4509 
4510   deframer_->set_visitor(&visitor);
4511 
4512   EXPECT_CALL(visitor, OnCommonHeader(0, 8, 0x7, 0x0));
4513   EXPECT_CALL(visitor, OnGoAway(0x7fffffff, ERROR_CODE_NO_ERROR));
4514   EXPECT_CALL(visitor, OnGoAwayFrameData).WillRepeatedly(testing::Return(true));
4515   deframer_->ProcessInput(reinterpret_cast<const char*>(kH2FrameData),
4516                           ABSL_ARRAYSIZE(kH2FrameData));
4517   EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4518   EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
4519       << Http2DecoderAdapter::SpdyFramerErrorToString(
4520              deframer_->spdy_framer_error());
4521 }
4522 
TEST_P(SpdyFramerTest,OnAltSvcWithOrigin)4523 TEST_P(SpdyFramerTest, OnAltSvcWithOrigin) {
4524   const SpdyStreamId kStreamId = 0;  // Stream id must be zero if origin given.
4525 
4526   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4527 
4528   deframer_->set_visitor(&visitor);
4529 
4530   SpdyAltSvcWireFormat::AlternativeService altsvc1(
4531       "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
4532   SpdyAltSvcWireFormat::AlternativeService altsvc2(
4533       "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
4534   SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
4535   altsvc_vector.push_back(altsvc1);
4536   altsvc_vector.push_back(altsvc2);
4537   EXPECT_CALL(visitor, OnCommonHeader(kStreamId, _, 0x0A, 0x0));
4538   EXPECT_CALL(visitor,
4539               OnAltSvc(kStreamId, absl::string_view("o_r|g!n"), altsvc_vector));
4540 
4541   SpdyAltSvcIR altsvc_ir(kStreamId);
4542   altsvc_ir.set_origin("o_r|g!n");
4543   altsvc_ir.add_altsvc(altsvc1);
4544   altsvc_ir.add_altsvc(altsvc2);
4545   SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
4546   if (use_output_) {
4547     output_.Reset();
4548     EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
4549     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
4550   }
4551   deframer_->ProcessInput(frame.data(), frame.size());
4552 
4553   EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4554   EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
4555       << Http2DecoderAdapter::SpdyFramerErrorToString(
4556              deframer_->spdy_framer_error());
4557 }
4558 
TEST_P(SpdyFramerTest,OnAltSvcNoOrigin)4559 TEST_P(SpdyFramerTest, OnAltSvcNoOrigin) {
4560   const SpdyStreamId kStreamId = 1;
4561 
4562   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4563 
4564   deframer_->set_visitor(&visitor);
4565 
4566   SpdyAltSvcWireFormat::AlternativeService altsvc1(
4567       "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
4568   SpdyAltSvcWireFormat::AlternativeService altsvc2(
4569       "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
4570   SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
4571   altsvc_vector.push_back(altsvc1);
4572   altsvc_vector.push_back(altsvc2);
4573   EXPECT_CALL(visitor, OnCommonHeader(kStreamId, _, 0x0A, 0x0));
4574   EXPECT_CALL(visitor,
4575               OnAltSvc(kStreamId, absl::string_view(""), altsvc_vector));
4576 
4577   SpdyAltSvcIR altsvc_ir(kStreamId);
4578   altsvc_ir.add_altsvc(altsvc1);
4579   altsvc_ir.add_altsvc(altsvc2);
4580   SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
4581   deframer_->ProcessInput(frame.data(), frame.size());
4582 
4583   EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4584   EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
4585       << Http2DecoderAdapter::SpdyFramerErrorToString(
4586              deframer_->spdy_framer_error());
4587 }
4588 
TEST_P(SpdyFramerTest,OnAltSvcEmptyProtocolId)4589 TEST_P(SpdyFramerTest, OnAltSvcEmptyProtocolId) {
4590   const SpdyStreamId kStreamId = 0;  // Stream id must be zero if origin given.
4591 
4592   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4593 
4594   deframer_->set_visitor(&visitor);
4595 
4596   EXPECT_CALL(visitor, OnCommonHeader(kStreamId, _, 0x0A, 0x0));
4597   EXPECT_CALL(visitor,
4598               OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME, _));
4599 
4600   SpdyAltSvcIR altsvc_ir(kStreamId);
4601   altsvc_ir.set_origin("o1");
4602   altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
4603       "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()));
4604   altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
4605       "", "h1", 443, 10, SpdyAltSvcWireFormat::VersionVector()));
4606   SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
4607   if (use_output_) {
4608     output_.Reset();
4609     EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
4610     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
4611   }
4612   deframer_->ProcessInput(frame.data(), frame.size());
4613 
4614   EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
4615   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
4616             deframer_->spdy_framer_error())
4617       << Http2DecoderAdapter::SpdyFramerErrorToString(
4618              deframer_->spdy_framer_error());
4619 }
4620 
TEST_P(SpdyFramerTest,OnAltSvcBadLengths)4621 TEST_P(SpdyFramerTest, OnAltSvcBadLengths) {
4622   const unsigned char kType = SerializeFrameType(SpdyFrameType::ALTSVC);
4623   const unsigned char kFrameDataOriginLenLargerThanFrame[] = {
4624       0x00, 0x00, 0x05, kType, 0x00, 0x00, 0x00,
4625       0x00, 0x03, 0x42, 0x42,  'f',  'o',  'o',
4626   };
4627 
4628   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
4629 
4630   deframer_->set_visitor(&visitor);
4631   visitor.SimulateInFramer(kFrameDataOriginLenLargerThanFrame,
4632                            sizeof(kFrameDataOriginLenLargerThanFrame));
4633 
4634   EXPECT_EQ(1, visitor.error_count_);
4635   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
4636             visitor.deframer_.spdy_framer_error());
4637 }
4638 
4639 // Tests handling of ALTSVC frames delivered in small chunks.
TEST_P(SpdyFramerTest,ReadChunkedAltSvcFrame)4640 TEST_P(SpdyFramerTest, ReadChunkedAltSvcFrame) {
4641   SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
4642   SpdyAltSvcWireFormat::AlternativeService altsvc1(
4643       "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
4644   SpdyAltSvcWireFormat::AlternativeService altsvc2(
4645       "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
4646   altsvc_ir.add_altsvc(altsvc1);
4647   altsvc_ir.add_altsvc(altsvc2);
4648 
4649   SpdySerializedFrame control_frame(framer_.SerializeAltSvc(altsvc_ir));
4650   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
4651 
4652   // Read data in small chunks.
4653   size_t framed_data = 0;
4654   size_t unframed_data = control_frame.size();
4655   size_t kReadChunkSize = 5;  // Read five bytes at a time.
4656   while (unframed_data > 0) {
4657     size_t to_read = std::min(kReadChunkSize, unframed_data);
4658     visitor.SimulateInFramer(
4659         reinterpret_cast<unsigned char*>(control_frame.data() + framed_data),
4660         to_read);
4661     unframed_data -= to_read;
4662     framed_data += to_read;
4663   }
4664   EXPECT_EQ(0, visitor.error_count_);
4665   EXPECT_EQ(1, visitor.altsvc_count_);
4666   ASSERT_NE(nullptr, visitor.test_altsvc_ir_);
4667   ASSERT_EQ(2u, visitor.test_altsvc_ir_->altsvc_vector().size());
4668   EXPECT_TRUE(visitor.test_altsvc_ir_->altsvc_vector()[0] == altsvc1);
4669   EXPECT_TRUE(visitor.test_altsvc_ir_->altsvc_vector()[1] == altsvc2);
4670 }
4671 
4672 // While RFC7838 Section 4 says that an ALTSVC frame on stream 0 with empty
4673 // origin MUST be ignored, it is not implemented at the framer level: instead,
4674 // such frames are passed on to the consumer.
TEST_P(SpdyFramerTest,ReadAltSvcFrame)4675 TEST_P(SpdyFramerTest, ReadAltSvcFrame) {
4676   constexpr struct {
4677     uint32_t stream_id;
4678     const char* origin;
4679   } test_cases[] = {{0, ""},
4680                     {1, ""},
4681                     {0, "https://www.example.com"},
4682                     {1, "https://www.example.com"}};
4683   for (const auto& test_case : test_cases) {
4684     SpdyAltSvcIR altsvc_ir(test_case.stream_id);
4685     SpdyAltSvcWireFormat::AlternativeService altsvc(
4686         "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
4687     altsvc_ir.add_altsvc(altsvc);
4688     altsvc_ir.set_origin(test_case.origin);
4689     SpdySerializedFrame frame(framer_.SerializeAltSvc(altsvc_ir));
4690 
4691     TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
4692     deframer_->set_visitor(&visitor);
4693     deframer_->ProcessInput(frame.data(), frame.size());
4694 
4695     EXPECT_EQ(0, visitor.error_count_);
4696     EXPECT_EQ(1, visitor.altsvc_count_);
4697     EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4698     EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR,
4699               deframer_->spdy_framer_error())
4700         << Http2DecoderAdapter::SpdyFramerErrorToString(
4701                deframer_->spdy_framer_error());
4702   }
4703 }
4704 
4705 // An ALTSVC frame with invalid Alt-Svc-Field-Value results in an error.
TEST_P(SpdyFramerTest,ErrorOnAltSvcFrameWithInvalidValue)4706 TEST_P(SpdyFramerTest, ErrorOnAltSvcFrameWithInvalidValue) {
4707   // Alt-Svc-Field-Value must be "clear" or must contain an "=" character
4708   // per RFC7838 Section 3.
4709   const char kFrameData[] = {
4710       0x00, 0x00, 0x16,        //     Length: 22
4711       0x0a,                    //       Type: ALTSVC
4712       0x00,                    //      Flags: none
4713       0x00, 0x00, 0x00, 0x01,  //     Stream: 1
4714       0x00, 0x00,              // Origin-Len: 0
4715       0x74, 0x68, 0x69, 0x73,  // thisisnotavalidvalue
4716       0x69, 0x73, 0x6e, 0x6f, 0x74, 0x61, 0x76, 0x61,
4717       0x6c, 0x69, 0x64, 0x76, 0x61, 0x6c, 0x75, 0x65,
4718   };
4719 
4720   TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION);
4721   deframer_->set_visitor(&visitor);
4722   deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
4723 
4724   EXPECT_EQ(1, visitor.error_count_);
4725   EXPECT_EQ(0, visitor.altsvc_count_);
4726   EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, deframer_->state());
4727   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME,
4728             deframer_->spdy_framer_error())
4729       << Http2DecoderAdapter::SpdyFramerErrorToString(
4730              deframer_->spdy_framer_error());
4731 }
4732 
TEST_P(SpdyFramerTest,ReadPriorityUpdateFrame)4733 TEST_P(SpdyFramerTest, ReadPriorityUpdateFrame) {
4734   const char kFrameData[] = {
4735       0x00, 0x00, 0x07,        // payload length
4736       0x10,                    // frame type PRIORITY_UPDATE
4737       0x00,                    // flags
4738       0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
4739       0x00, 0x00, 0x00, 0x03,  // prioritized stream ID, must not be zero
4740       'f',  'o',  'o'          // priority field value
4741   };
4742 
4743   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4744   deframer_->set_visitor(&visitor);
4745 
4746   EXPECT_CALL(visitor, OnCommonHeader(0, 7, 0x10, 0x0));
4747   EXPECT_CALL(visitor, OnPriorityUpdate(3, "foo"));
4748   deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
4749   EXPECT_FALSE(deframer_->HasError());
4750 }
4751 
TEST_P(SpdyFramerTest,ReadPriorityUpdateFrameWithEmptyPriorityFieldValue)4752 TEST_P(SpdyFramerTest, ReadPriorityUpdateFrameWithEmptyPriorityFieldValue) {
4753   const char kFrameData[] = {
4754       0x00, 0x00, 0x04,        // payload length
4755       0x10,                    // frame type PRIORITY_UPDATE
4756       0x00,                    // flags
4757       0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
4758       0x00, 0x00, 0x00, 0x03   // prioritized stream ID, must not be zero
4759   };
4760 
4761   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4762   deframer_->set_visitor(&visitor);
4763 
4764   EXPECT_CALL(visitor, OnCommonHeader(0, 4, 0x10, 0x0));
4765   EXPECT_CALL(visitor, OnPriorityUpdate(3, ""));
4766   deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
4767   EXPECT_FALSE(deframer_->HasError());
4768 }
4769 
TEST_P(SpdyFramerTest,PriorityUpdateFrameWithEmptyPayload)4770 TEST_P(SpdyFramerTest, PriorityUpdateFrameWithEmptyPayload) {
4771   const char kFrameData[] = {
4772       0x00, 0x00, 0x00,        // payload length
4773       0x10,                    // frame type PRIORITY_UPDATE
4774       0x00,                    // flags
4775       0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
4776   };
4777 
4778   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4779   deframer_->set_visitor(&visitor);
4780 
4781   EXPECT_CALL(visitor, OnCommonHeader(0, 0, 0x10, 0x0));
4782   EXPECT_CALL(visitor,
4783               OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE, _));
4784   deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
4785   EXPECT_TRUE(deframer_->HasError());
4786 }
4787 
TEST_P(SpdyFramerTest,PriorityUpdateFrameWithShortPayload)4788 TEST_P(SpdyFramerTest, PriorityUpdateFrameWithShortPayload) {
4789   const char kFrameData[] = {
4790       0x00, 0x00, 0x02,        // payload length
4791       0x10,                    // frame type PRIORITY_UPDATE
4792       0x00,                    // flags
4793       0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
4794       0x00, 0x01  // payload not long enough to hold 32 bits of prioritized
4795                   // stream ID
4796   };
4797 
4798   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4799   deframer_->set_visitor(&visitor);
4800 
4801   EXPECT_CALL(visitor, OnCommonHeader(0, 2, 0x10, 0x0));
4802   EXPECT_CALL(visitor,
4803               OnError(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE, _));
4804   deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
4805   EXPECT_TRUE(deframer_->HasError());
4806 }
4807 
TEST_P(SpdyFramerTest,PriorityUpdateFrameOnIncorrectStream)4808 TEST_P(SpdyFramerTest, PriorityUpdateFrameOnIncorrectStream) {
4809   const char kFrameData[] = {
4810       0x00, 0x00, 0x04,        // payload length
4811       0x10,                    // frame type PRIORITY_UPDATE
4812       0x00,                    // flags
4813       0x00, 0x00, 0x00, 0x01,  // invalid stream ID, must be 0
4814       0x00, 0x00, 0x00, 0x01,  // prioritized stream ID, must not be zero
4815   };
4816 
4817   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4818   deframer_->set_visitor(&visitor);
4819 
4820   EXPECT_CALL(visitor, OnCommonHeader(1, 4, 0x10, 0x0));
4821   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
4822   deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
4823   EXPECT_TRUE(deframer_->HasError());
4824 }
4825 
TEST_P(SpdyFramerTest,PriorityUpdateFramePrioritizingIncorrectStream)4826 TEST_P(SpdyFramerTest, PriorityUpdateFramePrioritizingIncorrectStream) {
4827   const char kFrameData[] = {
4828       0x00, 0x00, 0x04,        // payload length
4829       0x10,                    // frame type PRIORITY_UPDATE
4830       0x00,                    // flags
4831       0x00, 0x00, 0x00, 0x00,  // stream ID, must be 0
4832       0x00, 0x00, 0x00, 0x00,  // prioritized stream ID, must not be zero
4833   };
4834 
4835   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4836   deframer_->set_visitor(&visitor);
4837 
4838   EXPECT_CALL(visitor, OnCommonHeader(0, 4, 0x10, 0x0));
4839   EXPECT_CALL(visitor, OnError(Http2DecoderAdapter::SPDY_INVALID_STREAM_ID, _));
4840   deframer_->ProcessInput(kFrameData, sizeof(kFrameData));
4841   EXPECT_TRUE(deframer_->HasError());
4842 }
4843 
4844 // Tests handling of PRIORITY frames.
TEST_P(SpdyFramerTest,ReadPriority)4845 TEST_P(SpdyFramerTest, ReadPriority) {
4846   SpdyPriorityIR priority(/* stream_id = */ 3,
4847                           /* parent_stream_id = */ 1,
4848                           /* weight = */ 256,
4849                           /* exclusive = */ false);
4850   SpdySerializedFrame frame(framer_.SerializePriority(priority));
4851   if (use_output_) {
4852     output_.Reset();
4853     ASSERT_TRUE(framer_.SerializePriority(priority, &output_));
4854     frame = MakeSerializedFrame(output_.Begin(), output_.Size());
4855   }
4856   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
4857   deframer_->set_visitor(&visitor);
4858   EXPECT_CALL(visitor, OnCommonHeader(3, 5, 0x2, 0x0));
4859   EXPECT_CALL(visitor, OnPriority(3, 1, 256, false));
4860   deframer_->ProcessInput(frame.data(), frame.size());
4861 
4862   EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
4863   EXPECT_EQ(Http2DecoderAdapter::SPDY_NO_ERROR, deframer_->spdy_framer_error())
4864       << Http2DecoderAdapter::SpdyFramerErrorToString(
4865              deframer_->spdy_framer_error());
4866 }
4867 
4868 // Tests handling of PRIORITY frame with incorrect size.
TEST_P(SpdyFramerTest,ReadIncorrectlySizedPriority)4869 TEST_P(SpdyFramerTest, ReadIncorrectlySizedPriority) {
4870   // PRIORITY frame of size 4, which isn't correct.
4871   const unsigned char kFrameData[] = {
4872       0x00, 0x00, 0x04,        // Length: 4
4873       0x02,                    //   Type: PRIORITY
4874       0x00,                    //  Flags: none
4875       0x00, 0x00, 0x00, 0x03,  // Stream: 3
4876       0x00, 0x00, 0x00, 0x01,  // Priority (Truncated)
4877   };
4878 
4879   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
4880   visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
4881 
4882   EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
4883   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
4884             visitor.deframer_.spdy_framer_error())
4885       << Http2DecoderAdapter::SpdyFramerErrorToString(
4886              visitor.deframer_.spdy_framer_error());
4887 }
4888 
4889 // Tests handling of PING frame with incorrect size.
TEST_P(SpdyFramerTest,ReadIncorrectlySizedPing)4890 TEST_P(SpdyFramerTest, ReadIncorrectlySizedPing) {
4891   // PING frame of size 4, which isn't correct.
4892   const unsigned char kFrameData[] = {
4893       0x00, 0x00, 0x04,        // Length: 4
4894       0x06,                    //   Type: PING
4895       0x00,                    //  Flags: none
4896       0x00, 0x00, 0x00, 0x00,  // Stream: 0
4897       0x00, 0x00, 0x00, 0x01,  // Ping (Truncated)
4898   };
4899 
4900   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
4901   visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
4902 
4903   EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
4904   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
4905             visitor.deframer_.spdy_framer_error())
4906       << Http2DecoderAdapter::SpdyFramerErrorToString(
4907              visitor.deframer_.spdy_framer_error());
4908 }
4909 
4910 // Tests handling of WINDOW_UPDATE frame with incorrect size.
TEST_P(SpdyFramerTest,ReadIncorrectlySizedWindowUpdate)4911 TEST_P(SpdyFramerTest, ReadIncorrectlySizedWindowUpdate) {
4912   // WINDOW_UPDATE frame of size 3, which isn't correct.
4913   const unsigned char kFrameData[] = {
4914       0x00, 0x00, 0x03,        // Length: 3
4915       0x08,                    //   Type: WINDOW_UPDATE
4916       0x00,                    //  Flags: none
4917       0x00, 0x00, 0x00, 0x03,  // Stream: 3
4918       0x00, 0x00, 0x01,        // WindowUpdate (Truncated)
4919   };
4920 
4921   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
4922   visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
4923 
4924   EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
4925   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
4926             visitor.deframer_.spdy_framer_error())
4927       << Http2DecoderAdapter::SpdyFramerErrorToString(
4928              visitor.deframer_.spdy_framer_error());
4929 }
4930 
4931 // Tests handling of RST_STREAM frame with incorrect size.
TEST_P(SpdyFramerTest,ReadIncorrectlySizedRstStream)4932 TEST_P(SpdyFramerTest, ReadIncorrectlySizedRstStream) {
4933   // RST_STREAM frame of size 3, which isn't correct.
4934   const unsigned char kFrameData[] = {
4935       0x00, 0x00, 0x03,        // Length: 3
4936       0x03,                    //   Type: RST_STREAM
4937       0x00,                    //  Flags: none
4938       0x00, 0x00, 0x00, 0x03,  // Stream: 3
4939       0x00, 0x00, 0x01,        // RstStream (Truncated)
4940   };
4941 
4942   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
4943   visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
4944 
4945   EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
4946   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
4947             visitor.deframer_.spdy_framer_error())
4948       << Http2DecoderAdapter::SpdyFramerErrorToString(
4949              visitor.deframer_.spdy_framer_error());
4950 }
4951 
4952 // Regression test for https://crbug.com/548674:
4953 // RST_STREAM with payload must not be accepted.
TEST_P(SpdyFramerTest,ReadInvalidRstStreamWithPayload)4954 TEST_P(SpdyFramerTest, ReadInvalidRstStreamWithPayload) {
4955   const unsigned char kFrameData[] = {
4956       0x00, 0x00, 0x07,        //  Length: 7
4957       0x03,                    //    Type: RST_STREAM
4958       0x00,                    //   Flags: none
4959       0x00, 0x00, 0x00, 0x01,  //  Stream: 1
4960       0x00, 0x00, 0x00, 0x00,  //   Error: NO_ERROR
4961       'f',  'o',  'o'          // Payload: "foo"
4962   };
4963 
4964   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
4965   visitor.SimulateInFramer(kFrameData, sizeof(kFrameData));
4966 
4967   EXPECT_EQ(Http2DecoderAdapter::SPDY_ERROR, visitor.deframer_.state());
4968   EXPECT_EQ(Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME_SIZE,
4969             visitor.deframer_.spdy_framer_error())
4970       << Http2DecoderAdapter::SpdyFramerErrorToString(
4971              visitor.deframer_.spdy_framer_error());
4972 }
4973 
4974 // Test that SpdyFramer processes all passed input in one call to ProcessInput.
TEST_P(SpdyFramerTest,ProcessAllInput)4975 TEST_P(SpdyFramerTest, ProcessAllInput) {
4976   auto visitor =
4977       std::make_unique<TestSpdyVisitor>(SpdyFramer::DISABLE_COMPRESSION);
4978   deframer_->set_visitor(visitor.get());
4979 
4980   // Create two input frames.
4981   SpdyHeadersIR headers(/* stream_id = */ 1);
4982   headers.SetHeader("alpha", "beta");
4983   headers.SetHeader("gamma", "charlie");
4984   headers.SetHeader("cookie", "key1=value1; key2=value2");
4985   SpdySerializedFrame headers_frame(SpdyFramerPeer::SerializeHeaders(
4986       &framer_, headers, use_output_ ? &output_ : nullptr));
4987 
4988   const char four_score[] = "Four score and seven years ago";
4989   SpdyDataIR four_score_ir(/* stream_id = */ 1, four_score);
4990   SpdySerializedFrame four_score_frame(framer_.SerializeData(four_score_ir));
4991 
4992   // Put them in a single buffer (new variables here to make it easy to
4993   // change the order and type of frames).
4994   SpdySerializedFrame frame1 = std::move(headers_frame);
4995   SpdySerializedFrame frame2 = std::move(four_score_frame);
4996 
4997   const size_t frame1_size = frame1.size();
4998   const size_t frame2_size = frame2.size();
4999 
5000   QUICHE_VLOG(1) << "frame1_size = " << frame1_size;
5001   QUICHE_VLOG(1) << "frame2_size = " << frame2_size;
5002 
5003   std::string input_buffer;
5004   input_buffer.append(frame1.data(), frame1_size);
5005   input_buffer.append(frame2.data(), frame2_size);
5006 
5007   const char* buf = input_buffer.data();
5008   const size_t buf_size = input_buffer.size();
5009 
5010   QUICHE_VLOG(1) << "buf_size = " << buf_size;
5011 
5012   size_t processed = deframer_->ProcessInput(buf, buf_size);
5013   EXPECT_EQ(buf_size, processed);
5014   EXPECT_EQ(Http2DecoderAdapter::SPDY_READY_FOR_FRAME, deframer_->state());
5015   EXPECT_EQ(1, visitor->headers_frame_count_);
5016   EXPECT_EQ(1, visitor->data_frame_count_);
5017   EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_));
5018 }
5019 
5020 namespace {
CheckFrameAndIRSize(SpdyFrameIR * ir,SpdyFramer * framer,ArrayOutputBuffer * array_output_buffer)5021 void CheckFrameAndIRSize(SpdyFrameIR* ir, SpdyFramer* framer,
5022                          ArrayOutputBuffer* array_output_buffer) {
5023   array_output_buffer->Reset();
5024   SpdyFrameType type = ir->frame_type();
5025   size_t ir_size = ir->size();
5026   framer->SerializeFrame(*ir, array_output_buffer);
5027   if (type == SpdyFrameType::HEADERS || type == SpdyFrameType::PUSH_PROMISE) {
5028     // For HEADERS and PUSH_PROMISE, the size is an estimate.
5029     EXPECT_GE(ir_size, array_output_buffer->Size() * 9 / 10);
5030     EXPECT_LT(ir_size, array_output_buffer->Size() * 11 / 10);
5031   } else {
5032     EXPECT_EQ(ir_size, array_output_buffer->Size());
5033   }
5034 }
5035 }  // namespace
5036 
TEST_P(SpdyFramerTest,SpdyFrameIRSize)5037 TEST_P(SpdyFramerTest, SpdyFrameIRSize) {
5038   SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION);
5039 
5040   const char bytes[] = "this is a very short data frame";
5041   SpdyDataIR data_ir(1, absl::string_view(bytes, ABSL_ARRAYSIZE(bytes)));
5042   CheckFrameAndIRSize(&data_ir, &framer, &output_);
5043 
5044   SpdyRstStreamIR rst_ir(/* stream_id = */ 1, ERROR_CODE_PROTOCOL_ERROR);
5045   CheckFrameAndIRSize(&rst_ir, &framer, &output_);
5046 
5047   SpdySettingsIR settings_ir;
5048   settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 5);
5049   settings_ir.AddSetting(SETTINGS_ENABLE_PUSH, 6);
5050   settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 7);
5051   CheckFrameAndIRSize(&settings_ir, &framer, &output_);
5052 
5053   SpdyPingIR ping_ir(42);
5054   CheckFrameAndIRSize(&ping_ir, &framer, &output_);
5055 
5056   SpdyGoAwayIR goaway_ir(97, ERROR_CODE_NO_ERROR, "Goaway description");
5057   CheckFrameAndIRSize(&goaway_ir, &framer, &output_);
5058 
5059   SpdyHeadersIR headers_ir(1);
5060   headers_ir.SetHeader("alpha", "beta");
5061   headers_ir.SetHeader("gamma", "charlie");
5062   headers_ir.SetHeader("cookie", "key1=value1; key2=value2");
5063   CheckFrameAndIRSize(&headers_ir, &framer, &output_);
5064 
5065   SpdyHeadersIR headers_ir_with_continuation(1);
5066   headers_ir_with_continuation.SetHeader("alpha", std::string(100000, 'x'));
5067   headers_ir_with_continuation.SetHeader("beta", std::string(100000, 'x'));
5068   headers_ir_with_continuation.SetHeader("cookie", "key1=value1; key2=value2");
5069   CheckFrameAndIRSize(&headers_ir_with_continuation, &framer, &output_);
5070 
5071   SpdyWindowUpdateIR window_update_ir(4, 1024);
5072   CheckFrameAndIRSize(&window_update_ir, &framer, &output_);
5073 
5074   SpdyPushPromiseIR push_promise_ir(3, 8);
5075   push_promise_ir.SetHeader("alpha", std::string(100000, 'x'));
5076   push_promise_ir.SetHeader("beta", std::string(100000, 'x'));
5077   push_promise_ir.SetHeader("cookie", "key1=value1; key2=value2");
5078   CheckFrameAndIRSize(&push_promise_ir, &framer, &output_);
5079 
5080   SpdyAltSvcWireFormat::AlternativeService altsvc1(
5081       "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector());
5082   SpdyAltSvcWireFormat::AlternativeService altsvc2(
5083       "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24});
5084   SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
5085   altsvc_vector.push_back(altsvc1);
5086   altsvc_vector.push_back(altsvc2);
5087   SpdyAltSvcIR altsvc_ir(0);
5088   altsvc_ir.set_origin("o_r|g!n");
5089   altsvc_ir.add_altsvc(altsvc1);
5090   altsvc_ir.add_altsvc(altsvc2);
5091   CheckFrameAndIRSize(&altsvc_ir, &framer, &output_);
5092 
5093   SpdyPriorityIR priority_ir(3, 1, 256, false);
5094   CheckFrameAndIRSize(&priority_ir, &framer, &output_);
5095 
5096   const char kDescription[] = "Unknown frame";
5097   const uint8_t kType = 0xaf;
5098   const uint8_t kFlags = 0x11;
5099   SpdyUnknownIR unknown_ir(2, kType, kFlags, kDescription);
5100   CheckFrameAndIRSize(&unknown_ir, &framer, &output_);
5101 }
5102 
5103 }  // namespace test
5104 
5105 }  // namespace spdy
5106