// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/quic/core/http/http_decoder.h"

#include <cstdint>

#include "net/third_party/quiche/src/quic/core/http/http_frames.h"
#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"

namespace quic {

HttpDecoder::HttpDecoder(Visitor* visitor)
    : visitor_(visitor),
      state_(STATE_READING_FRAME_TYPE),
      current_frame_type_(0),
      current_length_field_length_(0),
      remaining_length_field_length_(0),
      current_frame_length_(0),
      remaining_frame_length_(0),
      current_type_field_length_(0),
      remaining_type_field_length_(0),
      current_push_id_length_(0),
      remaining_push_id_length_(0),
      error_(QUIC_NO_ERROR),
      error_detail_("") {
  DCHECK(visitor_);
}

HttpDecoder::~HttpDecoder() {}

QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
  DCHECK_EQ(QUIC_NO_ERROR, error_);
  DCHECK_NE(STATE_ERROR, state_);

  QuicDataReader reader(data, len);
  bool continue_processing = true;
  while (continue_processing &&
         (reader.BytesRemaining() != 0 || state_ == STATE_FINISH_PARSING)) {
    // |continue_processing| must have been set to false upon error.
    DCHECK_EQ(QUIC_NO_ERROR, error_);
    DCHECK_NE(STATE_ERROR, state_);

    switch (state_) {
      case STATE_READING_FRAME_TYPE:
        ReadFrameType(&reader);
        break;
      case STATE_READING_FRAME_LENGTH:
        continue_processing = ReadFrameLength(&reader);
        break;
      case STATE_READING_FRAME_PAYLOAD:
        continue_processing = ReadFramePayload(&reader);
        break;
      case STATE_FINISH_PARSING:
        continue_processing = FinishParsing();
        break;
      case STATE_ERROR:
        break;
      default:
        QUIC_BUG << "Invalid state: " << state_;
    }
  }

  return len - reader.BytesRemaining();
}

void HttpDecoder::ReadFrameType(QuicDataReader* reader) {
  DCHECK_NE(0u, reader->BytesRemaining());
  if (current_type_field_length_ == 0) {
    // A new frame is coming.
    current_type_field_length_ = reader->PeekVarInt62Length();
    DCHECK_NE(0u, current_type_field_length_);
    if (current_type_field_length_ > reader->BytesRemaining()) {
      // Buffer a new type field.
      remaining_type_field_length_ = current_type_field_length_;
      BufferFrameType(reader);
      return;
    }
    // The reader has all type data needed, so no need to buffer.
    bool success = reader->ReadVarInt62(&current_frame_type_);
    DCHECK(success);
  } else {
    // Buffer the existing type field.
    BufferFrameType(reader);
    // The frame is still not buffered completely.
    if (remaining_type_field_length_ != 0) {
      return;
    }
    QuicDataReader type_reader(type_buffer_.data(), current_type_field_length_);
    bool success = type_reader.ReadVarInt62(&current_frame_type_);
    DCHECK(success);
  }

  state_ = STATE_READING_FRAME_LENGTH;
}

bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
  DCHECK_NE(0u, reader->BytesRemaining());
  if (current_length_field_length_ == 0) {
    // A new frame is coming.
    current_length_field_length_ = reader->PeekVarInt62Length();
    DCHECK_NE(0u, current_length_field_length_);
    if (current_length_field_length_ > reader->BytesRemaining()) {
      // Buffer a new length field.
      remaining_length_field_length_ = current_length_field_length_;
      BufferFrameLength(reader);
      return true;
    }
    // The reader has all length data needed, so no need to buffer.
    bool success = reader->ReadVarInt62(&current_frame_length_);
    DCHECK(success);
  } else {
    // Buffer the existing length field.
    BufferFrameLength(reader);
    // The frame is still not buffered completely.
    if (remaining_length_field_length_ != 0) {
      return true;
    }
    QuicDataReader length_reader(length_buffer_.data(),
                                 current_length_field_length_);
    bool success = length_reader.ReadVarInt62(&current_frame_length_);
    DCHECK(success);
  }

  if (current_frame_length_ > MaxFrameLength(current_frame_type_)) {
    // TODO(b/124216424): Use HTTP_EXCESSIVE_LOAD.
    RaiseError(QUIC_INVALID_FRAME_DATA, "Frame is too large");
    return false;
  }

  // Calling the following visitor methods does not require parsing of any
  // frame payload.
  bool continue_processing = true;
  const QuicByteCount header_length =
      current_length_field_length_ + current_type_field_length_;

  switch (current_frame_type_) {
    case static_cast<uint64_t>(HttpFrameType::DATA):
      continue_processing = visitor_->OnDataFrameStart(header_length);
      break;
    case static_cast<uint64_t>(HttpFrameType::HEADERS):
      continue_processing = visitor_->OnHeadersFrameStart(header_length);
      break;
    case static_cast<uint64_t>(HttpFrameType::PRIORITY):
      continue_processing = visitor_->OnPriorityFrameStart(header_length);
      break;
    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
      break;
    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
      continue_processing = visitor_->OnSettingsFrameStart(header_length);
      break;
    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE):
      // This edge case needs to be handled here, because ReadFramePayload()
      // does not get called if |current_frame_length_| is zero.
      if (current_frame_length_ == 0) {
        RaiseError(QUIC_INVALID_FRAME_DATA, "Corrupt PUSH_PROMISE frame.");
        return false;
      }
      continue_processing = visitor_->OnPushPromiseFrameStart(header_length);
      break;
    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
      break;
    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
      break;
    case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH):
      break;
    default:
      continue_processing =
          visitor_->OnUnknownFrameStart(current_frame_type_, header_length);
      break;
  }

  remaining_frame_length_ = current_frame_length_;
  state_ = (remaining_frame_length_ == 0) ? STATE_FINISH_PARSING
                                          : STATE_READING_FRAME_PAYLOAD;
  return continue_processing;
}

bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
  DCHECK_NE(0u, reader->BytesRemaining());
  DCHECK_NE(0u, remaining_frame_length_);

  bool continue_processing = true;

  switch (current_frame_type_) {
    case static_cast<uint64_t>(HttpFrameType::DATA): {
      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
          remaining_frame_length_, reader->BytesRemaining());
      quiche::QuicheStringPiece payload;
      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
      DCHECK(success);
      DCHECK(!payload.empty());
      continue_processing = visitor_->OnDataFramePayload(payload);
      remaining_frame_length_ -= payload.length();
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::HEADERS): {
      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
          remaining_frame_length_, reader->BytesRemaining());
      quiche::QuicheStringPiece payload;
      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
      DCHECK(success);
      DCHECK(!payload.empty());
      continue_processing = visitor_->OnHeadersFramePayload(payload);
      remaining_frame_length_ -= payload.length();
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::PRIORITY): {
      // TODO(rch): avoid buffering if the entire frame is present, and
      // instead parse directly out of |reader|.
      BufferFramePayload(reader);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
      BufferFramePayload(reader);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
      BufferFramePayload(reader);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
      PushId push_id;
      if (current_frame_length_ == remaining_frame_length_) {
        // A new Push Promise frame just arrived.
        DCHECK_EQ(0u, current_push_id_length_);
        current_push_id_length_ = reader->PeekVarInt62Length();
        if (current_push_id_length_ > remaining_frame_length_) {
          RaiseError(QUIC_INVALID_FRAME_DATA, "PUSH_PROMISE frame malformed.");
          return false;
        }
        if (current_push_id_length_ > reader->BytesRemaining()) {
          // Not all bytes of push id is present yet, buffer push id.
          DCHECK_EQ(0u, remaining_push_id_length_);
          remaining_push_id_length_ = current_push_id_length_;
          BufferPushId(reader);
          break;
        }
        bool success = reader->ReadVarInt62(&push_id);
        DCHECK(success);
        remaining_frame_length_ -= current_push_id_length_;
        if (!visitor_->OnPushPromiseFramePushId(push_id,
                                                current_push_id_length_)) {
          continue_processing = false;
          current_push_id_length_ = 0;
          break;
        }
        current_push_id_length_ = 0;
      } else if (remaining_push_id_length_ > 0) {
        // Waiting for more bytes on push id.
        BufferPushId(reader);
        if (remaining_push_id_length_ != 0) {
          break;
        }
        QuicDataReader push_id_reader(push_id_buffer_.data(),
                                      current_push_id_length_);

        bool success = push_id_reader.ReadVarInt62(&push_id);
        DCHECK(success);
        if (!visitor_->OnPushPromiseFramePushId(push_id,
                                                current_push_id_length_)) {
          continue_processing = false;
          current_push_id_length_ = 0;
          break;
        }
        current_push_id_length_ = 0;
      }

      // Read Push Promise headers.
      DCHECK_LT(remaining_frame_length_, current_frame_length_);
      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
          remaining_frame_length_, reader->BytesRemaining());
      if (bytes_to_read == 0) {
        break;
      }
      quiche::QuicheStringPiece payload;
      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
      DCHECK(success);
      DCHECK(!payload.empty());
      continue_processing = visitor_->OnPushPromiseFramePayload(payload);
      remaining_frame_length_ -= payload.length();
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
      BufferFramePayload(reader);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
      BufferFramePayload(reader);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH): {
      BufferFramePayload(reader);
      break;
    }
    default: {
      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
          remaining_frame_length_, reader->BytesRemaining());
      quiche::QuicheStringPiece payload;
      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
      DCHECK(success);
      DCHECK(!payload.empty());
      continue_processing = visitor_->OnUnknownFramePayload(payload);
      remaining_frame_length_ -= payload.length();
      break;
    }
  }

  if (remaining_frame_length_ == 0) {
    state_ = STATE_FINISH_PARSING;
  }

  return continue_processing;
}

