// 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_block_decoder.h"

// Tests of HpackBlockDecoder.

#include <cstdint>
#include <string>

#include "absl/strings/string_view.h"
#include "quiche/http2/decoder/decode_buffer.h"
#include "quiche/http2/hpack/http2_hpack_constants.h"
#include "quiche/http2/test_tools/hpack_block_builder.h"
#include "quiche/http2/test_tools/hpack_block_collector.h"
#include "quiche/http2/test_tools/hpack_example.h"
#include "quiche/http2/test_tools/http2_random.h"
#include "quiche/http2/test_tools/random_decoder_test_base.h"
#include "quiche/common/platform/api/quiche_expect_bug.h"
#include "quiche/common/platform/api/quiche_test.h"

namespace http2 {
namespace test {
namespace {

class HpackBlockDecoderTest : public RandomDecoderTest {
 protected:
  HpackBlockDecoderTest() : listener_(&collector_), decoder_(&listener_) {
    stop_decode_on_done_ = false;
    decoder_.Reset();
    // Make sure logging doesn't crash. Not examining the result.
    std::ostringstream strm;
    strm << decoder_;
  }

  DecodeStatus StartDecoding(DecodeBuffer* db) override {
    collector_.Clear();
    decoder_.Reset();
    return ResumeDecoding(db);
  }

  DecodeStatus ResumeDecoding(DecodeBuffer* db) override {
    DecodeStatus status = decoder_.Decode(db);

    // Make sure logging doesn't crash. Not examining the result.
    std::ostringstream strm;
    strm << decoder_;

    return status;
  }

  AssertionResult DecodeAndValidateSeveralWays(DecodeBuffer* db,
                                               const Validator& validator) {
    bool return_non_zero_on_first = false;
    return RandomDecoderTest::DecodeAndValidateSeveralWays(
        db, return_non_zero_on_first, validator);
  }

  AssertionResult DecodeAndValidateSeveralWays(const HpackBlockBuilder& hbb,
                                               const Validator& validator) {
    DecodeBuffer db(hbb.buffer());
    return DecodeAndValidateSeveralWays(&db, validator);
  }

  AssertionResult DecodeHpackExampleAndValidateSeveralWays(
      absl::string_view hpack_example, Validator validator) {
    std::string input = HpackExampleToStringOrDie(hpack_example);
    DecodeBuffer db(input);
    return DecodeAndValidateSeveralWays(&db, validator);
  }

  uint8_t Rand8() { return Random().Rand8(); }

  std::string Rand8String() { return Random().RandString(Rand8()); }

  HpackBlockCollector collector_;
  HpackEntryDecoderVLoggingListener listener_;
  HpackBlockDecoder decoder_;
};

// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.1
TEST_F(HpackBlockDecoderTest, SpecExample_C_2_1) {
  auto do_check = [this]() {
    return collector_.ValidateSoleLiteralNameValueHeader(
        HpackEntryType::kIndexedLiteralHeader, false, "custom-key", false,
        "custom-header");
  };
  const char hpack_example[] = R"(
      40                                      | == Literal indexed ==
      0a                                      |   Literal name (len = 10)
      6375 7374 6f6d 2d6b 6579                | custom-key
      0d                                      |   Literal value (len = 13)
      6375 7374 6f6d 2d68 6561 6465 72        | custom-header
                                              | -> custom-key:
                                              |   custom-header
      )";
  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
      hpack_example, ValidateDoneAndEmpty(do_check)));
  EXPECT_TRUE(do_check());
}

// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.2
TEST_F(HpackBlockDecoderTest, SpecExample_C_2_2) {
  auto do_check = [this]() {
    return collector_.ValidateSoleLiteralValueHeader(
        HpackEntryType::kUnindexedLiteralHeader, 4, false, "/sample/path");
  };
  const char hpack_example[] = R"(
      04                                      | == Literal not indexed ==
                                              |   Indexed name (idx = 4)
                                              |     :path
      0c                                      |   Literal value (len = 12)
      2f73 616d 706c 652f 7061 7468           | /sample/path
                                              | -> :path: /sample/path
      )";
  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
      hpack_example, ValidateDoneAndEmpty(do_check)));
  EXPECT_TRUE(do_check());
}

// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.3
TEST_F(HpackBlockDecoderTest, SpecExample_C_2_3) {
  auto do_check = [this]() {
    return collector_.ValidateSoleLiteralNameValueHeader(
        HpackEntryType::kNeverIndexedLiteralHeader, false, "password", false,
        "secret");
  };
  const char hpack_example[] = R"(
      10                                      | == Literal never indexed ==
      08                                      |   Literal name (len = 8)
      7061 7373 776f 7264                     | password
      06                                      |   Literal value (len = 6)
      7365 6372 6574                          | secret
                                              | -> password: secret
      )";
  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
      hpack_example, ValidateDoneAndEmpty(do_check)));
  EXPECT_TRUE(do_check());
}

