// Copyright 2016 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 "quiche/http2/hpack/decoder/hpack_whole_entry_buffer.h"

// Tests of HpackWholeEntryBuffer: does it buffer correctly, and does it
// detect Huffman decoding errors and oversize string errors?

#include "quiche/common/platform/api/quiche_test.h"

using ::testing::_;
using ::testing::AllOf;
using ::testing::InSequence;
using ::testing::Property;
using ::testing::StrictMock;

namespace http2 {
namespace test {
namespace {

constexpr size_t kMaxStringSize = 20;

class MockHpackWholeEntryListener : public HpackWholeEntryListener {
 public:
  ~MockHpackWholeEntryListener() override = default;

  MOCK_METHOD(void, OnIndexedHeader, (size_t index), (override));
  MOCK_METHOD(void, OnNameIndexAndLiteralValue,
              (HpackEntryType entry_type, size_t name_index,
               HpackDecoderStringBuffer* value_buffer),
              (override));
  MOCK_METHOD(void, OnLiteralNameAndValue,
              (HpackEntryType entry_type, HpackDecoderStringBuffer* name_buffer,
               HpackDecoderStringBuffer* value_buffer),
              (override));
  MOCK_METHOD(void, OnDynamicTableSizeUpdate, (size_t size), (override));
  MOCK_METHOD(void, OnHpackDecodeError,
              (HpackDecodingError error, std::string detailed_error),
              (override));
};

class HpackWholeEntryBufferTest : public quiche::test::QuicheTest {
 protected:
  HpackWholeEntryBufferTest() : entry_buffer_(&listener_, kMaxStringSize) {}
  ~HpackWholeEntryBufferTest() override = default;

  StrictMock<MockHpackWholeEntryListener> listener_;
  HpackWholeEntryBuffer entry_buffer_;
};

// OnIndexedHeader is an immediate pass through.
TEST_F(HpackWholeEntryBufferTest, OnIndexedHeader) {
  {
    InSequence seq;
    EXPECT_CALL(listener_, OnIndexedHeader(17));
    entry_buffer_.OnIndexedHeader(17);
  }
  {
    InSequence seq;
    EXPECT_CALL(listener_, OnIndexedHeader(62));
    entry_buffer_.OnIndexedHeader(62);
  }
  {
    InSequence seq;
    EXPECT_CALL(listener_, OnIndexedHeader(62));
    entry_buffer_.OnIndexedHeader(62);
  }
  {
    InSequence seq;
    EXPECT_CALL(listener_, OnIndexedHeader(128));
    entry_buffer_.OnIndexedHeader(128);
  }
  StrictMock<MockHpackWholeEntryListener> listener2;
  entry_buffer_.set_listener(&listener2);
  {
    InSequence seq;
    EXPECT_CALL(listener2, OnIndexedHeader(100));
    entry_buffer_.OnIndexedHeader(100);
  }
}

// OnDynamicTableSizeUpdate is an immediate pass through.
TEST_F(HpackWholeEntryBufferTest, OnDynamicTableSizeUpdate) {
  {
    InSequence seq;
    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(4096));
    entry_buffer_.OnDynamicTableSizeUpdate(4096);
  }
  {
    InSequence seq;
    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(0));
    entry_buffer_.OnDynamicTableSizeUpdate(0);
  }
  {
    InSequence seq;
    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(1024));
    entry_buffer_.OnDynamicTableSizeUpdate(1024);
  }
  {
    InSequence seq;
    EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(1024));
    entry_buffer_.OnDynamicTableSizeUpdate(1024);
  }
  StrictMock<MockHpackWholeEntryListener> listener2;
  entry_buffer_.set_listener(&listener2);
  {
    InSequence seq;
    EXPECT_CALL(listener2, OnDynamicTableSizeUpdate(0));
    entry_buffer_.OnDynamicTableSizeUpdate(0);
  }
}

TEST_F(HpackWholeEntryBufferTest, OnNameIndexAndLiteralValue) {
  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kNeverIndexedLiteralHeader,
                                     123);
  entry_buffer_.OnValueStart(false, 10);
  entry_buffer_.OnValueData("some data.", 10);

  // Force the value to be buffered.
  entry_buffer_.BufferStringsIfUnbuffered();

  EXPECT_CALL(
      listener_,
      OnNameIndexAndLiteralValue(
          HpackEntryType::kNeverIndexedLiteralHeader, 123,
          AllOf(Property(&HpackDecoderStringBuffer::str, "some data."),
                Property(&HpackDecoderStringBuffer::BufferedLength, 10))));

  entry_buffer_.OnValueEnd();
}

