// Copyright 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 "quic/core/qpack/qpack_instruction_decoder.h"

#include <algorithm>
#include <utility>

#include "absl/strings/string_view.h"
#include "quic/platform/api/quic_bug_tracker.h"
#include "quic/platform/api/quic_logging.h"

namespace quic {

namespace {

// Maximum length of header name and header value.  This limits the amount of
// memory the peer can make the decoder allocate when sending string literals.
const size_t kStringLiteralLengthLimit = 1024 * 1024;

}  // namespace

QpackInstructionDecoder::QpackInstructionDecoder(const QpackLanguage* language,
                                                 Delegate* delegate)
    : language_(language),
      delegate_(delegate),
      s_bit_(false),
      varint_(0),
      varint2_(0),
      is_huffman_encoded_(false),
      string_length_(0),
      error_detected_(false),
      state_(State::kStartInstruction) {}

bool QpackInstructionDecoder::Decode(absl::string_view data) {
  QUICHE_DCHECK(!data.empty());
  QUICHE_DCHECK(!error_detected_);

  while (true) {
    bool success = true;
    size_t bytes_consumed = 0;

    switch (state_) {
      case State::kStartInstruction:
        success = DoStartInstruction(data);
        break;
      case State::kStartField:
        success = DoStartField();
        break;
      case State::kReadBit:
        success = DoReadBit(data);
        break;
      case State::kVarintStart:
        success = DoVarintStart(data, &bytes_consumed);
        break;
      case State::kVarintResume:
        success = DoVarintResume(data, &bytes_consumed);
        break;
      case State::kVarintDone:
        success = DoVarintDone();
        break;
      case State::kReadString:
        success = DoReadString(data, &bytes_consumed);
        break;
      case State::kReadStringDone:
        success = DoReadStringDone();
        break;
    }

    if (!success) {
      return false;
    }

    // |success| must be false if an error is detected.
    QUICHE_DCHECK(!error_detected_);

    QUICHE_DCHECK_LE(bytes_consumed, data.size());

    data = absl::string_view(data.data() + bytes_consumed,
                             data.size() - bytes_consumed);

    // Stop processing if no more data but next state would require it.
    if (data.empty() && (state_ != State::kStartField) &&
        (state_ != State::kVarintDone) && (state_ != State::kReadStringDone)) {
      return true;
    }
  }

  return true;
}

bool QpackInstructionDecoder::AtInstructionBoundary() const {
  return state_ == State::kStartInstruction;
}

bool QpackInstructionDecoder::DoStartInstruction(absl::string_view data) {
  QUICHE_DCHECK(!data.empty());

  instruction_ = LookupOpcode(data[0]);
  field_ = instruction_->fields.begin();

  state_ = State::kStartField;
  return true;
}

bool QpackInstructionDecoder::DoStartField() {
  if (field_ == instruction_->fields.end()) {
    // Completed decoding this instruction.

    if (!delegate_->OnInstructionDecoded(instruction_)) {
      return false;
    }

    state_ = State::kStartInstruction;
    return true;
  }

  switch (field_->type) {
    case QpackInstructionFieldType::kSbit:
    case QpackInstructionFieldType::kName:
    case QpackInstructionFieldType::kValue:
      state_ = State::kReadBit;
      return true;
    case QpackInstructionFieldType::kVarint:
    case QpackInstructionFieldType::kVarint2:
      state_ = State::kVarintStart;
      return true;
    default:
      QUIC_BUG(quic_bug_10767_1) << "Invalid field type.";
      return false;
  }
}

bool QpackInstructionDecoder::DoReadBit(absl::string_view data) {
  QUICHE_DCHECK(!data.empty());

  switch (field_->type) {
    case QpackInstructionFieldType::kSbit: {
      const uint8_t bitmask = field_->param;
      s_bit_ = (data[0] & bitmask) == bitmask;

      ++field_;
      state_ = State::kStartField;

      return true;
    }
    case QpackInstructionFieldType::kName:
    case QpackInstructionFieldType::kValue: {
      const uint8_t prefix_length = field_->param;
      QUICHE_DCHECK_GE(7, prefix_length);
      const uint8_t bitmask = 1 << prefix_length;
      is_huffman_encoded_ = (data[0] & bitmask) == bitmask;

      state_ = State::kVarintStart;

      return true;
    }
    default:
      QUIC_BUG(quic_bug_10767_2) << "Invalid field type.";
      return false;
  }
}

bool QpackInstructionDecoder::DoVarintStart(absl::string_view data,
                                            size_t* bytes_consumed) {
  QUICHE_DCHECK(!data.empty());
  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
                field_->type == QpackInstructionFieldType::kVarint2 ||
                field_->type == QpackInstructionFieldType::kName ||
                field_->type == QpackInstructionFieldType::kValue);

  http2::DecodeBuffer buffer(data.data() + 1, data.size() - 1);
  http2::DecodeStatus status =
      varint_decoder_.Start(data[0], field_->param, &buffer);

