diff options
Diffstat (limited to 'src/lstrlib.c')
-rw-r--r-- | src/lstrlib.c | 109 |
1 files changed, 35 insertions, 74 deletions
diff --git a/src/lstrlib.c b/src/lstrlib.c index fcc61c9a..28acab83 100644 --- a/src/lstrlib.c +++ b/src/lstrlib.c @@ -1,11 +1,12 @@ /* -** $Id: lstrlib.c,v 1.178 2012/08/14 18:12:34 roberto Exp $ +** $Id: lstrlib.c,v 1.182 2013/06/20 15:06:51 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ #include <ctype.h> +#include <limits.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -43,20 +44,20 @@ static int str_len (lua_State *L) { /* translate a relative string position: negative means back from end */ -static size_t posrelat (ptrdiff_t pos, size_t len) { - if (pos >= 0) return (size_t)pos; +static lua_Integer posrelat (lua_Integer pos, size_t len) { + if (pos >= 0) return pos; else if (0u - (size_t)pos > len) return 0; - else return len - ((size_t)-pos) + 1; + else return (lua_Integer)len + pos + 1; } static int str_sub (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - size_t start = posrelat(luaL_checkinteger(L, 2), l); - size_t end = posrelat(luaL_optinteger(L, 3, -1), l); + lua_Integer start = posrelat(luaL_checkinteger(L, 2), l); + lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l); if (start < 1) start = 1; - if (end > l) end = l; + if (end > (lua_Integer)l) end = l; if (start <= end) lua_pushlstring(L, s + start - 1, end - start + 1); else lua_pushliteral(L, ""); @@ -102,13 +103,17 @@ static int str_upper (lua_State *L) { } -/* reasonable limit to avoid arithmetic overflow */ -#define MAXSIZE ((~(size_t)0) >> 1) +/* reasonable limit to avoid arithmetic overflow and strings too big */ +#if INT_MAX / 2 <= 0x10000000 +#define MAXSIZE ((size_t)(INT_MAX / 2)) +#else +#define MAXSIZE ((size_t)0x10000000) +#endif static int str_rep (lua_State *L) { size_t l, lsep; const char *s = luaL_checklstring(L, 1, &l); - int n = luaL_checkint(L, 2); + lua_Integer n = luaL_checkinteger(L, 2); const char *sep = luaL_optlstring(L, 3, "", &lsep); if (n <= 0) lua_pushliteral(L, ""); else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ @@ -133,14 +138,14 @@ static int str_rep (lua_State *L) { static int str_byte (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - size_t posi = posrelat(luaL_optinteger(L, 2, 1), l); - size_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l); + lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l); int n, i; if (posi < 1) posi = 1; - if (pose > l) pose = l; + if (pose > (lua_Integer)l) pose = l; if (posi > pose) return 0; /* empty interval; return no values */ n = (int)(pose - posi + 1); - if (posi + n <= pose) /* (size_t -> int) overflow? */ + if (posi + n <= pose) /* arithmetic overflow? */ return luaL_error(L, "string slice too long"); luaL_checkstack(L, n, "string slice too long"); for (i=0; i<n; i++) @@ -155,7 +160,7 @@ static int str_char (lua_State *L) { luaL_Buffer b; char *p = luaL_buffinitsize(L, &b, n); for (i=1; i<=n; i++) { - int c = luaL_checkint(L, i); + lua_Integer c = luaL_checkinteger(L, i); luaL_argcheck(L, uchar(c) == c, i, "value out of range"); p[i - 1] = uchar(c); } @@ -164,9 +169,9 @@ static int str_char (lua_State *L) { } -static int writer (lua_State *L, const void* b, size_t size, void* B) { +static int writer (lua_State *L, const void *b, size_t size, void *B) { (void)L; - luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); + luaL_addlstring((luaL_Buffer *) B, (const char *)b, size); return 0; } @@ -578,9 +583,9 @@ static int str_find_aux (lua_State *L, int find) { size_t ls, lp; const char *s = luaL_checklstring(L, 1, &ls); const char *p = luaL_checklstring(L, 2, &lp); - size_t init = posrelat(luaL_optinteger(L, 3, 1), ls); + lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls); if (init < 1) init = 1; - else if (init > ls + 1) { /* start after string's end? */ + else if (init > (lua_Integer)ls + 1) { /* start after string's end? */ lua_pushnil(L); /* cannot find anything */ return 1; } @@ -786,48 +791,17 @@ static int str_gsub (lua_State *L) { ** ======================================================= */ -/* -** LUA_INTFRMLEN is the length modifier for integer conversions in -** 'string.format'; LUA_INTFRM_T is the integer type corresponding to -** the previous length -*/ -#if !defined(LUA_INTFRMLEN) /* { */ -#if defined(LUA_USE_LONGLONG) - -#define LUA_INTFRMLEN "ll" -#define LUA_INTFRM_T long long - -#else - -#define LUA_INTFRMLEN "l" -#define LUA_INTFRM_T long - -#endif -#endif /* } */ - - -/* -** LUA_FLTFRMLEN is the length modifier for float conversions in -** 'string.format'; LUA_FLTFRM_T is the float type corresponding to -** the previous length -*/ -#if !defined(LUA_FLTFRMLEN) - -#define LUA_FLTFRMLEN "" -#define LUA_FLTFRM_T double - -#endif - - /* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ #define MAX_ITEM 512 + /* valid flags in a format specification */ #define FLAGS "-+ #0" + /* -** maximum size of each format specification (such as '%-099.99d') -** (+10 accounts for %99.99x plus margin of error) +** maximum size of each format specification (such as "%-099.99d") +** (+2 for length modifiers; +10 accounts for %99.99x plus margin of error) */ -#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) +#define MAX_FORMAT (sizeof(FLAGS) + 2 + 10) static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { @@ -914,24 +888,11 @@ static int str_format (lua_State *L) { nb = sprintf(buff, form, luaL_checkint(L, arg)); break; } - case 'd': case 'i': { - lua_Number n = luaL_checknumber(L, arg); - LUA_INTFRM_T ni = (LUA_INTFRM_T)n; - lua_Number diff = n - (lua_Number)ni; - luaL_argcheck(L, -1 < diff && diff < 1, arg, - "not a number in proper range"); - addlenmod(form, LUA_INTFRMLEN); - nb = sprintf(buff, form, ni); - break; - } + case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { - lua_Number n = luaL_checknumber(L, arg); - unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n; - lua_Number diff = n - (lua_Number)ni; - luaL_argcheck(L, -1 < diff && diff < 1, arg, - "not a non-negative number in proper range"); - addlenmod(form, LUA_INTFRMLEN); - nb = sprintf(buff, form, ni); + lua_Integer n = luaL_checkinteger(L, arg); + addlenmod(form, LUA_INTEGER_FRMLEN); + nb = sprintf(buff, form, n); break; } case 'e': case 'E': case 'f': @@ -939,8 +900,8 @@ static int str_format (lua_State *L) { case 'a': case 'A': #endif case 'g': case 'G': { - addlenmod(form, LUA_FLTFRMLEN); - nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); + addlenmod(form, LUA_NUMBER_FRMLEN); + nb = sprintf(buff, form, luaL_checknumber(L, arg)); break; } case 'q': { |