// 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 "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.h"

#include <algorithm>

#include "absl/strings/string_view.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"

using ::testing::_;
using ::testing::Eq;
using ::testing::Expectation;
using ::testing::InvokeWithoutArgs;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::Values;

namespace quic {
namespace test {
namespace {

// This instruction has three fields: an S bit and two varints.
const QpackInstruction* TestInstruction1() {
  static const QpackInstruction* const instruction =
      new QpackInstruction{QpackInstructionOpcode{0x00, 0x80},
                           {{QpackInstructionFieldType::kSbit, 0x40},
                            {QpackInstructionFieldType::kVarint, 6},
                            {QpackInstructionFieldType::kVarint2, 8}}};
  return instruction;
}

// This instruction has two fields: a header name with a 6-bit prefix, and a
// header value with a 7-bit prefix, both preceded by a Huffman bit.
const QpackInstruction* TestInstruction2() {
  static const QpackInstruction* const instruction =
      new QpackInstruction{QpackInstructionOpcode{0x80, 0x80},
                           {{QpackInstructionFieldType::kName, 6},
                            {QpackInstructionFieldType::kValue, 7}}};
  return instruction;
}

const QpackLanguage* TestLanguage() {
  static const QpackLanguage* const language =
      new QpackLanguage{TestInstruction1(), TestInstruction2()};
  return language;
}

class MockDelegate : public QpackInstructionDecoder::Delegate {
 public:
  MockDelegate() {
    ON_CALL(*this, OnInstructionDecoded(_)).WillByDefault(Return(true));
  }

  MockDelegate(const MockDelegate&) = delete;
  MockDelegate& operator=(const MockDelegate&) = delete;
  ~MockDelegate() override = default;

  MOCK_METHOD(bool,
              OnInstructionDecoded,
              (const QpackInstruction*),
              (override));
  MOCK_METHOD(void,
              OnInstructionDecodingError,
              (absl::string_view error_message),
              (override));
};

class QpackInstructionDecoderTest : public QuicTestWithParam<FragmentMode> {
 protected:
  QpackInstructionDecoderTest()
      : decoder_(std::make_unique<QpackInstructionDecoder>(TestLanguage(),
                                                           &delegate_)),
        fragment_mode_(GetParam()) {}
  ~QpackInstructionDecoderTest() override = default;

  void SetUp() override {
    // Destroy QpackInstructionDecoder on error to test that it does not crash.
    // See https://crbug.com/1025209.
    ON_CALL(delegate_, OnInstructionDecodingError(_))
        .WillByDefault(InvokeWithoutArgs([this]() { decoder_.reset(); }));
  }

  // Decode one full instruction with fragment sizes dictated by
  // |fragment_mode_|.
  // Assumes that |data| is a single complete instruction, and accordingly
  // verifies that AtInstructionBoundary() returns true before and after the
  // instruction, and returns false while decoding is in progress.
  // Assumes that delegate methods destroy |decoder_| if they return false.
  void DecodeInstruction(absl::string_view data) {
    EXPECT_TRUE(decoder_->AtInstructionBoundary());

    FragmentSizeGenerator fragment_size_generator =
        FragmentModeToFragmentSizeGenerator(fragment_mode_);

    while (!data.empty()) {
      size_t fragment_size = std::min(fragment_size_generator(), data.size());
      bool success = decoder_->Decode(data.substr(0, fragment_size));
      if (!decoder_) {
        EXPECT_FALSE(success);
        return;
      }
      EXPECT_TRUE(success);
      data = data.substr(fragment_size);
      if (!data.empty()) {
        EXPECT_FALSE(decoder_->AtInstructionBoundary());
      }
    }

    EXPECT_TRUE(decoder_->AtInstructionBoundary());
  }

  StrictMock<MockDelegate> delegate_;
  std::unique_ptr<QpackInstructionDecoder> decoder_;

 private:
  const FragmentMode fragment_mode_;
};

INSTANTIATE_TEST_SUITE_P(All,
                         QpackInstructionDecoderTest,
                         Values(FragmentMode::kSingleChunk,
                                FragmentMode::kOctetByOctet));

TEST_P(QpackInstructionDecoderTest, SBitAndVarint2) {
  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("7f01ff65"));

  EXPECT_TRUE(decoder_->s_bit());
  EXPECT_EQ(64u, decoder_->varint());
  EXPECT_EQ(356u, decoder_->varint2());

  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()));
  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("05c8"));

  EXPECT_FALSE(decoder_->s_bit());
  EXPECT_EQ(5u, decoder_->varint());
  EXPECT_EQ(200u, decoder_->varint2());
}

TEST_P(QpackInstructionDecoderTest, NameAndValue) {
  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("83666f6f03626172"));

  EXPECT_EQ("foo", decoder_->name());
  EXPECT_EQ("bar", decoder_->value());

  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("8000"));

  EXPECT_EQ("", decoder_->name());
  EXPECT_EQ("", decoder_->value());

  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction2()));
  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("c294e7838c767f"));

  EXPECT_EQ("foo", decoder_->name());
  EXPECT_EQ("bar", decoder_->value());
}

TEST_P(QpackInstructionDecoderTest, InvalidHuffmanEncoding) {
  EXPECT_CALL(delegate_, OnInstructionDecodingError(
                             Eq("Error in Huffman-encoded string.")));
  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("c1ff"));
}

TEST_P(QpackInstructionDecoderTest, InvalidVarintEncoding) {
  EXPECT_CALL(delegate_,
              OnInstructionDecodingError(Eq("Encoded integer too large.")));
  DecodeInstruction(
      quiche::QuicheTextUtils::HexDecode("ffffffffffffffffffffff"));
}

TEST_P(QpackInstructionDecoderTest, StringLiteralTooLong) {
  EXPECT_CALL(delegate_,
              OnInstructionDecodingError(Eq("String literal too long.")));
  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("bfffff7f"));
}

TEST_P(QpackInstructionDecoderTest, DelegateSignalsError) {
  // First instruction is valid.
  Expectation first_call =
      EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
          .WillOnce(InvokeWithoutArgs([this]() -> bool {
            EXPECT_EQ(1u, decoder_->varint());
            return true;
          }));

  // Second instruction is invalid.  Decoding must halt.
  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
      .After(first_call)
      .WillOnce(InvokeWithoutArgs([this]() -> bool {
        EXPECT_EQ(2u, decoder_->varint());
        return false;
      }));

  EXPECT_FALSE(decoder_->Decode(
      quiche::QuicheTextUtils::HexDecode("01000200030004000500")));
}

// QpackInstructionDecoder must not crash if it is destroyed from a
// Delegate::OnInstructionDecoded() call as long as it returns false.
TEST_P(QpackInstructionDecoderTest, DelegateSignalsErrorAndDestroysDecoder) {
  EXPECT_CALL(delegate_, OnInstructionDecoded(TestInstruction1()))
      .WillOnce(InvokeWithoutArgs([this]() -> bool {
        EXPECT_EQ(1u, decoder_->varint());
        decoder_.reset();
        return false;
      }));
  DecodeInstruction(quiche::QuicheTextUtils::HexDecode("0100"));
}

}  // namespace
}  // namespace test
}  // namespace quic
