// Copyright 2017 The Chromium OS 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 <limits>
#include <utility>

#include "cbor/reader.h"

#include "base/containers/span.h"
#include "base/cxx17_backports.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

/* Leveraging RFC 7049 examples from
   https://github.com/cbor/test-vectors/blob/master/appendix_a.json. */
namespace cbor {

namespace {

std::vector<uint8_t> WithExtraneousData(base::span<const uint8_t> original) {
  std::vector<uint8_t> ret(original.begin(), original.end());
  // Add a valid one byte long CBOR data item, namely, an unsigned integer
  // with value "1".
  ret.push_back(0x01);
  return ret;
}

}  // namespace

TEST(CBORReaderTest, TestReadUint) {
  struct UintTestCase {
    const int64_t value;
    const std::vector<uint8_t> cbor_data;
  };

  static const UintTestCase kUintTestCases[] = {
      {0, {0x00}},
      {1, {0x01}},
      {23, {0x17}},
      {24, {0x18, 0x18}},
      {std::numeric_limits<uint8_t>::max(), {0x18, 0xff}},
      {1LL << 8, {0x19, 0x01, 0x00}},
      {std::numeric_limits<uint16_t>::max(), {0x19, 0xff, 0xff}},
      {1LL << 16, {0x1a, 0x00, 0x01, 0x00, 0x00}},
      {std::numeric_limits<uint32_t>::max(), {0x1a, 0xff, 0xff, 0xff, 0xff}},
      {1LL << 32, {0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}},
      {std::numeric_limits<int64_t>::max(),
       {0x1b, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
  };

  for (const UintTestCase& test_case : kUintTestCases) {
    SCOPED_TRACE(testing::Message() << "testing uint: " << test_case.value);

    base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::UNSIGNED);
    EXPECT_EQ(cbor.value().GetInteger(), test_case.value);

    auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
    Reader::DecoderError error_code;
    cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

    size_t num_bytes_consumed;
    cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
                        &error_code);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::UNSIGNED);
    EXPECT_EQ(cbor.value().GetInteger(), test_case.value);
    EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
    EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
  }
}

TEST(CBORReaderTest, TestUintEncodedWithNonMinimumByteLength) {
  static const std::vector<uint8_t> non_minimal_uint_encodings[] = {
      // Uint 23 encoded with 1 byte.
      {0x18, 0x17},
      // Uint 255 encoded with 2 bytes.
      {0x19, 0x00, 0xff},
      // Uint 65535 encoded with 4 byte.
      {0x1a, 0x00, 0x00, 0xff, 0xff},
      // Uint 4294967295 encoded with 8 byte.
      {0x1b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff},

      // When decoding byte has more than one syntax error, the first syntax
      // error encountered during deserialization is returned as the error code.
      {
          0xa2,        // map with non-minimally encoded key
          0x17,        // key 24
          0x61, 0x42,  // value :"B"

          0x18, 0x17,  // key 23 encoded with extra byte
          0x61, 0x45   // value "E"
      },
      {
          0xa2,        // map with out of order and non-minimally encoded key
          0x18, 0x17,  // key 23 encoded with extra byte
          0x61, 0x45,  // value "E"
          0x17,        // key 23
          0x61, 0x42   // value :"B"
      },
      {
          0xa2,        // map with duplicate non-minimally encoded key
          0x18, 0x17,  // key 23 encoded with extra byte
          0x61, 0x45,  // value "E"
          0x18, 0x17,  // key 23 encoded with extra byte
          0x61, 0x42   // value :"B"
      },
  };

  int test_case_index = 0;
  Reader::DecoderError error_code;
  for (const auto& non_minimal_uint : non_minimal_uint_encodings) {
    SCOPED_TRACE(testing::Message()
                 << "testing element at index : " << test_case_index++);

    base::Optional<Value> cbor = Reader::Read(non_minimal_uint, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::NON_MINIMAL_CBOR_ENCODING);
  }
}

TEST(CBORReaderTest, TestReadNegativeInt) {
  struct NegativeIntTestCase {
    const int64_t negative_int;
    const std::vector<uint8_t> cbor_data;
  };

  static const NegativeIntTestCase kNegativeIntTestCases[] = {
      {-1LL, {0x20}},
      {-24LL, {0x37}},
      {-25LL, {0x38, 0x18}},
      {-256LL, {0x38, 0xff}},
      {-1000LL, {0x39, 0x03, 0xe7}},
      {-1000000LL, {0x3a, 0x00, 0x0f, 0x42, 0x3f}},
      {-4294967296LL, {0x3a, 0xff, 0xff, 0xff, 0xff}},
      {std::numeric_limits<int64_t>::min(),
       {0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}};

  for (const NegativeIntTestCase& test_case : kNegativeIntTestCases) {
    SCOPED_TRACE(testing::Message()
                 << "testing negative int : " << test_case.negative_int);

    base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::NEGATIVE);
    EXPECT_EQ(cbor.value().GetInteger(), test_case.negative_int);

    auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
    Reader::DecoderError error_code;
    cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

    size_t num_bytes_consumed;
    cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
                        &error_code);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::NEGATIVE);
    EXPECT_EQ(cbor.value().GetInteger(), test_case.negative_int);
    EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
    EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
  }
}

TEST(CBORReaderTest, TestReadBytes) {
  struct ByteTestCase {
    const std::vector<uint8_t> value;
    const std::vector<uint8_t> cbor_data;
  };

  static const ByteTestCase kByteStringTestCases[] = {
      // clang-format off
      {{}, {0x40}},
      {{0x01, 0x02, 0x03, 0x04}, {0x44, 0x01, 0x02, 0x03, 0x04}},
      // clang-format on
  };

  int element_index = 0;
  for (const ByteTestCase& test_case : kByteStringTestCases) {
    SCOPED_TRACE(testing::Message()
                 << "testing string test case at : " << element_index++);

    base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::BYTE_STRING);
    EXPECT_EQ(cbor.value().GetBytestring(), test_case.value);

    auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
    Reader::DecoderError error_code;
    cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

    size_t num_bytes_consumed;
    cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
                        &error_code);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::BYTE_STRING);
    EXPECT_EQ(cbor.value().GetBytestring(), test_case.value);
    EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
    EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
  }
}

