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 | |
| 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)
| -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 | /* }====================================================== */ |