bool HttpDecoder::FinishParsing() {
  DCHECK_EQ(0u, remaining_frame_length_);

  bool continue_processing = true;

  switch (current_frame_type_) {
    case static_cast<uint64_t>(HttpFrameType::DATA): {
      continue_processing = visitor_->OnDataFrameEnd();
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::HEADERS): {
      continue_processing = visitor_->OnHeadersFrameEnd();
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::PRIORITY): {
      // TODO(rch): avoid buffering if the entire frame is present, and
      // instead parse directly out of |reader|.
      PriorityFrame frame;
      QuicDataReader reader(buffer_.data(), current_frame_length_);
      if (!ParsePriorityFrame(&reader, &frame)) {
        return false;
      }
      continue_processing = visitor_->OnPriorityFrame(frame);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH): {
      CancelPushFrame frame;
      QuicDataReader reader(buffer_.data(), current_frame_length_);
      if (!reader.ReadVarInt62(&frame.push_id)) {
        // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
        RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read push_id");
        return false;
      }
      if (!reader.IsDoneReading()) {
        RaiseError(QUIC_INVALID_FRAME_DATA,
                   "Superfluous data in CANCEL_PUSH frame.");
        return false;
      }
      continue_processing = visitor_->OnCancelPushFrame(frame);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
      SettingsFrame frame;
      QuicDataReader reader(buffer_.data(), current_frame_length_);
      if (!ParseSettingsFrame(&reader, &frame)) {
        return false;
      }
      continue_processing = visitor_->OnSettingsFrame(frame);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::PUSH_PROMISE): {
      continue_processing = visitor_->OnPushPromiseFrameEnd();
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
      QuicDataReader reader(buffer_.data(), current_frame_length_);
      GoAwayFrame frame;
      static_assert(!std::is_same<decltype(frame.stream_id), uint64_t>::value,
                    "Please remove local |stream_id| variable and pass "
                    "&frame.stream_id directly to ReadVarInt62() when changing "
                    "QuicStreamId from uint32_t to uint64_t.");
      uint64_t stream_id;
      if (!reader.ReadVarInt62(&stream_id)) {
        // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
        RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read GOAWAY stream_id");
        return false;
      }
      if (!reader.IsDoneReading()) {
        RaiseError(QUIC_INVALID_FRAME_DATA,
                   "Superfluous data in GOAWAY frame.");
        return false;
      }
      frame.stream_id = static_cast<QuicStreamId>(stream_id);
      continue_processing = visitor_->OnGoAwayFrame(frame);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
      QuicDataReader reader(buffer_.data(), current_frame_length_);
      MaxPushIdFrame frame;
      if (!reader.ReadVarInt62(&frame.push_id)) {
        // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
        RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read push_id");
        return false;
      }
      if (!reader.IsDoneReading()) {
        RaiseError(QUIC_INVALID_FRAME_DATA,
                   "Superfluous data in MAX_PUSH_ID frame.");
        return false;
      }
      continue_processing = visitor_->OnMaxPushIdFrame(frame);
      break;
    }
    case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH): {
      QuicDataReader reader(buffer_.data(), current_frame_length_);
      DuplicatePushFrame frame;
      if (!reader.ReadVarInt62(&frame.push_id)) {
        // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
        RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read push_id");
        return false;
      }
      if (!reader.IsDoneReading()) {
        RaiseError(QUIC_INVALID_FRAME_DATA,
                   "Superfluous data in DUPLICATE_PUSH frame.");
        return false;
      }
      continue_processing = visitor_->OnDuplicatePushFrame(frame);
      break;
    }
    default: {
      continue_processing = visitor_->OnUnknownFrameEnd();
      break;
    }
  }

  current_length_field_length_ = 0;
  current_type_field_length_ = 0;
  state_ = STATE_READING_FRAME_TYPE;
  return continue_processing;
}

