aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-10-27 11:30:24 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-10-27 11:30:24 -0200
commitfa4d5c86895fa176c4d7435a23d48a053b15b176 (patch)
tree28e9a9443ca198560484dcf275fbd4ff623399ee /lstrlib.c
parentaef2d711b1d8457ecb5531d1e79d448453e8303c (diff)
downloadlua-fa4d5c86895fa176c4d7435a23d48a053b15b176.tar.gz
lua-fa4d5c86895fa176c4d7435a23d48a053b15b176.tar.bz2
lua-fa4d5c86895fa176c4d7435a23d48a053b15b176.zip
pack/unpack do not handle final '\0' as an "option" (it streches
unnecessarily the switch range)
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c30
1 files changed, 11 insertions, 19 deletions
diff --git a/lstrlib.c b/lstrlib.c
index 3eae0793..fad66510 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.206 2014/10/24 11:42:29 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.207 2014/10/25 11:50:46 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*/
@@ -1012,8 +1012,7 @@ typedef enum KOption {
1012 Kzstr, /* zero-terminated strings */ 1012 Kzstr, /* zero-terminated strings */
1013 Kpadding, /* padding */ 1013 Kpadding, /* padding */
1014 Kpaddalign, /* padding for alignment */ 1014 Kpaddalign, /* padding for alignment */
1015 Knop, /* no-op (configuration or spaces) */ 1015 Knop /* no-op (configuration or spaces) */
1016 Keof /* end of format */
1017} KOption; 1016} KOption;
1018 1017
1019 1018
@@ -1085,7 +1084,6 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
1085 case 'x': *size = 1; return Kpadding; 1084 case 'x': *size = 1; return Kpadding;
1086 case 'X': return Kpaddalign; 1085 case 'X': return Kpaddalign;
1087 case ' ': return Knop; 1086 case ' ': return Knop;
1088 case '\0': return Keof;
1089 case '<': h->islittle = 1; return Knop; 1087 case '<': h->islittle = 1; return Knop;
1090 case '>': h->islittle = 0; return Knop; 1088 case '>': h->islittle = 0; return Knop;
1091 case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); return Knop; 1089 case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); return Knop;
@@ -1108,14 +1106,10 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
1108*/ 1106*/
1109static KOption getdetails (Header *h, size_t totalsize, 1107static KOption getdetails (Header *h, size_t totalsize,
1110 const char **fmt, int *psize, int *ntoalign) { 1108 const char **fmt, int *psize, int *ntoalign) {
1111 int align; 1109 KOption opt = getoption(h, fmt, psize);
1112 KOption opt; 1110 int align = *psize; /* usually, alignment follows size */
1113 do {
1114 opt = getoption(h, fmt, psize);
1115 } while (opt == Knop); /* skip no-op options */
1116 align = *psize; /* usually, alignment follows size */
1117 if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ 1111 if (opt == Kpaddalign) { /* 'X' gets alignment from following option */
1118 if (getoption(h, fmt, &align) == Kchar || align == 0) 1112 if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0)
1119 luaL_argerror(h->L, 1, "invalid next option for option 'X'"); 1113 luaL_argerror(h->L, 1, "invalid next option for option 'X'");
1120 } 1114 }
1121 if (align <= 1 || opt == Kchar) /* need no alignment? */ 1115 if (align <= 1 || opt == Kchar) /* need no alignment? */
@@ -1171,7 +1165,7 @@ static int str_pack (lua_State *L) {
1171 initheader(L, &h); 1165 initheader(L, &h);
1172 lua_pushnil(L); /* mark to separate arguments from string buffer */ 1166 lua_pushnil(L); /* mark to separate arguments from string buffer */
1173 luaL_buffinit(L, &b); 1167 luaL_buffinit(L, &b);
1174 for (;;) { 1168 while (*fmt != '\0') {
1175 int size, ntoalign; 1169 int size, ntoalign;
1176 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); 1170 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1177 totalsize += ntoalign + size; 1171 totalsize += ntoalign + size;
@@ -1239,11 +1233,10 @@ static int str_pack (lua_State *L) {
1239 case Kpaddalign: case Knop: 1233 case Kpaddalign: case Knop:
1240 arg--; /* undo increment */ 1234 arg--; /* undo increment */
1241 break; 1235 break;
1242 case Keof: /* end of format */
1243 luaL_pushresult(&b);
1244 return 1;
1245 } 1236 }
1246 } 1237 }
1238 luaL_pushresult(&b);
1239 return 1;
1247} 1240}
1248 1241
1249 1242
@@ -1282,7 +1275,7 @@ static int str_unpack (lua_State *L) {
1282 int n = 0; /* number of results */ 1275 int n = 0; /* number of results */
1283 luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); 1276 luaL_argcheck(L, pos <= ld, 3, "initial position out of string");
1284 initheader(L, &h); 1277 initheader(L, &h);
1285 for (;;) { 1278 while (*fmt != '\0') {
1286 int size, ntoalign; 1279 int size, ntoalign;
1287 KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); 1280 KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
1288 if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) 1281 if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld)
@@ -1329,12 +1322,11 @@ static int str_unpack (lua_State *L) {
1329 case Kpaddalign: case Kpadding: case Knop: 1322 case Kpaddalign: case Kpadding: case Knop:
1330 n--; /* undo increment */ 1323 n--; /* undo increment */
1331 break; 1324 break;
1332 case Keof: /* end of format */
1333 lua_pushinteger(L, pos + 1); /* next position */
1334 return n;
1335 } 1325 }
1336 pos += size; 1326 pos += size;
1337 } 1327 }
1328 lua_pushinteger(L, pos + 1); /* next position */
1329 return n + 1;
1338} 1330}
1339 1331
1340/* }====================================================== */ 1332/* }====================================================== */