TEST(CBORReaderTest, TestReadString) {
  struct StringTestCase {
    const std::string value;
    const std::vector<uint8_t> cbor_data;
  };

  static const StringTestCase kStringTestCases[] = {
      {"", {0x60}},
      {"a", {0x61, 0x61}},
      {"IETF", {0x64, 0x49, 0x45, 0x54, 0x46}},
      {"\"\\", {0x62, 0x22, 0x5c}},
      {"\xc3\xbc", {0x62, 0xc3, 0xbc}},
      {"\xe6\xb0\xb4", {0x63, 0xe6, 0xb0, 0xb4}},
      {"\xf0\x90\x85\x91", {0x64, 0xf0, 0x90, 0x85, 0x91}},
  };

  for (const StringTestCase& test_case : kStringTestCases) {
    SCOPED_TRACE(testing::Message()
                 << "testing string value : " << test_case.value);

    base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::STRING);
    EXPECT_EQ(cbor.value().GetString(), test_case.value);

    auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
    Reader::DecoderError error_code;
    cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

    size_t num_bytes_consumed;
    cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
                        &error_code);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::STRING);
    EXPECT_EQ(cbor.value().GetString(), test_case.value);
    EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
    EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
  }
}

TEST(CBORReaderTest, TestReadStringWithNUL) {
  static const struct {
    const std::string value;
    const std::vector<uint8_t> cbor_data;
  } kStringTestCases[] = {
      {std::string("string_without_nul"),
       {0x72, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x77, 0x69, 0x74, 0x68,
        0x6F, 0x75, 0x74, 0x5F, 0x6E, 0x75, 0x6C}},
      {std::string("nul_terminated_string\0", 22),
       {0x76, 0x6E, 0x75, 0x6C, 0x5F, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, 0x61,
        0x74, 0x65, 0x64, 0x5F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x00}},
      {std::string("embedded\0nul", 12),
       {0x6C, 0x65, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x00, 0x6E, 0x75,
        0x6C}},
      {std::string("trailing_nuls\0\0", 15),
       {0x6F, 0x74, 0x72, 0x61, 0x69, 0x6C, 0x69, 0x6E, 0x67, 0x5F, 0x6E, 0x75,
        0x6C, 0x73, 0x00, 0x00}},
  };

  for (const auto& test_case : kStringTestCases) {
    SCOPED_TRACE(testing::Message()
                 << "testing string with nul bytes :" << test_case.value);

    base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::STRING);
    EXPECT_EQ(cbor.value().GetString(), test_case.value);

    auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
    Reader::DecoderError error_code;
    cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

    size_t num_bytes_consumed;
    cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
                        &error_code);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::STRING);
    EXPECT_EQ(cbor.value().GetString(), test_case.value);
    EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
    EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
  }
}

TEST(CBORReaderTest, TestReadStringWithInvalidByteSequenceAfterNUL) {
  // UTF-8 validation should not stop at the first NUL character in the string.
  // That is, a string with an invalid byte sequence should fail UTF-8
  // validation even if the invalid character is located after one or more NUL
  // characters. Here, 0xA6 is an unexpected continuation byte.
  static const std::vector<uint8_t> string_with_invalid_continuation_byte = {
      0x63, 0x00, 0x00, 0xA6};
  Reader::DecoderError error_code;
  base::Optional<Value> cbor =
      Reader::Read(string_with_invalid_continuation_byte, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::INVALID_UTF8);
}

TEST(CBORReaderTest, TestReadArray) {
  static const std::vector<uint8_t> kArrayTestCaseCbor = {
      // clang-format off
      0x98, 0x19,  // array of 25 elements
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
        0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
        0x18, 0x18, 0x19,
      // clang-format on
  };

  base::Optional<Value> cbor = Reader::Read(kArrayTestCaseCbor);
  ASSERT_TRUE(cbor.has_value());
  const Value cbor_array = std::move(cbor.value());
  ASSERT_EQ(cbor_array.type(), Value::Type::ARRAY);
  ASSERT_THAT(cbor_array.GetArray(), testing::SizeIs(25));

  std::vector<Value> array;
  for (int i = 0; i < 25; i++) {
    SCOPED_TRACE(testing::Message() << "testing array element at index " << i);

    ASSERT_EQ(cbor_array.GetArray()[i].type(), Value::Type::UNSIGNED);
    EXPECT_EQ(cbor_array.GetArray()[i].GetInteger(),
              static_cast<int64_t>(i + 1));
  }

  auto cbor_data_with_extra_byte = WithExtraneousData(kArrayTestCaseCbor);
  Reader::DecoderError error_code;
  cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

  size_t num_bytes_consumed;
  cbor =
      Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor_array.type(), Value::Type::ARRAY);
  ASSERT_THAT(cbor_array.GetArray(), testing::SizeIs(25));
  EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  EXPECT_EQ(num_bytes_consumed, kArrayTestCaseCbor.size());
}

TEST(CBORReaderTest, TestReadMapWithMapValue) {
  static const std::vector<uint8_t> kMapTestCaseCbor = {
      // clang-format off
      0xa4,  // map with 4 key value pairs:
        0x18, 0x18,  // 24
        0x63, 0x61, 0x62, 0x63,  // "abc"

        0x60,  // ""
        0x61, 0x2e,  // "."

        0x61, 0x62,  // "b"
        0x61, 0x42,  // "B"

        0x62, 0x61, 0x61,  // "aa"
        0x62, 0x41, 0x41,  // "AA"
      // clang-format on
  };

  base::Optional<Value> cbor = Reader::Read(kMapTestCaseCbor);
  ASSERT_TRUE(cbor.has_value());
  const Value cbor_val = std::move(cbor.value());
  ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
  ASSERT_EQ(cbor_val.GetMap().size(), 4u);

  const Value key_uint(24);
  ASSERT_EQ(cbor_val.GetMap().count(key_uint), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_uint)->second.type(),
            Value::Type::STRING);
  EXPECT_EQ(cbor_val.GetMap().find(key_uint)->second.GetString(), "abc");

  const Value key_empty_string("");
  ASSERT_EQ(cbor_val.GetMap().count(key_empty_string), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_empty_string)->second.type(),
            Value::Type::STRING);
  EXPECT_EQ(cbor_val.GetMap().find(key_empty_string)->second.GetString(), ".");

  const Value key_b("b");
  ASSERT_EQ(cbor_val.GetMap().count(key_b), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_b)->second.type(), Value::Type::STRING);
  EXPECT_EQ(cbor_val.GetMap().find(key_b)->second.GetString(), "B");

  const Value key_aa("aa");
  ASSERT_EQ(cbor_val.GetMap().count(key_aa), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_aa)->second.type(), Value::Type::STRING);
  EXPECT_EQ(cbor_val.GetMap().find(key_aa)->second.GetString(), "AA");

  auto cbor_data_with_extra_byte = WithExtraneousData(kMapTestCaseCbor);
  Reader::DecoderError error_code;
  cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

  size_t num_bytes_consumed;
  cbor =
      Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
  ASSERT_EQ(cbor_val.GetMap().size(), 4u);
  EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  EXPECT_EQ(num_bytes_consumed, kMapTestCaseCbor.size());
}

