summaryrefslogtreecommitdiff
path: root/src/lstrlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lstrlib.c')
-rw-r--r--src/lstrlib.c109
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': {