mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-05-30 07:52:41 +02:00
commit
ce96ca8bfc
@ -63,12 +63,122 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
|
|
||||||
typedef bool (*unpack_reference_func)(type::object_type, std::size_t, void*);
|
typedef bool (*unpack_reference_func)(type::object_type, std::size_t, void*);
|
||||||
|
|
||||||
|
struct unpack_error : public std::runtime_error {
|
||||||
|
explicit unpack_error(const std::string& msg)
|
||||||
|
:std::runtime_error(msg) {}
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
explicit unpack_error(const char* msg):
|
||||||
|
std::runtime_error(msg) {}
|
||||||
|
#endif // !defined(MSGPACK_USE_CPP03)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct parse_error : public unpack_error {
|
||||||
|
explicit parse_error(const std::string& msg)
|
||||||
|
:unpack_error(msg) {}
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
explicit parse_error(const char* msg)
|
||||||
|
:unpack_error(msg) {}
|
||||||
|
#endif // !defined(MSGPACK_USE_CPP03)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct insufficient_bytes : public unpack_error {
|
||||||
|
explicit insufficient_bytes(const std::string& msg)
|
||||||
|
:unpack_error(msg) {}
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
explicit insufficient_bytes(const char* msg)
|
||||||
|
:unpack_error(msg) {}
|
||||||
|
#endif // !defined(MSGPACK_USE_CPP03)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct size_overflow : public unpack_error {
|
||||||
|
explicit size_overflow(const std::string& msg)
|
||||||
|
:unpack_error(msg) {}
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
explicit size_overflow(const char* msg)
|
||||||
|
:unpack_error(msg) {}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct array_size_overflow : public size_overflow {
|
||||||
|
array_size_overflow(const std::string& msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
array_size_overflow(const char* msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct map_size_overflow : public size_overflow {
|
||||||
|
map_size_overflow(const std::string& msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
map_size_overflow(const char* msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct str_size_overflow : public size_overflow {
|
||||||
|
str_size_overflow(const std::string& msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
str_size_overflow(const char* msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bin_size_overflow : public size_overflow {
|
||||||
|
bin_size_overflow(const std::string& msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
bin_size_overflow(const char* msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ext_size_overflow : public size_overflow {
|
||||||
|
ext_size_overflow(const std::string& msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
ext_size_overflow(const char* msg)
|
||||||
|
:size_overflow(msg) {}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class unpack_limit {
|
||||||
|
public:
|
||||||
|
unpack_limit(
|
||||||
|
std::size_t array = 0xffffffff,
|
||||||
|
std::size_t map = 0xffffffff,
|
||||||
|
std::size_t str = 0xffffffff,
|
||||||
|
std::size_t bin = 0xffffffff,
|
||||||
|
std::size_t ext = 0xffffffff)
|
||||||
|
:array_(array),
|
||||||
|
map_(map),
|
||||||
|
str_(str),
|
||||||
|
bin_(bin),
|
||||||
|
ext_(ext) {}
|
||||||
|
std::size_t array() const { return array_; }
|
||||||
|
std::size_t map() const { return map_; }
|
||||||
|
std::size_t str() const { return str_; }
|
||||||
|
std::size_t bin() const { return bin_; }
|
||||||
|
std::size_t ext() const { return ext_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t array_;
|
||||||
|
std::size_t map_;
|
||||||
|
std::size_t str_;
|
||||||
|
std::size_t bin_;
|
||||||
|
std::size_t ext_;
|
||||||
|
};
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
class unpack_user {
|
class unpack_user {
|
||||||
public:
|
public:
|
||||||
unpack_user(unpack_reference_func f = nullptr, void* user_data = nullptr)
|
unpack_user(unpack_reference_func f = nullptr,
|
||||||
:m_func(f), m_user_data(user_data) {}
|
void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit())
|
||||||
|
:m_func(f), m_user_data(user_data), m_limit(limit) {}
|
||||||
msgpack::zone const& zone() const { return *m_zone; }
|
msgpack::zone const& zone() const { return *m_zone; }
|
||||||
msgpack::zone& zone() { return *m_zone; }
|
msgpack::zone& zone() { return *m_zone; }
|
||||||
void set_zone(msgpack::zone& zone) { m_zone = &zone; }
|
void set_zone(msgpack::zone& zone) { m_zone = &zone; }
|
||||||
@ -76,11 +186,15 @@ public:
|
|||||||
void set_referenced(bool referenced) { m_referenced = referenced; }
|
void set_referenced(bool referenced) { m_referenced = referenced; }
|
||||||
unpack_reference_func reference_func() const { return m_func; }
|
unpack_reference_func reference_func() const { return m_func; }
|
||||||
void* user_data() const { return m_user_data; }
|
void* user_data() const { return m_user_data; }
|
||||||
|
unpack_limit const& limit() const { return m_limit; }
|
||||||
|
unpack_limit& limit() { return m_limit; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
msgpack::zone* m_zone;
|
msgpack::zone* m_zone;
|
||||||
bool m_referenced;
|
bool m_referenced;
|
||||||
unpack_reference_func m_func;
|
unpack_reference_func m_func;
|
||||||
void* m_user_data;
|
void* m_user_data;
|
||||||
|
unpack_limit m_limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void unpack_uint8(uint8_t d, object& o)
|
inline void unpack_uint8(uint8_t d, object& o)
|
||||||
@ -128,6 +242,7 @@ inline void unpack_false(object& o)
|
|||||||
|
|
||||||
struct unpack_array {
|
struct unpack_array {
|
||||||
void operator()(unpack_user& u, uint32_t n, object& o) const {
|
void operator()(unpack_user& u, uint32_t n, object& o) const {
|
||||||
|
if (n > u.limit().array()) throw array_size_overflow("array size overflow");
|
||||||
o.type = type::ARRAY;
|
o.type = type::ARRAY;
|
||||||
o.via.array.size = 0;
|
o.via.array.size = 0;
|
||||||
o.via.array.ptr = static_cast<object*>(u.zone().allocate_align(n*sizeof(object)));
|
o.via.array.ptr = static_cast<object*>(u.zone().allocate_align(n*sizeof(object)));
|
||||||
@ -145,6 +260,7 @@ inline void unpack_array_item(object& c, object const& o)
|
|||||||
|
|
||||||
struct unpack_map {
|
struct unpack_map {
|
||||||
void operator()(unpack_user& u, uint32_t n, object& o) const {
|
void operator()(unpack_user& u, uint32_t n, object& o) const {
|
||||||
|
if (n > u.limit().map()) throw map_size_overflow("map size overflow");
|
||||||
o.type = type::MAP;
|
o.type = type::MAP;
|
||||||
o.via.map.size = 0;
|
o.via.map.size = 0;
|
||||||
o.via.map.ptr = static_cast<object_kv*>(u.zone().allocate_align(n*sizeof(object_kv)));
|
o.via.map.ptr = static_cast<object_kv*>(u.zone().allocate_align(n*sizeof(object_kv)));
|
||||||
@ -171,6 +287,7 @@ inline void unpack_str(unpack_user& u, const char* p, uint32_t l, object& o)
|
|||||||
u.set_referenced(true);
|
u.set_referenced(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (l > u.limit().str()) throw str_size_overflow("str size overflow");
|
||||||
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
|
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
|
||||||
std::memcpy(tmp, p, l);
|
std::memcpy(tmp, p, l);
|
||||||
o.via.str.ptr = tmp;
|
o.via.str.ptr = tmp;
|
||||||
@ -186,6 +303,7 @@ inline void unpack_bin(unpack_user& u, const char* p, uint32_t l, object& o)
|
|||||||
u.set_referenced(true);
|
u.set_referenced(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (l > u.limit().bin()) throw bin_size_overflow("bin size overflow");
|
||||||
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
|
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
|
||||||
std::memcpy(tmp, p, l);
|
std::memcpy(tmp, p, l);
|
||||||
o.via.bin.ptr = tmp;
|
o.via.bin.ptr = tmp;
|
||||||
@ -193,7 +311,7 @@ inline void unpack_bin(unpack_user& u, const char* p, uint32_t l, object& o)
|
|||||||
o.via.bin.size = l;
|
o.via.bin.size = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unpack_ext(unpack_user& u, const char* p, uint32_t l, object& o)
|
inline void unpack_ext(unpack_user& u, const char* p, std::size_t l, object& o)
|
||||||
{
|
{
|
||||||
o.type = type::EXT;
|
o.type = type::EXT;
|
||||||
if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
|
if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
|
||||||
@ -201,6 +319,7 @@ inline void unpack_ext(unpack_user& u, const char* p, uint32_t l, object& o)
|
|||||||
u.set_referenced(true);
|
u.set_referenced(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (l > u.limit().ext()) throw ext_size_overflow("ext size overflow");
|
||||||
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
|
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
|
||||||
std::memcpy(tmp, p, l);
|
std::memcpy(tmp, p, l);
|
||||||
o.via.ext.ptr = tmp;
|
o.via.ext.ptr = tmp;
|
||||||
@ -290,7 +409,8 @@ inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) ==
|
|||||||
|
|
||||||
class context {
|
class context {
|
||||||
public:
|
public:
|
||||||
context(unpack_reference_func f, void* user_data):m_trail(0), m_user(f, user_data), m_cs(CS_HEADER), m_top(0)
|
context(unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
|
:m_trail(0), m_user(f, user_data, limit), m_cs(CS_HEADER), m_top(0)
|
||||||
{
|
{
|
||||||
m_stack[0].set_obj(object());
|
m_stack[0].set_obj(object());
|
||||||
}
|
}
|
||||||
@ -318,8 +438,131 @@ public:
|
|||||||
return m_user;
|
return m_user;
|
||||||
}
|
}
|
||||||
|
|
||||||
int execute(const char* data, std::size_t len, std::size_t& off)
|
int execute(const char* data, std::size_t len, std::size_t& off);
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
static uint32_t next_cs(T p)
|
||||||
{
|
{
|
||||||
|
return static_cast<uint32_t>(*p) & 0x1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Func>
|
||||||
|
int push_aggregate(
|
||||||
|
Func const& f,
|
||||||
|
uint32_t container_type,
|
||||||
|
object& obj,
|
||||||
|
const char* load_pos,
|
||||||
|
std::size_t& off) {
|
||||||
|
if(m_top < MSGPACK_EMBED_STACK_SIZE /* FIXME */) {
|
||||||
|
typename value<T>::type tmp;
|
||||||
|
load<T>(tmp, load_pos);
|
||||||
|
f(m_user, tmp, m_stack[m_top].obj());
|
||||||
|
if(tmp == 0) {
|
||||||
|
obj = m_stack[m_top].obj();
|
||||||
|
int ret = push_proc(obj, off);
|
||||||
|
if (ret != 0) return ret;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_stack[m_top].set_container_type(container_type);
|
||||||
|
m_stack[m_top].set_count(tmp);
|
||||||
|
++m_top;
|
||||||
|
m_cs = CS_HEADER;
|
||||||
|
++m_current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
off = m_current - m_start;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int push_item(object& obj) {
|
||||||
|
bool finish = false;
|
||||||
|
while (!finish) {
|
||||||
|
if(m_top == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
m_stack_idx = m_top - 1;
|
||||||
|
unpack_stack* sp = &m_stack[m_stack_idx];
|
||||||
|
switch(sp->container_type()) {
|
||||||
|
case CT_ARRAY_ITEM:
|
||||||
|
unpack_array_item(sp->obj(), obj);
|
||||||
|
if(sp->decl_count() == 0) {
|
||||||
|
obj = sp->obj();
|
||||||
|
--m_top;
|
||||||
|
/*printf("stack pop %d\n", m_top);*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
finish = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CT_MAP_KEY:
|
||||||
|
sp->set_map_key(obj);
|
||||||
|
sp->set_container_type(CT_MAP_VALUE);
|
||||||
|
finish = true;
|
||||||
|
break;
|
||||||
|
case CT_MAP_VALUE:
|
||||||
|
unpack_map_item(sp->obj(), sp->map_key(), obj);
|
||||||
|
if(sp->decl_count() == 0) {
|
||||||
|
obj = sp->obj();
|
||||||
|
--m_top;
|
||||||
|
/*printf("stack pop %d\n", m_top);*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sp->set_container_type(CT_MAP_KEY);
|
||||||
|
finish = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int push_proc(object& obj, std::size_t& off) {
|
||||||
|
int ret = push_item(obj);
|
||||||
|
if (ret > 0) {
|
||||||
|
m_stack[0].set_obj(obj);
|
||||||
|
++m_current;
|
||||||
|
/*printf("-- finish --\n"); */
|
||||||
|
off = m_current - m_start;
|
||||||
|
}
|
||||||
|
else if (ret < 0) {
|
||||||
|
off = m_current - m_start;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_cs = CS_HEADER;
|
||||||
|
++m_current;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N>
|
||||||
|
static void check_ext_size(std::size_t size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
char const* m_start;
|
||||||
|
char const* m_current;
|
||||||
|
|
||||||
|
std::size_t m_trail;
|
||||||
|
unpack_user m_user;
|
||||||
|
uint32_t m_cs;
|
||||||
|
uint32_t m_top;
|
||||||
|
uint32_t m_stack_idx;
|
||||||
|
unpack_stack m_stack[MSGPACK_EMBED_STACK_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline void context::check_ext_size<4>(std::size_t size) {
|
||||||
|
if (size == 0xffffffff) throw ext_size_overflow("ext size overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int context::execute(const char* data, std::size_t len, std::size_t& off)
|
||||||
|
{
|
||||||
assert(len >= off);
|
assert(len >= off);
|
||||||
|
|
||||||
m_start = data;
|
m_start = data;
|
||||||
@ -647,7 +890,9 @@ public:
|
|||||||
case CS_EXT_32: {
|
case CS_EXT_32: {
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
load<uint32_t>(tmp, n);
|
load<uint32_t>(tmp, n);
|
||||||
m_trail = tmp + 1;
|
check_ext_size<sizeof(std::size_t)>(tmp);
|
||||||
|
m_trail = tmp;
|
||||||
|
++m_trail;
|
||||||
if(m_trail == 0) {
|
if(m_trail == 0) {
|
||||||
unpack_ext(m_user, n, m_trail, obj);
|
unpack_ext(m_user, n, m_trail, obj);
|
||||||
int ret = push_proc(obj, off);
|
int ret = push_proc(obj, off);
|
||||||
@ -704,134 +949,11 @@ public:
|
|||||||
|
|
||||||
off = m_current - m_start;
|
off = m_current - m_start;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
template <typename T>
|
|
||||||
static uint32_t next_cs(T p)
|
|
||||||
{
|
|
||||||
return static_cast<uint32_t>(*p) & 0x1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename Func>
|
|
||||||
int push_aggregate(
|
|
||||||
Func const& f,
|
|
||||||
uint32_t container_type,
|
|
||||||
object& obj,
|
|
||||||
const char* load_pos,
|
|
||||||
std::size_t& off) {
|
|
||||||
if(m_top < MSGPACK_EMBED_STACK_SIZE /* FIXME */) {
|
|
||||||
typename value<T>::type tmp;
|
|
||||||
load<T>(tmp, load_pos);
|
|
||||||
f(m_user, tmp, m_stack[m_top].obj());
|
|
||||||
if(tmp == 0) {
|
|
||||||
obj = m_stack[m_top].obj();
|
|
||||||
int ret = push_proc(obj, off);
|
|
||||||
if (ret != 0) return ret;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_stack[m_top].set_container_type(container_type);
|
|
||||||
m_stack[m_top].set_count(tmp);
|
|
||||||
++m_top;
|
|
||||||
m_cs = CS_HEADER;
|
|
||||||
++m_current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
off = m_current - m_start;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int push_item(object& obj) {
|
|
||||||
bool finish = false;
|
|
||||||
while (!finish) {
|
|
||||||
if(m_top == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
m_stack_idx = m_top - 1;
|
|
||||||
unpack_stack* sp = &m_stack[m_stack_idx];
|
|
||||||
switch(sp->container_type()) {
|
|
||||||
case CT_ARRAY_ITEM:
|
|
||||||
unpack_array_item(sp->obj(), obj);
|
|
||||||
if(sp->decl_count() == 0) {
|
|
||||||
obj = sp->obj();
|
|
||||||
--m_top;
|
|
||||||
/*printf("stack pop %d\n", m_top);*/
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
finish = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CT_MAP_KEY:
|
|
||||||
sp->set_map_key(obj);
|
|
||||||
sp->set_container_type(CT_MAP_VALUE);
|
|
||||||
finish = true;
|
|
||||||
break;
|
|
||||||
case CT_MAP_VALUE:
|
|
||||||
unpack_map_item(sp->obj(), sp->map_key(), obj);
|
|
||||||
if(sp->decl_count() == 0) {
|
|
||||||
obj = sp->obj();
|
|
||||||
--m_top;
|
|
||||||
/*printf("stack pop %d\n", m_top);*/
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sp->set_container_type(CT_MAP_KEY);
|
|
||||||
finish = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int push_proc(object& obj, std::size_t& off) {
|
|
||||||
int ret = push_item(obj);
|
|
||||||
if (ret > 0) {
|
|
||||||
m_stack[0].set_obj(obj);
|
|
||||||
++m_current;
|
|
||||||
/*printf("-- finish --\n"); */
|
|
||||||
off = m_current - m_start;
|
|
||||||
}
|
|
||||||
else if (ret < 0) {
|
|
||||||
off = m_current - m_start;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_cs = CS_HEADER;
|
|
||||||
++m_current;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
char const* m_start;
|
|
||||||
char const* m_current;
|
|
||||||
|
|
||||||
uint32_t m_trail;
|
|
||||||
unpack_user m_user;
|
|
||||||
uint32_t m_cs;
|
|
||||||
uint32_t m_top;
|
|
||||||
uint32_t m_stack_idx;
|
|
||||||
unpack_stack m_stack[MSGPACK_EMBED_STACK_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
|
|
||||||
struct unpack_error : public std::runtime_error {
|
|
||||||
#if defined(MSGPACK_USE_CPP03)
|
|
||||||
unpack_error(const std::string& msg) :
|
|
||||||
std::runtime_error(msg) { }
|
|
||||||
#else
|
|
||||||
unpack_error(const char* msg) :
|
|
||||||
std::runtime_error(msg) { }
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class unpacked {
|
class unpacked {
|
||||||
public:
|
public:
|
||||||
unpacked() {}
|
unpacked() {}
|
||||||
@ -861,7 +983,8 @@ class unpacker {
|
|||||||
public:
|
public:
|
||||||
unpacker(unpack_reference_func f = &unpacker::default_reference_func,
|
unpacker(unpack_reference_func f = &unpacker::default_reference_func,
|
||||||
void* user_data = nullptr,
|
void* user_data = nullptr,
|
||||||
std::size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
|
std::size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
|
|
||||||
#if !defined(MSGPACK_USE_CPP03)
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
unpacker(unpacker&& other);
|
unpacker(unpacker&& other);
|
||||||
@ -987,37 +1110,47 @@ private:
|
|||||||
|
|
||||||
inline unpacked unpack(
|
inline unpacked unpack(
|
||||||
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
inline unpacked unpack(
|
inline unpacked unpack(
|
||||||
const char* data, std::size_t len, std::size_t& off,
|
const char* data, std::size_t len, std::size_t& off,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
inline unpacked unpack(
|
inline unpacked unpack(
|
||||||
const char* data, std::size_t len, bool& referenced,
|
const char* data, std::size_t len, bool& referenced,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
inline unpacked unpack(
|
inline unpacked unpack(
|
||||||
const char* data, std::size_t len,
|
const char* data, std::size_t len,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
|
|
||||||
#endif // !defined(MSGPACK_USE_CPP03)
|
#endif // !defined(MSGPACK_USE_CPP03)
|
||||||
|
|
||||||
|
|
||||||
inline void unpack(unpacked& result,
|
inline void unpack(unpacked& result,
|
||||||
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
inline void unpack(unpacked& result,
|
inline void unpack(unpacked& result,
|
||||||
const char* data, std::size_t len, std::size_t& off,
|
const char* data, std::size_t len, std::size_t& off,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
inline void unpack(unpacked& result,
|
inline void unpack(unpacked& result,
|
||||||
const char* data, std::size_t len, bool& referenced,
|
const char* data, std::size_t len, bool& referenced,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
|
|
||||||
inline void unpack(unpacked& result,
|
inline void unpack(unpacked& result,
|
||||||
const char* data, std::size_t len,
|
const char* data, std::size_t len,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
|
|
||||||
// obsolete
|
// obsolete
|
||||||
inline void unpack(unpacked* result,
|
inline void unpack(unpacked* result,
|
||||||
const char* data, std::size_t len, std::size_t* off = nullptr, bool* referenced = nullptr,
|
const char* data, std::size_t len, std::size_t* off = nullptr, bool* referenced = nullptr,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit());
|
||||||
|
|
||||||
|
|
||||||
// for internal use
|
// for internal use
|
||||||
@ -1030,8 +1163,9 @@ typedef enum {
|
|||||||
|
|
||||||
inline unpacker::unpacker(unpack_reference_func f,
|
inline unpacker::unpacker(unpack_reference_func f,
|
||||||
void* user_data,
|
void* user_data,
|
||||||
std::size_t initial_buffer_size)
|
std::size_t initial_buffer_size,
|
||||||
:m_z(new zone), m_ctx(f, user_data)
|
unpack_limit const& limit)
|
||||||
|
:m_z(new zone), m_ctx(f, user_data, limit)
|
||||||
{
|
{
|
||||||
if(initial_buffer_size < COUNTER_SIZE) {
|
if(initial_buffer_size < COUNTER_SIZE) {
|
||||||
initial_buffer_size = COUNTER_SIZE;
|
initial_buffer_size = COUNTER_SIZE;
|
||||||
@ -1181,7 +1315,7 @@ inline bool unpacker::next(unpacked& result, bool& referenced)
|
|||||||
referenced = false;
|
referenced = false;
|
||||||
int ret = execute_imp();
|
int ret = execute_imp();
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
throw unpack_error("parse error");
|
throw parse_error("parse error");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ret == 0) {
|
if(ret == 0) {
|
||||||
@ -1214,7 +1348,7 @@ inline bool unpacker::execute()
|
|||||||
{
|
{
|
||||||
int ret = execute_imp();
|
int ret = execute_imp();
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
throw unpack_error("parse error");
|
throw parse_error("parse error");
|
||||||
} else if(ret == 0) {
|
} else if(ret == 0) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -1314,7 +1448,8 @@ namespace detail {
|
|||||||
inline unpack_return
|
inline unpack_return
|
||||||
unpack_imp(const char* data, std::size_t len, std::size_t& off,
|
unpack_imp(const char* data, std::size_t len, std::size_t& off,
|
||||||
zone& result_zone, object& result, bool& referenced,
|
zone& result_zone, object& result, bool& referenced,
|
||||||
unpack_reference_func f = nullptr, void* user_data = nullptr)
|
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||||
|
unpack_limit const& limit = unpack_limit())
|
||||||
{
|
{
|
||||||
std::size_t noff = off;
|
std::size_t noff = off;
|
||||||
|
|
||||||
@ -1323,7 +1458,7 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
|
|||||||
return UNPACK_CONTINUE;
|
return UNPACK_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::context ctx(f, user_data);
|
detail::context ctx(f, user_data, limit);
|
||||||
ctx.init();
|
ctx.init();
|
||||||
|
|
||||||
ctx.user().set_zone(result_zone);
|
ctx.user().set_zone(result_zone);
|
||||||
@ -1359,13 +1494,13 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
|
|||||||
|
|
||||||
inline unpacked unpack(
|
inline unpacked unpack(
|
||||||
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
||||||
unpack_reference_func f, void* user_data)
|
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
{
|
{
|
||||||
object obj;
|
object obj;
|
||||||
msgpack::unique_ptr<zone> z(new zone);
|
msgpack::unique_ptr<zone> z(new zone);
|
||||||
referenced = false;
|
referenced = false;
|
||||||
unpack_return ret = detail::unpack_imp(
|
unpack_return ret = detail::unpack_imp(
|
||||||
data, len, off, *z, obj, referenced, f, user_data);
|
data, len, off, *z, obj, referenced, f, user_data, limit);
|
||||||
|
|
||||||
switch(ret) {
|
switch(ret) {
|
||||||
case UNPACK_SUCCESS:
|
case UNPACK_SUCCESS:
|
||||||
@ -1373,37 +1508,37 @@ inline unpacked unpack(
|
|||||||
case UNPACK_EXTRA_BYTES:
|
case UNPACK_EXTRA_BYTES:
|
||||||
return unpacked(obj, msgpack::move(z));
|
return unpacked(obj, msgpack::move(z));
|
||||||
case UNPACK_CONTINUE:
|
case UNPACK_CONTINUE:
|
||||||
throw unpack_error("insufficient bytes");
|
throw insufficient_bytes("insufficient bytes");
|
||||||
case UNPACK_PARSE_ERROR:
|
case UNPACK_PARSE_ERROR:
|
||||||
default:
|
default:
|
||||||
throw unpack_error("parse error");
|
throw parse_error("parse error");
|
||||||
}
|
}
|
||||||
return unpacked();
|
return unpacked();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unpacked unpack(
|
inline unpacked unpack(
|
||||||
const char* data, std::size_t len, std::size_t& off,
|
const char* data, std::size_t len, std::size_t& off,
|
||||||
unpack_reference_func f, void* user_data)
|
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
{
|
{
|
||||||
bool referenced;
|
bool referenced;
|
||||||
return unpack(data, len, off, referenced, f, user_data);
|
return unpack(data, len, off, referenced, f, user_data, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unpacked unpack(
|
inline unpacked unpack(
|
||||||
const char* data, std::size_t len, bool& referenced,
|
const char* data, std::size_t len, bool& referenced,
|
||||||
unpack_reference_func f, void* user_data)
|
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
{
|
{
|
||||||
std::size_t off = 0;
|
std::size_t off = 0;
|
||||||
return unpack(data, len, off, referenced, f, user_data);
|
return unpack(data, len, off, referenced, f, user_data, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unpacked unpack(
|
inline unpacked unpack(
|
||||||
const char* data, std::size_t len,
|
const char* data, std::size_t len,
|
||||||
unpack_reference_func f, void* user_data)
|
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
{
|
{
|
||||||
bool referenced;
|
bool referenced;
|
||||||
std::size_t off = 0;
|
std::size_t off = 0;
|
||||||
return unpack(data, len, off, referenced, f, user_data);
|
return unpack(data, len, off, referenced, f, user_data, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !defined(MSGPACK_USE_CPP03)
|
#endif // !defined(MSGPACK_USE_CPP03)
|
||||||
@ -1411,13 +1546,13 @@ inline unpacked unpack(
|
|||||||
|
|
||||||
inline void unpack(unpacked& result,
|
inline void unpack(unpacked& result,
|
||||||
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
||||||
unpack_reference_func f, void* user_data)
|
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
{
|
{
|
||||||
object obj;
|
object obj;
|
||||||
msgpack::unique_ptr<zone> z(new zone);
|
msgpack::unique_ptr<zone> z(new zone);
|
||||||
referenced = false;
|
referenced = false;
|
||||||
unpack_return ret = detail::unpack_imp(
|
unpack_return ret = detail::unpack_imp(
|
||||||
data, len, off, *z, obj, referenced, f, user_data);
|
data, len, off, *z, obj, referenced, f, user_data, limit);
|
||||||
|
|
||||||
switch(ret) {
|
switch(ret) {
|
||||||
case UNPACK_SUCCESS:
|
case UNPACK_SUCCESS:
|
||||||
@ -1429,50 +1564,50 @@ inline void unpack(unpacked& result,
|
|||||||
result.zone() = msgpack::move(z);
|
result.zone() = msgpack::move(z);
|
||||||
return;
|
return;
|
||||||
case UNPACK_CONTINUE:
|
case UNPACK_CONTINUE:
|
||||||
throw unpack_error("insufficient bytes");
|
throw insufficient_bytes("insufficient bytes");
|
||||||
case UNPACK_PARSE_ERROR:
|
case UNPACK_PARSE_ERROR:
|
||||||
default:
|
default:
|
||||||
throw unpack_error("parse error");
|
throw parse_error("parse error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unpack(unpacked& result,
|
inline void unpack(unpacked& result,
|
||||||
const char* data, std::size_t len, std::size_t& off,
|
const char* data, std::size_t len, std::size_t& off,
|
||||||
unpack_reference_func f, void* user_data)
|
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
{
|
{
|
||||||
bool referenced;
|
bool referenced;
|
||||||
unpack(result, data, len, off, referenced, f, user_data);
|
unpack(result, data, len, off, referenced, f, user_data, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unpack(unpacked& result,
|
inline void unpack(unpacked& result,
|
||||||
const char* data, std::size_t len, bool& referenced,
|
const char* data, std::size_t len, bool& referenced,
|
||||||
unpack_reference_func f, void* user_data)
|
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
{
|
{
|
||||||
std::size_t off = 0;
|
std::size_t off = 0;
|
||||||
unpack(result, data, len, off, referenced, f, user_data);
|
unpack(result, data, len, off, referenced, f, user_data, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unpack(unpacked& result,
|
inline void unpack(unpacked& result,
|
||||||
const char* data, std::size_t len,
|
const char* data, std::size_t len,
|
||||||
unpack_reference_func f, void* user_data)
|
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
{
|
{
|
||||||
bool referenced;
|
bool referenced;
|
||||||
std::size_t off = 0;
|
std::size_t off = 0;
|
||||||
unpack(result, data, len, off, referenced, f, user_data);
|
unpack(result, data, len, off, referenced, f, user_data, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// obsolete
|
// obsolete
|
||||||
// pointer version
|
// pointer version
|
||||||
inline void unpack(unpacked* result,
|
inline void unpack(unpacked* result,
|
||||||
const char* data, std::size_t len, std::size_t* off, bool* referenced,
|
const char* data, std::size_t len, std::size_t* off, bool* referenced,
|
||||||
unpack_reference_func f, void* user_data)
|
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||||
{
|
{
|
||||||
if (off)
|
if (off)
|
||||||
if (referenced) unpack(*result, data, len, *off, *referenced, f, user_data);
|
if (referenced) unpack(*result, data, len, *off, *referenced, f, user_data, limit);
|
||||||
else unpack(*result, data, len, *off, f, user_data);
|
else unpack(*result, data, len, *off, f, user_data, limit);
|
||||||
else
|
else
|
||||||
if (referenced) unpack(*result, data, len, *referenced, f, user_data);
|
if (referenced) unpack(*result, data, len, *referenced, f, user_data, limit);
|
||||||
else unpack(*result, data, len, f, user_data);
|
else unpack(*result, data, len, f, user_data, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool unpacker::default_reference_func(type::object_type /*type*/, std::size_t /*len*/, void*)
|
inline bool unpacker::default_reference_func(type::object_type /*type*/, std::size_t /*len*/, void*)
|
||||||
|
@ -28,6 +28,7 @@ LIST (APPEND check_PROGRAMS
|
|||||||
msgpack_vref.cpp
|
msgpack_vref.cpp
|
||||||
msgpack_c.cpp
|
msgpack_c.cpp
|
||||||
reference.cpp
|
reference.cpp
|
||||||
|
limit.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
IF (MSGPACK_CXX11)
|
IF (MSGPACK_CXX11)
|
||||||
|
@ -24,7 +24,8 @@ check_PROGRAMS = \
|
|||||||
msgpack_vref \
|
msgpack_vref \
|
||||||
msgpack_cpp11 \
|
msgpack_cpp11 \
|
||||||
reference_cpp11 \
|
reference_cpp11 \
|
||||||
reference
|
reference \
|
||||||
|
limit
|
||||||
|
|
||||||
TESTS = $(check_PROGRAMS)
|
TESTS = $(check_PROGRAMS)
|
||||||
|
|
||||||
@ -73,4 +74,6 @@ reference_SOURCES = reference.cpp
|
|||||||
|
|
||||||
reference_cpp11_SOURCES = reference_cpp11.cpp
|
reference_cpp11_SOURCES = reference_cpp11.cpp
|
||||||
|
|
||||||
|
limit_SOURCES = limit.cpp
|
||||||
|
|
||||||
EXTRA_DIST = cases.mpac cases_compact.mpac
|
EXTRA_DIST = cases.mpac cases_compact.mpac
|
||||||
|
509
test/limit.cpp
Normal file
509
test/limit.cpp
Normal file
@ -0,0 +1,509 @@
|
|||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_no_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(3, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_map_no_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::map<int, int> m;
|
||||||
|
m[1] = 1;
|
||||||
|
m[2] = 2;
|
||||||
|
m[3] = 3;
|
||||||
|
msgpack::pack(ss, m);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 3, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(msgpack::map_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_map_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::map<int, int> m;
|
||||||
|
m[1] = 1;
|
||||||
|
m[2] = 2;
|
||||||
|
m[3] = 3;
|
||||||
|
msgpack::pack(ss, m);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 2, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::map_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_str_no_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::string s("123");
|
||||||
|
msgpack::pack(ss, s);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 0, 3, 0, 0));
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(msgpack::str_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_str_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::string s("123");
|
||||||
|
msgpack::pack(ss, s);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 0, 2, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::str_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_bin_no_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<char> v;
|
||||||
|
v.push_back('1');
|
||||||
|
v.push_back('2');
|
||||||
|
v.push_back('3');
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 0, 0, 3, 0));
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(msgpack::bin_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_bin_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<char> v;
|
||||||
|
v.push_back('1');
|
||||||
|
v.push_back('2');
|
||||||
|
v.push_back('3');
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 0, 0, 2, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::bin_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_ext_no_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
msgpack::packer<std::stringstream> packer(ss);
|
||||||
|
char const buf [] = { 1, 2, 3 };
|
||||||
|
packer.pack_ext(sizeof(buf), 1);
|
||||||
|
packer.pack_ext_body(buf, sizeof(buf));
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 0, 0, 0, 3+1));
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(msgpack::ext_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_ext_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
msgpack::packer<std::stringstream> packer(ss);
|
||||||
|
char const buf [] = { 1, 2, 3 };
|
||||||
|
packer.pack_ext(sizeof(buf), 1);
|
||||||
|
packer.pack_ext_body(buf, sizeof(buf));
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 0, 0, 0, 2+1));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::ext_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_ext_over_32_bit)
|
||||||
|
{
|
||||||
|
if (sizeof(std::size_t) == 4) {
|
||||||
|
char const buf [] = {
|
||||||
|
static_cast<char>(0xc9),
|
||||||
|
static_cast<char>(0xff),
|
||||||
|
static_cast<char>(0xff),
|
||||||
|
static_cast<char>(0xff),
|
||||||
|
static_cast<char>(0xff),
|
||||||
|
static_cast<char>(0x01),
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, buf, sizeof(buf), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 0, 0, 0, 0xffffffff));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::ext_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_ext_no_over_64_bit)
|
||||||
|
{
|
||||||
|
if (sizeof(std::size_t) == 8) {
|
||||||
|
char const buf [] = {
|
||||||
|
static_cast<char>(0xc9),
|
||||||
|
static_cast<char>(0xff),
|
||||||
|
static_cast<char>(0xff),
|
||||||
|
static_cast<char>(0xff),
|
||||||
|
static_cast<char>(0xff),
|
||||||
|
static_cast<char>(0x01),
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, buf, sizeof(buf), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(0, 0, 0, 0, 0xffffffff));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::ext_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::insufficient_bytes const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(MSGPACK_USE_CPP03)
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_over_cpp11_no_off_no_ref)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp =
|
||||||
|
msgpack::unpack(ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_over_cpp11_no_off_ref)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
bool ref;
|
||||||
|
msgpack::unpacked unp =
|
||||||
|
msgpack::unpack(ss.str().c_str(), ss.str().size(), ref, nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_over_cpp11_off_no_ref)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
std::size_t off = 0;
|
||||||
|
msgpack::unpacked unp =
|
||||||
|
msgpack::unpack(ss.str().c_str(), ss.str().size(), off, nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_over_cpp11_off_ref)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
bool ref;
|
||||||
|
std::size_t off = 0;
|
||||||
|
msgpack::unpacked unp =
|
||||||
|
msgpack::unpack(ss.str().c_str(), ss.str().size(), off, ref, nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined(MSGPACK_USE_CPP03)
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_over_no_off_no_ref)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_over_no_off_ref)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
bool ref;
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), ref, nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_over_off_no_ref)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
std::size_t off = 0;
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), off, nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpack_array_over_off_ref)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
bool ref;
|
||||||
|
std::size_t off = 0;
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), off, ref, nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// obsolete
|
||||||
|
TEST(limit, unpack_array_over_off_ref_pointer)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
bool ref;
|
||||||
|
std::size_t off = 0;
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
msgpack::unpack(&unp, ss.str().c_str(), ss.str().size(), &off, &ref, nullptr, nullptr,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(limit, unpacker_array_over)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.push_back(1);
|
||||||
|
v.push_back(2);
|
||||||
|
v.push_back(3);
|
||||||
|
msgpack::pack(ss, v);
|
||||||
|
try {
|
||||||
|
msgpack::unpacker u(nullptr, nullptr, MSGPACK_UNPACKER_INIT_BUFFER_SIZE,
|
||||||
|
msgpack::unpack_limit(2, 0, 0, 0, 0));
|
||||||
|
u.reserve_buffer(ss.str().size());
|
||||||
|
memcpy(u.buffer(), ss.str().c_str(), ss.str().size());
|
||||||
|
u.buffer_consumed(ss.str().size());
|
||||||
|
msgpack::unpacked unp;
|
||||||
|
u.next(unp);
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
catch(msgpack::array_size_overflow const&) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user