TEST(CBORReaderTest, TestReadMapWithIntegerKeys) {
  static const std::vector<uint8_t> kMapWithIntegerKeyCbor = {
      // clang-format off
      0xA4,                 // map with 4 key value pairs
         0x01,              // key : 1
         0x61, 0x61,        // value : "a"

         0x09,              // key : 9
         0x61, 0x62,        // value : "b"

         0x19, 0x03, 0xE7,  // key : 999
         0x61, 0x63,        // value "c"

         0x19, 0x04, 0x57,  // key : 1111
         0x61, 0x64,        // value : "d"
      // clang-format on
  };

  base::Optional<Value> cbor = Reader::Read(kMapWithIntegerKeyCbor);
  ASSERT_TRUE(cbor.has_value());
  const Value cbor_val = std::move(cbor.value());
  ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
  ASSERT_EQ(cbor_val.GetMap().size(), 4u);

  const Value key_1(1);
  ASSERT_EQ(cbor_val.GetMap().count(key_1), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_1)->second.type(), Value::Type::STRING);
  EXPECT_EQ(cbor_val.GetMap().find(key_1)->second.GetString(), "a");

  const Value key_9(9);
  ASSERT_EQ(cbor_val.GetMap().count(key_9), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_9)->second.type(), Value::Type::STRING);
  EXPECT_EQ(cbor_val.GetMap().find(key_9)->second.GetString(), "b");

  const Value key_999(999);
  ASSERT_EQ(cbor_val.GetMap().count(key_999), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_999)->second.type(),
            Value::Type::STRING);
  EXPECT_EQ(cbor_val.GetMap().find(key_999)->second.GetString(), "c");

  const Value key_1111(1111);
  ASSERT_EQ(cbor_val.GetMap().count(key_1111), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_1111)->second.type(),
            Value::Type::STRING);
  EXPECT_EQ(cbor_val.GetMap().find(key_1111)->second.GetString(), "d");

  auto cbor_data_with_extra_byte = WithExtraneousData(kMapWithIntegerKeyCbor);
  Reader::DecoderError error_code;
  cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

  size_t num_bytes_consumed;
  cbor =
      Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
  ASSERT_EQ(cbor_val.GetMap().size(), 4u);
  EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  EXPECT_EQ(num_bytes_consumed, kMapWithIntegerKeyCbor.size());
}

TEST(CBORReaderTest, TestReadMapWithNegativeIntegersKeys) {
  static const std::vector<uint8_t> kMapWithIntegerKeyCbor = {
      // clang-format off
      0xA3,                 // map with 3 key value pairs
         0x20,              // key : -1
         0x01,

         0x21,              // key : -2
         0x02,

         0x38, 0x63,        // key : -100
         0x03,
      // clang-format on
  };

  base::Optional<Value> cbor = Reader::Read(kMapWithIntegerKeyCbor);
  ASSERT_TRUE(cbor.has_value());
  const Value cbor_val = std::move(cbor.value());
  ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
  ASSERT_EQ(cbor_val.GetMap().size(), 3u);

  const Value key_1(-1);
  ASSERT_EQ(cbor_val.GetMap().count(key_1), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_1)->second.type(),
            Value::Type::UNSIGNED);
  EXPECT_EQ(cbor_val.GetMap().find(key_1)->second.GetInteger(), 1);

  const Value key_2(-2);
  ASSERT_EQ(cbor_val.GetMap().count(key_2), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_2)->second.type(),
            Value::Type::UNSIGNED);
  EXPECT_EQ(cbor_val.GetMap().find(key_2)->second.GetInteger(), 2);

  const Value key_100(-100);
  ASSERT_EQ(cbor_val.GetMap().count(key_100), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_100)->second.type(),
            Value::Type::UNSIGNED);
  EXPECT_EQ(cbor_val.GetMap().find(key_100)->second.GetInteger(), 3);

  auto cbor_data_with_extra_byte = WithExtraneousData(kMapWithIntegerKeyCbor);
  Reader::DecoderError error_code;
  cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

  size_t num_bytes_consumed;
  cbor =
      Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
  ASSERT_EQ(cbor_val.GetMap().size(), 3u);
  EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  EXPECT_EQ(num_bytes_consumed, kMapWithIntegerKeyCbor.size());
}