void HttpDecoder::DiscardFramePayload(QuicDataReader* reader) {
  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
      remaining_frame_length_, reader->BytesRemaining());
  quiche::QuicheStringPiece payload;
  bool success = reader->ReadStringPiece(&payload, bytes_to_read);
  DCHECK(success);
  remaining_frame_length_ -= payload.length();
  if (remaining_frame_length_ == 0) {
    state_ = STATE_READING_FRAME_TYPE;
    current_length_field_length_ = 0;
    current_type_field_length_ = 0;
  }
}

void HttpDecoder::BufferFramePayload(QuicDataReader* reader) {
  if (current_frame_length_ == remaining_frame_length_) {
    buffer_.erase(buffer_.size());
    buffer_.reserve(current_frame_length_);
  }
  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
      remaining_frame_length_, reader->BytesRemaining());
  bool success = reader->ReadBytes(
      &(buffer_[0]) + current_frame_length_ - remaining_frame_length_,
      bytes_to_read);
  DCHECK(success);
  remaining_frame_length_ -= bytes_to_read;
}

void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
      remaining_length_field_length_, reader->BytesRemaining());
  bool success =
      reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
                            remaining_length_field_length_,
                        bytes_to_read);
  DCHECK(success);
  remaining_length_field_length_ -= bytes_to_read;
}

void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
      remaining_type_field_length_, reader->BytesRemaining());
  bool success =
      reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
                            remaining_type_field_length_,
                        bytes_to_read);
  DCHECK(success);
  remaining_type_field_length_ -= bytes_to_read;
}

void HttpDecoder::BufferPushId(QuicDataReader* reader) {
  DCHECK_LE(remaining_push_id_length_, current_frame_length_);
  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
      reader->BytesRemaining(), remaining_push_id_length_);
  bool success =
      reader->ReadBytes(push_id_buffer_.data() + current_push_id_length_ -
                            remaining_push_id_length_,
                        bytes_to_read);
  DCHECK(success);
  remaining_push_id_length_ -= bytes_to_read;
  remaining_frame_length_ -= bytes_to_read;
}

