1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/third_party/quiche/src/quic/core/http/http_decoder.h"
6 
7 #include <cstdint>
8 
9 #include "net/third_party/quiche/src/quic/core/http/http_frames.h"
10 #include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
11 #include "net/third_party/quiche/src/quic/core/quic_types.h"
12 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
13 #include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h"
14 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
15 
16 namespace quic {
17 
HttpDecoder(Visitor * visitor)18 HttpDecoder::HttpDecoder(Visitor* visitor)
19     : visitor_(visitor),
20       state_(STATE_READING_FRAME_TYPE),
21       current_frame_type_(0),
22       current_length_field_length_(0),
23       remaining_length_field_length_(0),
24       current_frame_length_(0),
25       remaining_frame_length_(0),
26       current_type_field_length_(0),
27       remaining_type_field_length_(0),
28       current_push_id_length_(0),
29       remaining_push_id_length_(0),
30       error_(QUIC_NO_ERROR),
31       error_detail_("") {
32   DCHECK(visitor_);
33 }
34 
~HttpDecoder()35 HttpDecoder::~HttpDecoder() {}
36 
ProcessInput(const char * data,QuicByteCount len)37 QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
38   DCHECK_EQ(QUIC_NO_ERROR, error_);
39   DCHECK_NE(STATE_ERROR, state_);
40 
41   QuicDataReader reader(data, len);
42   bool continue_processing = true;
43   while (continue_processing &&
44          (reader.BytesRemaining() != 0 || state_ == STATE_FINISH_PARSING)) {
45     // |continue_processing| must have been set to false upon error.
46     DCHECK_EQ(QUIC_NO_ERROR, error_);
47     DCHECK_NE(STATE_ERROR, state_);
48 
49     switch (state_) {
50       case STATE_READING_FRAME_TYPE:
51         ReadFrameType(&reader);
52         break;
53       case STATE_READING_FRAME_LENGTH:
54         continue_processing = ReadFrameLength(&reader);
55         break;
56       case STATE_READING_FRAME_PAYLOAD:
57         continue_processing = ReadFramePayload(&reader);
58         break;
59       case STATE_FINISH_PARSING:
60         continue_processing = FinishParsing();
61         break;
62       case STATE_ERROR:
63         break;
64       default:
65         QUIC_BUG << "Invalid state: " << state_;
66     }
67   }
68 
69   return len - reader.BytesRemaining();
70 }
71 
ReadFrameType(QuicDataReader * reader)72 void HttpDecoder::ReadFrameType(QuicDataReader* reader) {
73   DCHECK_NE(0u, reader->BytesRemaining());
74   if (current_type_field_length_ == 0) {
75     // A new frame is coming.
76     current_type_field_length_ = reader->PeekVarInt62Length();
77     DCHECK_NE(0u, current_type_field_length_);
78     if (current_type_field_length_ > reader->BytesRemaining()) {
79       // Buffer a new type field.
80       remaining_type_field_length_ = current_type_field_length_;
81       BufferFrameType(reader);
82       return;
83     }
84     // The reader has all type data needed, so no need to buffer.
85     bool success = reader->ReadVarInt62(&current_frame_type_);
86     DCHECK(success);
87   } else {
88     // Buffer the existing type field.
89     BufferFrameType(reader);
90     // The frame is still not buffered completely.
91     if (remaining_type_field_length_ != 0) {
92       return;
93     }
94     QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_);
95     bool success = type_reader.ReadVarInt62(&current_frame_type_);
96     DCHECK(success);
97   }
98 
99   state_ = STATE_READING_FRAME_LENGTH;
100 }
101 
ReadFrameLength(QuicDataReader * reader)102 bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
103   DCHECK_NE(0u, reader->BytesRemaining());
104   if (current_length_field_length_ == 0) {
105     // A new frame is coming.
106     current_length_field_length_ = reader->PeekVarInt62Length();
107     DCHECK_NE(0u, current_length_field_length_);
108     if (current_length_field_length_ > reader->BytesRemaining()) {
109       // Buffer a new length field.
110       remaining_length_field_length_ = current_length_field_length_;
111       BufferFrameLength(reader);
112       return true;
113     }
114     // The reader has all length data needed, so no need to buffer.
115     bool success = reader->ReadVarInt62(&current_frame_length_);
116     DCHECK(success);
117   } else {
118     // Buffer the existing length field.
119     BufferFrameLength(reader);
120     // The frame is still not buffered completely.
121     if (remaining_length_field_length_ != 0) {
122       return true;
123     }
124     QuicDataReader length_reader(length_buffer_.data(),
125                                  current_length_field_length_);
126     bool success = length_reader.ReadVarInt62(&current_frame_length_);
127     DCHECK(success);
128   }
129 
130   if (current_frame_length_ > MaxFrameLength(current_frame_type_)) {
131     RaiseError(QUIC_HTTP_FRAME_TOO_LARGE, "Frame is too large.");
132     return false;
133   }
134 
135   // Calling the following visitor methods does not require parsing of any
136   // frame payload.
137   bool continue_processing = true;
138   const QuicByteCount header_length =
139       current_length_field_length_ + current_type_field_length_;
140 
141   switch (current_frame_type_) {
142     case static_cast<uint64_t>(HttpFrameType::DATA):
143       continue_processing =
144           visitor_->OnDataFrameStart(header_length, current_frame_length_);
145       break;
146     case static_cast<uint64_t>(HttpFrameType::HEADERS):
147       continue_processing =
148           visitor_->OnHeadersFrameStart(header_length, current_frame_length_);
149       break;
150     case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
151       break;
152     case static_cast<uint64_t>(HttpFrameType::SETTINGS):
153       continue_processing = visitor_->OnSettingsFrameStart(header_length);
154       break;
155     case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
156       // This edge case needs to be handled here, because ReadFramePayload()
157       // does not get called if |current_frame_length_| is zero.
158       if (current_frame_length_ == 0) {
159         RaiseError(QUIC_HTTP_FRAME_ERROR,
160                    "PUSH_PROMISE frame with empty payload.");
161         return false;
162       }
163       continue_processing = visitor_->OnPushPromiseFrameStart(header_length);
164       break;
165     case static_cast<uint64_t>(HttpFrameType::GOAWAY):
166       break;
167     case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
168       break;
169     case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE):
170       continue_processing = visitor_->OnPriorityUpdateFrameStart(header_length);
171       break;
172     default:
173       continue_processing = visitor_->OnUnknownFrameStart(
174           current_frame_type_, header_length, current_frame_length_);
175       break;
176   }
177 
178   remaining_frame_length_ = current_frame_length_;
179   state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
180                                           : STATE_READING_FRAME_PAYLOAD;
181   return continue_processing;
182 }
183 
ReadFramePayload(QuicDataReader * reader)184 bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
185   DCHECK_NE(0u, reader->BytesRemaining());
186   DCHECK_NE(0u, remaining_frame_length_);
187 
188   bool continue_processing = true;
189 
190   switch (current_frame_type_) {
191     case static_cast<uint64_t>(HttpFrameType::DATA): {
192       QuicByteCount bytes_to_read = std::min<QuicByteCount>(
193           remaining_frame_length_, reader->BytesRemaining());
194       quiche::QuicheStringPiece payload;
195       bool success = reader->ReadStringPiece(&payload, bytes_to_read);
196       DCHECK(success);
197       DCHECK(!payload.empty());
198       continue_processing = visitor_->OnDataFramePayload(payload);
199       remaining_frame_length_ -= payload.length();
200       break;
201     }
202     case static_cast<uint64_t>(HttpFrameType::HEADERS): {
203       QuicByteCount bytes_to_read = std::min<QuicByteCount>(
204           remaining_frame_length_, reader->BytesRemaining());
205       quiche::QuicheStringPiece payload;
206       bool success = reader->ReadStringPiece(&payload, bytes_to_read);
207       DCHECK(success);
208       DCHECK(!payload.empty());
209       continue_processing = visitor_->OnHeadersFramePayload(payload);
210       remaining_frame_length_ -= payload.length();
211       break;
212     }
213     case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
214       BufferFramePayload(reader);
215       break;
216     }
217     case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
218       BufferFramePayload(reader);
219       break;
220     }
221     case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
222       PushId push_id;
223       if (current_frame_length_ == remaining_frame_length_) {
224         // A new Push Promise frame just arrived.
225         DCHECK_EQ(0u, current_push_id_length_);
226         current_push_id_length_ = reader->PeekVarInt62Length();
227         if (current_push_id_length_ > remaining_frame_length_) {
228           RaiseError(QUIC_HTTP_FRAME_ERROR,
229                      "Unable to read PUSH_PROMISE push_id.");
230           return false;
231         }
232         if (current_push_id_length_ > reader->BytesRemaining()) {
233           // Not all bytes of push id is present yet, buffer push id.
234           DCHECK_EQ(0u, remaining_push_id_length_);
235           remaining_push_id_length_ = current_push_id_length_;
236           BufferPushId(reader);
237           break;
238         }
239         bool success = reader->ReadVarInt62(&push_id);
240         DCHECK(success);
241         remaining_frame_length_ -= current_push_id_length_;
242         if (!visitor_->OnPushPromiseFramePushId(
243                 push_id, current_push_id_length_,
244                 current_frame_length_ - current_push_id_length_)) {
245           continue_processing = false;
246           current_push_id_length_ = 0;
247           break;
248         }
249         current_push_id_length_ = 0;
250       } else if (remaining_push_id_length_ > 0) {
251         // Waiting for more bytes on push id.
252         BufferPushId(reader);
253         if (remaining_push_id_length_ != 0) {
254           break;
255         }
256         QuicDataReader push_id_reader(push_id_buffer_.data(),
257                                       current_push_id_length_);
258 
259         bool success = push_id_reader.ReadVarInt62(&push_id);
260         DCHECK(success);
261         if (!visitor_->OnPushPromiseFramePushId(
262                 push_id, current_push_id_length_,
263                 current_frame_length_ - current_push_id_length_)) {
264           continue_processing = false;
265           current_push_id_length_ = 0;
266           break;
267         }
268         current_push_id_length_ = 0;
269       }
270 
271       // Read Push Promise headers.
272       DCHECK_LT(remaining_frame_length_, current_frame_length_);
273       QuicByteCount bytes_to_read = std::min<QuicByteCount>(
274           remaining_frame_length_, reader->BytesRemaining());
275       if (bytes_to_read == 0) {
276         break;
277       }
278       quiche::QuicheStringPiece payload;
279       bool success = reader->ReadStringPiece(&payload, bytes_to_read);
280       DCHECK(success);
281       DCHECK(!payload.empty());
282       continue_processing = visitor_->OnPushPromiseFramePayload(payload);
283       remaining_frame_length_ -= payload.length();
284       break;
285     }
286     case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
287       BufferFramePayload(reader);
288       break;
289     }
290     case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
291       BufferFramePayload(reader);
292       break;
293     }
294     case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE): {
295       // TODO(bnc): Avoid buffering if the entire frame is present, and
296       // instead parse directly out of |reader|.
297       BufferFramePayload(reader);
298       break;
299     }
300     default: {
301       QuicByteCount bytes_to_read = std::min<QuicByteCount>(
302           remaining_frame_length_, reader->BytesRemaining());
303       quiche::QuicheStringPiece payload;
304       bool success = reader->ReadStringPiece(&payload, bytes_to_read);
305       DCHECK(success);
306       DCHECK(!payload.empty());
307       continue_processing = visitor_->OnUnknownFramePayload(payload);
308       remaining_frame_length_ -= payload.length();
309       break;
310     }
311   }
312 
313   if (remaining_frame_length_ == 0) {
314     state_ = STATE_FINISH_PARSING;
315   }
316 
317   return continue_processing;
318 }
319 
FinishParsing()320 bool HttpDecoder::FinishParsing() {
321   DCHECK_EQ(0u, remaining_frame_length_);
322 
323   bool continue_processing = true;
324 
325   switch (current_frame_type_) {
326     case static_cast<uint64_t>(HttpFrameType::DATA): {
327       continue_processing = visitor_->OnDataFrameEnd();
328       break;
329     }
330     case static_cast<uint64_t>(HttpFrameType::HEADERS): {
331       continue_processing = visitor_->OnHeadersFrameEnd();
332       break;
333     }
334     case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
335       CancelPushFrame frame;
336       QuicDataReader reader(buffer_.data(), current_frame_length_);
337       if (!reader.ReadVarInt62(&frame.push_id)) {
338         RaiseError(QUIC_HTTP_FRAME_ERROR,
339                    "Unable to read CANCEL_PUSH push_id.");
340         return false;
341       }
342       if (!reader.IsDoneReading()) {
343         RaiseError(QUIC_HTTP_FRAME_ERROR,
344                    "Superfluous data in CANCEL_PUSH frame.");
345         return false;
346       }
347       continue_processing = visitor_->OnCancelPushFrame(frame);
348       break;
349     }
350     case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
351       SettingsFrame frame;
352       QuicDataReader reader(buffer_.data(), current_frame_length_);
353       if (!ParseSettingsFrame(&reader, &frame)) {
354         return false;
355       }
356       continue_processing = visitor_->OnSettingsFrame(frame);
357       break;
358     }
359     case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
360       continue_processing = visitor_->OnPushPromiseFrameEnd();
361       break;
362     }
363     case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
364       QuicDataReader reader(buffer_.data(), current_frame_length_);
365       GoAwayFrame frame;
366       static_assert(!std::is_same<decltype(frame.stream_id), uint64_t>::value,
367                     "Please remove local |stream_id| variable and pass "
368                     "&frame.stream_id directly to ReadVarInt62() when changing "
369                     "QuicStreamId from uint32_t to uint64_t.");
370       uint64_t stream_id;
371       if (!reader.ReadVarInt62(&stream_id)) {
372         RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read GOAWAY stream_id.");
373         return false;
374       }
375       if (!reader.IsDoneReading()) {
376         RaiseError(QUIC_HTTP_FRAME_ERROR, "Superfluous data in GOAWAY frame.");
377         return false;
378       }
379       frame.stream_id = static_cast<QuicStreamId>(stream_id);
380       continue_processing = visitor_->OnGoAwayFrame(frame);
381       break;
382     }
383     case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
384       QuicDataReader reader(buffer_.data(), current_frame_length_);
385       MaxPushIdFrame frame;
386       if (!reader.ReadVarInt62(&frame.push_id)) {
387         RaiseError(QUIC_HTTP_FRAME_ERROR,
388                    "Unable to read MAX_PUSH_ID push_id.");
389         return false;
390       }
391       if (!reader.IsDoneReading()) {
392         RaiseError(QUIC_HTTP_FRAME_ERROR,
393                    "Superfluous data in MAX_PUSH_ID frame.");
394         return false;
395       }
396       continue_processing = visitor_->OnMaxPushIdFrame(frame);
397       break;
398     }
399     case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE): {
400       // TODO(bnc): Avoid buffering if the entire frame is present, and
401       // instead parse directly out of |reader|.
402       PriorityUpdateFrame frame;
403       QuicDataReader reader(buffer_.data(), current_frame_length_);
404       if (!ParsePriorityUpdateFrame(&reader, &frame)) {
405         return false;
406       }
407       continue_processing = visitor_->OnPriorityUpdateFrame(frame);
408       break;
409     }
410     default: {
411       continue_processing = visitor_->OnUnknownFrameEnd();
412       break;
413     }
414   }
415 
416   current_length_field_length_ = 0;
417   current_type_field_length_ = 0;
418   state_ = STATE_READING_FRAME_TYPE;
419   return continue_processing;
420 }
421 
DiscardFramePayload(QuicDataReader * reader)422 void HttpDecoder::DiscardFramePayload(QuicDataReader* reader) {
423   QuicByteCount bytes_to_read = std::min<QuicByteCount>(
424       remaining_frame_length_, reader->BytesRemaining());
425   quiche::QuicheStringPiece payload;
426   bool success = reader->ReadStringPiece(&payload, bytes_to_read);
427   DCHECK(success);
428   remaining_frame_length_ -= payload.length();
429   if (remaining_frame_length_ == 0) {
430     state_ = STATE_READING_FRAME_TYPE;
431     current_length_field_length_ = 0;
432     current_type_field_length_ = 0;
433   }
434 }
435 
BufferFramePayload(QuicDataReader * reader)436 void HttpDecoder::BufferFramePayload(QuicDataReader* reader) {
437   if (current_frame_length_ == remaining_frame_length_) {
438     buffer_.erase(buffer_.size());
439     buffer_.reserve(current_frame_length_);
440   }
441   QuicByteCount bytes_to_read = std::min<QuicByteCount>(
442       remaining_frame_length_, reader->BytesRemaining());
443   bool success = reader->ReadBytes(
444       &(buffer_[0]) + current_frame_length_ - remaining_frame_length_,
445       bytes_to_read);
446   DCHECK(success);
447   remaining_frame_length_ -= bytes_to_read;
448 }
449 
BufferFrameLength(QuicDataReader * reader)450 void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
451   QuicByteCount bytes_to_read = std::min<QuicByteCount>(
452       remaining_length_field_length_, reader->BytesRemaining());
453   bool success =
454       reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
455                             remaining_length_field_length_,
456                         bytes_to_read);
457   DCHECK(success);
458   remaining_length_field_length_ -= bytes_to_read;
459 }
460 
BufferFrameType(QuicDataReader * reader)461 void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
462   QuicByteCount bytes_to_read = std::min<QuicByteCount>(
463       remaining_type_field_length_, reader->BytesRemaining());
464   bool success =
465       reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
466                             remaining_type_field_length_,
467                         bytes_to_read);
468   DCHECK(success);
469   remaining_type_field_length_ -= bytes_to_read;
470 }
471 
BufferPushId(QuicDataReader * reader)472 void HttpDecoder::BufferPushId(QuicDataReader* reader) {
473   DCHECK_LE(remaining_push_id_length_, current_frame_length_);
474   QuicByteCount bytes_to_read = std::min<QuicByteCount>(
475       reader->BytesRemaining(), remaining_push_id_length_);
476   bool success =
477       reader->ReadBytes(push_id_buffer_.data() + current_push_id_length_ -
478                             remaining_push_id_length_,
479                         bytes_to_read);
480   DCHECK(success);
481   remaining_push_id_length_ -= bytes_to_read;
482   remaining_frame_length_ -= bytes_to_read;
483 }
484 
RaiseError(QuicErrorCode error,std::string error_detail)485 void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
486   state_ = STATE_ERROR;
487   error_ = error;
488   error_detail_ = std::move(error_detail);
489   visitor_->OnError(this);
490 }
491 
ParseSettingsFrame(QuicDataReader * reader,SettingsFrame * frame)492 bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
493                                      SettingsFrame* frame) {
494   while (!reader->IsDoneReading()) {
495     uint64_t id;
496     if (!reader->ReadVarInt62(&id)) {
497       RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting identifier.");
498       return false;
499     }
500     uint64_t content;
501     if (!reader->ReadVarInt62(&content)) {
502       RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting value.");
503       return false;
504     }
505     auto result = frame->values.insert({id, content});
506     if (!result.second) {
507       RaiseError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER,
508                  "Duplicate setting identifier.");
509       return false;
510     }
511   }
512   return true;
513 }
514 
ParsePriorityUpdateFrame(QuicDataReader * reader,PriorityUpdateFrame * frame)515 bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader,
516                                            PriorityUpdateFrame* frame) {
517   uint8_t prioritized_element_type;
518   if (!reader->ReadUInt8(&prioritized_element_type)) {
519     RaiseError(QUIC_HTTP_FRAME_ERROR,
520                "Unable to read prioritized element type.");
521     return false;
522   }
523 
524   if (prioritized_element_type != REQUEST_STREAM &&
525       prioritized_element_type != PUSH_STREAM) {
526     RaiseError(QUIC_HTTP_FRAME_ERROR, "Invalid prioritized element type.");
527     return false;
528   }
529 
530   frame->prioritized_element_type =
531       static_cast<PrioritizedElementType>(prioritized_element_type);
532 
533   if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
534     RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id.");
535     return false;
536   }
537 
538   quiche::QuicheStringPiece priority_field_value =
539       reader->ReadRemainingPayload();
540   frame->priority_field_value =
541       std::string(priority_field_value.data(), priority_field_value.size());
542 
543   return true;
544 }
545 
MaxFrameLength(uint64_t frame_type)546 QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
547   switch (frame_type) {
548     case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
549       return sizeof(PushId);
550     case static_cast<uint64_t>(HttpFrameType::SETTINGS):
551       // This limit is arbitrary.
552       return 1024 * 1024;
553     case static_cast<uint64_t>(HttpFrameType::GOAWAY):
554       return VARIABLE_LENGTH_INTEGER_LENGTH_8;
555     case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
556       return sizeof(PushId);
557     case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE):
558       // This limit is arbitrary.
559       return 1024 * 1024;
560     default:
561       // Other frames require no data buffering, so it's safe to have no limit.
562       return std::numeric_limits<QuicByteCount>::max();
563   }
564 }
565 
566 }  // namespace quic
567