TEST(CBORReaderTest, TestReadMapWithArray) {
  static const std::vector<uint8_t> kMapArrayTestCaseCbor = {
      // clang-format off
      0xa2,  // map of 2 pairs
        0x61, 0x61,  // "a"
        0x01,

        0x61, 0x62,  // "b"
        0x82,        // array with 2 elements
          0x02,
          0x03,
      // clang-format on
  };

  base::Optional<Value> cbor = Reader::Read(kMapArrayTestCaseCbor);
  ASSERT_TRUE(cbor.has_value());
  const Value cbor_val = std::move(cbor.value());
  ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
  ASSERT_EQ(cbor_val.GetMap().size(), 2u);

  const Value key_a("a");
  ASSERT_EQ(cbor_val.GetMap().count(key_a), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_a)->second.type(),
            Value::Type::UNSIGNED);
  EXPECT_EQ(cbor_val.GetMap().find(key_a)->second.GetInteger(), 1u);

  const Value key_b("b");
  ASSERT_EQ(cbor_val.GetMap().count(key_b), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_b)->second.type(), Value::Type::ARRAY);

  const Value nested_array = cbor_val.GetMap().find(key_b)->second.Clone();
  ASSERT_EQ(nested_array.GetArray().size(), 2u);
  for (int i = 0; i < 2; i++) {
    ASSERT_THAT(nested_array.GetArray()[i].type(), Value::Type::UNSIGNED);
    EXPECT_EQ(nested_array.GetArray()[i].GetInteger(),
              static_cast<int64_t>(i + 2));
  }

  auto cbor_data_with_extra_byte = WithExtraneousData(kMapArrayTestCaseCbor);
  Reader::DecoderError error_code;
  cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

  size_t num_bytes_consumed;
  cbor =
      Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
  ASSERT_EQ(cbor_val.GetMap().size(), 2u);
  EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  EXPECT_EQ(num_bytes_consumed, kMapArrayTestCaseCbor.size());
}

TEST(CBORReaderTest, TestReadMapWithTextStringKeys) {
  static const std::vector<uint8_t> kMapTestCase{
      // clang-format off
      0xa2,  // map of 2 pairs
        0x61, 'k', // text string "k"
        0x61, 'v',

        0x63, 'f', 'o', 'o', // text string "foo"
        0x63, 'b', 'a', 'r',
      // clang-format on
  };

  Reader::DecoderError error_code;
  base::Optional<Value> cbor = Reader::Read(kMapTestCase, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor->type(), Value::Type::MAP);
  ASSERT_EQ(cbor->GetMap().size(), 2u);

  const Value key_k("k");
  ASSERT_EQ(cbor->GetMap().count(key_k), 1u);
  ASSERT_EQ(cbor->GetMap().find(key_k)->second.type(), Value::Type::STRING);
  EXPECT_EQ(cbor->GetMap().find(key_k)->second.GetString(), "v");

  const Value key_foo("foo");
  ASSERT_EQ(cbor->GetMap().count(key_foo), 1u);
  ASSERT_EQ(cbor->GetMap().find(key_foo)->second.type(), Value::Type::STRING);
  EXPECT_EQ(cbor->GetMap().find(key_foo)->second.GetString(), "bar");

  auto cbor_data_with_extra_byte = WithExtraneousData(kMapTestCase);
  cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

  size_t num_bytes_consumed;
  cbor =
      Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor->type(), Value::Type::MAP);
  ASSERT_EQ(cbor->GetMap().size(), 2u);
  EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  EXPECT_EQ(num_bytes_consumed, kMapTestCase.size());
}

TEST(CBORReaderTest, TestReadMapWithByteStringKeys) {
  static const std::vector<uint8_t> kMapTestCase{
      // clang-format off
      0xa2,  // map of 2 pairs
        0x41, 'k', // byte string "k"
        0x41, 'v',

        0x43, 'f', 'o', 'o', // byte string "foo"
        0x43, 'b', 'a', 'r',
      // clang-format on
  };

  Reader::DecoderError error_code;
  base::Optional<Value> cbor = Reader::Read(kMapTestCase, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor->type(), Value::Type::MAP);
  ASSERT_EQ(cbor->GetMap().size(), 2u);

  const Value key_k(std::vector<uint8_t>{'k'});
  ASSERT_EQ(cbor->GetMap().count(key_k), 1u);
  ASSERT_EQ(cbor->GetMap().find(key_k)->second.type(),
            Value::Type::BYTE_STRING);
  EXPECT_EQ(cbor->GetMap().find(key_k)->second.GetBytestring(),
            std::vector<uint8_t>{'v'});

  const Value key_foo(std::vector<uint8_t>{'f', 'o', 'o'});
  ASSERT_EQ(cbor->GetMap().count(key_foo), 1u);
  ASSERT_EQ(cbor->GetMap().find(key_foo)->second.type(),
            Value::Type::BYTE_STRING);
  static const std::vector<uint8_t> kBarBytes{'b', 'a', 'r'};
  EXPECT_EQ(cbor->GetMap().find(key_foo)->second.GetBytestring(), kBarBytes);

  auto cbor_data_with_extra_byte = WithExtraneousData(kMapTestCase);
  cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

  size_t num_bytes_consumed;
  cbor =
      Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor->type(), Value::Type::MAP);
  ASSERT_EQ(cbor->GetMap().size(), 2u);
  EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  EXPECT_EQ(num_bytes_consumed, kMapTestCase.size());
}

TEST(CBORReaderTest, TestReadMapWithMixedKeys) {
  // Example adopted from:
  // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html
  static const uint8_t kMapTestCase[] = {
      // clang-format off
      0xa6, // map of 6 pairs
        0x0a, // 10
        0x00,

        0x18, 0x64, // 100
        0x01,

        0x20, // -1
        0x02,

        // This entry is not in the example, but added to test byte string key
        0x42, 'x', 'y', // byte string "xy"
        0x03,

        0x61, 'z', // text string "z"
        0x04,

        0x62, 'a', 'a', // text string "aa"
        0x05,

      /*
        0x81, 0x18, 0x64, // [100] (array as map key is not yet supported)
        0x06,

        0x81, 0x20,  // [-1] (array as map key is not yet supported)
        0x07,

        0xf4, // false (boolean  as map key is not yet supported)
        0x08,
      */
      // clang-format on
  };

  Reader::DecoderError error_code;
  base::Optional<Value> cbor = Reader::Read(kMapTestCase, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor->type(), Value::Type::MAP);
  ASSERT_EQ(cbor->GetMap().size(), 6u);

  std::vector<Value> keys;
  keys.emplace_back(10);
  keys.emplace_back(100);
  keys.emplace_back(-1);
  keys.emplace_back(Value::BinaryValue{'x', 'y'});
  keys.emplace_back("z");
  keys.emplace_back("aa");
  for (size_t i = 0; i < keys.size(); ++i) {
    SCOPED_TRACE(testing::Message() << "testing key at index: " << i);
    ASSERT_EQ(cbor->GetMap().count(keys[i]), 1u);
    ASSERT_EQ(cbor->GetMap().find(keys[i])->second.type(),
              Value::Type::UNSIGNED);
    EXPECT_EQ(cbor->GetMap().find(keys[i])->second.GetInteger(),
              static_cast<int>(i));
  }

  auto cbor_data_with_extra_byte = WithExtraneousData(kMapTestCase);
  cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

  size_t num_bytes_consumed;
  cbor =
      Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
  ASSERT_TRUE(cbor.has_value());
  ASSERT_EQ(cbor->type(), Value::Type::MAP);
  ASSERT_EQ(cbor->GetMap().size(), 6u);
  EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  EXPECT_EQ(num_bytes_consumed, base::size(kMapTestCase));
}

