Skip to content

Instantly share code, notes, and snippets.

@antirez
Created May 15, 2018 11:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antirez/149e6d291046298814ae4a941cae6e87 to your computer and use it in GitHub Desktop.
Save antirez/149e6d291046298814ae4a941cae6e87 to your computer and use it in GitHub Desktop.
Patch for all the problems found so far
diff --git a/deps/lua/src/lua_cmsgpack.c b/deps/lua/src/lua_cmsgpack.c
index 90a388f3..89215479 100644
--- a/deps/lua/src/lua_cmsgpack.c
+++ b/deps/lua/src/lua_cmsgpack.c
@@ -385,6 +385,7 @@ void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) {
#endif
mp_encode_array(L,buf,len);
+ luaL_checkstack(L, 1, "in function mp_encode_lua_table_as_array");
for (j = 1; j <= len; j++) {
lua_pushnumber(L,j);
lua_gettable(L,-2);
@@ -400,6 +401,7 @@ void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) {
* Lua API, we need to iterate a first time. Note that an alternative
* would be to do a single run, and then hack the buffer to insert the
* map opcodes for message pack. Too hackish for this lib. */
+ luaL_checkstack(L, 3, "in function mp_encode_lua_table_as_map");
lua_pushnil(L);
while(lua_next(L,-2)) {
lua_pop(L,1); /* remove value, keep key for next iteration. */
@@ -515,10 +517,14 @@ int mp_pack(lua_State *L) {
if (nargs == 0)
return luaL_argerror(L, 0, "MessagePack pack needs input.");
+ if (!lua_checkstack(L, nargs))
+ return luaL_argerror(L, 0, "Too many arguments for MessagePack pack.");
+
buf = mp_buf_new(L);
for(i = 1; i <= nargs; i++) {
/* Copy argument i to top of stack for _encode processing;
* the encode function pops it from the stack when complete. */
+ luaL_checkstack(L, 1, "in function mp_check");
lua_pushvalue(L, i);
mp_encode_lua_type(L,buf,0);
@@ -547,6 +553,7 @@ void mp_decode_to_lua_array(lua_State *L, mp_cur *c, size_t len) {
int index = 1;
lua_newtable(L);
+ luaL_checkstack(L, 1, "in function mp_decode_to_lua_array");
while(len--) {
lua_pushnumber(L,index++);
mp_decode_to_lua_type(L,c);
@@ -821,6 +828,9 @@ int mp_unpack_full(lua_State *L, int limit, int offset) {
* subtract the entire buffer size from the unprocessed size
* to get our next start offset */
int offset = len - c.left;
+
+ luaL_checkstack(L, 1, "in function mp_unpack_full");
+
/* Return offset -1 when we have have processed the entire buffer. */
lua_pushinteger(L, c.left == 0 ? -1 : offset);
/* Results are returned with the arg elements still
diff --git a/deps/lua/src/lua_struct.c b/deps/lua/src/lua_struct.c
index a602bb43..4d5f027b 100644
--- a/deps/lua/src/lua_struct.c
+++ b/deps/lua/src/lua_struct.c
@@ -1,7 +1,7 @@
/*
** {======================================================
** Library for packing/unpacking structures.
-** $Id: struct.c,v 1.4 2012/07/04 18:54:29 roberto Exp $
+** $Id: struct.c,v 1.7 2018/05/11 22:04:31 roberto Exp $
** See Copyright Notice at the end of this file
** =======================================================
*/
@@ -15,8 +15,8 @@
** h/H - signed/unsigned short
** l/L - signed/unsigned long
** T - size_t
-** i/In - signed/unsigned integer with size `n' (default is size of int)
-** cn - sequence of `n' chars (from/to a string); when packing, n==0 means
+** i/In - signed/unsigned integer with size 'n' (default is size of int)
+** cn - sequence of 'n' chars (from/to a string); when packing, n==0 means
the whole string; when unpacking, n==0 means use the previous
read number as the string length
** s - zero-terminated string
@@ -89,14 +89,12 @@ typedef struct Header {
} Header;
-static int getnum (lua_State *L, const char **fmt, int df) {
+static int getnum (const char **fmt, int df) {
if (!isdigit(**fmt)) /* no number? */
return df; /* return default value */
else {
int a = 0;
do {
- if (a > (INT_MAX / 10) || a * 10 > (INT_MAX - (**fmt - '0')))
- luaL_error(L, "integral size overflow");
a = a*10 + *((*fmt)++) - '0';
} while (isdigit(**fmt));
return a;
@@ -117,9 +115,9 @@ static size_t optsize (lua_State *L, char opt, const char **fmt) {
case 'f': return sizeof(float);
case 'd': return sizeof(double);
case 'x': return 1;
- case 'c': return getnum(L, fmt, 1);
+ case 'c': return getnum(fmt, 1);
case 'i': case 'I': {
- int sz = getnum(L, fmt, sizeof(int));
+ int sz = getnum(fmt, sizeof(int));
if (sz > MAXINTSIZE)
luaL_error(L, "integral size %d is larger than limit of %d",
sz, MAXINTSIZE);
@@ -152,7 +150,7 @@ static void controloptions (lua_State *L, int opt, const char **fmt,
case '>': h->endian = BIG; return;
case '<': h->endian = LITTLE; return;
case '!': {
- int a = getnum(L, fmt, MAXALIGN);
+ int a = getnum(fmt, MAXALIGN);
if (!isp2(a))
luaL_error(L, "alignment %d is not a power of 2", a);
h->align = a;
@@ -295,21 +293,26 @@ static int b_unpack (lua_State *L) {
const char *fmt = luaL_checkstring(L, 1);
size_t ld;
const char *data = luaL_checklstring(L, 2, &ld);
- size_t pos = luaL_optinteger(L, 3, 1) - 1;
+ size_t pos = luaL_optinteger(L, 3, 1);
+ luaL_argcheck(L, pos > 0, 3, "offset must be 1 or greater");
+ pos--; /* Lua indexes are 1-based, but here we want 0-based for C
+ * pointer math. */
+ int n = 0; /* number of results */
defaultoptions(&h);
- lua_settop(L, 2);
while (*fmt) {
int opt = *fmt++;
size_t size = optsize(L, opt, &fmt);
pos += gettoalign(pos, &h, opt, size);
- luaL_argcheck(L, pos+size <= ld, 2, "data string too short");
- luaL_checkstack(L, 1, "too many results");
+ luaL_argcheck(L, size <= ld && pos <= ld - size,
+ 2, "data string too short");
+ /* stack space for item + next position */
+ luaL_checkstack(L, 2, "too many results");
switch (opt) {
case 'b': case 'B': case 'h': case 'H':
case 'l': case 'L': case 'T': case 'i': case 'I': { /* integer types */
int issigned = islower(opt);
lua_Number res = getinteger(data+pos, h.endian, issigned, size);
- lua_pushnumber(L, res);
+ lua_pushnumber(L, res); n++;
break;
}
case 'x': {
@@ -319,25 +322,26 @@ static int b_unpack (lua_State *L) {
float f;
memcpy(&f, data+pos, size);
correctbytes((char *)&f, sizeof(f), h.endian);
- lua_pushnumber(L, f);
+ lua_pushnumber(L, f); n++;
break;
}
case 'd': {
double d;
memcpy(&d, data+pos, size);
correctbytes((char *)&d, sizeof(d), h.endian);
- lua_pushnumber(L, d);
+ lua_pushnumber(L, d); n++;
break;
}
case 'c': {
if (size == 0) {
- if (!lua_isnumber(L, -1))
- luaL_error(L, "format `c0' needs a previous size");
+ if (n == 0 || !lua_isnumber(L, -1))
+ luaL_error(L, "format 'c0' needs a previous size");
size = lua_tonumber(L, -1);
- lua_pop(L, 1);
- luaL_argcheck(L, pos+size <= ld, 2, "data string too short");
+ lua_pop(L, 1); n--;
+ luaL_argcheck(L, size <= ld && pos <= ld - size,
+ 2, "data string too short");
}
- lua_pushlstring(L, data+pos, size);
+ lua_pushlstring(L, data+pos, size); n++;
break;
}
case 's': {
@@ -345,15 +349,15 @@ static int b_unpack (lua_State *L) {
if (e == NULL)
luaL_error(L, "unfinished string in data");
size = (e - (data+pos)) + 1;
- lua_pushlstring(L, data+pos, size - 1);
+ lua_pushlstring(L, data+pos, size - 1); n++;
break;
}
default: controloptions(L, opt, &fmt, &h);
}
pos += size;
}
- lua_pushinteger(L, pos + 1);
- return lua_gettop(L) - 2;
+ lua_pushinteger(L, pos + 1); /* next position */
+ return n + 1;
}
@@ -399,7 +403,7 @@ LUALIB_API int luaopen_struct (lua_State *L) {
/******************************************************************************
-* Copyright (C) 2010-2012 Lua.org, PUC-Rio. All rights reserved.
+* Copyright (C) 2010-2018 Lua.org, PUC-Rio. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment