*/
#include "cbor_encoding.h"
+#include "cbor_parsing.h"
#include "common.h"
#include "crypto/common.h"
#include "exception.h"
#include <webauthn-types.h>
#include <webauthn.h>
+using Exception::EncodingFailed;
+using Exception::Unknown;
+
namespace {
struct date {
const Hint GA = {'g', 'a'};
const Hint MC = {'m', 'c'};
+constexpr inline int64_t INT64_VALUES[] = {0,
+ 1,
+ 10,
+ 23,
+ 24,
+ 25,
+ 100,
+ 10000,
+ 1'000'000,
+ 10'000'000,
+ std::numeric_limits<int64_t>::max(),
+ std::numeric_limits<int64_t>::min(),
+ -1'000'000,
+ -10000,
+ -100,
+ -25,
+ -24,
+ -23,
+ -10,
+ -1};
+
+constexpr inline bool BOOL_VALUES[] = {true, false};
+
+const Buffer BYTE_STRING_VALUE = {0x83,
+ 0x03,
+ 0x6B,
+ 0x73,
+ 0x6F,
+ 0x6D,
+ 0x65,
+ 0x20,
+ 0x73,
+ 0x74,
+ 0x72,
+ 0x69,
+ 0x6E,
+ 0x67,
+ 0x83,
+ 0x04,
+ 0x05,
+ 0x06};
+
+constexpr inline std::string_view STRING_VIEW_VALUES[] = {
+ "Fusce", "congue", "maximus", "at", "lobortis", "Nulla", "feugiat",
+ "arcu", "quis", "arcu", "faucibus", "a", "tincidunt", "tellus",
+ "malesuada", "Nam", "vel", "commodo", "eros", "nec", "bibendum",
+ "est", "Fusce", "pulvinar", "mauris", "ac", "lorem", "sodales",
+ "eu", "pulvinar", "turpis", "maximus", "Quisque", "suscipit", "est",
+ "sed", "ante", "dignissim", "et", "finibus", "orci", "viverra"};
+
struct tm convertToTm(struct date &date)
{
struct tm ret;
buffer.size = 10;
ASSERT_THROW(map.AppendByteStringAt(0x04, buffer), Exception::InvalidParam);
}
+
+TEST(Cbor, MapInt64EncodingAndDecoding)
+{
+ Buffer buffer(78);
+ static constexpr size_t MAP_SIZE = std::extent_v<decltype(INT64_VALUES)>;
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(MAP_SIZE);
+ for (size_t i = 0; i < MAP_SIZE; i++)
+ EXPECT_NO_THROW(map.AppendInt64At(i, INT64_VALUES[i]));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ for (size_t i = 0; i < MAP_SIZE; i++)
+ EXPECT_EQ(parserMap.GetInt64At(i).value(), INT64_VALUES[i]);
+}
+
+TEST(Cbor, MapBoolEncodingAndDecoding)
+{
+ Buffer buffer(5);
+ static constexpr size_t MAP_SIZE = std::extent_v<decltype(BOOL_VALUES)>;
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(MAP_SIZE);
+ for (size_t i = 0; i < MAP_SIZE; i++)
+ EXPECT_NO_THROW(map.AppendBooleanAt(i, BOOL_VALUES[i]));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ for (size_t i = 0; i < MAP_SIZE; i++)
+ EXPECT_EQ(parserMap.GetBooleanAt(i).value(), BOOL_VALUES[i]);
+}
+
+TEST(Cbor, MapByteStringEncodingAndDecoding)
+{
+ Buffer buffer(21);
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(1);
+ EXPECT_NO_THROW(map.AppendByteStringAt(0, BYTE_STRING_VALUE));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ EXPECT_EQ(parserMap.GetByteStringAt(0).value(), BYTE_STRING_VALUE);
+
+ Buffer buffer2(21);
+ wauthn_const_buffer_s wauthnConstBuffer;
+ wauthnConstBuffer.data = BYTE_STRING_VALUE.data();
+ wauthnConstBuffer.size = BYTE_STRING_VALUE.size();
+ auto wauthnEncoder = CborEncoding::Encoder::Create(buffer2.data(), buffer2.size());
+ {
+ auto map = wauthnEncoder.OpenMap(1);
+ EXPECT_NO_THROW(map.AppendByteStringAt(1, wauthnConstBuffer));
+ }
+
+ EXPECT_EQ(wauthnEncoder.GetBufferSize(), buffer2.size());
+
+ auto wauthnParser = CborParsing::Parser::Create(buffer2.data(), buffer2.size());
+ auto wauthnParserMap = wauthnParser.EnterMap();
+
+ EXPECT_EQ(wauthnParserMap.GetByteStringAt(1), BYTE_STRING_VALUE);
+}
+
+TEST(Cbor, MapStringZEncodingAndDecoding)
+{
+ Buffer buffer(330);
+ const size_t MAP_SIZE = std::extent_v<decltype(STRING_VIEW_VALUES)>;
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(MAP_SIZE);
+ for (size_t i = 0; i < MAP_SIZE; i++)
+ EXPECT_NO_THROW(map.AppendTextStringZAt(i, STRING_VIEW_VALUES[i].data()));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ for (size_t i = 0; i < MAP_SIZE; i++)
+ EXPECT_EQ(parserMap.GetTextStringAt(i).value(), STRING_VIEW_VALUES[i]);
+}
+
+TEST(Cbor, ArrayStringEncodingAndDecoding)
+{
+ Buffer buffer(270);
+ static constexpr size_t ARRAY_SIZE = std::extent_v<decltype(STRING_VIEW_VALUES)>;
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto array = encoder.OpenArray(ARRAY_SIZE);
+ for (size_t i = 0; i < ARRAY_SIZE; i++)
+ EXPECT_NO_THROW(array.AppendTextString(STRING_VIEW_VALUES[i]));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserArray = parser.EnterArray();
+
+ for (size_t i = 0; i < ARRAY_SIZE; i++)
+ EXPECT_EQ(parserArray.GetTextString(), STRING_VIEW_VALUES[i]);
+}
+
+TEST(Cbor, MapOptionalTextStringEncodingAndDecoding)
+{
+ Buffer buffer(330);
+ static constexpr size_t MAP_SIZE = std::extent_v<decltype(STRING_VIEW_VALUES)>;
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(MAP_SIZE);
+ map.AppendOptionalTextStringZAt(-1, nullptr);
+ for (size_t i = 0; i < MAP_SIZE; i++)
+ EXPECT_NO_THROW(map.AppendOptionalTextStringZAt(i, STRING_VIEW_VALUES[i].data()));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ EXPECT_EQ(parserMap.GetTextStringAt(-1), std::nullopt);
+ for (size_t i = 0; i < MAP_SIZE; i++)
+ EXPECT_EQ(parserMap.GetTextStringAt(i).value(), STRING_VIEW_VALUES[i].data());
+}
+
+TEST(Cbor, EncodingToNullBuffer)
+{
+ std::vector<uint8_t> emptyBuffer(0);
+ ASSERT_THROW(CborEncoding::Encoder::Create(emptyBuffer.data(), emptyBuffer.size()), Unknown);
+}
+
+TEST(Cbor, EmptyStringEncoding)
+{
+ std::vector<uint8_t> buffer(3);
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(2);
+ ASSERT_THROW(map.AppendTextStringZAt(1, nullptr), Unknown);
+ ASSERT_NO_THROW(map.AppendTextStringZAt(2, ""));
+ }
+}
+
+TEST(Cbor, MapDecodingValuesOfDifferentTypeThanExpected)
+{
+ Buffer buffer(24);
+ static constexpr bool BOOL_VALUE = true;
+ static constexpr int64_t INT64T_VALUE = 117;
+ static constexpr char STRING_VALUE[] = "characters";
+ const Buffer BYTE_STRING_VALUE = {0x86, 0x33, 0x45, 0x17};
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(4);
+ EXPECT_NO_THROW(map.AppendBooleanAt(0, BOOL_VALUE));
+ EXPECT_NO_THROW(map.AppendInt64At(1, INT64T_VALUE));
+ EXPECT_NO_THROW(map.AppendTextStringZAt(2, STRING_VALUE));
+ EXPECT_NO_THROW(map.AppendByteStringAt(3, BYTE_STRING_VALUE));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ ASSERT_THROW(parserMap.GetByteStringAt(0), Unknown);
+ EXPECT_EQ(parserMap.GetTextStringAt(1), std::nullopt);
+ EXPECT_EQ(parserMap.GetInt64At(2), std::nullopt);
+ EXPECT_EQ(parserMap.GetUint64At(2), std::nullopt);
+ EXPECT_EQ(parserMap.GetBooleanAt(3), std::nullopt);
+}
+
+TEST(Cbor, DecodingMapWithNotSortedKeysFails)
+{
+ Buffer buffer(19);
+ static constexpr int64_t INT64T_VALUE = 117;
+ static constexpr char STRING_VALUE[] = "text";
+ const Buffer BYTE_STRING_VALUE = {0x86, 0x33, 0x45, 0x17};
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(3);
+ EXPECT_NO_THROW(map.AppendInt64At(0x66, INT64T_VALUE));
+ EXPECT_NO_THROW(map.AppendTextStringZAt(0x33, STRING_VALUE));
+ EXPECT_NO_THROW(map.AppendByteStringAt(0x24, BYTE_STRING_VALUE));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ ASSERT_THROW(CborParsing::Parser::Create(buffer.data(), buffer.size()), Unknown);
+}
+
+TEST(Cbor, DecodingMapWithDuplicatedKeysFails)
+{
+ Buffer buffer(7);
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(2);
+ EXPECT_NO_THROW(map.AppendInt64At(0x12, 111));
+ EXPECT_NO_THROW(map.AppendInt64At(0x12, 199));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ ASSERT_THROW(CborParsing::Parser::Create(buffer.data(), buffer.size()), Unknown);
+}
+
+TEST(Cbor, MapWithKeysOfDifferentTypesEncodingAndDecoding)
+{
+ Buffer buffer(15);
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(4);
+ EXPECT_NO_THROW(map.AppendInt64At(1, 11));
+ EXPECT_NO_THROW(map.AppendInt64At(2, 12));
+ EXPECT_NO_THROW(map.AppendInt64At("one", 13));
+ EXPECT_NO_THROW(map.AppendInt64At("two", 14));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ EXPECT_EQ(parserMap.GetInt64At(1), 11);
+ EXPECT_EQ(parserMap.GetInt64At(2), 12);
+ EXPECT_EQ(parserMap.GetInt64At("one"), 13);
+ EXPECT_EQ(parserMap.GetInt64At("two"), 14);
+}
+
+TEST(Cbor, ReadingMapOutOfOrder)
+{
+ Buffer buffer(15);
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(4);
+ EXPECT_NO_THROW(map.AppendInt64At(1, 15));
+ EXPECT_NO_THROW(map.AppendInt64At(2, 16));
+ EXPECT_NO_THROW(map.AppendInt64At("one", 13));
+ EXPECT_NO_THROW(map.AppendInt64At("two", 14));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ EXPECT_EQ(parserMap.GetInt64At(1), 15);
+ EXPECT_EQ(parserMap.GetInt64At(2), 16);
+ EXPECT_EQ(parserMap.GetInt64At("two"), 14);
+ EXPECT_EQ(parserMap.GetInt64At("one"), std::nullopt);
+}
+
+TEST(Cbor, DecodingMissingMapKeys)
+{
+ Buffer buffer(4);
+ static constexpr int64_t INT64T_VALUE = 117;
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(1);
+ EXPECT_NO_THROW(map.AppendInt64At(1, INT64T_VALUE));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ EXPECT_EQ(parserMap.GetInt64At(3), std::nullopt);
+}
+
+TEST(Cbor, MapDecodingDifferentKeyType)
+{
+ Buffer buffer(11);
+ static constexpr int64_t INT64T_VALUE = 127;
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(1);
+ EXPECT_NO_THROW(map.AppendInt64At("passkey", INT64T_VALUE));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ EXPECT_EQ(parserMap.GetInt64At(0), std::nullopt);
+ EXPECT_EQ(parserMap.GetInt64At("passkey"), INT64T_VALUE);
+}
+
+TEST(CborParsing, SortedMapPeekAndLocateKey)
+{
+ Buffer buffer(9);
+ static constexpr int KEY = 16;
+ static constexpr int VALUE = 16;
+ static constexpr std::string_view TEXT = "text";
+
+ CborEncoder encoder, mapEncoder;
+ ASSERT_NO_THROW(cbor_encoder_init(&encoder, buffer.data(), buffer.size(), 0));
+ ASSERT_NO_THROW(cbor_encoder_create_map(&encoder, &mapEncoder, 2));
+ ASSERT_NO_THROW(cbor_encode_int(&mapEncoder, KEY));
+ ASSERT_NO_THROW(cbor_encode_text_string(&mapEncoder, TEXT.data(), TEXT.size()));
+ ASSERT_NO_THROW(cbor_encode_null(&mapEncoder));
+ ASSERT_NO_THROW(cbor_encode_int(&mapEncoder, VALUE));
+ ASSERT_NO_THROW(cbor_encoder_close_container(&encoder, &mapEncoder));
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto map = parser.EnterMap();
+ EXPECT_EQ(std::get<int64_t>(map.PeekKey()), 16);
+ EXPECT_EQ(map.GetTextStringAt(16), TEXT);
+ ASSERT_THROW(map.PeekKey(), Unknown);
+ EXPECT_EQ(map.GetInt64At("test"), std::nullopt);
+ ASSERT_THROW(map.PeekKey(), Unknown);
+}
+
+TEST(Cbor, SkippingUnknownKeysWhileDecodingMap)
+{
+ Buffer buffer(23);
+ static constexpr int64_t INT64T_VALUE = 64;
+ static constexpr char STRING_VALUE[] = "string_value";
+ const Buffer BYTE_STRING_VALUE = {0x27, 0x48, 0x75};
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(3);
+ EXPECT_NO_THROW(map.AppendInt64At(0x00, INT64T_VALUE));
+ EXPECT_NO_THROW(map.AppendTextStringZAt(0x02, STRING_VALUE));
+ EXPECT_NO_THROW(map.AppendByteStringAt(0x03, BYTE_STRING_VALUE));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ EXPECT_EQ(parserMap.GetInt64At(0x64), std::nullopt);
+ EXPECT_EQ(parserMap.GetTextStringAt("key"), std::nullopt);
+
+ EXPECT_EQ(parserMap.GetUint64At(0x00), INT64T_VALUE);
+ EXPECT_EQ(parserMap.GetTextStringAt(0x02), STRING_VALUE);
+ EXPECT_EQ(parserMap.GetByteStringAt(0x03), BYTE_STRING_VALUE);
+}
+
+TEST(Cbor, DecodingGarbageAtEnd)
+{
+ Buffer buffer(4);
+ static constexpr int64_t VALUE = 24;
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(1);
+ EXPECT_NO_THROW(map.AppendInt64At(0x00, VALUE));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+ buffer.emplace_back(0x00);
+
+ ASSERT_THROW(CborParsing::Parser::Create(buffer.data(), buffer.size()), Unknown);
+}
+
+TEST(Cbor, DecodingMapUnknownIntKey)
+{
+ Buffer buffer(10);
+ const std::vector<int64_t> VALUES = {17, 18, 19, 40};
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(VALUES.size());
+ for (size_t i = 0; i < VALUES.size(); i++)
+ EXPECT_NO_THROW(map.AppendInt64At(i, VALUES[i]));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ ASSERT_NO_THROW(parserMap.EnterMapAt(5));
+ EXPECT_EQ(parserMap.GetInt64At(5), std::nullopt);
+}
+
+TEST(Cbor, DecodingMapNonexistentKeys)
+{
+ Buffer buffer(26);
+ static constexpr int16_t INT64T_VALUES = -128;
+ static constexpr u_int64_t UINT64T_VALUES = 128;
+ static constexpr bool BOOL_VALUE = false;
+ static constexpr char STRING_VALUE[] = "fourtyfour";
+ const Buffer BYTE_STRING_VALUE = {0x08, 0x10, 0x12};
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(5);
+ EXPECT_NO_THROW(map.AppendInt64At(0x00, INT64T_VALUES));
+ EXPECT_NO_THROW(map.AppendInt64At(0x01, UINT64T_VALUES));
+ EXPECT_NO_THROW(map.AppendBooleanAt(0x02, BOOL_VALUE));
+ EXPECT_NO_THROW(map.AppendTextStringZAt(0x03, STRING_VALUE));
+ EXPECT_NO_THROW(map.AppendByteStringAt(0x04, BYTE_STRING_VALUE));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ EXPECT_EQ(parserMap.GetInt64At(0x08), std::nullopt);
+ EXPECT_EQ(parserMap.GetInt64At(0x00), INT64T_VALUES);
+
+ EXPECT_EQ(parserMap.GetUint64At(0x16), std::nullopt);
+ EXPECT_EQ(parserMap.GetUint64At(0x01), UINT64T_VALUES);
+
+ EXPECT_EQ(parserMap.GetBooleanAt(0x32), std::nullopt);
+ EXPECT_EQ(parserMap.GetBooleanAt(0x02), BOOL_VALUE);
+
+ EXPECT_EQ(parserMap.GetTextStringAt(0x64), std::nullopt);
+ EXPECT_EQ(parserMap.GetTextStringAt(0x03), STRING_VALUE);
+
+ EXPECT_EQ(parserMap.GetByteStringAt(0x128), std::nullopt);
+ EXPECT_EQ(parserMap.GetByteStringAt(0x04), BYTE_STRING_VALUE);
+}
+
+TEST(Cbor, NestedStructuresEncodingAndDecoding1)
+{
+ Buffer buffer(62);
+ const std::vector<int64_t> INT64T_VALUES = {17, 18, 19, 40};
+ const std::vector<std::string_view> STRING_VALUES = {"Lorem", "ipsum", "dolores"};
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(3);
+ {
+ auto firstArray = map.OpenArrayAt(0, INT64T_VALUES.size());
+ for (auto x : INT64T_VALUES)
+ EXPECT_NO_THROW(firstArray.AppendInt64(x));
+ }
+
+ {
+ auto firstMap = map.OpenMapAt(1, STRING_VALUES.size());
+ for (size_t i = 0; i < STRING_VALUES.size(); i++)
+ EXPECT_NO_THROW(firstMap.AppendTextStringZAt("text_" + std::to_string(i),
+ STRING_VALUES[i].data()));
+ }
+
+ {
+ auto secondMap = map.OpenMapAt(2, 2);
+ EXPECT_NO_THROW(secondMap.AppendBooleanAt(3, true));
+
+ auto secondArray = secondMap.OpenArrayAt(4, INT64T_VALUES.size());
+ for (auto x : INT64T_VALUES)
+ EXPECT_NO_THROW(secondArray.AppendInt64(x));
+ }
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ {
+ auto firstArrayParser = parserMap.EnterArrayAt(0).value();
+ for (auto x : INT64T_VALUES)
+ EXPECT_EQ(firstArrayParser.GetInt64(), x);
+ ASSERT_THROW(firstArrayParser.GetInt64(), Unknown);
+ }
+
+ {
+ auto firstMapParser = parserMap.EnterMapAt(1).value();
+ EXPECT_EQ(firstMapParser.GetTextStringAt("text_0"), STRING_VALUES[0]);
+ EXPECT_EQ(firstMapParser.GetTextStringAt("text_1"), STRING_VALUES[1]);
+ EXPECT_EQ(firstMapParser.GetTextStringAt("text_2"), STRING_VALUES[2]);
+ }
+
+ {
+ auto secondMapParser = parserMap.EnterMapAt(2).value();
+ EXPECT_EQ(secondMapParser.GetBooleanAt(3), true);
+
+ auto secondArrayParser = secondMapParser.EnterArrayAt(4).value();
+ for (auto x : INT64T_VALUES)
+ EXPECT_EQ(secondArrayParser.GetInt64(), x);
+ ASSERT_THROW(secondArrayParser.GetInt64(), Unknown);
+ }
+}
+
+TEST(Cbor, NestedStructuresEncodingAndDecoding2)
+{
+ Buffer buffer(56);
+ const std::vector<int64_t> INT64T_VALUES = {33, 11, 93, 39};
+ const std::vector<std::string_view> STRING_VALUES = {"edoras", "nimrais", "dimholt"};
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto array = encoder.OpenArray(6);
+ for (auto x : INT64T_VALUES)
+ EXPECT_NO_THROW(array.AppendInt64(x));
+
+ {
+ auto nestedMap = array.OpenMap(STRING_VALUES.size() + 1);
+ for (size_t i = 0; i < STRING_VALUES.size(); i++)
+ EXPECT_NO_THROW(nestedMap.AppendTextStringZAt(i + 1, STRING_VALUES[i].data()));
+
+ auto nestedArray = nestedMap.OpenArrayAt(4, INT64T_VALUES.size());
+ for (auto int64tValue : INT64T_VALUES)
+ EXPECT_NO_THROW(nestedArray.AppendInt64(int64tValue));
+ }
+
+ {
+ auto lastArray = array.OpenMap(INT64T_VALUES.size());
+ for (size_t i = 0; i < INT64T_VALUES.size(); i++)
+ EXPECT_NO_THROW(lastArray.AppendInt64At(i + 1, INT64T_VALUES[i]));
+ }
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserArray = parser.EnterArray();
+
+ for (auto x : INT64T_VALUES)
+ EXPECT_EQ(parserArray.GetInt64(), x);
+
+ {
+ auto firstMapParser = parserArray.EnterMap();
+ EXPECT_EQ(firstMapParser.GetTextStringAt(1), STRING_VALUES[0]);
+ EXPECT_EQ(firstMapParser.GetTextStringAt(2), STRING_VALUES[1]);
+ EXPECT_EQ(firstMapParser.GetTextStringAt(3), STRING_VALUES[2]);
+
+ auto nestedArrayParser = firstMapParser.EnterArrayAt(4).value();
+ for (auto x : INT64T_VALUES)
+ EXPECT_EQ(nestedArrayParser.GetInt64(), x);
+ }
+
+ {
+ auto secondMapParser = parserArray.EnterMap();
+ EXPECT_EQ(secondMapParser.GetInt64At(1), INT64T_VALUES[0]);
+ EXPECT_EQ(secondMapParser.GetInt64At(2), INT64T_VALUES[1]);
+ EXPECT_EQ(secondMapParser.GetInt64At(3), INT64T_VALUES[2]);
+ EXPECT_EQ(secondMapParser.GetInt64At(4), INT64T_VALUES[3]);
+ }
+}
+
+TEST(Cbor, DifferentTypesInArrayEncodingAndDecoding)
+{
+ Buffer buffer(12);
+ const std::vector<int64_t> INT64T_VALUES = {17, 22};
+ static constexpr std::string_view STRING_VALUE = "testing";
+ static constexpr bool BOOL_VALUE = false;
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto array = encoder.OpenArray(4);
+ EXPECT_NO_THROW(array.AppendInt64(INT64T_VALUES[0]));
+ EXPECT_NO_THROW(array.AppendTextString(STRING_VALUE.data()));
+ EXPECT_NO_THROW(array.AppendBoolean(BOOL_VALUE));
+ EXPECT_NO_THROW(array.AppendInt64(INT64T_VALUES[1]));
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserArray = parser.EnterArray();
+
+ EXPECT_EQ(parserArray.GetInt64(), INT64T_VALUES[0]);
+ EXPECT_EQ(parserArray.GetTextString(), STRING_VALUE);
+ EXPECT_EQ(parserArray.GetBoolean(), BOOL_VALUE);
+ EXPECT_EQ(parserArray.GetInt64(), INT64T_VALUES[1]);
+}
+
+TEST(Cbor, SkippingUndecodedEntriesUponContainerClose)
+{
+ Buffer buffer(62);
+ const Buffer BYTE_STRING = {0x063};
+ const std::vector<int64_t> INT64T_VALUES = {94, 38};
+ const std::vector<std::string_view> STRING_VALUES = {"restless", "agitated"};
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size());
+ {
+ auto map = encoder.OpenMap(5);
+ map.AppendInt64At(1, INT64T_VALUES[0]);
+ {
+ auto nestedMap = map.OpenMapAt(2, 3);
+ EXPECT_NO_THROW(nestedMap.AppendInt64At(1, INT64T_VALUES[1]));
+ EXPECT_NO_THROW(nestedMap.AppendTextStringZAt(2, STRING_VALUES[0].data()));
+ EXPECT_NO_THROW(nestedMap.AppendByteStringAt(3, BYTE_STRING));
+ }
+
+ map.AppendTextStringZAt(3, STRING_VALUES[1].data());
+ {
+ auto array = map.OpenArrayAt(4, 3);
+ array.AppendInt64(INT64T_VALUES[0]);
+ {
+ auto nestedArray = array.OpenArray(3);
+ EXPECT_NO_THROW(nestedArray.AppendInt64(INT64T_VALUES[1]));
+ EXPECT_NO_THROW(nestedArray.AppendTextStringZ(STRING_VALUES[0].data()));
+ EXPECT_NO_THROW(nestedArray.AppendByteString(BYTE_STRING));
+ }
+
+ array.AppendTextStringZ(STRING_VALUES[1].data());
+ }
+
+ map.AppendInt64At(5, INT64T_VALUES[1]);
+ }
+
+ EXPECT_EQ(encoder.GetBufferSize(), buffer.size());
+
+ auto parser = CborParsing::Parser::Create(buffer.data(), buffer.size());
+ auto parserMap = parser.EnterMap();
+
+ {
+ auto nestedMapParser = parserMap.EnterMapAt(2);
+ EXPECT_EQ(nestedMapParser.value().GetInt64At(1), INT64T_VALUES[1]);
+ }
+
+ EXPECT_EQ(parserMap.GetTextStringAt(3), STRING_VALUES[1]);
+
+ {
+ auto parserArray = parserMap.EnterArrayAt(4);
+ EXPECT_EQ(parserArray.value().GetInt64(), INT64T_VALUES[0]);
+
+ auto nestedArrayParser = parserArray.value().EnterArray();
+ EXPECT_EQ(nestedArrayParser.GetInt64(), INT64T_VALUES[1]);
+ }
+
+ EXPECT_EQ(parserMap.GetInt64At(5), INT64T_VALUES[1]);
+}
+
+#define TEST_CBOR_ENCODING(name, expectedValue, containerType, appendStatement) \
+ TEST(CborEncoding, name) \
+ { \
+ static constexpr char rawData[] = expectedValue; \
+ static constexpr auto expectedData = std::string_view{rawData, sizeof(rawData) - 1}; \
+ Buffer buffer(expectedData.size()); \
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size()); \
+ { \
+ containerType; \
+ appendStatement; \
+ } \
+ EXPECT_EQ(encoder.GetBufferSize(), expectedData.size()); \
+ EXPECT_EQ(std::string_view(reinterpret_cast<const char *>(buffer.data()), buffer.size()), \
+ expectedData); \
+ }
+
+#define TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(name, expectedSize, containerType, appendStatement) \
+ TEST(CborEncoding, name) \
+ { \
+ Buffer buffer(expectedSize); \
+ auto encoder = CborEncoding::Encoder::Create(buffer.data(), buffer.size()); \
+ { \
+ containerType; \
+ appendStatement; \
+ } \
+ }
+
+#define TEST_CBOR_PARSING(name, expectedValue, containerType, assertStatement) \
+ TEST(CborParsing, name) \
+ { \
+ static constexpr auto data = std::string_view{expectedValue}; \
+ auto parser = CborParsing::Parser::Create(reinterpret_cast<const uint8_t *>(data.data()), \
+ data.size()); \
+ containerType; \
+ assertStatement; \
+ }
+
+#define TEST_CBOR_PARSING_PREMATURE_END(name, expectedValue, parserStatement) \
+ TEST(CborParsing, name) \
+ { \
+ static constexpr auto data = std::string_view{expectedValue}; \
+ parserStatement; \
+ }
+
+// AppendTextStringZ tests
+TEST_CBOR_ENCODING(ContainerNullInAppendTextStringZ,
+ "\x81",
+ auto array = encoder.OpenArray(1),
+ ASSERT_THROW(array.AppendTextStringZ(nullptr), Unknown))
+TEST_CBOR_ENCODING(ContainerEmptyStringInAppendTextStringZ,
+ "\x81\x60",
+ auto array = encoder.OpenArray(1),
+ array.AppendTextStringZ(""))
+TEST_CBOR_ENCODING(ContainerStringInAppendTextStringZ,
+ "\x81\x64\x74\x65\x78\x74",
+ auto array = encoder.OpenArray(1),
+ array.AppendTextStringZ("text"))
+TEST_CBOR_ENCODING(ContainerEmptyStringInAppendTextString,
+ "\x81\x60",
+ auto array = encoder.OpenArray(1),
+ array.AppendTextString(""))
+TEST_CBOR_ENCODING(ContainerStringInAppendTextString,
+ "\x81\x64\x74\x65\x78\x74",
+ auto array = encoder.OpenArray(1),
+ array.AppendTextString("text"))
+
+// AppendInt64 tests
+TEST_CBOR_ENCODING(ContainerMinInt64ValueInAppendInt64,
+ "\x81\x3B\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ auto array = encoder.OpenArray(1),
+ array.AppendInt64(std::numeric_limits<int64_t>::min()))
+TEST_CBOR_ENCODING(ContainerMaxInt64ValueInAppendInt64,
+ "\x81\x1B\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ auto array = encoder.OpenArray(1),
+ array.AppendInt64(std::numeric_limits<int64_t>::max()))
+TEST_CBOR_ENCODING(ContainerNegativeValueInAppendInt64,
+ "\x81\x20",
+ auto array = encoder.OpenArray(1),
+ array.AppendInt64(-1))
+TEST_CBOR_ENCODING(ContainerZeroValueInAppendInt64,
+ "\x81\x00",
+ auto array = encoder.OpenArray(1),
+ array.AppendInt64(0))
+
+// AppendByteString tests
+const unsigned char wauthnChars[] = {0x83, 0x03, 0x6B};
+wauthn_const_buffer_s wauthnConstBuffer = {wauthnChars, sizeof(wauthnChars)};
+
+TEST_CBOR_ENCODING(ContainerEmptyStringInBufferTypeAppendByteString,
+ "\x81\x40",
+ auto array = encoder.OpenArray(1),
+ array.AppendByteString(Buffer{}))
+TEST_CBOR_ENCODING(ContainerByteValueInBufferTypeAppendByteString,
+ "\x81\x43\x83\x03\x6B",
+ auto array = encoder.OpenArray(1),
+ array.AppendByteString(Buffer{0x83, 0x03, 0x6B}))
+TEST_CBOR_ENCODING(ContainerEmptyStringInWauthnBufferTypeAppendByteString,
+ "\x81\x40",
+ auto array = encoder.OpenArray(1),
+ array.AppendByteString(wauthn_const_buffer_s{}))
+TEST_CBOR_ENCODING(ContainerByteValueInWauthnBufferTypeAppendByteString,
+ "\x81\x43\x83\x03\x6B",
+ auto array = encoder.OpenArray(1),
+ array.AppendByteString(wauthnConstBuffer))
+
+// AppendBoolean tests
+TEST_CBOR_ENCODING(ContainerByteValueInAppendBooleanFalse,
+ "\x81\xF4",
+ auto array = encoder.OpenArray(1),
+ array.AppendBoolean(false))
+TEST_CBOR_ENCODING(ContainerByteValueInAppendBooleanTrue,
+ "\x81\xF5",
+ auto array = encoder.OpenArray(1),
+ array.AppendBoolean(true))
+
+// AppendByteStringAt(const Buffer&) tests
+TEST_CBOR_ENCODING(SortedMapIntKeyInAppendByteStringAtOfBuffer,
+ "\xa1\x07\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt(7, Buffer{0x83, 0x03, 0x6B}))
+TEST_CBOR_ENCODING(SortedMapCStrKeyInAppendByteStringAtOfBuffer,
+ "\xa1\x63\x61\x62\x63\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt("abc", Buffer{0x83, 0x03, 0x6B}))
+TEST_CBOR_ENCODING(SortedMapEmptyCStrKeyInAppendByteStringAtOfBuffer,
+ "\xa1\x60\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt("", Buffer{0x83, 0x03, 0x6B}))
+TEST_CBOR_ENCODING(SortedMapEmptyValueInAppendByteStringAtOfBuffer,
+ "\xa1\x63\x61\x62\x63\x40",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt("abc", Buffer{}))
+TEST_CBOR_ENCODING(SortedMapStringKeyInAppendByteStringAtOfBuffer,
+ "\xa1\x63\x61\x62\x63\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt(std::string_view{"abc"}, Buffer{0x83, 0x03, 0x6B}))
+TEST_CBOR_ENCODING(SortedMapEmptyStringKeyInAppendByteStringAtOfBuffer,
+ "\xa1\x60\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt(std::string_view{""}, Buffer{0x83, 0x03, 0x6B}))
+TEST_CBOR_ENCODING(SortedMapNullKeyInAppendByteStringAtOfBuffer,
+ "\xa1",
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendByteStringAt(nullptr, Buffer{0x03}), Unknown))
+
+// AppendByteStringAt(const wauthn_const_buffer&) tests
+TEST_CBOR_ENCODING(SortedMapIntKeyInAppendByteStringAtOfWauthnBuffer,
+ "\xa1\x07\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt(7, wauthnConstBuffer))
+TEST_CBOR_ENCODING(SortedMapCStrKeyInAppendByteStringAtOfWauthnBuffer,
+ "\xa1\x63\x61\x62\x63\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt("abc", wauthnConstBuffer))
+TEST_CBOR_ENCODING(SortedMapEmptyCStrKeyInAppendByteStringAtOfWauthnBuffer,
+ "\xa1\x60\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt("", wauthnConstBuffer))
+TEST_CBOR_ENCODING(SortedMapEmptyValueInAppendByteStringAtOfWauthnBuffer,
+ "\xa1\x63\x61\x62\x63\x40",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt("abc", wauthn_const_buffer_s{}))
+TEST_CBOR_ENCODING(SortedMapStringKeyInAppendByteStringAtOfWauthnBuffer,
+ "\xa1\x63\x61\x62\x63\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt(std::string_view{"abc"}, wauthnConstBuffer))
+TEST_CBOR_ENCODING(SortedMapEmptyStringKeyAppendByteStringAtOfWauthnBuffer,
+ "\xa1\x60\x43\x83\x03\x6B",
+ auto map = encoder.OpenMap(1),
+ map.AppendByteStringAt(std::string_view{""}, wauthnConstBuffer))
+TEST_CBOR_ENCODING(SortedMapNullKeyInAppendByteStringAtOfWauthnBuffer,
+ "\xa1",
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendByteStringAt(nullptr, wauthnConstBuffer), Unknown))
+
+// AppendTextStringZAt tests
+TEST_CBOR_ENCODING(SortedMapIntKeyInAppendTextStringZAt,
+ "\xa1\x07\x63\x61\x62\x63",
+ auto map = encoder.OpenMap(1),
+ map.AppendTextStringZAt(7, "abc"))
+TEST_CBOR_ENCODING(SortedMapCStrKeyInAppendTextStringZAt,
+ "\xa1\x63\x61\x62\x63\x63\x78\x79\x7A",
+ auto map = encoder.OpenMap(1),
+ map.AppendTextStringZAt("abc", "xyz"))
+TEST_CBOR_ENCODING(SortedMapEmptyCStrKeyInAppendTextStringZAt,
+ "\xa1\x60\x63\x78\x79\x7A",
+ auto map = encoder.OpenMap(1),
+ map.AppendTextStringZAt("", "xyz"))
+TEST_CBOR_ENCODING(SortedMapEmptyStringValueInAppendTextStringZAt,
+ "\xa1\x63\x61\x62\x63\x60",
+ auto map = encoder.OpenMap(1),
+ map.AppendTextStringZAt("abc", ""))
+TEST_CBOR_ENCODING(SortedMapNullStringValueInAppendTextStringZAt,
+ "\xa1",
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendTextStringZAt("abc", nullptr), Unknown))
+TEST_CBOR_ENCODING(SortedMapStringKeyInAppendTextStringZAt,
+ "\xa1\x63\x61\x62\x63\x63\x61\x62\x63",
+ auto map = encoder.OpenMap(1),
+ map.AppendTextStringZAt(std::string_view{"abc"}, "abc"))
+TEST_CBOR_ENCODING(SortedMapEmptyStringKeyInAppendTextStringZAt,
+ "\xa1\x60\x63\x61\x62\x63",
+ auto map = encoder.OpenMap(1),
+ map.AppendTextStringZAt(std::string_view{""}, "abc"))
+TEST_CBOR_ENCODING(SortedMapNullKeyInAppendAppendTextStringZAt,
+ "\xa1",
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendTextStringZAt(nullptr, "abc"), Unknown))
+
+// AppendOptionalTextStringZAt tests
+TEST_CBOR_ENCODING(SortedMapIntKeyInAppendOptionalTextStringZAt,
+ "\xa1\x07\x63\x61\x62\x63",
+ auto map = encoder.OpenMap(1),
+ map.AppendOptionalTextStringZAt(7, "abc"))
+TEST_CBOR_ENCODING(SortedMapCStrKeyInAppendOptionalTextStringZAt,
+ "\xa1\x63\x61\x62\x63\x63\x78\x79\x7A",
+ auto map = encoder.OpenMap(1),
+ map.AppendOptionalTextStringZAt("abc", "xyz"))
+TEST_CBOR_ENCODING(SortedMapEmptyCStrKeyInAppendOptionalTextStringZAt,
+ "\xa1\x60\x63\x78\x79\x7A",
+ auto map = encoder.OpenMap(1),
+ map.AppendOptionalTextStringZAt("", "xyz"))
+TEST_CBOR_ENCODING(SortedMapEmptyStringValueInAppendOptionalTextStringZAt,
+ "\xa1\x63\x61\x62\x63\x60",
+ auto map = encoder.OpenMap(1),
+ map.AppendOptionalTextStringZAt("abc", ""))
+TEST_CBOR_ENCODING(SortedMapNullStringValueInAppendOptionalTextStringZAt,
+ "\xa1",
+ auto map = encoder.OpenMap(1),
+ map.AppendOptionalTextStringZAt("abc", nullptr))
+TEST_CBOR_ENCODING(SortedMapStringKeyInAppendOptionalTextStringZAt,
+ "\xa1\x63\x61\x62\x63\x63\x78\x79\x7A",
+ auto map = encoder.OpenMap(1),
+ map.AppendOptionalTextStringZAt(std::string_view{"abc"}, "xyz"))
+TEST_CBOR_ENCODING(SortedMapEmptyStringKeyInAppendOptionalTextStringZAt,
+ "\xa1\x60\x63\x78\x79\x7A",
+ auto map = encoder.OpenMap(1),
+ map.AppendOptionalTextStringZAt(std::string_view{""}, "xyz"))
+TEST_CBOR_ENCODING(SortedMapNullKeyInAppendOptionalTextStringZAt,
+ "\xa1",
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendOptionalTextStringZAt(nullptr, "abc"), Unknown))
+
+// AppendInt64At tests
+TEST_CBOR_ENCODING(SortedMapIntKeyInAppendInt64At,
+ "\xa1\x07\x07",
+ auto map = encoder.OpenMap(1),
+ map.AppendInt64At(7, 7))
+TEST_CBOR_ENCODING(SortedMapCStrKeyInAppendInt64At,
+ "\xa1\x63\x61\x62\x63\x07",
+ auto map = encoder.OpenMap(1),
+ map.AppendInt64At("abc", 7))
+TEST_CBOR_ENCODING(SortedMapEmptyCStrKeyInAppendInt64At,
+ "\xa1\x60\x07",
+ auto map = encoder.OpenMap(1),
+ map.AppendInt64At("", 7))
+TEST_CBOR_ENCODING(SortedMapMinInt64ValueInAppendInt64At,
+ "\xa1\x07\x3B\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ auto map = encoder.OpenMap(1),
+ map.AppendInt64At(7, std::numeric_limits<int64_t>::min()))
+TEST_CBOR_ENCODING(SortedMapMaxInt64ValueInAppendInt64At,
+ "\xa1\x07\x1B\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ auto map = encoder.OpenMap(1),
+ map.AppendInt64At(7, std::numeric_limits<int64_t>::max()))
+TEST_CBOR_ENCODING(SortedMapZeroValueInAppendInt64At,
+ "\xa1\x02\x00",
+ auto map = encoder.OpenMap(1),
+ map.AppendInt64At(2, 0))
+TEST_CBOR_ENCODING(SortedMapStringKeyInAppendInt64At,
+ "\xa1\x63\x61\x62\x63\x07",
+ auto map = encoder.OpenMap(1),
+ map.AppendInt64At(std::string_view{"abc"}, 7))
+TEST_CBOR_ENCODING(SortedMapEmptyStringKeyInAppendInt64At,
+ "\xa1\x60\x07",
+ auto map = encoder.OpenMap(1),
+ map.AppendInt64At(std::string_view{""}, 7))
+TEST_CBOR_ENCODING(SortedMapNullKeyInAppendInt64At,
+ "\xa1",
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendInt64At(nullptr, 7), Unknown))
+
+// AppendBooleanAt tests
+TEST_CBOR_ENCODING(SortedMapIntKeyInAppendBooleanAt,
+ "\xa1\x07\xF5",
+ auto map = encoder.OpenMap(1),
+ map.AppendBooleanAt(7, true))
+TEST_CBOR_ENCODING(SortedMapCStrKeyInAppendBooleanAt,
+ "\xa1\x63\x61\x62\x63\xF5",
+ auto map = encoder.OpenMap(1),
+ map.AppendBooleanAt("abc", true))
+TEST_CBOR_ENCODING(SortedMapEmptyCStrKeyInAppendBooleanAt,
+ "\xa1\x60\xF5",
+ auto map = encoder.OpenMap(1),
+ map.AppendBooleanAt("", true))
+TEST_CBOR_ENCODING(SortedMapTrueValueInAppendBooleanAt,
+ "\xa1\x07\xF5",
+ auto map = encoder.OpenMap(1),
+ map.AppendBooleanAt(7, true))
+TEST_CBOR_ENCODING(SortedMapFalseValueInAppendBooleanAt,
+ "\xa1\x02\xF4",
+ auto map = encoder.OpenMap(1),
+ map.AppendBooleanAt(2, false))
+TEST_CBOR_ENCODING(SortedMapStringKeyInAppendBooleanAt,
+ "\xa1\x63\x61\x62\x63\xF5",
+ auto map = encoder.OpenMap(1),
+ map.AppendBooleanAt(std::string_view{"abc"}, true))
+TEST_CBOR_ENCODING(SortedMapEmptyStringKeyInAppendBooleanAt,
+ "\xa1\x60\xF5",
+ auto map = encoder.OpenMap(1),
+ map.AppendBooleanAt(std::string_view{""}, true))
+TEST_CBOR_ENCODING(SortedMapNullKeyInAppendBooleanAt,
+ "\xa1",
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendBooleanAt(nullptr, true), Unknown))
+
+// Too short buffer array encoding tests
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInContainerAppendTextStringZ,
+ 2 - 1,
+ auto array = encoder.OpenArray(1),
+ EXPECT_THROW(array.AppendTextStringZ(""), EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInContainerAppendTextString,
+ 2 - 1,
+ auto array = encoder.OpenArray(1),
+ EXPECT_THROW(array.AppendTextString(""), EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInContainerAppendInt64,
+ 2 - 1,
+ auto array = encoder.OpenArray(1),
+ EXPECT_THROW(array.AppendInt64(0), EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInContainerAppendByteStringOfBuffer,
+ 2 - 1,
+ auto array = encoder.OpenArray(1),
+ EXPECT_THROW(array.AppendByteString(Buffer{}), EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInContainerAppendBoolean,
+ 2 - 1,
+ auto array = encoder.OpenArray(1),
+ EXPECT_THROW(array.AppendBoolean(true), EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInContainerAppendByteStringOfWauthnBuffer,
+ 2 - 1,
+ auto array = encoder.OpenArray(1),
+ EXPECT_THROW(array.AppendByteString(wauthn_const_buffer_s{}),
+ EncodingFailed))
+
+// Too short buffer map encoding tests
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInSortedMapAppendByteStringAtOfBuffer,
+ 3 - 1,
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendByteStringAt("", Buffer{}),
+ EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInSortedMapAppendTextStringZAt,
+ 3 - 1,
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendTextStringZAt("", ""), EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInSortedMapAppendOptionalTextStringZAt,
+ 3 - 1,
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendOptionalTextStringZAt("", ""),
+ EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInSortedMapAppendInt64At,
+ 3 - 1,
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendInt64At(0, 0), EncodingFailed))
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(TooShortBufferInSortedMapAppendBooleanAt,
+ 3 - 1,
+ auto map = encoder.OpenMap(1),
+ {
+ EXPECT_THROW(map.AppendBooleanAt(0, false), EncodingFailed);
+ })
+TEST_CBOR_ENCODING_TOO_SHORT_BUFFER(
+ TooShortBufferInSortedMapAppendByteStringAtOfWauthnBuffer,
+ 3 - 1,
+ auto map = encoder.OpenMap(1),
+ EXPECT_THROW(map.AppendByteStringAt("", wauthn_const_buffer_s{}), EncodingFailed))
+
+// Parser premature end test
+TEST_CBOR_PARSING_PREMATURE_END(ContainerArrayEndedPrematurely, "\x81\x61", {
+ EXPECT_THROW(
+ CborParsing::Parser::Create(reinterpret_cast<const uint8_t *>(data.data()), data.size()),
+ Unknown);
+})
+TEST_CBOR_PARSING_PREMATURE_END(SortedMapMapEndedPrematurely, "\xa1\x61", {
+ EXPECT_THROW(
+ CborParsing::Parser::Create(reinterpret_cast<const uint8_t *>(data.data()), data.size()),
+ Unknown);
+})
+
+// GetInt64 tests
+TEST_CBOR_PARSING(ContainerCorrectValueInGetInt64,
+ "\x81\x11",
+ auto container = parser.EnterArray(),
+ EXPECT_EQ(container.GetInt64(), 17))
+TEST_CBOR_PARSING(ContainerNullValueInGetInt64,
+ "\x81\xF6",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetInt64(), Unknown))
+TEST_CBOR_PARSING(ContainerUndefinedValueInGetInt64,
+ "\x81\xF7",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetInt64(), Unknown))
+TEST_CBOR_PARSING(ContainerDifferentTypeValueInGetInt64,
+ "\x81\x40",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetInt64(), Unknown))
+TEST_CBOR_PARSING(ContainerArrayEndedInGetInt64,
+ "\x80",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetInt64(), Unknown))
+
+// GetTextString tests
+TEST_CBOR_PARSING(ContainerEmptyValueInGetTextString,
+ "\x81\x60",
+ auto container = parser.EnterArray(),
+ EXPECT_EQ(container.GetTextString(), ""))
+TEST_CBOR_PARSING(ContainerCorrectValueInGetTextString,
+ "\x81\x64\x74\x65\x73\x74",
+ auto container = parser.EnterArray(),
+ EXPECT_EQ(container.GetTextString(), "test"))
+TEST_CBOR_PARSING(ContainerNullValueInGetTextString,
+ "\x81\xF6",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetTextString(), Unknown))
+TEST_CBOR_PARSING(ContainerUndefinedValueInGetTextString,
+ "\x81\xF7",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetTextString(), Unknown))
+TEST_CBOR_PARSING(ContainerDifferentTypeValueInGetTextString,
+ "\x81\x40",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetTextString(), Unknown))
+TEST_CBOR_PARSING(ContainerArrayEndedInGetTextString,
+ "\x80",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetTextString(), Unknown))
+
+// GetByteString tests
+TEST_CBOR_PARSING(ContainerEmptyValueInGetByteString,
+ "\x81\x40",
+ auto container = parser.EnterArray(),
+ EXPECT_EQ(container.GetByteString(), Buffer{}))
+TEST_CBOR_PARSING(ContainerCorrectValueInGetByteString,
+ "\x81\x41\x83",
+ auto container = parser.EnterArray(),
+ EXPECT_EQ(container.GetByteString(), Buffer{0x83}))
+TEST_CBOR_PARSING(ContainerNullValueInGetByteString,
+ "\x81\xF6",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetByteString(), Unknown))
+TEST_CBOR_PARSING(ContainerUndefinedValueInGetByteString,
+ "\x81\xF7",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetByteString(), Unknown))
+TEST_CBOR_PARSING(ContainerDifferentTypeValueInGetByteString,
+ "\x81\x60",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetByteString(), Unknown))
+TEST_CBOR_PARSING(ContainerArrayEndedInGetByteString,
+ "\x80",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetByteString(), Unknown))
+
+// GetBoolean tests
+TEST_CBOR_PARSING(ContainerTrueValueInGetBoolean,
+ "\x81\xF5",
+ auto container = parser.EnterArray(),
+ EXPECT_EQ(container.GetBoolean(), true))
+TEST_CBOR_PARSING(ContainerFalseValueInGetBoolean,
+ "\x81\xF4",
+ auto container = parser.EnterArray(),
+ EXPECT_EQ(container.GetBoolean(), false))
+TEST_CBOR_PARSING(ContainerNullValueInGetBoolean,
+ "\x81\xF6",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetBoolean(), Unknown))
+TEST_CBOR_PARSING(ContainerUndefinedValueInGetBoolean,
+ "\x81\xF7",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetBoolean(), Unknown))
+TEST_CBOR_PARSING(ContainerDifferentTypeValueInGetBoolean,
+ "\x81\x40",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetBoolean(), Unknown))
+TEST_CBOR_PARSING(ContainerArrayEndedInGetBoolean,
+ "\x80",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetBoolean(), Unknown))
+
+// GetUint64 tests
+TEST_CBOR_PARSING(ContainerCorrectValueInGetUint64,
+ "\x81\x10",
+ auto container = parser.EnterArray(),
+ EXPECT_EQ(container.GetUint64(), 16))
+TEST_CBOR_PARSING(ContainerNegativeValueInGetUint64,
+ "\x81\x20",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetUint64(), Unknown))
+TEST_CBOR_PARSING(ContainerNullValueInGetUint64,
+ "\x81\xF6",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetUint64(), Unknown))
+TEST_CBOR_PARSING(ContainerUndefinedValueInGetUint64,
+ "\x81\xF7",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetUint64(), Unknown))
+TEST_CBOR_PARSING(ContainerDifferentTypeValueInGetUint64,
+ "\x81\x40",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetUint64(), Unknown))
+TEST_CBOR_PARSING(ContainerArrayEndedInGetUint64,
+ "\x80",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetUint64(), Unknown))
+
+// EnterMap tests
+TEST_CBOR_PARSING(ContainerCorrectValueInEnterMap,
+ "\xA1\x01\x10",
+ auto container = parser.EnterMap(),
+ EXPECT_EQ(container.GetUint64At(1), 16))
+TEST_CBOR_PARSING(ContainerEmptyMapInEnterMap,
+ "\xA0",
+ auto container = parser.EnterMap(),
+ EXPECT_EQ(container.GetUint64At(0), std::nullopt))
+TEST_CBOR_PARSING(ContainerNullValueInEnterMap,
+ "\xF6",
+ EXPECT_THROW(parser.EnterMap(), Unknown),
+ {})
+TEST_CBOR_PARSING(ContainerUndefinedValueInEnterMap,
+ "\xF7",
+ EXPECT_THROW(parser.EnterMap(), Unknown),
+ {})
+TEST_CBOR_PARSING(ContainerDifferentTypeValueInEnterMap,
+ "\x40",
+ EXPECT_THROW(parser.EnterMap(), Unknown),
+ {})
+TEST_CBOR_PARSING(ContainerArrayInEnterMap,
+ "\x81\x01",
+ EXPECT_THROW(parser.EnterMap(), Unknown),
+ {})
+
+// EnterArray tests
+TEST_CBOR_PARSING(ContainerCorrectValueInEnterArray,
+ "\x81\x10",
+ auto container = parser.EnterArray(),
+ EXPECT_EQ(container.GetUint64(), 16))
+TEST_CBOR_PARSING(ContainerEmptyArrayInEnterArray,
+ "\x80",
+ auto container = parser.EnterArray(),
+ EXPECT_THROW(container.GetUint64(), Unknown))
+TEST_CBOR_PARSING(ContainerNullValueInEnterArray,
+ "\xF6",
+ EXPECT_THROW(parser.EnterArray(), Unknown),
+ {})
+TEST_CBOR_PARSING(ContainerUndefinedValueInEnterArray,
+ "\xF7",
+ EXPECT_THROW(parser.EnterArray(), Unknown),
+ {})
+TEST_CBOR_PARSING(ContainerDifferentTypeValueInEnterArray,
+ "\x40",
+ EXPECT_THROW(parser.EnterArray(), Unknown),
+ {})
+TEST_CBOR_PARSING(ContainerMapInEnterArray,
+ "\xA1\x01\x01",
+ EXPECT_THROW(parser.EnterArray(), Unknown),
+ {})
+
+// EnterArrayAt tests
+TEST_CBOR_PARSING(SortedMapNullKeyInEnterArrayAt,
+ "\xa1\xF6\x81\x63\x61\x62\x63",
+ EXPECT_THROW(parser.EnterMap().EnterArrayAt(nullptr), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapUndefinedKeyInEnterArrayAt,
+ "\xa1\xF7\x81\x63\x61\x62\x63",
+ EXPECT_THROW(parser.EnterMap().EnterArrayAt(CborParsing::CURRENT_KEY), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapNullValueInEnterArrayAt,
+ "\xa1\x07\xF6",
+ EXPECT_THROW(parser.EnterMap().EnterArrayAt(7), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapUndefinedValueInEnterArrayAt,
+ "\xa1\x07\xF7",
+ auto outerMap = parser.EnterMap();
+ EXPECT_THROW(auto map = outerMap.EnterArrayAt(7), Unknown), {})
+TEST_CBOR_PARSING(SortedMapEmptyMapInEnterArrayAt,
+ "\xa1\x07\xa0",
+ EXPECT_THROW(parser.EnterMap().EnterArrayAt(7), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapValueOfDifferentTypeInEnterArrayAt,
+ "\xa1\x07\x40",
+ EXPECT_THROW(parser.EnterMap().EnterArrayAt(7), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapMapInEnterArrayAt,
+ "\xa1\x07\xa1\x01\x07",
+ EXPECT_THROW(parser.EnterMap().EnterArrayAt(7), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapEmptyArrayInEnterArrayAt,
+ "\xa1\x07\x80",
+ auto outerMap = parser.EnterMap();
+ auto map = outerMap.EnterArrayAt(7).value(),
+ EXPECT_THROW(map.GetInt64(), Unknown))
+TEST_CBOR_PARSING(SortedMapNonEmptyArrayInEnterArrayAt,
+ "\xa1\x07\x81\x07",
+ auto outerMap = parser.EnterMap();
+ auto map = outerMap.EnterArrayAt(7).value(), EXPECT_EQ(map.GetInt64(), 7))
+TEST_CBOR_PARSING(SortedMapCurrentKeyNullKeyInEnterArrayAt,
+ "\xa1\xF6\x81\x07",
+ auto outerMap = parser.EnterMap();
+ EXPECT_THROW(outerMap.EnterArrayAt(CborParsing::CURRENT_KEY), Unknown), {})
+TEST_CBOR_PARSING(SortedMapCurrentKeyUndefinedKeyInEnterArrayAt,
+ "\xa1\xF7\x81\x07",
+ auto outerMap = parser.EnterMap();
+ EXPECT_THROW(outerMap.EnterArrayAt(CborParsing::CURRENT_KEY), Unknown), {})
+
+// EnterMapAt tests
+TEST_CBOR_PARSING(SortedMapNullKeyInEnterMapAt,
+ "\xa1\xF6\xa1\x02\x63\x61\x62\x63",
+ EXPECT_THROW(parser.EnterMap().EnterMapAt(nullptr), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapUndefinedKeyInEnterMapAt,
+ "\xa1\xF7\xa1\x02\x63\x61\x62\x63",
+ EXPECT_THROW(parser.EnterMap().EnterMapAt(CborParsing::CURRENT_KEY), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapNullValueInEnterMapAt,
+ "\xa1\x07\xF6",
+ EXPECT_THROW(parser.EnterMap().EnterMapAt(7), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapUndefinedValueInEnterMapAt,
+ "\xa1\x07\xF7",
+ EXPECT_THROW(parser.EnterMap().EnterMapAt(7), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapEmptyArrayInEnterMapAt,
+ "\xa1\x07\x80",
+ auto outerMap = parser.EnterMap();
+ EXPECT_THROW(outerMap.EnterMapAt(7), Unknown), {})
+TEST_CBOR_PARSING(SortedMapValueOfDifferentTypeInEnterMapAt,
+ "\xa1\x07\x40",
+ EXPECT_THROW(parser.EnterMap().EnterMapAt(7), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapArrayInEnterMapAt,
+ "\xa1\x07\x81\x07",
+ EXPECT_THROW(parser.EnterMap().EnterMapAt(7), Unknown),
+ {})
+TEST_CBOR_PARSING(SortedMapEmptyMapInEnterMapAt, "\xa1\x07\xa0", auto outerMap = parser.EnterMap();
+ auto map = outerMap.EnterMapAt(7).value(),
+ EXPECT_EQ(map.GetInt64At(CborParsing::CURRENT_KEY), std::nullopt))
+TEST_CBOR_PARSING(SortedMapNonEmptyMapInEnterMapAt,
+ "\xa1\x07\xa1\x01\x07",
+ auto outerMap = parser.EnterMap();
+ auto map = outerMap.EnterMapAt(7).value(), EXPECT_EQ(map.GetInt64At(1), 7))
+TEST_CBOR_PARSING(SortedMapCurrentKeyNullKeyInEnterMapAt,
+ "\xa1\xF6\xa1\x01\x07",
+ auto outerMap = parser.EnterMap();
+ EXPECT_THROW(outerMap.EnterMapAt(CborParsing::CURRENT_KEY), Unknown), {})
+TEST_CBOR_PARSING(SortedMapCurrentKeyUndefinedKeyInEnterMapAt,
+ "\xa1\xF7\xa1\x01\x07",
+ auto outerMap = parser.EnterMap();
+ EXPECT_THROW(outerMap.EnterMapAt(CborParsing::CURRENT_KEY), Unknown), {})
+
+// GetInt64At tests
+TEST_CBOR_PARSING(SortedMapIntKeyInGetInt64At,
+ "\xa1\x07\07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetInt64At(7), 7))
+TEST_CBOR_PARSING(SortedMapEmptyStringInGetInt64At,
+ "\xa1\x60\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetInt64At(""), 7))
+TEST_CBOR_PARSING(SortedMapCurrentIntKeyInGetInt64At,
+ "\xa1\x07\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetInt64At(CborParsing::CURRENT_KEY), 7))
+TEST_CBOR_PARSING(SortedMapCurrentStringKeyInGetInt64At,
+ "\xa1\x63\x61\x62\x63\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetInt64At(CborParsing::CURRENT_KEY), 7))
+TEST_CBOR_PARSING(SortedMapCurrentKeyInEmptyMapInGetInt64At,
+ "\xa0",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetInt64At(CborParsing::CURRENT_KEY), std::nullopt))
+TEST_CBOR_PARSING(SortedMapNullValueInGetInt64At,
+ "\xa1\x60\xF6",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapUndefinedValueInGetInt64At,
+ "\xa1\x60\xF7",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapCurrentKeyAtEndOfMapInGetInt64At,
+ "\xa1\x07\x07",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetInt64At(CborParsing::CURRENT_KEY), 7);
+ EXPECT_EQ(map.GetInt64At(CborParsing::CURRENT_KEY), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNonexistentIntKeyInGetInt64At,
+ "\xa1\x07\x07",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetInt64At(5), std::nullopt);
+ EXPECT_EQ(map.GetInt64At(CborParsing::CURRENT_KEY), 7);
+ EXPECT_EQ(map.GetInt64At(42), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNonexistentStringKeyInGetInt64At,
+ "\xa1\x63\x61\x62\x63\x07",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetInt64At("xyz"), std::nullopt);
+ EXPECT_EQ(map.GetInt64At(CborParsing::CURRENT_KEY), 7);
+ EXPECT_EQ(map.GetInt64At("qwe"), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapDifferentValueInGetInt64At,
+ "\xa1\x60\x40",
+ auto map = parser.EnterMap(),
+ { EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown); })
+TEST_CBOR_PARSING(SortedMapNullKeyInGetInt64At, "\xa1\xF6\x07", auto map = parser.EnterMap(), {
+ EXPECT_EQ(map.GetInt64At(""), std::nullopt);
+ EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown);
+})
+TEST_CBOR_PARSING(SortedMapUndefinedKeyInGetInt64At, "\xa1\xF7\x07", auto map = parser.EnterMap(), {
+ EXPECT_EQ(map.GetInt64At(""), std::nullopt);
+ EXPECT_THROW(map.GetInt64At(CborParsing::CURRENT_KEY), Unknown);
+})
+
+// GetTextStringAt tests
+TEST_CBOR_PARSING(SortedMapCurrentIntKeyInGetTextStringAt,
+ "\xa1\x07\x63\x61\x62\x63",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetTextStringAt(CborParsing::CURRENT_KEY), "abc"))
+TEST_CBOR_PARSING(SortedMapCurrentStringKeyInGetTextStringAt,
+ "\xa1\x63\x61\x62\x63\x63\x78\x79\x7A",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetTextStringAt(CborParsing::CURRENT_KEY), "xyz"))
+TEST_CBOR_PARSING(SortedMapIntKeyInGetTextStringAt,
+ "\xa1\x07\x63\x61\x62\x63",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetTextStringAt(7), "abc"))
+TEST_CBOR_PARSING(SortedMapEmptyStringInGetTextStringAt,
+ "\xa1\x60\x63\x78\x79\x7a",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetTextStringAt(""), "xyz"))
+TEST_CBOR_PARSING(SortedMapCurrentKeyInEmptyMapInGetTextStringAt,
+ "\xa0",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetTextStringAt(CborParsing::CURRENT_KEY), std::nullopt))
+TEST_CBOR_PARSING(SortedMapNullValueInGetTextStringAt,
+ "\xa1\x60\xF6",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetTextStringAt(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapUndefinedValueInGetTextStringAt,
+ "\xa1\x60\xF7",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetTextStringAt(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapDifferentValueInGetTextStringAt,
+ "\xa1\x60\x40",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetTextStringAt(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapCurrentKeyAtEndOfMapInGetTextStringAt,
+ "\xa1\x07\x60",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetTextStringAt(CborParsing::CURRENT_KEY), "");
+ EXPECT_EQ(map.GetTextStringAt(CborParsing::CURRENT_KEY), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNonexistentIntKeyInGetTextStringAt,
+ "\xa1\x07\x63\x61\x62\x63",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetTextStringAt(5), std::nullopt);
+ EXPECT_EQ(map.GetTextStringAt(CborParsing::CURRENT_KEY), "abc");
+ EXPECT_EQ(map.GetTextStringAt(42), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNonexistentStringKeyInGetTextStringAt,
+ "\xa1\x63\x61\x62\x63\x63\x61\x62\x63",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetTextStringAt("xyz"), std::nullopt);
+ EXPECT_EQ(map.GetTextStringAt(CborParsing::CURRENT_KEY), "abc");
+ EXPECT_EQ(map.GetTextStringAt("qwe"), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNullKeyInGetTextStringAt,
+ "\xa1\xF6\x63\x78\x79\x7A",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetTextStringAt(""), std::nullopt);
+ EXPECT_THROW(map.GetTextStringAt(CborParsing::CURRENT_KEY), Unknown);
+ })
+TEST_CBOR_PARSING(SortedMapUndefinedKeyInGetTextStringAt,
+ "\xa1\xF7\x63\x61\x62\x63",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetTextStringAt(""), std::nullopt);
+ EXPECT_THROW(map.GetTextStringAt(CborParsing::CURRENT_KEY), Unknown);
+ })
+
+// GetByteStringAt tests
+TEST_CBOR_PARSING(SortedMapIntKeyInGetByteStringAt,
+ "\xa1\x07\x43\x83\x03\x6B",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetByteStringAt(7), (Buffer{0x83, 0x03, 0x6B})))
+TEST_CBOR_PARSING(SortedMapEmptyStringInGetByteStringAt,
+ "\xa1\x60\x43\x83\x03\x6B",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetByteStringAt(""), (Buffer{0x83, 0x03, 0x6B})))
+TEST_CBOR_PARSING(SortedMapCurrentIntKeyInGetByteStringAt,
+ "\xa1\x07\x43\x83\x03\x6B",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetByteStringAt(CborParsing::CURRENT_KEY),
+ (Buffer{0x83, 0x03, 0x6B})))
+TEST_CBOR_PARSING(SortedMapCurrentStringKeyInGetByteStringAt,
+ "\xa1\x63\x61\x62\x63\x43\x83\x03\x6B",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetByteStringAt(CborParsing::CURRENT_KEY),
+ (Buffer{0x83, 0x03, 0x6B})))
+TEST_CBOR_PARSING(SortedMapCurrentKeyInEmptyMapInGetByteStringAt,
+ "\xa0",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetByteStringAt(CborParsing::CURRENT_KEY), std::nullopt))
+TEST_CBOR_PARSING(SortedMapNullValueInGetByteStringAt,
+ "\xa1\x60\xF6",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetByteStringAt(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapUndefinedValueInGetByteStringAt,
+ "\xa1\x60\xF7",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetByteStringAt(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapDifferentValueInGetByteStringAt,
+ "\xa1\x60\x60",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetByteStringAt(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(
+ SortedMapCurrentKeyAtEndOfMapInGetByteStringAt,
+ "\xa1\x07\x43\x83\x03\x6B",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetByteStringAt(CborParsing::CURRENT_KEY), (Buffer{0x83, 0x03, 0x6B}));
+ EXPECT_EQ(map.GetByteStringAt(CborParsing::CURRENT_KEY), std::nullopt);
+ })
+TEST_CBOR_PARSING(
+ SortedMapNonexistentIntKeyInGetByteStringAt,
+ "\xa1\x07\x43\x83\x03\x6B",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetByteStringAt(5), std::nullopt);
+ EXPECT_EQ(map.GetByteStringAt(CborParsing::CURRENT_KEY), (Buffer{0x83, 0x03, 0x6B}));
+ EXPECT_EQ(map.GetByteStringAt(42), std::nullopt);
+ })
+TEST_CBOR_PARSING(
+ SortedMapNonexistentStringKeyInGetByteStringAt,
+ "\xa1\x63\x61\x62\x63\x43\x83\x03\x6B",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetByteStringAt("xyz"), std::nullopt);
+ EXPECT_EQ(map.GetByteStringAt(CborParsing::CURRENT_KEY), (Buffer{0x83, 0x03, 0x6B}));
+ EXPECT_EQ(map.GetByteStringAt("qwe"), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNullKeyInGetByteStringAt,
+ "\xa1\xF6\x43\x83\x03\x6B",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetByteStringAt(""), std::nullopt);
+ EXPECT_THROW(map.GetByteStringAt(CborParsing::CURRENT_KEY), Unknown);
+ })
+TEST_CBOR_PARSING(SortedMapUndefinedKeyInGetByteStringAt,
+ "\xa1\xF7\x43\x83\x03\x6B",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetByteStringAt(""), std::nullopt);
+ EXPECT_THROW(map.GetByteStringAt(CborParsing::CURRENT_KEY), Unknown);
+ })
+
+// GetBooleanAt tests
+TEST_CBOR_PARSING(SortedMapCurrentIntKeyInGetBooleanAt,
+ "\xa1\x07\xF5",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetBooleanAt(CborParsing::CURRENT_KEY), true))
+TEST_CBOR_PARSING(SortedMapCurrentStringKeyInGetBooleanAt,
+ "\xa1\x63\x61\x62\x63\xF5",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetBooleanAt(CborParsing::CURRENT_KEY), true))
+TEST_CBOR_PARSING(SortedMapCurrentKeyInEmptyMapInGetBooleanAt,
+ "\xa0",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetBooleanAt(CborParsing::CURRENT_KEY), std::nullopt))
+TEST_CBOR_PARSING(SortedMapIntKeyInGetBooleanAt,
+ "\xa1\x07\xF5",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetBooleanAt(7), true))
+TEST_CBOR_PARSING(SortedMapEmptyStringInGetBooleanAt,
+ "\xa1\x60\xF4",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetBooleanAt(""), false))
+TEST_CBOR_PARSING(SortedMapNullValueInGetBooleanAt,
+ "\xa1\x60\xF6",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetBooleanAt(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapUndefinedValueInGetBooleanAt,
+ "\xa1\x60\xF7",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetBooleanAt(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapDifferentValueInGetBooleanAt,
+ "\xa1\x60\x40",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetBooleanAt(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapCurrentKeyAtEndOfMapInGetBooleanAt,
+ "\xa1\x07\xF5",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetBooleanAt(CborParsing::CURRENT_KEY), true);
+ EXPECT_EQ(map.GetBooleanAt(CborParsing::CURRENT_KEY), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNonexistentIntKeyInGetBooleanAt,
+ "\xa1\x07\xF5",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetBooleanAt(5), std::nullopt);
+ EXPECT_EQ(map.GetBooleanAt(CborParsing::CURRENT_KEY), true);
+ EXPECT_EQ(map.GetBooleanAt(42), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNonexistentStringKeyInGetBooleanAt,
+ "\xa1\x63\x61\x62\x63\xF5",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetBooleanAt("xyz"), std::nullopt);
+ EXPECT_EQ(map.GetBooleanAt(CborParsing::CURRENT_KEY), true);
+ EXPECT_EQ(map.GetBooleanAt("qwe"), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapUndefinedKeyInGetBooleanAt,
+ "\xa1\xF7\xF5",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetBooleanAt(""), std::nullopt);
+ EXPECT_THROW(map.GetBooleanAt(CborParsing::CURRENT_KEY), Unknown);
+ })
+TEST_CBOR_PARSING(SortedMapNullKeyInGetBooleanAt, "\xa1\xF6\xF5", auto map = parser.EnterMap(), {
+ EXPECT_EQ(map.GetBooleanAt(""), std::nullopt);
+ EXPECT_THROW(map.GetBooleanAt(CborParsing::CURRENT_KEY), Unknown);
+})
+
+// GetUInt64At tests
+TEST_CBOR_PARSING(SortedMapIntKeyInGetUint64At,
+ "\xa1\x07\07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetUint64At(7), 7))
+TEST_CBOR_PARSING(SortedMapCurrentIntKeyInGetUint64At,
+ "\xa1\x07\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetUint64At(CborParsing::CURRENT_KEY), 7))
+TEST_CBOR_PARSING(SortedMapCurrentStringKeyInGetUint64At,
+ "\xa1\x63\x61\x62\x63\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetUint64At(CborParsing::CURRENT_KEY), 7))
+TEST_CBOR_PARSING(SortedMapCurrentKeyInEmptyMapInGetUint64At,
+ "\xa0",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetUint64At(CborParsing::CURRENT_KEY), std::nullopt))
+TEST_CBOR_PARSING(SortedMapEmptyStringInGetUint64At,
+ "\xa1\x60\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.GetUint64At(""), 7))
+TEST_CBOR_PARSING(SortedMapNullValueInGetUint64At,
+ "\xa1\x60\xF6",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetUint64At(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapUndefinedValueInGetUint64At,
+ "\xa1\x60\xF7",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetUint64At(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapDifferentValueInGetUint64At,
+ "\xa1\x60\x40",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.GetUint64At(CborParsing::CURRENT_KEY), Unknown))
+TEST_CBOR_PARSING(SortedMapCurrentKeyAtEndOfMapInGetUint64At,
+ "\xa1\x07\x07",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetUint64At(CborParsing::CURRENT_KEY), 7);
+ EXPECT_EQ(map.GetUint64At(CborParsing::CURRENT_KEY), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNonexistentIntKeyInGetUint64At,
+ "\xa1\x07\x07",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetUint64At(5), std::nullopt);
+ EXPECT_EQ(map.GetUint64At(CborParsing::CURRENT_KEY), 7);
+ EXPECT_EQ(map.GetUint64At(42), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapNonexistentStringKeyInGetUint64At,
+ "\xa1\x63\x61\x62\x63\x07",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetUint64At("xyz"), std::nullopt);
+ EXPECT_EQ(map.GetUint64At(CborParsing::CURRENT_KEY), 7);
+ EXPECT_EQ(map.GetUint64At("qwe"), std::nullopt);
+ })
+TEST_CBOR_PARSING(SortedMapUndefinedKeyInGetUint64At,
+ "\xa1\xF7\x07",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetUint64At(""), std::nullopt);
+ EXPECT_THROW(map.GetUint64At(CborParsing::CURRENT_KEY), Unknown);
+ })
+TEST_CBOR_PARSING(SortedMapNullKeyInGetUint64At, "\xa1\xF6\x07", auto map = parser.EnterMap(), {
+ EXPECT_EQ(map.GetUint64At(""), std::nullopt);
+ EXPECT_THROW(map.GetUint64At(CborParsing::CURRENT_KEY), Unknown);
+})
+
+// PeekKey tests
+TEST_CBOR_PARSING(SortedMapIntKeyInPeekKey,
+ "\xa1\x07\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(std::get<int64_t>(map.PeekKey()), 7))
+TEST_CBOR_PARSING(SortedMapStringKeyInPeekKey,
+ "\xa1\x63\x61\x62\x63\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(std::get<std::string>(map.PeekKey()), "abc"))
+TEST_CBOR_PARSING(SortedMapEmptyStringKeyInPeekKey,
+ "\xa1\x60\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(std::get<std::string>(map.PeekKey()), ""))
+TEST_CBOR_PARSING(SortedMapUndefinedKeyInPeekKey,
+ "\xa1\xF7\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(map.PeekKey(), Unknown))
+TEST_CBOR_PARSING(SortedMapEmptyMapInPeekKey,
+ "\xa0",
+ auto map = parser.EnterMap(),
+ ASSERT_THROW(map.PeekKey(), Unknown))
+TEST_CBOR_PARSING(SortedMapNullKeyInPeekKey,
+ "\xa1\xF6\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(std::get<std::int64_t>(map.PeekKey()), Unknown))
+TEST_CBOR_PARSING(SortedMapBoolKeyInPeekKey,
+ "\xa1\xF4\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(std::get<std::int64_t>(map.PeekKey()), Unknown))
+TEST_CBOR_PARSING(SortedMapByteStringKeyInPeekKey,
+ "\xa1\x40\x07",
+ auto map = parser.EnterMap(),
+ EXPECT_THROW(std::get<std::int64_t>(map.PeekKey()), Unknown))
+TEST_CBOR_PARSING(SortedMapSecondKeyPeekInPeekKey,
+ "\xa2\x07\x07\x08\x08",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetInt64At(7), 7);
+ EXPECT_EQ(std::get<int64_t>(map.PeekKey()), 8);
+ })
+TEST_CBOR_PARSING(SortedMapKeyAtTheEndOfMapInPeekKey,
+ "\xa1\x01\x07",
+ auto map = parser.EnterMap(),
+ {
+ EXPECT_EQ(map.GetInt64At(1), 7);
+ EXPECT_THROW(std::get<int64_t>(map.PeekKey()), Unknown);
+ })
+
+// Length tests
+TEST_CBOR_PARSING(SortedMapMapOfSize0Length,
+ "\xa0",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.Length(), 0))
+TEST_CBOR_PARSING(SortedMapMapOfSize1Length,
+ "\xa1\x01\x01",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.Length(), 1))
+TEST_CBOR_PARSING(SortedMapMapOfSize2Length,
+ "\xa2\x01\x01\x02\x02",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.Length(), 2))
+TEST_CBOR_PARSING(SortedMapMapOfSize3Length,
+ "\xa3\x01\x01\x02\x02\x03\x03",
+ auto map = parser.EnterMap(),
+ EXPECT_EQ(map.Length(), 3))
+TEST_CBOR_PARSING(SortedMapArrayOfSize0Length,
+ "\x80",
+ auto array = parser.EnterArray(),
+ EXPECT_EQ(array.Length(), 0))
+TEST_CBOR_PARSING(SortedMapArrayOfSize1Length,
+ "\x81\x01",
+ auto array = parser.EnterArray(),
+ EXPECT_EQ(array.Length(), 1))
+TEST_CBOR_PARSING(SortedMapArrayOfSize2Length,
+ "\x82\x01\x02",
+ auto array = parser.EnterArray(),
+ EXPECT_EQ(array.Length(), 2))
+TEST_CBOR_PARSING(SortedMapArrayOfSize3Length,
+ "\x83\x01\x02\x03",
+ auto array = parser.EnterArray(),
+ EXPECT_EQ(array.Length(), 3))
+
+// Asserts
+static_assert(&CborParsing::Parser::GetInt64 == &CborParsing::Container::GetInt64,
+ "Copy GetInt64 test from Container");
+
+static_assert(&CborParsing::Parser::GetTextString == &CborParsing::Container::GetTextString,
+ "Copy GetTextString test from Container");
+
+static_assert(&CborParsing::Parser::GetByteString == &CborParsing::Container::GetByteString,
+ "Copy GetByteString test from Container");
+
+static_assert(&CborParsing::Parser::GetBoolean == &CborParsing::Container::GetBoolean,
+ "Copy GetBoolean test from Container");
+
+static_assert(&CborParsing::Parser::GetUint64 == &CborParsing::Container::GetUint64,
+ "Copy GetUint64 test from Container");
+
+static_assert(&CborParsing::Parser::Length == &CborParsing::Container::Length,
+ "Copy Length test from Container");
+
+static_assert(&CborParsing::Parser::EnterMap == &CborParsing::Container::EnterMap,
+ "Copy EnterMap test from Container");
+
+static_assert(&CborParsing::Parser::EnterArray == &CborParsing::Container::EnterArray,
+ "Copy EnterArray test from Container");