diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-12-11 11:40:40 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-12-11 11:40:40 -0200 |
commit | ef7d29c66601ac2484ce474fde9b058b3dd4eaa0 (patch) | |
tree | 91c33284a879625016039d1f231067c006a56533 /lstrlib.c | |
parent | 81ecaf6178aaf6349260156a254782455cd024cb (diff) | |
download | lua-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.c | 29 |
1 files changed, 17 insertions, 12 deletions
@@ -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 | ||
40 | static int str_len (lua_State *L) { | 49 | static 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 | |||
115 | static int str_rep (lua_State *L) { | 117 | static 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) { | |||
1261 | static int str_packsize (lua_State *L) { | 1263 | static 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 | ||