From 48b7d0895afce6d19e791137748445d5f68beb78 Mon Sep 17 00:00:00 2001 From: jeffro256 Date: Fri, 7 Jul 2023 16:45:38 -0500 Subject: [PATCH] epee binary: container can read from empty seq of any type --- tests/unit_tests/epee_serialization.cpp | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/tests/unit_tests/epee_serialization.cpp b/tests/unit_tests/epee_serialization.cpp index 035f5e206..ecc26e971 100644 --- a/tests/unit_tests/epee_serialization.cpp +++ b/tests/unit_tests/epee_serialization.cpp @@ -29,8 +29,11 @@ #include #include +#include +#include "serialization/keyvalue_serialization.h" #include "storages/portable_storage.h" +#include "storages/portable_storage_template_helper.h" #include "span.h" TEST(epee_binary, two_keys) @@ -54,3 +57,87 @@ TEST(epee_binary, duplicate_key) epee::serialization::portable_storage storage{}; EXPECT_FALSE(storage.load_from_binary(data)); } + +namespace +{ +struct ObjOfObjs +{ + std::vector x; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(x) + END_KV_SERIALIZE_MAP() +}; + +struct ObjOfInts +{ + std::list x; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(x) + END_KV_SERIALIZE_MAP() +}; +} + +TEST(epee_binary, any_empty_seq) +{ + // Test that any c++ sequence type (std::vector, std::list, etc) can deserialize without error + // from an *empty* epee binary array of any type. This property is useful for other projects who + // maintain code which serializes epee binary but don't know the type of arrays until runtime. + // Without any elements to actually serialize, they don't know what type code to use for arrays + // and should be able to choose a default typecode. + + static constexpr const std::uint8_t data_empty_bool[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x8B /*array of bools*/, 0x00 /*length 0*/ + }; + + static constexpr const std::uint8_t data_empty_double[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x89 /*array of doubles*/, 0x00 /*length 0*/ + }; + + static constexpr const std::uint8_t data_empty_string[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x8A /*array of strings*/, 0x00 /*length 0*/ + }; + + static constexpr const std::uint8_t data_empty_int64[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x81 /*array of int64s*/, 0x00 /*length 0*/ + }; + + static constexpr const std::uint8_t data_empty_object[] = { + 0x01, 0x11, 0x01, 0x1, 0x01, 0x01, 0x02, 0x1, 0x1, 0x04, 0x01, 'x', 0x8C /*array of objects*/, 0x00 /*length 0*/ + }; + + ObjOfObjs o; + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span(data_empty_bool))); + EXPECT_EQ(0, o.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span(data_empty_double))); + EXPECT_EQ(0, o.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span(data_empty_string))); + EXPECT_EQ(0, o.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span(data_empty_int64))); + EXPECT_EQ(0, o.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span(data_empty_object))); + EXPECT_EQ(0, o.x.size()); + + ObjOfInts i; + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span(data_empty_bool))); + EXPECT_EQ(0, i.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span(data_empty_double))); + EXPECT_EQ(0, i.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span(data_empty_string))); + EXPECT_EQ(0, i.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span(data_empty_int64))); + EXPECT_EQ(0, i.x.size()); + + EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span(data_empty_object))); + EXPECT_EQ(0, i.x.size()); +}