aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-05-25 10:39:32 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-05-25 10:39:32 -0300
commitb2d4d0642849319f90df48c067ba71c32d763523 (patch)
treef8ef0ff328a76cc7d257dc81d1ac841db88a26cb /lstrlib.c
parent3b8dba5279e98e03a194f048a82fcab9945bbbed (diff)
downloadlua-b2d4d0642849319f90df48c067ba71c32d763523.tar.gz
lua-b2d4d0642849319f90df48c067ba71c32d763523.tar.bz2
lua-b2d4d0642849319f90df48c067ba71c32d763523.zip
avoid possible overflows when checking sizes in 'string.unpack'
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/lstrlib.c b/lstrlib.c
index 54692a6e..b43464ab 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.261 2018/02/21 13:48:44 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.262 2018/02/21 17:48:31 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*/
@@ -1522,17 +1522,12 @@ static int str_packsize (lua_State *L) {
1522 while (*fmt != '\0') { 1522 while (*fmt != '\0') {
1523 int size, ntoalign; 1523 int size, ntoalign;
1524 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); 1524 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1525 luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1,
1526 "variable-length format");
1525 size += ntoalign; /* total space used by option */ 1527 size += ntoalign; /* total space used by option */
1526 luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, 1528 luaL_argcheck(L, totalsize <= MAXSIZE - size, 1,
1527 "format result too large"); 1529 "format result too large");
1528 totalsize += size; 1530 totalsize += size;
1529 switch (opt) {
1530 case Kstring: /* strings with length count */
1531 case Kzstr: /* zero-terminated string */
1532 luaL_argerror(L, 1, "variable-length format");
1533 /* call never return, but to avoid warnings: *//* FALLTHROUGH */
1534 default: break;
1535 }
1536 } 1531 }
1537 lua_pushinteger(L, (lua_Integer)totalsize); 1532 lua_pushinteger(L, (lua_Integer)totalsize);
1538 return 1; 1533 return 1;
@@ -1585,8 +1580,8 @@ static int str_unpack (lua_State *L) {
1585 while (*fmt != '\0') { 1580 while (*fmt != '\0') {
1586 int size, ntoalign; 1581 int size, ntoalign;
1587 KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); 1582 KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
1588 if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) 1583 luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2,
1589 luaL_argerror(L, 2, "data string too short"); 1584 "data string too short");
1590 pos += ntoalign; /* skip alignment */ 1585 pos += ntoalign; /* skip alignment */
1591 /* stack space for item + next position */ 1586 /* stack space for item + next position */
1592 luaL_checkstack(L, 2, "too many results"); 1587 luaL_checkstack(L, 2, "too many results");
@@ -1615,13 +1610,15 @@ static int str_unpack (lua_State *L) {
1615 } 1610 }
1616 case Kstring: { 1611 case Kstring: {
1617 size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); 1612 size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0);
1618 luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); 1613 luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short");
1619 lua_pushlstring(L, data + pos + size, len); 1614 lua_pushlstring(L, data + pos + size, len);
1620 pos += len; /* skip string */ 1615 pos += len; /* skip string */
1621 break; 1616 break;
1622 } 1617 }
1623 case Kzstr: { 1618 case Kzstr: {
1624 size_t len = (int)strlen(data + pos); 1619 size_t len = (int)strlen(data + pos);
1620 luaL_argcheck(L, pos + len < ld, 2,
1621 "unfinished string for format 'z'");
1625 lua_pushlstring(L, data + pos, len); 1622 lua_pushlstring(L, data + pos, len);
1626 pos += len + 1; /* skip string plus final '\0' */ 1623 pos += len + 1; /* skip string plus final '\0' */
1627 break; 1624 break;