aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lstrlib.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/lstrlib.c b/lstrlib.c
index 321d6a0b..d9735903 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -132,27 +132,31 @@ static int str_upper (lua_State *L) {
132} 132}
133 133
134 134
135/*
136** MAX_SIZE is limited both by size_t and lua_Integer.
137** When x <= MAX_SIZE, x can be safely cast to size_t or lua_Integer.
138*/
135static int str_rep (lua_State *L) { 139static int str_rep (lua_State *L) {
136 size_t l, lsep; 140 size_t len, lsep;
137 const char *s = luaL_checklstring(L, 1, &l); 141 const char *s = luaL_checklstring(L, 1, &len);
138 lua_Integer n = luaL_checkinteger(L, 2); 142 lua_Integer n = luaL_checkinteger(L, 2);
139 const char *sep = luaL_optlstring(L, 3, "", &lsep); 143 const char *sep = luaL_optlstring(L, 3, "", &lsep);
140 if (n <= 0) 144 if (n <= 0)
141 lua_pushliteral(L, ""); 145 lua_pushliteral(L, "");
142 else if (l_unlikely(l + lsep < l || l + lsep > MAX_SIZE / cast_sizet(n))) 146 else if (l_unlikely(len > MAX_SIZE - lsep ||
147 cast_st2S(len + lsep) > cast_st2S(MAX_SIZE) / n))
143 return luaL_error(L, "resulting string too large"); 148 return luaL_error(L, "resulting string too large");
144 else { 149 else {
145 size_t totallen = ((size_t)n * (l + lsep)) - lsep; 150 size_t totallen = (cast_sizet(n) * (len + lsep)) - lsep;
146 luaL_Buffer b; 151 luaL_Buffer b;
147 char *p = luaL_buffinitsize(L, &b, totallen); 152 char *p = luaL_buffinitsize(L, &b, totallen);
148 while (n-- > 1) { /* first n-1 copies (followed by separator) */ 153 while (n-- > 1) { /* first n-1 copies (followed by separator) */
149 memcpy(p, s, l * sizeof(char)); p += l; 154 memcpy(p, s, len * sizeof(char)); p += len;
150 if (lsep > 0) { /* empty 'memcpy' is not that cheap */ 155 if (lsep > 0) { /* empty 'memcpy' is not that cheap */
151 memcpy(p, sep, lsep * sizeof(char)); 156 memcpy(p, sep, lsep * sizeof(char)); p += lsep;
152 p += lsep;
153 } 157 }
154 } 158 }
155 memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ 159 memcpy(p, s, len * sizeof(char)); /* last copy without separator */
156 luaL_pushresultsize(&b, totallen); 160 luaL_pushresultsize(&b, totallen);
157 } 161 }
158 return 1; 162 return 1;
@@ -1544,8 +1548,10 @@ static KOption getdetails (Header *h, size_t totalsize, const char **fmt,
1544 else { 1548 else {
1545 if (align > h->maxalign) /* enforce maximum alignment */ 1549 if (align > h->maxalign) /* enforce maximum alignment */
1546 align = h->maxalign; 1550 align = h->maxalign;
1547 if (l_unlikely(!ispow2(align))) /* not a power of 2? */ 1551 if (l_unlikely(!ispow2(align))) { /* not a power of 2? */
1552 *ntoalign = 0; /* to avoid warnings */
1548 luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); 1553 luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
1554 }
1549 else { 1555 else {
1550 /* 'szmoda' = totalsize % align */ 1556 /* 'szmoda' = totalsize % align */
1551 unsigned szmoda = cast_uint(totalsize & (align - 1)); 1557 unsigned szmoda = cast_uint(totalsize & (align - 1));
@@ -1809,8 +1815,8 @@ static int str_unpack (lua_State *L) {
1809 lua_Unsigned len = (lua_Unsigned)unpackint(L, data + pos, 1815 lua_Unsigned len = (lua_Unsigned)unpackint(L, data + pos,
1810 h.islittle, cast_int(size), 0); 1816 h.islittle, cast_int(size), 0);
1811 luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); 1817 luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short");
1812 lua_pushlstring(L, data + pos + size, len); 1818 lua_pushlstring(L, data + pos + size, cast_sizet(len));
1813 pos += len; /* skip string */ 1819 pos += cast_sizet(len); /* skip string */
1814 break; 1820 break;
1815 } 1821 }
1816 case Kzstr: { 1822 case Kzstr: {