// 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 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
