aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-12-11 11:40:40 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-12-11 11:40:40 -0200
commitef7d29c66601ac2484ce474fde9b058b3dd4eaa0 (patch)
tree91c33284a879625016039d1f231067c006a56533 /lstrlib.c
parent81ecaf6178aaf6349260156a254782455cd024cb (diff)
downloadlua-ef7d29c66601ac2484ce474fde9b058b3dd4eaa0.tar.gz
lua-ef7d29c66601ac2484ce474fde9b058b3dd4eaa0.tar.bz2
lua-ef7d29c66601ac2484ce474fde9b058b3dd4eaa0.zip
better limits for 'sting.rep' and 'string.packsize'
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/lstrlib.c b/lstrlib.c
index d220ffb6..786016b4 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.218 2014/12/04 16:25:40 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.219 2014/12/10 11:36:03 roberto Exp roberto $
3** Standard library for string operations and pattern-matching 3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -36,6 +36,15 @@
36#define uchar(c) ((unsigned char)(c)) 36#define uchar(c) ((unsigned char)(c))
37 37
38 38
39/*
40** Some sizes are better limited to fit in 'int', but must also fit in
41** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.)
42*/
43#define MAXSIZE \
44 (sizeof(size_t) < sizeof(int) ? (~(size_t)0) : (size_t)(INT_MAX))
45
46
47
39 48
40static int str_len (lua_State *L) { 49static int str_len (lua_State *L) {
41 size_t l; 50 size_t l;
@@ -105,13 +114,6 @@ static int str_upper (lua_State *L) {
105} 114}
106 115
107 116
108/* reasonable limit to avoid arithmetic overflow and strings too big */
109#if LUA_MAXINTEGER / 2 <= 0x10000000
110#define MAXSIZE ((size_t)(LUA_MAXINTEGER / 2))
111#else
112#define MAXSIZE ((size_t)0x10000000)
113#endif
114
115static int str_rep (lua_State *L) { 117static int str_rep (lua_State *L) {
116 size_t l, lsep; 118 size_t l, lsep;
117 const char *s = luaL_checklstring(L, 1, &l); 119 const char *s = luaL_checklstring(L, 1, &l);
@@ -1033,7 +1035,7 @@ static int getnum (const char **fmt, int df) {
1033 int a = 0; 1035 int a = 0;
1034 do { 1036 do {
1035 a = a*10 + *((*fmt)++) - '0'; 1037 a = a*10 + *((*fmt)++) - '0';
1036 } while (digit(**fmt) && a < (INT_MAX/10 - 10)); 1038 } while (digit(**fmt) && a < ((int)MAXSIZE/10 - 10));
1037 return a; 1039 return a;
1038 } 1040 }
1039} 1041}
@@ -1261,12 +1263,15 @@ static int str_pack (lua_State *L) {
1261static int str_packsize (lua_State *L) { 1263static int str_packsize (lua_State *L) {
1262 Header h; 1264 Header h;
1263 const char *fmt = luaL_checkstring(L, 1); /* format string */ 1265 const char *fmt = luaL_checkstring(L, 1); /* format string */
1264 lua_Integer totalsize = 0; /* accumulate total size of result */ 1266 size_t totalsize = 0; /* accumulate total size of result */
1265 initheader(L, &h); 1267 initheader(L, &h);
1266 while (*fmt != '\0') { 1268 while (*fmt != '\0') {
1267 int size, ntoalign; 1269 int size, ntoalign;
1268 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); 1270 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1269 totalsize += ntoalign + size; 1271 size += ntoalign; /* total space used by option */
1272 luaL_argcheck(L, totalsize <= MAXSIZE - size, 1,
1273 "format result too large");
1274 totalsize += size;
1270 switch (opt) { 1275 switch (opt) {
1271 case Kstring: /* strings with length count */ 1276 case Kstring: /* strings with length count */
1272 case Kzstr: /* zero-terminated string */ 1277 case Kzstr: /* zero-terminated string */
@@ -1275,7 +1280,7 @@ static int str_packsize (lua_State *L) {
1275 default: break; 1280 default: break;
1276 } 1281 }
1277 } 1282 }
1278 lua_pushinteger(L, totalsize); 1283 lua_pushinteger(L, (lua_Integer)totalsize);
1279 return 1; 1284 return 1;
1280} 1285}
1281 1286