  *bytes_consumed = 1 + buffer.Offset();
  switch (status) {
    case http2::DecodeStatus::kDecodeDone:
      state_ = State::kVarintDone;
      return true;
    case http2::DecodeStatus::kDecodeInProgress:
      state_ = State::kVarintResume;
      return true;
    case http2::DecodeStatus::kDecodeError:
      OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
      return false;
    default:
      QUIC_BUG(quic_bug_10767_3) << "Unknown decode status " << status;
      return false;
  }
}

bool QpackInstructionDecoder::DoVarintResume(absl::string_view data,
                                             size_t* bytes_consumed) {
  QUICHE_DCHECK(!data.empty());
  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
                field_->type == QpackInstructionFieldType::kVarint2 ||
                field_->type == QpackInstructionFieldType::kName ||
                field_->type == QpackInstructionFieldType::kValue);

  http2::DecodeBuffer buffer(data);
  http2::DecodeStatus status = varint_decoder_.Resume(&buffer);

  *bytes_consumed = buffer.Offset();
  switch (status) {
    case http2::DecodeStatus::kDecodeDone:
      state_ = State::kVarintDone;
      return true;
    case http2::DecodeStatus::kDecodeInProgress:
      QUICHE_DCHECK_EQ(*bytes_consumed, data.size());
      QUICHE_DCHECK(buffer.Empty());
      return true;
    case http2::DecodeStatus::kDecodeError:
      OnError(ErrorCode::INTEGER_TOO_LARGE, "Encoded integer too large.");
      return false;
    default:
      QUIC_BUG(quic_bug_10767_4) << "Unknown decode status " << status;
      return false;
  }
}

bool QpackInstructionDecoder::DoVarintDone() {
  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kVarint ||
                field_->type == QpackInstructionFieldType::kVarint2 ||
                field_->type == QpackInstructionFieldType::kName ||
                field_->type == QpackInstructionFieldType::kValue);

  if (field_->type == QpackInstructionFieldType::kVarint) {
    varint_ = varint_decoder_.value();

    ++field_;
    state_ = State::kStartField;
    return true;
  }

  if (field_->type == QpackInstructionFieldType::kVarint2) {
    varint2_ = varint_decoder_.value();

    ++field_;
    state_ = State::kStartField;
    return true;
  }

  string_length_ = varint_decoder_.value();
  if (string_length_ > kStringLiteralLengthLimit) {
    OnError(ErrorCode::STRING_LITERAL_TOO_LONG, "String literal too long.");
    return false;
  }

  std::string* const string =
      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
  string->clear();

  if (string_length_ == 0) {
    ++field_;
    state_ = State::kStartField;
    return true;
  }

  string->reserve(string_length_);

  state_ = State::kReadString;
  return true;
}

bool QpackInstructionDecoder::DoReadString(absl::string_view data,
                                           size_t* bytes_consumed) {
  QUICHE_DCHECK(!data.empty());
  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
                field_->type == QpackInstructionFieldType::kValue);

  std::string* const string =
      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
  QUICHE_DCHECK_LT(string->size(), string_length_);

  *bytes_consumed = std::min(string_length_ - string->size(), data.size());
  string->append(data.data(), *bytes_consumed);

  QUICHE_DCHECK_LE(string->size(), string_length_);
  if (string->size() == string_length_) {
    state_ = State::kReadStringDone;
  }
  return true;
}

bool QpackInstructionDecoder::DoReadStringDone() {
  QUICHE_DCHECK(field_->type == QpackInstructionFieldType::kName ||
                field_->type == QpackInstructionFieldType::kValue);

  std::string* const string =
      (field_->type == QpackInstructionFieldType::kName) ? &name_ : &value_;
  QUICHE_DCHECK_EQ(string->size(), string_length_);

  if (is_huffman_encoded_) {
    huffman_decoder_.Reset();
    // HpackHuffmanDecoder::Decode() cannot perform in-place decoding.
    std::string decoded_value;
    huffman_decoder_.Decode(*string, &decoded_value);
    if (!huffman_decoder_.InputProperlyTerminated()) {
      OnError(ErrorCode::HUFFMAN_ENCODING_ERROR,
              "Error in Huffman-encoded string.");
      return false;
    }
    *string = std::move(decoded_value);
  }

  ++field_;
  state_ = State::kStartField;
  return true;
}

const QpackInstruction* QpackInstructionDecoder::LookupOpcode(
    uint8_t byte) const {
  for (const auto* instruction : *language_) {
    if ((byte & instruction->opcode.mask) == instruction->opcode.value) {
      return instruction;
    }
  }
  // |language_| should be defined such that instruction opcodes cover every
  // possible input.
  QUICHE_DCHECK(false);
  return nullptr;
}

void QpackInstructionDecoder::OnError(ErrorCode error_code,
                                      absl::string_view error_message) {
  QUICHE_DCHECK(!error_detected_);

  error_detected_ = true;
  delegate_->OnInstructionDecodingError(error_code, error_message);
}

}  // namespace quic
