aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-04-10 16:45:43 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-04-10 16:45:43 -0300
commit115fa770091881d27bf265c61078dd80f17fd1a0 (patch)
tree081185f79ccaadfac21b1c60b436d0d3c83498ef
parent561030c211a8de6b46554fca4df13925b38a4758 (diff)
downloadlua-115fa770091881d27bf265c61078dd80f17fd1a0.tar.gz
lua-115fa770091881d27bf265c61078dd80f17fd1a0.tar.bz2
lua-115fa770091881d27bf265c61078dd80f17fd1a0.zip
maximum size for dump of integers is size of lua_Integer (which
means that there is no overflows when undumping)
-rw-r--r--lstrlib.c53
1 files changed, 17 insertions, 36 deletions
diff --git a/lstrlib.c b/lstrlib.c
index 32ba2632..de5ec0fc 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.192 2014/04/03 13:29:24 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.193 2014/04/10 18:24:12 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*/
@@ -946,9 +946,6 @@ static int str_format (lua_State *L) {
946** ======================================================= 946** =======================================================
947*/ 947*/
948 948
949/* maximum size for the binary representation of an integer */
950#define MAXINTSIZE 8
951
952 949
953/* number of bits in a character */ 950/* number of bits in a character */
954#define NB CHAR_BIT 951#define NB CHAR_BIT
@@ -959,9 +956,12 @@ static int str_format (lua_State *L) {
959/* mask for one character without sign ((NB - 1) ones) */ 956/* mask for one character without sign ((NB - 1) ones) */
960#define SM ((1 << (NB - 1)) - 1) 957#define SM ((1 << (NB - 1)) - 1)
961 958
962 959/* size of a lua_Integer */
963#define SZINT ((int)sizeof(lua_Integer)) 960#define SZINT ((int)sizeof(lua_Integer))
964 961
962/* maximum size for the binary representation of an integer */
963#define MAXINTSIZE SZINT
964
965 965
966static union { 966static union {
967 int dummy; 967 int dummy;
@@ -989,7 +989,7 @@ static int getintsize (lua_State *L, int arg) {
989} 989}
990 990
991 991
992static int dumpint (char *buff, lua_Integer n, int littleendian, int size) { 992static int dumpint (char *buff, lua_Unsigned n, int littleendian, int size) {
993 int i; 993 int i;
994 if (littleendian) { 994 if (littleendian) {
995 for (i = 0; i < size - 1; i++) { 995 for (i = 0; i < size - 1; i++) {
@@ -1004,10 +1004,13 @@ static int dumpint (char *buff, lua_Integer n, int littleendian, int size) {
1004 } 1004 }
1005 } 1005 }
1006 buff[i] = (n & MC); /* last byte */ 1006 buff[i] = (n & MC); /* last byte */
1007 /* test for overflow: OK if there are only zeros left in higher bytes, 1007 if (size < SZINT) { /* need test for overflow? */
1008 or if there are only ones left and dumped number is negative (signal 1008 /* OK if there are only zeros left in higher bytes,
1009 bit, the higher bit in last byte, is one) */ 1009 or only ones left (excluding non-signal bits in last byte) */
1010 return ((n & ~(lua_Integer)MC) == 0 || (n | SM) == ~(lua_Integer)0); 1010 return ((n & ~(lua_Integer)MC) == 0 ||
1011 (n | SM) == (~(lua_Unsigned)0 >> ((size - 1) * NB)));
1012 }
1013 else return 1; /* no overflow can occur with full size */
1011} 1014}
1012 1015
1013 1016
@@ -1016,7 +1019,7 @@ static int dumpint_l (lua_State *L) {
1016 lua_Integer n = luaL_checkinteger(L, 1); 1019 lua_Integer n = luaL_checkinteger(L, 1);
1017 int size = getintsize(L, 2); 1020 int size = getintsize(L, 2);
1018 int endian = getendian(L, 3); 1021 int endian = getendian(L, 3);
1019 if (dumpint(buff, n, endian, size)) 1022 if (dumpint(buff, (lua_Unsigned)n, endian, size))
1020 lua_pushlstring(L, buff, size); 1023 lua_pushlstring(L, buff, size);
1021 else 1024 else
1022 luaL_error(L, "integer does not fit into given size (%d)", size); 1025 luaL_error(L, "integer does not fit into given size (%d)", size);
@@ -1024,27 +1027,10 @@ static int dumpint_l (lua_State *L) {
1024} 1027}
1025 1028
1026 1029
1027/* mask to check higher-order byte in a Lua integer */ 1030static lua_Integer undumpint (const char *buff, int littleendian, int size) {
1028#define HIGHERBYTE ((lua_Unsigned)MC << (NB * (SZINT - 1)))
1029
1030/* mask to check higher-order byte + signal bit of next (lower) byte */
1031#define HIGHERBYTE1 (HIGHERBYTE | (HIGHERBYTE >> 1))
1032
1033static int undumpint (const char *buff, lua_Integer *res,
1034 int littleendian, int size) {
1035 lua_Integer n = 0; 1031 lua_Integer n = 0;
1036 int i; 1032 int i;
1037 for (i = 0; i < size; i++) { 1033 for (i = 0; i < size; i++) {
1038 if (i >= SZINT) { /* will throw away a byte? */
1039 /* check for overflow: it is OK to throw away leading zeros for a
1040 positive number, leading ones for a negative number, and a
1041 leading zero byte to allow unsigned integers with a 1 in
1042 its "signal bit" */
1043 if (!((n & HIGHERBYTE1) == 0 || /* zeros for positive number */
1044 (n & HIGHERBYTE1) == HIGHERBYTE1 || /* ones for negative number */
1045 ((n & HIGHERBYTE) == 0 && i == size - 1))) /* leading zero */
1046 return 0; /* overflow */
1047 }
1048 n <<= NB; 1034 n <<= NB;
1049 n |= (lua_Integer)(unsigned char)buff[littleendian ? size - 1 - i : i]; 1035 n |= (lua_Integer)(unsigned char)buff[littleendian ? size - 1 - i : i];
1050 } 1036 }
@@ -1052,13 +1038,11 @@ static int undumpint (const char *buff, lua_Integer *res,
1052 lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); 1038 lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1);
1053 n = (lua_Integer)((n ^ mask) - mask); /* do sign extension */ 1039 n = (lua_Integer)((n ^ mask) - mask); /* do sign extension */
1054 } 1040 }
1055 *res = n; 1041 return n;
1056 return 1;
1057} 1042}
1058 1043
1059 1044
1060static int undumpint_l (lua_State *L) { 1045static int undumpint_l (lua_State *L) {
1061 lua_Integer res;
1062 size_t len; 1046 size_t len;
1063 const char *s = luaL_checklstring(L, 1, &len); 1047 const char *s = luaL_checklstring(L, 1, &len);
1064 lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len); 1048 lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len);
@@ -1066,10 +1050,7 @@ static int undumpint_l (lua_State *L) {
1066 int endian = getendian(L, 4); 1050 int endian = getendian(L, 4);
1067 luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1, 1051 luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1,
1068 "string too short"); 1052 "string too short");
1069 if(undumpint(s + pos - 1, &res, endian, size)) 1053 lua_pushinteger(L, undumpint(s + pos - 1, endian, size));
1070 lua_pushinteger(L, res);
1071 else
1072 luaL_error(L, "result does not fit into a Lua integer");
1073 return 1; 1054 return 1;
1074} 1055}
1075 1056