|
@@ -1447,14 +1447,14 @@ typedef enum KOption {
|
|
|
*/
|
|
|
static int digit (int c) { return '0' <= c && c <= '9'; }
|
|
|
|
|
|
-static int getnum (const char **fmt, int df) {
|
|
|
+static size_t getnum (const char **fmt, size_t df) {
|
|
|
if (!digit(**fmt)) /* no number? */
|
|
|
return df; /* return default value */
|
|
|
else {
|
|
|
- int a = 0;
|
|
|
+ size_t a = 0;
|
|
|
do {
|
|
|
a = a*10 + (*((*fmt)++) - '0');
|
|
|
- } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10);
|
|
|
+ } while (digit(**fmt) && a <= (MAX_SIZE - 9)/10);
|
|
|
return a;
|
|
|
}
|
|
|
}
|
|
@@ -1462,14 +1462,14 @@ static int getnum (const char **fmt, int df) {
|
|
|
|
|
|
/*
|
|
|
** Read an integer numeral and raises an error if it is larger
|
|
|
-** than the maximum size for integers.
|
|
|
+** than the maximum size of integers.
|
|
|
*/
|
|
|
static int getnumlimit (Header *h, const char **fmt, int df) {
|
|
|
- int sz = getnum(fmt, df);
|
|
|
- if (l_unlikely(sz > MAXINTSIZE || sz <= 0))
|
|
|
+ size_t sz = getnum(fmt, df);
|
|
|
+ if (l_unlikely((sz - 1u) >= MAXINTSIZE))
|
|
|
return luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
|
|
|
sz, MAXINTSIZE);
|
|
|
- return sz;
|
|
|
+ return cast_int(sz);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1486,7 +1486,7 @@ static void initheader (lua_State *L, Header *h) {
|
|
|
/*
|
|
|
** Read and classify next option. 'size' is filled with option's size.
|
|
|
*/
|
|
|
-static KOption getoption (Header *h, const char **fmt, int *size) {
|
|
|
+static KOption getoption (Header *h, const char **fmt, size_t *size) {
|
|
|
/* dummy structure to get native alignment requirements */
|
|
|
struct cD { char c; union { LUAI_MAXALIGN; } u; };
|
|
|
int opt = *((*fmt)++);
|
|
@@ -1508,8 +1508,8 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
|
|
|
case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint;
|
|
|
case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring;
|
|
|
case 'c':
|
|
|
- *size = getnum(fmt, -1);
|
|
|
- if (l_unlikely(*size == -1))
|
|
|
+ *size = getnum(fmt, cast_sizet(-1));
|
|
|
+ if (l_unlikely(*size == cast_sizet(-1)))
|
|
|
luaL_error(h->L, "missing size for format option 'c'");
|
|
|
return Kchar;
|
|
|
case 'z': return Kzstr;
|
|
@@ -1540,9 +1540,9 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
|
|
|
** despite its size.
|
|
|
*/
|
|
|
static KOption getdetails (Header *h, size_t totalsize,
|
|
|
- const char **fmt, int *psize, int *ntoalign) {
|
|
|
+ const char **fmt, size_t *psize, int *ntoalign) {
|
|
|
KOption opt = getoption(h, fmt, psize);
|
|
|
- int align = *psize; /* usually, alignment follows size */
|
|
|
+ size_t align = *psize; /* usually, alignment follows size */
|
|
|
if (opt == Kpaddalign) { /* 'X' gets alignment from following option */
|
|
|
if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0)
|
|
|
luaL_argerror(h->L, 1, "invalid next option for option 'X'");
|
|
@@ -1550,9 +1550,9 @@ static KOption getdetails (Header *h, size_t totalsize,
|
|
|
if (align <= 1 || opt == Kchar) /* need no alignment? */
|
|
|
*ntoalign = 0;
|
|
|
else {
|
|
|
- if (align > h->maxalign) /* enforce maximum alignment */
|
|
|
+ if (align > cast_sizet(h->maxalign)) /* enforce maximum alignment */
|
|
|
align = h->maxalign;
|
|
|
- if (l_unlikely((align & (align - 1)) != 0)) /* not a power of 2? */
|
|
|
+ if (l_unlikely(!ispow2(align))) /* not a power of 2? */
|
|
|
luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
|
|
|
*ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1);
|
|
|
}
|
|
@@ -1609,8 +1609,11 @@ static int str_pack (lua_State *L) {
|
|
|
lua_pushnil(L); /* mark to separate arguments from string buffer */
|
|
|
luaL_buffinit(L, &b);
|
|
|
while (*fmt != '\0') {
|
|
|
- int size, ntoalign;
|
|
|
+ int ntoalign;
|
|
|
+ size_t size;
|
|
|
KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
|
|
|
+ luaL_argcheck(L, size + ntoalign <= MAX_SIZE - totalsize, arg,
|
|
|
+ "result too long");
|
|
|
totalsize += ntoalign + size;
|
|
|
while (ntoalign-- > 0)
|
|
|
luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */
|
|
@@ -1660,18 +1663,21 @@ static int str_pack (lua_State *L) {
|
|
|
case Kchar: { /* fixed-size string */
|
|
|
size_t len;
|
|
|
const char *s = luaL_checklstring(L, arg, &len);
|
|
|
- luaL_argcheck(L, len <= (size_t)size, arg,
|
|
|
- "string longer than given size");
|
|
|
+ luaL_argcheck(L, len <= size, arg, "string longer than given size");
|
|
|
luaL_addlstring(&b, s, len); /* add string */
|
|
|
- while (len++ < (size_t)size) /* pad extra space */
|
|
|
- luaL_addchar(&b, LUAL_PACKPADBYTE);
|
|
|
+ if (len < size) { /* does it need padding? */
|
|
|
+ size_t psize = size - len; /* pad size */
|
|
|
+ char *buff = luaL_prepbuffsize(&b, psize);
|
|
|
+ memset(buff, LUAL_PACKPADBYTE, psize);
|
|
|
+ luaL_addsize(&b, psize);
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
case Kstring: { /* strings with length count */
|
|
|
size_t len;
|
|
|
const char *s = luaL_checklstring(L, arg, &len);
|
|
|
- luaL_argcheck(L, size >= (int)sizeof(size_t) ||
|
|
|
- len < ((size_t)1 << (size * NB)),
|
|
|
+ luaL_argcheck(L, size >= sizeof(lua_Unsigned) ||
|
|
|
+ len < ((lua_Unsigned)1 << (size * NB)),
|
|
|
arg, "string length does not fit in given size");
|
|
|
packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */
|
|
|
luaL_addlstring(&b, s, len);
|
|
@@ -1701,19 +1707,20 @@ static int str_pack (lua_State *L) {
|
|
|
static int str_packsize (lua_State *L) {
|
|
|
Header h;
|
|
|
const char *fmt = luaL_checkstring(L, 1); /* format string */
|
|
|
- size_t totalsize = 0; /* accumulate total size of result */
|
|
|
+ lua_Integer totalsize = 0; /* accumulate total size of result */
|
|
|
initheader(L, &h);
|
|
|
while (*fmt != '\0') {
|
|
|
- int size, ntoalign;
|
|
|
+ int ntoalign;
|
|
|
+ size_t size;
|
|
|
KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
|
|
|
luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1,
|
|
|
"variable-length format");
|
|
|
size += ntoalign; /* total space used by option */
|
|
|
- luaL_argcheck(L, totalsize <= MAXSIZE - size, 1,
|
|
|
- "format result too large");
|
|
|
+ luaL_argcheck(L, totalsize <= LUA_MAXINTEGER - cast(lua_Integer, size),
|
|
|
+ 1, "format result too large");
|
|
|
totalsize += size;
|
|
|
}
|
|
|
- lua_pushinteger(L, (lua_Integer)totalsize);
|
|
|
+ lua_pushinteger(L, totalsize);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -1762,9 +1769,10 @@ static int str_unpack (lua_State *L) {
|
|
|
luaL_argcheck(L, pos <= ld, 3, "initial position out of string");
|
|
|
initheader(L, &h);
|
|
|
while (*fmt != '\0') {
|
|
|
- int size, ntoalign;
|
|
|
+ int ntoalign;
|
|
|
+ size_t size;
|
|
|
KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
|
|
|
- luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2,
|
|
|
+ luaL_argcheck(L, ntoalign + size <= ld - pos, 2,
|
|
|
"data string too short");
|
|
|
pos += ntoalign; /* skip alignment */
|
|
|
/* stack space for item + next position */
|
|
@@ -1801,7 +1809,8 @@ static int str_unpack (lua_State *L) {
|
|
|
break;
|
|
|
}
|
|
|
case Kstring: {
|
|
|
- size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0);
|
|
|
+ lua_Unsigned len = (lua_Unsigned)unpackint(L, data + pos,
|
|
|
+ h.islittle, size, 0);
|
|
|
luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short");
|
|
|
lua_pushlstring(L, data + pos + size, len);
|
|
|
pos += len; /* skip string */
|