Skip to content
This repository has been archived by the owner on Oct 4, 2019. It is now read-only.

Commit

Permalink
Merge pull request #1015 from GolosChain/fix-unpack
Browse files Browse the repository at this point in the history
Fix unpack() early memory allocation
  • Loading branch information
afalaleev authored Dec 23, 2018
2 parents f545587 + 198862f commit 3a1e2bb
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 6 deletions.
10 changes: 5 additions & 5 deletions libraries/chain/include/golos/chain/steem_object_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ namespace fc {
}

template<typename Stream, typename T>
inline void unpack(Stream &s, chainbase::object_id<T> &id) {
inline void unpack(Stream &s, chainbase::object_id<T> &id, uint32_t = 0) {
s.read((char *)&id._id, sizeof(id._id));
}
}
Expand All @@ -189,16 +189,16 @@ namespace fc {
}

template<typename T>
inline void unpack(const golos::chain::buffer_type &raw, T &v) {
inline void unpack(const golos::chain::buffer_type &raw, T &v, uint32_t depth = 0) {
datastream<const char *> ds(raw.data(), raw.size());
unpack(ds, v);
unpack(ds, v, depth);
}

template<typename T>
inline T unpack(const golos::chain::buffer_type &raw) {
inline T unpack(const golos::chain::buffer_type &raw, uint32_t depth = 0) {
T v;
datastream<const char *> ds(raw.data(), raw.size());
unpack(ds, v);
unpack(ds, v, depth);
return v;
}
}
Expand Down
92 changes: 92 additions & 0 deletions tests/tests/serialization_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,5 +314,97 @@ BOOST_FIXTURE_TEST_SUITE(serialization_tests, clean_database_fixture)
FC_LOG_AND_RETHROW();
}

BOOST_AUTO_TEST_CASE(unpack_clear_test) { try {
std::stringstream ss1;
std::stringstream ss2;

signed_block b1;

for (int i = 0; i < 10; i++) {
signed_transaction tx;

vote_operation op;
op.voter = "alice";
op.author = "bob";
op.permlink = "permlink1";
op.weight = STEEMIT_100_PERCENT;
tx.operations.push_back(op);

vote_operation op2;
op2.voter = "charlie";
op2.author = "sam";
op2.permlink = "permlink2";
op2.weight = STEEMIT_100_PERCENT;
tx.operations.push_back(op2);

tx.ref_block_num = 1000;
tx.ref_block_prefix = 1000000000;
tx.expiration = fc::time_point_sec(1514764800 + i);

b1.transactions.push_back(tx);
}

signed_block b2;

for (int i = 0; i < 20; i++) {
signed_transaction tx;
vote_operation op;
op.voter = "dave";
op.author = "greg";
op.permlink = "foobar";
op.weight = STEEMIT_100_PERCENT/2;
tx.ref_block_num = 4000;
tx.ref_block_prefix = 4000000000;
tx.expiration = fc::time_point_sec(1714764800 + i);
tx.operations.push_back(op);

b2.transactions.push_back(tx);
}

fc::raw::pack(ss2, b2);
fc::raw::pack(ss1, b1);

signed_block unpacked_block;
fc::raw::unpack(ss2, unpacked_block);

// This operation should completely overwrite signed block 'b2'
fc::raw::unpack(ss1, unpacked_block);

BOOST_REQUIRE(b1.transactions.size() == unpacked_block.transactions.size());
for (size_t i = 0; i < unpacked_block.transactions.size(); i++) {
signed_transaction tx = unpacked_block.transactions[i];
BOOST_REQUIRE(unpacked_block.transactions[i].operations.size() == b1.transactions[i].operations.size());

vote_operation op = tx.operations[0].get<vote_operation>();
BOOST_REQUIRE(op.voter == "alice");
BOOST_REQUIRE(op.author == "bob");
BOOST_REQUIRE(op.permlink == "permlink1");
BOOST_REQUIRE(op.weight == STEEMIT_100_PERCENT);

vote_operation op2 = tx.operations[1].get<vote_operation>();
BOOST_REQUIRE(op2.voter == "charlie");
BOOST_REQUIRE(op2.author == "sam");
BOOST_REQUIRE(op2.permlink == "permlink2");
BOOST_REQUIRE(op2.weight == STEEMIT_100_PERCENT);

BOOST_REQUIRE(tx.ref_block_num == 1000);
BOOST_REQUIRE(tx.ref_block_prefix == 1000000000);
BOOST_REQUIRE(tx.expiration == fc::time_point_sec(1514764800 + i));
}
} FC_LOG_AND_RETHROW(); }

BOOST_AUTO_TEST_CASE(unpack_recursion_test) { try {
std::stringstream ss;
int recursion_level = 100000;
uint64_t allocation_per_level = 500000;
for (int i = 0; i < recursion_level; i++) {
fc::raw::pack(ss, unsigned_int(allocation_per_level));
fc::raw::pack(ss, static_cast<uint8_t>(variant::array_type));
}
std::vector<fc::variant> v;
STEEMIT_REQUIRE_THROW(fc::raw::unpack(ss, v), fc::assert_exception);
} FC_LOG_AND_RETHROW(); }


BOOST_AUTO_TEST_SUITE_END()
#endif

0 comments on commit 3a1e2bb

Please sign in to comment.