diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-10-27 11:30:24 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-10-27 11:30:24 -0200 |
commit | fa4d5c86895fa176c4d7435a23d48a053b15b176 (patch) | |
tree | 28e9a9443ca198560484dcf275fbd4ff623399ee /lstrlib.c | |
parent | aef2d711b1d8457ecb5531d1e79d448453e8303c (diff) | |
download | lua-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.c | 30 |
1 files changed, 11 insertions, 19 deletions
@@ -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 | */ |
1109 | static KOption getdetails (Header *h, size_t totalsize, | 1107 | static 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 | /* }====================================================== */ |