mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-05-28 23:24:11 +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*);
|
||||
|
||||
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 {
|
||||
|
||||
class unpack_user {
|
||||
public:
|
||||
unpack_user(unpack_reference_func f = nullptr, void* user_data = nullptr)
|
||||
:m_func(f), m_user_data(user_data) {}
|
||||
unpack_user(unpack_reference_func f = nullptr,
|
||||
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& zone() { return *m_zone; }
|
||||
void set_zone(msgpack::zone& zone) { m_zone = &zone; }
|
||||
@ -76,11 +186,15 @@ public:
|
||||
void set_referenced(bool referenced) { m_referenced = referenced; }
|
||||
unpack_reference_func reference_func() const { return m_func; }
|
||||
void* user_data() const { return m_user_data; }
|
||||
unpack_limit const& limit() const { return m_limit; }
|
||||
unpack_limit& limit() { return m_limit; }
|
||||
|
||||
private:
|
||||
msgpack::zone* m_zone;
|
||||
bool m_referenced;
|
||||
unpack_reference_func m_func;
|
||||
void* m_user_data;
|
||||
unpack_limit m_limit;
|
||||
};
|
||||
|
||||
inline void unpack_uint8(uint8_t d, object& o)
|
||||
@ -128,6 +242,7 @@ inline void unpack_false(object& o)
|
||||
|
||||
struct unpack_array {
|
||||
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.via.array.size = 0;
|
||||
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 {
|
||||
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.via.map.size = 0;
|
||||
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);
|
||||
}
|
||||
else {
|
||||
if (l > u.limit().str()) throw str_size_overflow("str size overflow");
|
||||
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
|
||||
std::memcpy(tmp, p, l);
|
||||
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);
|
||||
}
|
||||
else {
|
||||
if (l > u.limit().bin()) throw bin_size_overflow("bin size overflow");
|
||||
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
|
||||
std::memcpy(tmp, p, l);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
else {
|
||||
if (l > u.limit().ext()) throw ext_size_overflow("ext size overflow");
|
||||
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
|
||||
std::memcpy(tmp, p, l);
|
||||
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 {
|
||||
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());
|
||||
}
|
||||
@ -318,8 +438,131 @@ public:
|
||||
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);
|
||||
|
||||
m_start = data;
|
||||
@ -647,7 +890,9 @@ public:
|
||||
case CS_EXT_32: {
|
||||
uint32_t tmp;
|
||||
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) {
|
||||
unpack_ext(m_user, n, m_trail, obj);
|
||||
int ret = push_proc(obj, off);
|
||||
@ -704,134 +949,11 @@ public:
|
||||
|
||||
off = m_current - m_start;
|
||||
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
|
||||
|
||||
|
||||
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 {
|
||||
public:
|
||||
unpacked() {}
|
||||
@ -861,7 +983,8 @@ class unpacker {
|
||||
public:
|
||||
unpacker(unpack_reference_func f = &unpacker::default_reference_func,
|
||||
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)
|
||||
unpacker(unpacker&& other);
|
||||
@ -987,37 +1110,47 @@ private:
|
||||
|
||||
inline unpacked unpack(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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)
|
||||
|
||||
|
||||
inline void unpack(unpacked& result,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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
|
||||
inline void unpack(unpacked* result,
|
||||
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
|
||||
@ -1030,8 +1163,9 @@ typedef enum {
|
||||
|
||||
inline unpacker::unpacker(unpack_reference_func f,
|
||||
void* user_data,
|
||||
std::size_t initial_buffer_size)
|
||||
:m_z(new zone), m_ctx(f, user_data)
|
||||
std::size_t initial_buffer_size,
|
||||
unpack_limit const& limit)
|
||||
:m_z(new zone), m_ctx(f, user_data, limit)
|
||||
{
|
||||
if(initial_buffer_size < COUNTER_SIZE) {
|
||||
initial_buffer_size = COUNTER_SIZE;
|
||||
@ -1181,7 +1315,7 @@ inline bool unpacker::next(unpacked& result, bool& referenced)
|
||||
referenced = false;
|
||||
int ret = execute_imp();
|
||||
if(ret < 0) {
|
||||
throw unpack_error("parse error");
|
||||
throw parse_error("parse error");
|
||||
}
|
||||
|
||||
if(ret == 0) {
|
||||
@ -1214,7 +1348,7 @@ inline bool unpacker::execute()
|
||||
{
|
||||
int ret = execute_imp();
|
||||
if(ret < 0) {
|
||||
throw unpack_error("parse error");
|
||||
throw parse_error("parse error");
|
||||
} else if(ret == 0) {
|
||||
return false;
|
||||
} else {
|
||||
@ -1314,7 +1448,8 @@ namespace detail {
|
||||
inline unpack_return
|
||||
unpack_imp(const char* data, std::size_t len, std::size_t& off,
|
||||
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;
|
||||
|
||||
@ -1323,7 +1458,7 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
|
||||
return UNPACK_CONTINUE;
|
||||
}
|
||||
|
||||
detail::context ctx(f, user_data);
|
||||
detail::context ctx(f, user_data, limit);
|
||||
ctx.init();
|
||||
|
||||
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(
|
||||
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;
|
||||
msgpack::unique_ptr<zone> z(new zone);
|
||||
referenced = false;
|
||||
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) {
|
||||
case UNPACK_SUCCESS:
|
||||
@ -1373,37 +1508,37 @@ inline unpacked unpack(
|
||||
case UNPACK_EXTRA_BYTES:
|
||||
return unpacked(obj, msgpack::move(z));
|
||||
case UNPACK_CONTINUE:
|
||||
throw unpack_error("insufficient bytes");
|
||||
throw insufficient_bytes("insufficient bytes");
|
||||
case UNPACK_PARSE_ERROR:
|
||||
default:
|
||||
throw unpack_error("parse error");
|
||||
throw parse_error("parse error");
|
||||
}
|
||||
return unpacked();
|
||||
}
|
||||
|
||||
inline unpacked unpack(
|
||||
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;
|
||||
return unpack(data, len, off, referenced, f, user_data);
|
||||
return unpack(data, len, off, referenced, f, user_data, limit);
|
||||
}
|
||||
|
||||
inline unpacked unpack(
|
||||
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;
|
||||
return unpack(data, len, off, referenced, f, user_data);
|
||||
return unpack(data, len, off, referenced, f, user_data, limit);
|
||||
}
|
||||
|
||||
inline unpacked unpack(
|
||||
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;
|
||||
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)
|
||||
@ -1411,13 +1546,13 @@ inline unpacked unpack(
|
||||
|
||||
inline void unpack(unpacked& result,
|
||||
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;
|
||||
msgpack::unique_ptr<zone> z(new zone);
|
||||
referenced = false;
|
||||
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) {
|
||||
case UNPACK_SUCCESS:
|
||||
@ -1429,50 +1564,50 @@ inline void unpack(unpacked& result,
|
||||
result.zone() = msgpack::move(z);
|
||||
return;
|
||||
case UNPACK_CONTINUE:
|
||||
throw unpack_error("insufficient bytes");
|
||||
throw insufficient_bytes("insufficient bytes");
|
||||
case UNPACK_PARSE_ERROR:
|
||||
default:
|
||||
throw unpack_error("parse error");
|
||||
throw parse_error("parse error");
|
||||
}
|
||||
}
|
||||
|
||||
inline void unpack(unpacked& result,
|
||||
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;
|
||||
unpack(result, data, len, off, referenced, f, user_data);
|
||||
unpack(result, data, len, off, referenced, f, user_data, limit);
|
||||
}
|
||||
|
||||
inline void unpack(unpacked& result,
|
||||
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;
|
||||
unpack(result, data, len, off, referenced, f, user_data);
|
||||
unpack(result, data, len, off, referenced, f, user_data, limit);
|
||||
}
|
||||
|
||||
inline void unpack(unpacked& result,
|
||||
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;
|
||||
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
|
||||
// pointer version
|
||||
inline void unpack(unpacked* result,
|
||||
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 (referenced) unpack(*result, data, len, *off, *referenced, f, user_data);
|
||||
else unpack(*result, data, len, *off, f, user_data);
|
||||
if (referenced) unpack(*result, data, len, *off, *referenced, f, user_data, limit);
|
||||
else unpack(*result, data, len, *off, f, user_data, limit);
|
||||
else
|
||||
if (referenced) unpack(*result, data, len, *referenced, f, user_data);
|
||||
else unpack(*result, data, len, f, user_data);
|
||||
if (referenced) unpack(*result, data, len, *referenced, f, user_data, limit);
|
||||
else unpack(*result, data, len, f, user_data, limit);
|
||||
}
|
||||
|
||||
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_c.cpp
|
||||
reference.cpp
|
||||
limit.cpp
|
||||
)
|
||||
|
||||
IF (MSGPACK_CXX11)
|
||||
|
@ -24,7 +24,8 @@ check_PROGRAMS = \
|
||||
msgpack_vref \
|
||||
msgpack_cpp11 \
|
||||
reference_cpp11 \
|
||||
reference
|
||||
reference \
|
||||
limit
|
||||
|
||||
TESTS = $(check_PROGRAMS)
|
||||
|
||||
@ -73,4 +74,6 @@ reference_SOURCES = reference.cpp
|
||||
|
||||
reference_cpp11_SOURCES = reference_cpp11.cpp
|
||||
|
||||
limit_SOURCES = limit.cpp
|
||||
|
||||
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