Skip to content

Commit

Permalink
Add max_depth parameter to pack/unpack functions
Browse files Browse the repository at this point in the history
  • Loading branch information
abitmore committed Mar 11, 2018
1 parent 782e7d6 commit 86e1866
Show file tree
Hide file tree
Showing 15 changed files with 610 additions and 476 deletions.
4 changes: 4 additions & 0 deletions include/fc/config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#ifndef FC_PACK_MAX_DEPTH
// The maximum level of object nesting is around 20% of this value
#define FC_PACK_MAX_DEPTH 1000
#endif
5 changes: 3 additions & 2 deletions include/fc/container/deque_fwd.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#pragma once

#include <fc/config.hpp>
#include <deque>

namespace fc {

namespace raw {
template<typename Stream, typename T>
void pack( Stream& s, const std::deque<T>& value );
void pack( Stream& s, const std::deque<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T>
void unpack( Stream& s, std::deque<T>& value );
void unpack( Stream& s, std::deque<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
}
} // namespace fc
42 changes: 24 additions & 18 deletions include/fc/container/flat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,61 +8,66 @@
namespace fc {
namespace raw {
template<typename Stream, typename T>
inline void pack( Stream& s, const flat_set<T>& value ) {
pack( s, unsigned_int((uint32_t)value.size()) );
inline void pack( Stream& s, const flat_set<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto itr = value.begin();
auto end = value.end();
while( itr != end ) {
fc::raw::pack( s, *itr );
fc::raw::pack( s, *itr, _max_depth - 1 );
++itr;
}
}
template<typename Stream, typename T>
inline void unpack( Stream& s, flat_set<T>& value ) {
unsigned_int size; unpack( s, size );
inline void unpack( Stream& s, flat_set<T>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
unsigned_int size; unpack( s, size, _max_depth - 1 );
value.clear();
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
value.reserve(size.value);
for( uint32_t i = 0; i < size.value; ++i )
{
T tmp;
fc::raw::unpack( s, tmp );
fc::raw::unpack( s, tmp, _max_depth - 1 );
value.insert( std::move(tmp) );
}
}
template<typename Stream, typename K, typename... V>
inline void pack( Stream& s, const flat_map<K,V...>& value ) {
pack( s, unsigned_int((uint32_t)value.size()) );
inline void pack( Stream& s, const flat_map<K,V...>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto itr = value.begin();
auto end = value.end();
while( itr != end ) {
fc::raw::pack( s, *itr );
fc::raw::pack( s, *itr, _max_depth - 1 );
++itr;
}
}
template<typename Stream, typename K, typename V, typename... A>
inline void unpack( Stream& s, flat_map<K,V,A...>& value )
inline void unpack( Stream& s, flat_map<K,V,A...>& value, uint32_t _max_depth )
{
unsigned_int size; unpack( s, size );
FC_ASSERT( _max_depth > 0 );
unsigned_int size; unpack( s, size, _max_depth - 1 );
value.clear();
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
value.reserve(size.value);
for( uint32_t i = 0; i < size.value; ++i )
{
std::pair<K,V> tmp;
fc::raw::unpack( s, tmp );
fc::raw::unpack( s, tmp, _max_depth - 1 );
value.insert( std::move(tmp) );
}
}

template<typename Stream, typename T, typename A>
void pack( Stream& s, const bip::vector<T,A>& value ) {
pack( s, unsigned_int((uint32_t)value.size()) );
void pack( Stream& s, const bip::vector<T,A>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
if( !std::is_fundamental<T>::value ) {
auto itr = value.begin();
auto end = value.end();
while( itr != end ) {
fc::raw::pack( s, *itr );
fc::raw::pack( s, *itr, _max_depth - 1 );
++itr;
}
} else {
Expand All @@ -71,13 +76,14 @@ namespace fc {
}

template<typename Stream, typename T, typename A>
void unpack( Stream& s, bip::vector<T,A>& value ) {
void unpack( Stream& s, bip::vector<T,A>& value, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
unsigned_int size;
unpack( s, size );
unpack( s, size, _max_depth - 1 );
value.resize( size );
if( !std::is_fundamental<T>::value ) {
for( auto& item : value )
unpack( s, item );
unpack( s, item, _max_depth - 1 );
} else {
s.read( (char*)value.data(), value.size() );
}
Expand Down
15 changes: 8 additions & 7 deletions include/fc/container/flat_fwd.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
#pragma once
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <fc/config.hpp>

namespace fc {

Expand All @@ -11,19 +12,19 @@ namespace fc {

namespace raw {
template<typename Stream, typename T>
void pack( Stream& s, const flat_set<T>& value );
void pack( Stream& s, const flat_set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T>
void unpack( Stream& s, flat_set<T>& value );
void unpack( Stream& s, flat_set<T>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename... V>
void pack( Stream& s, const flat_map<K,V...>& value );
void pack( Stream& s, const flat_map<K,V...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename K, typename V, typename... A>
void unpack(Stream& s, flat_map<K, V, A...>& value);
void unpack(Stream& s, flat_map<K, V, A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );


template<typename Stream, typename T, typename A>
void pack( Stream& s, const bip::vector<T,A>& value );
void pack( Stream& s, const bip::vector<T,A>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T, typename A>
void unpack( Stream& s, bip::vector<T,A>& value );
void unpack( Stream& s, bip::vector<T,A>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
} // namespace raw

} // fc
20 changes: 12 additions & 8 deletions include/fc/crypto/elliptic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,31 +260,35 @@ namespace fc {
namespace raw
{
template<typename Stream>
void unpack( Stream& s, fc::ecc::public_key& pk)
void unpack( Stream& s, fc::ecc::public_key& pk, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
ecc::public_key_data ser;
fc::raw::unpack(s,ser);
fc::raw::unpack( s, ser, _max_depth - 1 );
pk = fc::ecc::public_key( ser );
}

template<typename Stream>
void pack( Stream& s, const fc::ecc::public_key& pk)
void pack( Stream& s, const fc::ecc::public_key& pk, uint32_t _max_depth )
{
fc::raw::pack( s, pk.serialize() );
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, pk.serialize(), _max_depth - 1 );
}

template<typename Stream>
void unpack( Stream& s, fc::ecc::private_key& pk)
void unpack( Stream& s, fc::ecc::private_key& pk, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
fc::sha256 sec;
unpack( s, sec );
unpack( s, sec, _max_depth - 1 );
pk = ecc::private_key::regenerate(sec);
}

template<typename Stream>
void pack( Stream& s, const fc::ecc::private_key& pk)
void pack( Stream& s, const fc::ecc::private_key& pk, uint32_t _max_depth )
{
fc::raw::pack( s, pk.get_secret() );
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, pk.get_secret(), _max_depth - 1 );
}

} // namespace raw
Expand Down
20 changes: 12 additions & 8 deletions include/fc/crypto/pke.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,31 +76,35 @@ namespace fc {
namespace raw
{
template<typename Stream>
void unpack( Stream& s, fc::public_key& pk)
void unpack( Stream& s, fc::public_key& pk, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{
FC_ASSERT( _max_depth > 0 );
bytes ser;
fc::raw::unpack(s,ser);
fc::raw::unpack( s, ser, _max_depth - 1 );
pk = fc::public_key( ser );
}

template<typename Stream>
void pack( Stream& s, const fc::public_key& pk)
void pack( Stream& s, const fc::public_key& pk, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{
fc::raw::pack( s, pk.serialize() );
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, pk.serialize(), _max_depth - 1 );
}

template<typename Stream>
void unpack( Stream& s, fc::private_key& pk)
void unpack( Stream& s, fc::private_key& pk, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{
FC_ASSERT( _max_depth > 0 );
bytes ser;
fc::raw::unpack(s,ser);
fc::raw::unpack( s, ser, _max_depth - 1 );
pk = fc::private_key( ser );
}

template<typename Stream>
void pack( Stream& s, const fc::private_key& pk)
void pack( Stream& s, const fc::private_key& pk, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{
fc::raw::pack( s, pk.serialize() );
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, pk.serialize(), _max_depth - 1 );
}
}
class variant;
Expand Down
14 changes: 8 additions & 6 deletions include/fc/fixed_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,18 @@ namespace fc {
namespace raw
{
template<typename Stream, typename Storage>
inline void pack( Stream& s, const fc::fixed_string<Storage>& u ) {
inline void pack( Stream& s, const fc::fixed_string<Storage>& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 );
unsigned_int size = u.size();
pack( s, size );
pack( s, size, _max_depth - 1 );
s.write( (const char*)&u.data, size );
}

template<typename Stream, typename Storage>
inline void unpack( Stream& s, fc::fixed_string<Storage>& u ) {
inline void unpack( Stream& s, fc::fixed_string<Storage>& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 );
unsigned_int size;
fc::raw::unpack( s, size );
fc::raw::unpack( s, size, _max_depth - 1 );
if( size.value > 0 ) {
if( size.value > sizeof(Storage) ) {
s.read( (char*)&u.data, sizeof(Storage) );
Expand Down Expand Up @@ -135,12 +137,12 @@ namespace fc {

/*
template<typename Stream, typename... Args>
inline void pack( Stream& s, const boost::multiprecision::number<Args...>& d ) {
inline void pack( Stream& s, const boost::multiprecision::number<Args...>& d, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
s.write( (const char*)&d, sizeof(d) );
}
template<typename Stream, typename... Args>
inline void unpack( Stream& s, boost::multiprecision::number<Args...>& u ) {
inline void unpack( Stream& s, boost::multiprecision::number<Args...>& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
s.read( (const char*)&u, sizeof(u) );
}
*/
Expand Down
30 changes: 16 additions & 14 deletions include/fc/interprocess/container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,22 +122,24 @@ namespace fc {
namespace bip = boost::interprocess;

template<typename Stream, typename T, typename... A>
inline void pack( Stream& s, const bip::vector<T,A...>& value ) {
pack( s, unsigned_int((uint32_t)value.size()) );
auto itr = value.begin();
auto end = value.end();
while( itr != end ) {
fc::raw::pack( s, *itr );
++itr;
}
inline void pack( Stream& s, const bip::vector<T,A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 );
pack( s, unsigned_int((uint32_t)value.size()), _max_depth - 1 );
auto itr = value.begin();
auto end = value.end();
while( itr != end ) {
fc::raw::pack( s, *itr, _max_depth - 1 );
++itr;
}
}
template<typename Stream, typename T, typename... A>
inline void unpack( Stream& s, bip::vector<T,A...>& value ) {
unsigned_int size;
unpack( s, size );
value.clear(); value.resize(size);
for( auto& item : value )
fc::raw::unpack( s, item );
inline void unpack( Stream& s, bip::vector<T,A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 );
unsigned_int size;
unpack( s, size, _max_depth - 1 );
value.clear(); value.resize(size);
for( auto& item : value )
fc::raw::unpack( s, item, _max_depth - 1 );
}
}
}
22 changes: 12 additions & 10 deletions include/fc/io/enum_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ namespace fc
public:
enum_type( EnumType t )
:value(t){}

enum_type( IntType t )
:value( (EnumType)t ){}

enum_type(){}

explicit operator IntType()const { return static_cast<IntType>(value); }
operator EnumType()const { return value; }
operator std::string()const { return fc::reflector<EnumType>::to_string(value); }

enum_type& operator=( IntType i ) { value = (EnumType)i; return *this;}
enum_type& operator=( EnumType i ) { value = i; return *this;}
bool operator<( EnumType i ) const { return value < i; }
Expand Down Expand Up @@ -60,19 +60,21 @@ namespace fc


/** serializes like an IntType */
namespace raw
{
namespace raw
{
template<typename Stream, typename IntType, typename EnumType>
inline void pack( Stream& s, const fc::enum_type<IntType,EnumType>& tp )
inline void pack( Stream& s, const fc::enum_type<IntType,EnumType>& tp, uint32_t _max_depth )
{
fc::raw::pack( s, static_cast<IntType>(tp) );
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, static_cast<IntType>(tp), _max_depth - 1 );
}

template<typename Stream, typename IntType, typename EnumType>
inline void unpack( Stream& s, fc::enum_type<IntType,EnumType>& tp )
inline void unpack( Stream& s, fc::enum_type<IntType,EnumType>& tp, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
IntType t;
fc::raw::unpack( s, t );
fc::raw::unpack( s, t, _max_depth - 1 );
tp = t;
}
}
Expand Down
Loading

0 comments on commit 86e1866

Please sign in to comment.