Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

epee binary: container can read from empty seq of any type #8940

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
87 changes: 87 additions & 0 deletions tests/unit_tests/epee_serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@

#include <cstdint>
#include <gtest/gtest.h>
#include <vector>

#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)
Expand All @@ -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<ObjOfObjs> x;

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(x)
END_KV_SERIALIZE_MAP()
};

struct ObjOfInts
{
std::list<int> 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<const std::uint8_t>(data_empty_bool)));
EXPECT_EQ(0, o.x.size());

EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_double)));
EXPECT_EQ(0, o.x.size());

EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_string)));
EXPECT_EQ(0, o.x.size());

EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_int64)));
EXPECT_EQ(0, o.x.size());

EXPECT_TRUE(epee::serialization::load_t_from_binary(o, epee::span<const std::uint8_t>(data_empty_object)));
EXPECT_EQ(0, o.x.size());

ObjOfInts i;

EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_bool)));
EXPECT_EQ(0, i.x.size());

EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_double)));
EXPECT_EQ(0, i.x.size());

EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_string)));
EXPECT_EQ(0, i.x.size());

EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_int64)));
EXPECT_EQ(0, i.x.size());

EXPECT_TRUE(epee::serialization::load_t_from_binary(i, epee::span<const std::uint8_t>(data_empty_object)));
EXPECT_EQ(0, i.x.size());
}