TEST(CBORReaderTest, TestReadNestedMap) {
  static const std::vector<uint8_t> kNestedMapTestCase = {
      // clang-format off
      0xa2,  // map of 2 pairs
        0x61, 0x61,  // "a"
        0x01,

        0x61, 0x62,  // "b"
        0xa2,        // map of 2 pairs
          0x61, 0x63,  // "c"
          0x02,

          0x61, 0x64,  // "d"
          0x03,
      // clang-format on
  };

  base::Optional<Value> cbor = Reader::Read(kNestedMapTestCase);
  ASSERT_TRUE(cbor.has_value());
  const Value cbor_val = std::move(cbor.value());
  ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
  ASSERT_EQ(cbor_val.GetMap().size(), 2u);

  const Value key_a("a");
  ASSERT_EQ(cbor_val.GetMap().count(key_a), 1u);
  ASSERT_EQ(cbor_val.GetMap().find(key_a)->second.type(),
            Value::Type::UNSIGNED);
  EXPECT_EQ(cbor_val.GetMap().find(key_a)->second.GetInteger(), 1u);

  const Value key_b("b");
  ASSERT_EQ(cbor_val.GetMap().count(key_b), 1u);
  const Value nested_map = cbor_val.GetMap().find(key_b)->second.Clone();
  ASSERT_EQ(nested_map.type(), Value::Type::MAP);
  ASSERT_EQ(nested_map.GetMap().size(), 2u);

  const Value key_c("c");
  ASSERT_EQ(nested_map.GetMap().count(key_c), 1u);
  ASSERT_EQ(nested_map.GetMap().find(key_c)->second.type(),
            Value::Type::UNSIGNED);
  EXPECT_EQ(nested_map.GetMap().find(key_c)->second.GetInteger(), 2u);

  const Value key_d("d");
  ASSERT_EQ(nested_map.GetMap().count(key_d), 1u);
  ASSERT_EQ(nested_map.GetMap().find(key_d)->second.type(),
            Value::Type::UNSIGNED);
  EXPECT_EQ(nested_map.GetMap().find(key_d)->second.GetInteger(), 3u);
}

