From 081ee0e99aa6b975ecab4fc30ed6beffd39a0cfe Mon Sep 17 00:00:00 2001 From: Takatoshi Kondo Date: Tue, 10 Mar 2015 20:00:16 +0900 Subject: [PATCH] Added depth limit on unpack. --- include/msgpack/unpack.hpp | 24 +++++++++++++++++--- test/limit.cpp | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/include/msgpack/unpack.hpp b/include/msgpack/unpack.hpp index 1c2d5961..4e33c061 100644 --- a/include/msgpack/unpack.hpp +++ b/include/msgpack/unpack.hpp @@ -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 depth_size_overflow("depth size overflow"); + } m_cs = MSGPACK_CS_HEADER; ++m_current; } diff --git a/test/limit.cpp b/test/limit.cpp index e8483f1a..3f95c2ad 100644 --- a/test/limit.cpp +++ b/test/limit.cpp @@ -269,6 +269,52 @@ TEST(limit, unpack_ext_no_over_64_bit) } } +TEST(limit, unpack_depth_no_over) +{ + std::stringstream ss; + std::vector inner; + inner.push_back(1); + std::vector > 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 inner; + inner.push_back(1); + std::vector > 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)