Skip to content

Commit 081ee0e

Browse files
committed
Added depth limit on unpack.
1 parent de68fbd commit 081ee0e

File tree

2 files changed

+67
-3
lines changed

2 files changed

+67
-3
lines changed

include/msgpack/unpack.hpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,31 +149,44 @@ struct ext_size_overflow : public size_overflow {
149149
#endif
150150
};
151151

152+
struct depth_size_overflow : public size_overflow {
153+
depth_size_overflow(const std::string& msg)
154+
:size_overflow(msg) {}
155+
#if !defined(MSGPACK_USE_CPP03)
156+
depth_size_overflow(const char* msg)
157+
:size_overflow(msg) {}
158+
#endif
159+
};
160+
152161
class unpack_limit {
153162
public:
154163
unpack_limit(
155164
std::size_t array = 0xffffffff,
156165
std::size_t map = 0xffffffff,
157166
std::size_t str = 0xffffffff,
158167
std::size_t bin = 0xffffffff,
159-
std::size_t ext = 0xffffffff)
168+
std::size_t ext = 0xffffffff,
169+
std::size_t depth = 0xffffffff)
160170
:array_(array),
161171
map_(map),
162172
str_(str),
163173
bin_(bin),
164-
ext_(ext) {}
174+
ext_(ext),
175+
depth_(depth) {}
165176
std::size_t array() const { return array_; }
166177
std::size_t map() const { return map_; }
167178
std::size_t str() const { return str_; }
168179
std::size_t bin() const { return bin_; }
169180
std::size_t ext() const { return ext_; }
181+
std::size_t depth() const { return depth_; }
170182

171183
private:
172184
std::size_t array_;
173185
std::size_t map_;
174186
std::size_t str_;
175187
std::size_t bin_;
176188
std::size_t ext_;
189+
std::size_t depth_;
177190
};
178191

179192
namespace detail {
@@ -492,7 +505,12 @@ class context {
492505
else {
493506
m_stack.back().set_container_type(container_type);
494507
m_stack.back().set_count(tmp);
495-
m_stack.push_back(unpack_stack());
508+
if (m_stack.size() <= m_user.limit().depth()) {
509+
m_stack.push_back(unpack_stack());
510+
}
511+
else {
512+
throw depth_size_overflow("depth size overflow");
513+
}
496514
m_cs = MSGPACK_CS_HEADER;
497515
++m_current;
498516
}

test/limit.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,52 @@ TEST(limit, unpack_ext_no_over_64_bit)
269269
}
270270
}
271271

272+
TEST(limit, unpack_depth_no_over)
273+
{
274+
std::stringstream ss;
275+
std::vector<int> inner;
276+
inner.push_back(1);
277+
std::vector<std::vector<int> > outer;
278+
outer.push_back(inner);
279+
msgpack::pack(ss, outer);
280+
try {
281+
msgpack::unpacked unp;
282+
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
283+
msgpack::unpack_limit(1, 0, 0, 0, 0, 2));
284+
EXPECT_TRUE(true);
285+
}
286+
catch(msgpack::depth_size_overflow const&) {
287+
EXPECT_TRUE(false);
288+
}
289+
catch(...) {
290+
EXPECT_TRUE(false);
291+
}
292+
}
293+
294+
TEST(limit, unpack_depth_over)
295+
{
296+
std::stringstream ss;
297+
std::vector<int> inner;
298+
inner.push_back(1);
299+
std::vector<std::vector<int> > outer;
300+
outer.push_back(inner);
301+
msgpack::pack(ss, outer);
302+
try {
303+
msgpack::unpacked unp;
304+
msgpack::unpack(unp, ss.str().c_str(), ss.str().size(), nullptr, nullptr,
305+
msgpack::unpack_limit(1, 0, 0, 0, 0, 1));
306+
EXPECT_TRUE(false);
307+
}
308+
catch(msgpack::depth_size_overflow const&) {
309+
EXPECT_TRUE(true);
310+
}
311+
catch(...) {
312+
EXPECT_TRUE(false);
313+
}
314+
}
315+
316+
317+
272318
#if !defined(MSGPACK_USE_CPP03)
273319

274320
TEST(limit, unpack_array_over_cpp11_no_off_no_ref)

0 commit comments

Comments
 (0)