void HttpDecoder::RaiseError(QuicErrorCode error, std::string error_detail) {
  state_ = STATE_ERROR;
  error_ = error;
  error_detail_ = std::move(error_detail);
  visitor_->OnError(this);
}

bool HttpDecoder::ParsePriorityFrame(QuicDataReader* reader,
                                     PriorityFrame* frame) {
  uint8_t flags;
  if (!reader->ReadUInt8(&flags)) {
    // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
    RaiseError(QUIC_INVALID_FRAME_DATA, "Unable to read PRIORITY frame flags.");
    return false;
  }

  // Assign two most significant bits to prioritized_type.
  frame->prioritized_type = static_cast<PriorityElementType>((flags >> 6) & 3);
  // Assign the next two most significant bits to dependency type.
  frame->dependency_type = static_cast<PriorityElementType>((flags >> 4) & 3);
  frame->exclusive = flags & kPriorityExclusiveBit;
  // TODO(bnc): Close connection with HTTP_MALFORMED_FRAME
  // if lowest three bits are not all zero.

  if (frame->prioritized_type != ROOT_OF_TREE &&
      !reader->ReadVarInt62(&frame->prioritized_element_id)) {
    // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
    RaiseError(QUIC_INVALID_FRAME_DATA,
               "Unable to read prioritized_element_id.");
    return false;
  }
  if (frame->dependency_type != ROOT_OF_TREE &&
      !reader->ReadVarInt62(&frame->element_dependency_id)) {
    // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
    RaiseError(QUIC_INVALID_FRAME_DATA,
               "Unable to read element_dependency_id.");
    return false;
  }
  if (!reader->ReadUInt8(&frame->weight)) {
    // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
    RaiseError(QUIC_INVALID_FRAME_DATA,
               "Unable to read PRIORITY frame weight.");
    return false;
  }
  if (!reader->IsDoneReading()) {
    // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
    RaiseError(QUIC_INVALID_FRAME_DATA, "Superfluous data in PRIORITY frame.");
    return false;
  }
  return true;
}

bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
                                     SettingsFrame* frame) {
  while (!reader->IsDoneReading()) {
    uint64_t id;
    if (!reader->ReadVarInt62(&id)) {
      // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
      RaiseError(QUIC_INVALID_FRAME_DATA,
                 "Unable to read settings frame identifier");
      return false;
    }
    uint64_t content;
    if (!reader->ReadVarInt62(&content)) {
      // TODO(b/124216424): Use HTTP_MALFORMED_FRAME.
      RaiseError(QUIC_INVALID_FRAME_DATA,
                 "Unable to read settings frame content");
      return false;
    }
    auto result = frame->values.insert({id, content});
    if (!result.second) {
      // TODO(b/124216424): Use HTTP_SETTINGS_ERROR.
      RaiseError(QUIC_INVALID_FRAME_DATA, "Duplicate SETTINGS identifier.");
      return false;
    }
  }
  return true;
}

QuicByteCount HttpDecoder::MaxFrameLength(uint64_t frame_type) {
  switch (frame_type) {
    case static_cast<uint64_t>(HttpFrameType::PRIORITY):
      return kPriorityFirstByteLength + VARIABLE_LENGTH_INTEGER_LENGTH_8 * 2 +
             kPriorityWeightLength;
    case static_cast<uint64_t>(HttpFrameType::CANCEL_PUSH):
      return sizeof(PushId);
    case static_cast<uint64_t>(HttpFrameType::SETTINGS):
      // This limit is arbitrary.
      return 1024 * 1024;
    case static_cast<uint64_t>(HttpFrameType::GOAWAY):
      return VARIABLE_LENGTH_INTEGER_LENGTH_8;
    case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
      return sizeof(PushId);
    case static_cast<uint64_t>(HttpFrameType::DUPLICATE_PUSH):
      return sizeof(PushId);
    default:
      // Other frames require no data buffering, so it's safe to have no limit.
      return std::numeric_limits<QuicByteCount>::max();
  }
}

}  // namespace quic