TEST_F(HpackWholeEntryBufferTest, OnLiteralNameAndValue) {
  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 0);
  // Force the name to be buffered by delivering it in two pieces.
  entry_buffer_.OnNameStart(false, 9);
  entry_buffer_.OnNameData("some-", 5);
  entry_buffer_.OnNameData("name", 4);
  entry_buffer_.OnNameEnd();
  entry_buffer_.OnValueStart(false, 12);
  entry_buffer_.OnValueData("Header Value", 12);

  EXPECT_CALL(
      listener_,
      OnLiteralNameAndValue(
          HpackEntryType::kIndexedLiteralHeader,
          AllOf(Property(&HpackDecoderStringBuffer::str, "some-name"),
                Property(&HpackDecoderStringBuffer::BufferedLength, 9)),
          AllOf(Property(&HpackDecoderStringBuffer::str, "Header Value"),
                Property(&HpackDecoderStringBuffer::BufferedLength, 0))));

  entry_buffer_.OnValueEnd();
}

// Verify that a name longer than the allowed size generates an error.
TEST_F(HpackWholeEntryBufferTest, NameTooLong) {
  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 0);
  EXPECT_CALL(listener_,
              OnHpackDecodeError(HpackDecodingError::kNameTooLong, _));
  entry_buffer_.OnNameStart(false, kMaxStringSize + 1);
}

// Verify that a value longer than the allowed size generates an error.
TEST_F(HpackWholeEntryBufferTest, ValueTooLong) {
  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 0);
  EXPECT_CALL(listener_,
              OnHpackDecodeError(
                  HpackDecodingError::kValueTooLong,
                  "Value length (21) of [path] is longer than permitted (20)"));
  entry_buffer_.OnNameStart(false, 4);
  entry_buffer_.OnNameData("path", 4);
  entry_buffer_.OnNameEnd();
  entry_buffer_.OnValueStart(false, kMaxStringSize + 1);
}

// Regression test for b/162141899.
TEST_F(HpackWholeEntryBufferTest, ValueTooLongWithoutName) {
  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kIndexedLiteralHeader, 1);
  EXPECT_CALL(listener_,
              OnHpackDecodeError(
                  HpackDecodingError::kValueTooLong,
                  "Value length (21) of [] is longer than permitted (20)"));
  entry_buffer_.OnValueStart(false, kMaxStringSize + 1);
}

// Verify that a Huffman encoded name with an explicit EOS generates an error
// for an explicit EOS.
TEST_F(HpackWholeEntryBufferTest, NameHuffmanError) {
  const char data[] = "\xff\xff\xff";
  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kUnindexedLiteralHeader,
                                     0);
  entry_buffer_.OnNameStart(true, 4);
  entry_buffer_.OnNameData(data, 3);

  EXPECT_CALL(listener_,
              OnHpackDecodeError(HpackDecodingError::kNameHuffmanError, _));

  entry_buffer_.OnNameData(data, 1);

  // After an error is reported, the listener is not called again.
  EXPECT_CALL(listener_, OnDynamicTableSizeUpdate(8096)).Times(0);
  entry_buffer_.OnDynamicTableSizeUpdate(8096);
}

// Verify that a Huffman encoded value that isn't properly terminated with
// a partial EOS symbol generates an error.
TEST_F(HpackWholeEntryBufferTest, ValueHuffmanError) {
  const char data[] = "\x00\x00\x00";
  entry_buffer_.OnStartLiteralHeader(HpackEntryType::kNeverIndexedLiteralHeader,
                                     61);
  entry_buffer_.OnValueStart(true, 3);
  entry_buffer_.OnValueData(data, 3);

  EXPECT_CALL(listener_,
              OnHpackDecodeError(HpackDecodingError::kValueHuffmanError, _));

  entry_buffer_.OnValueEnd();

  // After an error is reported, the listener is not called again.
  EXPECT_CALL(listener_, OnIndexedHeader(17)).Times(0);
  entry_buffer_.OnIndexedHeader(17);
}

}  // namespace
}  // namespace test
}  // namespace http2
