Skip to content

Commit 2926b83

Browse files
committed
Fix potential segfault
If more than ~20 objects were being returned at once, Lua would segfault because the default stack size is 20 and nobody was resizing the stack. Now we can return up to ~8,000 objects at once before erroring out the function properly instead of segfaulting. Also added test for segfault. All tests currently pass.
1 parent 6628b01 commit 2926b83

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

lua_cmsgpack.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,16 @@ void mp_decode_to_lua_hash(lua_State *L, mp_cur *c, size_t len) {
561561
* a Lua type, that is left as the only result on the stack. */
562562
void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
563563
mp_cur_need(c,1);
564+
565+
/* If we return more than 18 elements, we must resize the stack to
566+
* fit all our return values. But, there is no way to
567+
* determine how many objects a msgpack will unpack to up front, so
568+
* we request a +1 larger stack on each iteration (noop if stack is
569+
* big enough, and when stack does require resize it doubles in size) */
570+
luaL_checkstack(L, 1,
571+
"too many return values at once; "
572+
"use unpack_one or unpack_limit instead.");
573+
564574
switch(c->p[0]) {
565575
case 0xcc: /* uint 8 */
566576
mp_cur_need(c,2);

test.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,10 @@ pack = cmsgpack.pack(a)
369369
test_pack("regression for issue #4 output matching",a,"82a17905a17881a17882a17905a17881a17882a17905a17881a17882a17905a17881a17882a17905a17881a17882a17905a17881a17882a17905a17881a17882a17905a17881a178c0", "82a17881a17882a17881a17882a17881a17882a17881a17882a17881a17882a17881a17882a17881a17882a17881a178c0a17905a17905a17905a17905a17905a17905a17905a17905")
370370
test_circular("regression for issue #4 circular",a)
371371

372+
-- test unpacking malformed input without crashing. This actually returns one integer value (the ASCII code)
373+
-- for each character in the string. We don't care about the return value, just that we don't segfault.
374+
cmsgpack.unpack("82a17881a17882a17881a17882a17881a17882a17881a17882a17881a17882a17881a17882a17881a17882a17881a17")
375+
372376
-- Tests from github.com/moteus
373377
test_circular("map with number keys", {[1] = {1,2,3}})
374378
test_circular("map with float keys", {[1.5] = {1,2,3}})

0 commit comments

Comments
 (0)