diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-05-07 13:32:55 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-05-07 13:32:55 -0300 |
commit | 8efe9f23faecbb0892a453c6fb503747c7dbb004 (patch) | |
tree | afdd706db268d88a2e5b53915bb8e99452187917 | |
parent | a29377972f3706ad6299fb2c398734bd4accef4c (diff) | |
download | lua-8efe9f23faecbb0892a453c6fb503747c7dbb004.tar.gz lua-8efe9f23faecbb0892a453c6fb503747c7dbb004.tar.bz2 lua-8efe9f23faecbb0892a453c6fb503747c7dbb004.zip |
BUG: compiler can optimize away overflow check in 'table.unpack'
-rw-r--r-- | ltablib.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltablib.c,v 1.65 2013/03/07 18:17:24 roberto Exp $ | 2 | ** $Id: ltablib.c,v 1.65.1.1 2013/04/12 18:48:47 roberto Exp roberto $ |
3 | ** Library for Table Manipulation | 3 | ** Library for Table Manipulation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
6 | 6 | ||
7 | 7 | ||
8 | #include <limits.h> | ||
8 | #include <stddef.h> | 9 | #include <stddef.h> |
9 | 10 | ||
10 | #define ltablib_c | 11 | #define ltablib_c |
@@ -134,13 +135,14 @@ static int pack (lua_State *L) { | |||
134 | 135 | ||
135 | 136 | ||
136 | static int unpack (lua_State *L) { | 137 | static int unpack (lua_State *L) { |
137 | int i, e, n; | 138 | int i, e; |
139 | unsigned int n; | ||
138 | luaL_checktype(L, 1, LUA_TTABLE); | 140 | luaL_checktype(L, 1, LUA_TTABLE); |
139 | i = luaL_optint(L, 2, 1); | 141 | i = luaL_optint(L, 2, 1); |
140 | e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); | 142 | e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); |
141 | if (i > e) return 0; /* empty range */ | 143 | if (i > e) return 0; /* empty range */ |
142 | n = e - i + 1; /* number of elements */ | 144 | n = (unsigned int)e - (unsigned int)i; /* number of elements minus 1 */ |
143 | if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ | 145 | if (n > (INT_MAX - 10) || !lua_checkstack(L, ++n)) |
144 | return luaL_error(L, "too many results to unpack"); | 146 | return luaL_error(L, "too many results to unpack"); |
145 | lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ | 147 | lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ |
146 | while (i++ < e) /* push arg[i + 1...e] */ | 148 | while (i++ < e) /* push arg[i + 1...e] */ |