Merge pull request #236 from redboltz/add_depth_limit2

Added depth limit on unpack.
This commit is contained in:
Nobuyuki Kubota 2015-03-10 21:08:01 +09:00
commit cc2ded6338
2 changed files with 67 additions and 3 deletions

View File

@ -149,6 +149,15 @@ struct ext_size_overflow : public size_overflow {
#endif
};
struct depth_size_overflow : public size_overflow {
depth_size_overflow(const std::string& msg)
:size_overflow(msg) {}
#if !defined(MSGPACK_USE_CPP03)
depth_size_overflow(const char* msg)
:size_overflow(msg) {}
#endif
};
class unpack_limit {
public:
unpack_limit(
@ -156,17 +165,20 @@ public:
std::size_t map = 0xffffffff,
std::size_t str = 0xffffffff,
std::size_t bin = 0xffffffff,
std::size_t ext = 0xffffffff)
std::size_t ext = 0xffffffff,
std::size_t depth = 0xffffffff)
:array_(array),
map_(map),
str_(str),
bin_(bin),
ext_(ext) {}
ext_(ext),
depth_(depth) {}
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_; }
std::size_t depth() const { return depth_; }
private:
std::size_t array_;
@ -174,6 +186,7 @@ private:
std::size_t str_;
std::size_t bin_;
std::size_t ext_;
std::size_t depth_;
};
namespace detail {
@ -492,7 +505,12 @@ private:
else {
m_stack.back().set_container_type(container_type);
m_stack.back().set_count(tmp);
m_stack.push_back(unpack_stack());
if (m_stack.size() <= m_user.limit().depth()) {
m_stack.push_back(unpack_stack());
}
else {
throw msgpack::depth_size_overflow("depth size overflow");
}
m_cs = MSGPACK_CS_HEADER;
++m_current;
}

View File

@ -269,6 +269,52 @@ TEST(limit, unpack_ext_no_over_64_bit)
}
}
TEST(limit, unpack_depth_no_over)
{
std::stringstream ss;
std::vector<int> inner;
inner.push_back(1);
std::vector<std::vector<int> > outer;
outer.push_back(inner);
msgpack::pack(ss, outer);
try {
msgpack::unpacked unp;
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
msgpack::unpack_limit(1, 0, 0, 0, 0, 2));
EXPECT_TRUE(true);
}
catch(msgpack::depth_size_overflow const&) {
EXPECT_TRUE(false);
}
catch(...) {
EXPECT_TRUE(false);
}
}
TEST(limit, unpack_depth_over)
{
std::stringstream ss;
std::vector<int> inner;
inner.push_back(1);
std::vector<std::vector<int> > outer;
outer.push_back(inner);
msgpack::pack(ss, outer);
try {
msgpack::unpacked unp;
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
msgpack::unpack_limit(1, 0, 0, 0, 0, 1));
EXPECT_TRUE(false);
}
catch(msgpack::depth_size_overflow const&) {
EXPECT_TRUE(true);
}
catch(...) {
EXPECT_TRUE(false);
}
}
#if !defined(MSGPACK_USE_CPP03)
TEST(limit, unpack_array_over_cpp11_no_off_no_ref)