TEST(CBORReaderTest, TestIntegerRange) {
  static const std::vector<uint8_t> kMaxPositiveInt = {
      0x1b, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  static const std::vector<uint8_t> kMinNegativeInt = {
      0x3b, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

  base::Optional<Value> max_positive_int = Reader::Read(kMaxPositiveInt);
  ASSERT_TRUE(max_positive_int.has_value());
  EXPECT_EQ(max_positive_int.value().GetInteger(), INT64_MAX);

  base::Optional<Value> min_negative_int = Reader::Read(kMinNegativeInt);
  ASSERT_TRUE(min_negative_int.has_value());
  EXPECT_EQ(min_negative_int.value().GetInteger(), INT64_MIN);
}

TEST(CBORReaderTest, TestIntegerOutOfRangeError) {
  static const std::vector<uint8_t> kOutOfRangePositiveInt = {
      0x1b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  static const std::vector<uint8_t> kOutOfRangeNegativeInt = {
      0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  Reader::DecoderError error_code;
  base::Optional<Value> positive_int_out_of_range_cbor =
      Reader::Read(kOutOfRangePositiveInt, &error_code);
  EXPECT_FALSE(positive_int_out_of_range_cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::OUT_OF_RANGE_INTEGER_VALUE);

  base::Optional<Value> negative_int_out_of_range_cbor =
      Reader::Read(kOutOfRangeNegativeInt, &error_code);
  EXPECT_FALSE(negative_int_out_of_range_cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::OUT_OF_RANGE_INTEGER_VALUE);
}

TEST(CBORReaderTest, TestReadSimpleValue) {
  static const struct {
    const Value::SimpleValue value;
    const std::vector<uint8_t> cbor_data;
  } kSimpleValueTestCases[] = {
      {Value::SimpleValue::FALSE_VALUE, {0xf4}},
      {Value::SimpleValue::TRUE_VALUE, {0xf5}},
      {Value::SimpleValue::NULL_VALUE, {0xf6}},
      {Value::SimpleValue::UNDEFINED, {0xf7}},
  };

  int test_element_index = 0;
  for (const auto& test_case : kSimpleValueTestCases) {
    SCOPED_TRACE(testing::Message()
                 << "testing simple value at index : " << test_element_index++);

    base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::SIMPLE_VALUE);
    EXPECT_EQ(cbor.value().GetSimpleValue(), test_case.value);

    auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
    Reader::DecoderError error_code;
    cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);

    size_t num_bytes_consumed;
    cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
                        &error_code);
    ASSERT_TRUE(cbor.has_value());
    ASSERT_EQ(cbor.value().type(), Value::Type::SIMPLE_VALUE);
    EXPECT_EQ(cbor.value().GetSimpleValue(), test_case.value);
    EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
    EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
  }
}

TEST(CBORReaderTest, TestReadUnsupportedFloatingPointNumbers) {
  static const std::vector<uint8_t> floating_point_cbors[] = {
      // 16 bit floating point value.
      {0xf9, 0x10, 0x00},
      // 32 bit floating point value.
      {0xfa, 0x10, 0x00, 0x00, 0x00},
      // 64 bit floating point value.
      {0xfb, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};

  for (const auto& unsupported_floating_point : floating_point_cbors) {
    SCOPED_TRACE(testing::Message()
                 << "testing unsupported floating point : "
                 << testing::PrintToString(unsupported_floating_point));
    Reader::DecoderError error_code;
    base::Optional<Value> cbor =
        Reader::Read(unsupported_floating_point, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code,
              Reader::DecoderError::UNSUPPORTED_FLOATING_POINT_VALUE);
  }
}

TEST(CBORReaderTest, TestIncompleteCBORDataError) {
  static const std::vector<uint8_t> incomplete_cbor_list[] = {
      // Additional info byte corresponds to unsigned int that corresponds
      // to 2 additional bytes. But actual data encoded  in one byte.
      {0x19, 0x03},
      // CBOR bytestring of length 3 encoded with additional info of length 4.
      {0x44, 0x01, 0x02, 0x03},
      // CBOR string data "IETF" of length 4 encoded with additional info of
      // length 5.
      {0x65, 0x49, 0x45, 0x54, 0x46},
      // CBOR array of length 1 encoded with additional info of length 2.
      {0x82, 0x02},
      // CBOR map with single key value pair encoded with additional info of
      // length 2.
      {0xa2, 0x61, 0x61, 0x01},
      {0x18},  // unsigned with pending 1 byte of numeric value.
      {0x99},  // array with pending 2 byte of numeric value (length).
      {0xba},  // map with pending 4 byte of numeric value (length).
      {0x5b},  // byte string with pending 4 byte of numeric value (length).
      {0x3b},  // negative integer with pending 8 byte of numeric value.
      {0x99, 0x01},  // array with pending 2 byte of numeric value (length),
                     // with only 1 byte of additional data.
      {0xba, 0x01, 0x02, 0x03},  // map with pending 4 byte of numeric value
                                 // (length), with only 3 bytes of additional
                                 // data.
      {0x3b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
       0x07},  // negative integer with pending 8 byte of
               // numeric value, with only 7 bytes of
               // additional data.
  };

  int test_element_index = 0;
  for (const auto& incomplete_data : incomplete_cbor_list) {
    SCOPED_TRACE(testing::Message() << "testing incomplete data at index : "
                                    << test_element_index++);

    Reader::DecoderError error_code;
    base::Optional<Value> cbor = Reader::Read(incomplete_data, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::INCOMPLETE_CBOR_DATA);
  }
}

// While RFC 7049 allows CBOR map keys with all types, current decoder only
// supports unsigned integer and string keys.
TEST(CBORReaderTest, TestUnsupportedMapKeyFormatError) {
  static const std::vector<uint8_t> kMapWithUintKey = {
      // clang-format off
      0xa2,        // map of 2 pairs

        0x82, 0x01, 0x02,  // invalid key : [1, 2]
        0x02,              // value : 2

        0x61, 0x64,  // key : "d"
        0x03,        // value : 3
      // clang-format on
  };

  Reader::DecoderError error_code;
  base::Optional<Value> cbor = Reader::Read(kMapWithUintKey, &error_code);
  EXPECT_FALSE(cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::INCORRECT_MAP_KEY_TYPE);
}

TEST(CBORReaderTest, TestUnknownAdditionalInfoError) {
  static const std::vector<uint8_t> kUnknownAdditionalInfoList[] = {
      // "IETF" encoded with major type 3 and additional info of 28.
      {0x7C, 0x49, 0x45, 0x54, 0x46},
      // "\"\\" encoded with major type 3 and additional info of 29.
      {0x7D, 0x22, 0x5c},
      // "\xc3\xbc" encoded with major type 3 and additional info of 30.
      {0x7E, 0xc3, 0xbc},
      // "\xe6\xb0\xb4" encoded with major type 3 and additional info of 31.
      {0x7F, 0xe6, 0xb0, 0xb4},
      // Major type 7, additional information 28: unassigned.
      {0xFC},
      // Major type 7, additional information 29: unassigned.
      {0xFD},
      // Major type 7, additional information 30: unassigned.
      {0xFE},
      // Major type 7, additional information 31: "break" stop code for
      // indefinite-length items.
      {0xFF},
  };

  int test_element_index = 0;
  for (const auto& incorrect_cbor : kUnknownAdditionalInfoList) {
    SCOPED_TRACE(testing::Message()
                 << "testing data at index : " << test_element_index++);

    Reader::DecoderError error_code;
    base::Optional<Value> cbor = Reader::Read(incorrect_cbor, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::UNKNOWN_ADDITIONAL_INFO);
  }
}

TEST(CBORReaderTest, TestTooMuchNestingError) {
  static const std::vector<uint8_t> kZeroDepthCBORList[] = {
      // Unsigned int with value 100.
      {0x18, 0x64},
      // CBOR bytestring of length 4.
      {0x44, 0x01, 0x02, 0x03, 0x04},
      // CBOR string of corresponding to "IETF.
      {0x64, 0x49, 0x45, 0x54, 0x46},
      // Empty CBOR array.
      {0x80},
      // Empty CBOR Map
      {0xa0},
  };

  int test_element_index = 0;
  for (const auto& zero_depth_data : kZeroDepthCBORList) {
    SCOPED_TRACE(testing::Message()
                 << "testing zero nested data : " << test_element_index++);
    Reader::DecoderError error_code;
    base::Optional<Value> cbor = Reader::Read(zero_depth_data, &error_code, 0);
    EXPECT_TRUE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  }

  // Corresponds to a CBOR structure with a nesting depth of 2:
  //      {"a": 1,
  //       "b": [2, 3]}
  static const std::vector<uint8_t> kNestedCBORData = {
      // clang-format off
      0xa2,  // map of 2 pairs
        0x61, 0x61,  // "a"
        0x01,

        0x61, 0x62,  // "b"
        0x82,        // array with 2 elements
          0x02,
          0x03,
      // clang-format on
  };

  Reader::DecoderError error_code;
  base::Optional<Value> cbor_single_layer_max =
      Reader::Read(kNestedCBORData, &error_code, 1);
  EXPECT_FALSE(cbor_single_layer_max.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::TOO_MUCH_NESTING);

  base::Optional<Value> cbor_double_layer_max =
      Reader::Read(kNestedCBORData, &error_code, 2);
  EXPECT_TRUE(cbor_double_layer_max.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
}

TEST(CBORReaderTest, TestOutOfOrderKeyError) {
  static const std::vector<uint8_t> kMapsWithUnsortedKeys[] = {
      // clang-format off
      {0xa2,  // map with 2 keys with same major type and length
         0x61, 0x62,  // key "b"
         0x61, 0x42,  // value "B"

         0x61, 0x61,  // key "a" (out of order byte-wise lexically)
         0x61, 0x45   // value "E"
      },
      {0xa2,  // map with 2 keys with different major type
         0x61, 0x62,        // key "b"
         0x02,              // value 2

         // key 1000 (out of order since lower major type sorts first)
         0x19, 0x03, 0xe8,
         0x61, 0x61,        // value a
      },
      {0xa2,  // map with 2 keys with same major type
         0x19, 0x03, 0xe8,  // key 1000  (out of order due to longer length)
         0x61, 0x61,        //value "a"

         0x0a,              // key 10
         0x61, 0x62},       // value "b"
      {0xa2,  // map with 2 text string keys
         0x62, 'a', 'a', // key text string "aa"
                         // (out of order due to longer length)
         0x02,

         0x61, 'b',   // key "b"
         0x01,
      },
      {0xa2,  // map with 2 byte string keys
         0x42, 'x', 'x', // key byte string "xx"
                         // (out of order due to longer length)
         0x02,

         0x41, 'y',  // key byte string "y"
         0x01,
      },
      //clang-format on
  };

  int test_element_index = 0;
  for (const auto& unsorted_map : kMapsWithUnsortedKeys) {
    testing::Message scope_message;
    scope_message << "testing unsorted map : " << test_element_index++;
    SCOPED_TRACE(scope_message);

    // Expect `OUT_OF_ORDER_KEY`.
    {
      Reader::DecoderError error_code;
      base::Optional<Value> cbor =
          Reader::Read(unsorted_map, &error_code);
      EXPECT_FALSE(cbor.has_value());
      EXPECT_EQ(error_code, Reader::DecoderError::OUT_OF_ORDER_KEY);
    }

    // When `allow_and_canonicalize_out_of_order_keys` flag is set, expect
    // `CBOR_NO_ERROR`.
    {
      Reader::DecoderError error_code;
      Reader::Config config;
      config.error_code_out = &error_code;
      config.allow_and_canonicalize_out_of_order_keys = true;

      base::Optional<Value> cbor =
          Reader::Read(unsorted_map, config);
      EXPECT_TRUE(cbor);
      EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
    }
  }
}

TEST(CBORReaderTest, TestOutOfOrderKeyErrorWithDuplicateKeys) {
  static const std::vector<uint8_t> kMapsWithUnsortedKeys[] = {
      // clang-format off
      {0xa3,  // map with 3 keys with same major type and length
         0x61, 0x62,  // key "b"
         0x61, 0x42,  // value "B"

         0x61, 0x61,  // key "a" (out of order byte-wise lexically)
         0x61, 0x45,   // value "E"

         0x61, 0x62,  // key "b" (duplicate)
         0x61, 0x42,  // value "B"
      },
      {0xa3,  // map with 3 byte string keys
         0x42, 'x', 'x', // key byte string "xx"
                         // (out of order due to longer length)
         0x02,

         0x41, 'y',  // key byte string "y"
         0x01,

         0x41, 'y',  // key byte string "y" (duplicate)
         0x02,
      },
      //clang-format on
  };

  int test_element_index = 0;
  for (const auto& unsorted_map : kMapsWithUnsortedKeys) {
    testing::Message scope_message;
    scope_message << "testing unsorted map : " << test_element_index++;
    SCOPED_TRACE(scope_message);

    // Expect `OUT_OF_ORDER_KEY`.
    {
      Reader::DecoderError error_code;
      base::Optional<Value> cbor =
          Reader::Read(unsorted_map, &error_code);
      EXPECT_FALSE(cbor.has_value());
      EXPECT_EQ(error_code, Reader::DecoderError::OUT_OF_ORDER_KEY);
    }

    // When `allow_and_canonicalize_out_of_order_keys` flag is set, expect
    // `DUPLICATE_KEY`.
    {
      Reader::DecoderError error_code;
      Reader::Config config;
      config.error_code_out = &error_code;
      config.allow_and_canonicalize_out_of_order_keys = true;

      base::Optional<Value> cbor =
          Reader::Read(unsorted_map, config);
      EXPECT_FALSE(cbor);
      EXPECT_EQ(error_code, Reader::DecoderError::DUPLICATE_KEY);
    }
  }
}

TEST(CBORReaderTest, TestDuplicateKeyError) {
  static const std::vector<uint8_t> kMapWithDuplicateKey = {
      // clang-format off
      0xa6,  // map of 6 pairs:
        0x60,  // ""
        0x61, 0x2e,  // "."

        0x61, 0x62,  // "b"
        0x61, 0x42,  // "B"

        0x61, 0x62,  // "b" (Duplicate key)
        0x61, 0x43,  // "C"

        0x61, 0x64,  // "d"
        0x61, 0x44,  // "D"

        0x61, 0x65,  // "e"
        0x61, 0x44,  // "D"

        0x62, 0x61, 0x61,  // "aa"
        0x62, 0x41, 0x41,  // "AA"
      // clang-format on
  };

  {
    Reader::DecoderError error_code;
    base::Optional<Value> cbor =
        Reader::Read(kMapWithDuplicateKey, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::DUPLICATE_KEY);
  }

  {
    Reader::DecoderError error_code;
    Reader::Config config;
    config.error_code_out = &error_code;
    config.allow_and_canonicalize_out_of_order_keys = true;

    base::Optional<Value> cbor = Reader::Read(kMapWithDuplicateKey, config);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::DUPLICATE_KEY);
  }
}

// Leveraging Markus Kuhn’s UTF-8 decoder stress test. See
// http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt for details.
TEST(CBORReaderTest, TestIncorrectStringEncodingError) {
  static const std::vector<uint8_t> utf8_character_encodings[] = {
      // Corresponds to utf8 encoding of "퟿" (section 2.3.1 of stress test).
      {0x63, 0xED, 0x9F, 0xBF},
      // Corresponds to utf8 encoding of "" (section 2.3.2 of stress test).
      {0x63, 0xEE, 0x80, 0x80},
      // Corresponds to utf8 encoding of "�"  (section 2.3.3 of stress test).
      {0x63, 0xEF, 0xBF, 0xBD},
  };

  int test_element_index = 0;
  Reader::DecoderError error_code;
  for (const auto& cbor_byte : utf8_character_encodings) {
    SCOPED_TRACE(testing::Message() << "testing cbor data utf8 encoding : "
                                    << test_element_index++);

    base::Optional<Value> correctly_encoded_cbor =
        Reader::Read(cbor_byte, &error_code);
    EXPECT_TRUE(correctly_encoded_cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
  }

  // Incorrect UTF8 encoding referenced by section 3.5.3 of the stress test.
  std::vector<uint8_t> impossible_utf_byte{0x64, 0xfe, 0xfe, 0xff, 0xff};
  base::Optional<Value> incorrectly_encoded_cbor =
      Reader::Read(impossible_utf_byte, &error_code);
  EXPECT_FALSE(incorrectly_encoded_cbor.has_value());
  EXPECT_EQ(error_code, Reader::DecoderError::INVALID_UTF8);
}

TEST(CBORReaderTest, TestExtraneousCBORDataError) {
  static const std::vector<uint8_t> zero_padded_cbor_list[] = {
      // 1 extra byte after a 2-byte unsigned int.
      {0x19, 0x03, 0x05, 0x00},
      // 1 extra byte after a 4-byte cbor byte array.
      {0x44, 0x01, 0x02, 0x03, 0x04, 0x00},
      // 1 extra byte after a 4-byte string.
      {0x64, 0x49, 0x45, 0x54, 0x46, 0x00},
      // 1 extra byte after CBOR array of length 2.
      {0x82, 0x01, 0x02, 0x00},
      // 1 extra key value pair after CBOR map of size 2.
      {0xa1, 0x61, 0x63, 0x02, 0x61, 0x64, 0x03},
  };

  int test_element_index = 0;
  for (const auto& extraneous_cbor_data : zero_padded_cbor_list) {
    SCOPED_TRACE(testing::Message()
                 << "testing cbor extraneous data : " << test_element_index++);

    Reader::DecoderError error_code;
    base::Optional<Value> cbor =
        Reader::Read(extraneous_cbor_data, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
  }
}

TEST(CBORReaderTest, TestUnsupportedSimpleValue) {
  static const std::vector<uint8_t> unsupported_simple_values[] = {
      // Simple value (0, unassigned)
      {0xE0},
      // Simple value (19, unassigned)
      {0xF3},
      // Simple value (24, reserved)
      {0xF8, 0x18},
      // Simple value (28, reserved)
      {0xF8, 0x1C},
      // Simple value (29, reserved)
      {0xF8, 0x1D},
      // Simple value (30, reserved)
      {0xF8, 0x1E},
      // Simple value (31, reserved)
      {0xF8, 0x1F},
      // Simple value (32, unassigned)
      {0xF8, 0x20},
      // Simple value (255, unassigned)
      {0xF8, 0xFF},
  };

  for (const auto& unsupported_simple_val : unsupported_simple_values) {
    SCOPED_TRACE(testing::Message()
                 << "testing unsupported cbor simple value  : "
                 << ::testing::PrintToString(unsupported_simple_val));

    Reader::DecoderError error_code;
    base::Optional<Value> cbor =
        Reader::Read(unsupported_simple_val, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::UNSUPPORTED_SIMPLE_VALUE);
  }
}

TEST(CBORReaderTest, TestSuperLongContentDontCrash) {
  static const std::vector<uint8_t> kTestCases[] = {
      // CBOR array of 0xffffffff length.
      {0x9b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
      // CBOR map of 0xffffffff pairs.
      {0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
  };
  for (const auto& test_case : kTestCases) {
    Reader::DecoderError error_code;
    base::Optional<Value> cbor = Reader::Read(test_case, &error_code);
    EXPECT_FALSE(cbor.has_value());
    EXPECT_EQ(error_code, Reader::DecoderError::INCOMPLETE_CBOR_DATA);
  }
}

TEST(CBORReaderTest, AllowInvalidUTF8) {
  static const uint8_t kInvalidUTF8[] = {
      // clang-format off
      0xa1,                    // map of length 1
        0x61, 'x',             // "x"
        0x81,                  // array of length 1
          0xa2,                // map of length 2
            0x61, 'y',         // "y"
            0x62, 0xe2, 0x80,  // invalid UTF-8 value
            0x61, 'z',         // "z"
            0x61, '.',         // "."
      // clang-format on
  };

  Reader::DecoderError error;
  Reader::Config config;
  config.error_code_out = &error;

  base::Optional<Value> cbor = Reader::Read(kInvalidUTF8, config);
  EXPECT_FALSE(cbor);
  EXPECT_EQ(Reader::DecoderError::INVALID_UTF8, error);

  cbor = Reader::Read(kInvalidUTF8, config);
  EXPECT_FALSE(cbor);
  EXPECT_EQ(Reader::DecoderError::INVALID_UTF8, error);

  config.allow_invalid_utf8 = true;

  cbor = Reader::Read(kInvalidUTF8, config);
  EXPECT_TRUE(cbor);
  EXPECT_EQ(Reader::DecoderError::CBOR_NO_ERROR, error);
  const cbor::Value& invalid_value = cbor->GetMap()
                                         .find(Value("x"))
                                         ->second.GetArray()[0]
                                         .GetMap()
                                         .find(Value("y"))
                                         ->second;
  ASSERT_TRUE(invalid_value.is_invalid_utf8());
  EXPECT_EQ(std::vector<uint8_t>({0xe2, 0x80}), invalid_value.GetInvalidUTF8());

  static const uint8_t kInvalidUTF8InMapKey[] = {
      // clang-format off
      0xa1,                    // map of length 1
        0x62, 0xe2, 0x80,      // invalid UTF-8 map key
        0x61, '.',             // "."
      // clang-format on
  };

  EXPECT_TRUE(config.allow_invalid_utf8);
  cbor = Reader::Read(kInvalidUTF8InMapKey, config);
  EXPECT_FALSE(cbor);
  EXPECT_EQ(Reader::DecoderError::INVALID_UTF8, error);
}

}  // namespace cbor