// http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.4
TEST_F(HpackBlockDecoderTest, SpecExample_C_2_4) {
  auto do_check = [this]() { return collector_.ValidateSoleIndexedHeader(2); };
  const char hpack_example[] = R"(
      82                                      | == Indexed - Add ==
                                              |   idx = 2
                                              | -> :method: GET
      )";
  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
      hpack_example, ValidateDoneAndEmpty(do_check)));
  EXPECT_TRUE(do_check());
}
// http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1
TEST_F(HpackBlockDecoderTest, SpecExample_C_3_1) {
  std::string example = R"(
      82                                      | == Indexed - Add ==
                                              |   idx = 2
                                              | -> :method: GET
      86                                      | == Indexed - Add ==
                                              |   idx = 6
                                              | -> :scheme: http
      84                                      | == Indexed - Add ==
                                              |   idx = 4
                                              | -> :path: /
      41                                      | == Literal indexed ==
                                              |   Indexed name (idx = 1)
                                              |     :authority
      0f                                      |   Literal value (len = 15)
      7777 772e 6578 616d 706c 652e 636f 6d   | www.example.com
                                              | -> :authority:
                                              |   www.example.com
      )";
  HpackBlockCollector expected;
  expected.ExpectIndexedHeader(2);
  expected.ExpectIndexedHeader(6);
  expected.ExpectIndexedHeader(4);
  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
                                          1, false, "www.example.com");
  NoArgValidator do_check = [expected, this]() {
    return collector_.VerifyEq(expected);
  };
  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
      example, ValidateDoneAndEmpty(do_check)));
  EXPECT_TRUE(do_check());
}

// http://httpwg.org/specs/rfc7541.html#rfc.section.C.5.1
TEST_F(HpackBlockDecoderTest, SpecExample_C_5_1) {
  std::string example = R"(
      48                                      | == Literal indexed ==
                                              |   Indexed name (idx = 8)
                                              |     :status
      03                                      |   Literal value (len = 3)
      3330 32                                 | 302
                                              | -> :status: 302
      58                                      | == Literal indexed ==
                                              |   Indexed name (idx = 24)
                                              |     cache-control
      07                                      |   Literal value (len = 7)
      7072 6976 6174 65                       | private
                                              | -> cache-control: private
      61                                      | == Literal indexed ==
                                              |   Indexed name (idx = 33)
                                              |     date
      1d                                      |   Literal value (len = 29)
      4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013
      2032 303a 3133 3a32 3120 474d 54        |  20:13:21 GMT
                                              | -> date: Mon, 21 Oct 2013
                                              |   20:13:21 GMT
      6e                                      | == Literal indexed ==
                                              |   Indexed name (idx = 46)
                                              |     location
      17                                      |   Literal value (len = 23)
      6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam
      706c 652e 636f 6d                       | ple.com
                                              | -> location:
                                              |   https://www.example.com
      )";
  HpackBlockCollector expected;
  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
                                          8, false, "302");
  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
                                          24, false, "private");
  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
                                          33, false,
                                          "Mon, 21 Oct 2013 20:13:21 GMT");
  expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader,
                                          46, false, "https://www.example.com");
  NoArgValidator do_check = [expected, this]() {
    return collector_.VerifyEq(expected);
  };
  EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays(
      example, ValidateDoneAndEmpty(do_check)));
  EXPECT_TRUE(do_check());
}

// Generate a bunch of HPACK block entries to expect, use those expectations
// to generate an HPACK block, then decode it and confirm it matches those
// expectations. Some of these are invalid (such as Indexed, with index=0),
// but well-formed, and the decoder doesn't check for validity, just
// well-formedness. That includes the validity of the strings not being checked,
// such as lower-case ascii for the names, and valid Huffman encodings.
TEST_F(HpackBlockDecoderTest, Computed) {
  HpackBlockCollector expected;
  expected.ExpectIndexedHeader(0);
  expected.ExpectIndexedHeader(1);
  expected.ExpectIndexedHeader(126);
  expected.ExpectIndexedHeader(127);
  expected.ExpectIndexedHeader(128);
  expected.ExpectDynamicTableSizeUpdate(0);
  expected.ExpectDynamicTableSizeUpdate(1);
  expected.ExpectDynamicTableSizeUpdate(14);
  expected.ExpectDynamicTableSizeUpdate(15);
  expected.ExpectDynamicTableSizeUpdate(30);
  expected.ExpectDynamicTableSizeUpdate(31);
  expected.ExpectDynamicTableSizeUpdate(4095);
  expected.ExpectDynamicTableSizeUpdate(4096);
  expected.ExpectDynamicTableSizeUpdate(8192);
  for (auto type : {HpackEntryType::kIndexedLiteralHeader,
                    HpackEntryType::kUnindexedLiteralHeader,
                    HpackEntryType::kNeverIndexedLiteralHeader}) {
    for (bool value_huffman : {false, true}) {
      // An entry with an index for the name. Ensure the name index
      // is not zero by adding one to the Rand8() result.
      expected.ExpectNameIndexAndLiteralValue(type, Rand8() + 1, value_huffman,
                                              Rand8String());
      // And two entries with literal names, one plain, one huffman encoded.
      expected.ExpectLiteralNameAndValue(type, false, Rand8String(),
                                         value_huffman, Rand8String());
      expected.ExpectLiteralNameAndValue(type, true, Rand8String(),
                                         value_huffman, Rand8String());
    }
  }
  // Shuffle the entries and serialize them to produce an HPACK block.
  expected.ShuffleEntries(RandomPtr());
  HpackBlockBuilder hbb;
  expected.AppendToHpackBlockBuilder(&hbb);

  NoArgValidator do_check = [expected, this]() {
    return collector_.VerifyEq(expected);
  };
  EXPECT_TRUE(
      DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check)));
  EXPECT_TRUE(do_check());
}

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