aboutsummaryrefslogtreecommitdiff
path: root/lundump.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lundump.c73
1 files changed, 45 insertions, 28 deletions
diff --git a/lundump.c b/lundump.c
index d074a073..76f0ddc1 100644
--- a/lundump.c
+++ b/lundump.c
@@ -37,7 +37,7 @@ typedef struct {
37 const char *name; 37 const char *name;
38 Table *h; /* list for string reuse */ 38 Table *h; /* list for string reuse */
39 size_t offset; /* current position relative to beginning of dump */ 39 size_t offset; /* current position relative to beginning of dump */
40 lua_Integer nstr; /* number of strings in the list */ 40 lua_Unsigned nstr; /* number of strings in the list */
41 lu_byte fixed; /* dump is fixed in memory */ 41 lu_byte fixed; /* dump is fixed in memory */
42} LoadState; 42} LoadState;
43 43
@@ -94,8 +94,8 @@ static lu_byte loadByte (LoadState *S) {
94} 94}
95 95
96 96
97static size_t loadVarint (LoadState *S, size_t limit) { 97static lua_Unsigned loadVarint (LoadState *S, lua_Unsigned limit) {
98 size_t x = 0; 98 lua_Unsigned x = 0;
99 int b; 99 int b;
100 limit >>= 7; 100 limit >>= 7;
101 do { 101 do {
@@ -109,7 +109,7 @@ static size_t loadVarint (LoadState *S, size_t limit) {
109 109
110 110
111static size_t loadSize (LoadState *S) { 111static size_t loadSize (LoadState *S) {
112 return loadVarint(S, MAX_SIZE); 112 return cast_sizet(loadVarint(S, MAX_SIZE));
113} 113}
114 114
115 115
@@ -127,9 +127,12 @@ static lua_Number loadNumber (LoadState *S) {
127 127
128 128
129static lua_Integer loadInteger (LoadState *S) { 129static lua_Integer loadInteger (LoadState *S) {
130 lua_Integer x; 130 lua_Unsigned cx = loadVarint(S, LUA_MAXUNSIGNED);
131 loadVar(S, x); 131 /* decode unsigned to signed */
132 return x; 132 if ((cx & 1) != 0)
133 return l_castU2S(~(cx >> 1));
134 else
135 return l_castU2S(cx >> 1);
133} 136}
134 137
135 138
@@ -149,10 +152,11 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
149 return; 152 return;
150 } 153 }
151 else if (size == 1) { /* previously saved string? */ 154 else if (size == 1) { /* previously saved string? */
152 lua_Integer idx = cast(lua_Integer, loadSize(S)); /* get its index */ 155 lua_Unsigned idx = loadVarint(S, LUA_MAXUNSIGNED); /* get its index */
153 TValue stv; 156 TValue stv;
154 luaH_getint(S->h, idx, &stv); /* get its value */ 157 if (novariant(luaH_getint(S->h, l_castU2S(idx), &stv)) != LUA_TSTRING)
155 *sl = ts = tsvalue(&stv); 158 error(S, "invalid string index");
159 *sl = ts = tsvalue(&stv); /* get its value */
156 luaC_objbarrier(L, p, ts); 160 luaC_objbarrier(L, p, ts);
157 return; /* do not save it again */ 161 return; /* do not save it again */
158 } 162 }
@@ -175,7 +179,7 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
175 /* add string to list of saved strings */ 179 /* add string to list of saved strings */
176 S->nstr++; 180 S->nstr++;
177 setsvalue(L, &sv, ts); 181 setsvalue(L, &sv, ts);
178 luaH_setint(L, S->h, S->nstr, &sv); 182 luaH_setint(L, S->h, l_castU2S(S->nstr), &sv);
179 luaC_objbarrierback(L, obj2gco(S->h), ts); 183 luaC_objbarrierback(L, obj2gco(S->h), ts);
180} 184}
181 185
@@ -234,7 +238,7 @@ static void loadConstants (LoadState *S, Proto *f) {
234 f->source = NULL; 238 f->source = NULL;
235 break; 239 break;
236 } 240 }
237 default: lua_assert(0); 241 default: error(S, "invalid constant");
238 } 242 }
239 } 243 }
240} 244}
@@ -345,13 +349,29 @@ static void checkliteral (LoadState *S, const char *s, const char *msg) {
345} 349}
346 350
347 351
348static void fchecksize (LoadState *S, size_t size, const char *tname) { 352static l_noret numerror (LoadState *S, const char *what, const char *tname) {
349 if (loadByte(S) != size) 353 const char *msg = luaO_pushfstring(S->L, "%s %s mismatch", tname, what);
350 error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); 354 error(S, msg);
351} 355}
352 356
353 357
354#define checksize(S,t) fchecksize(S,sizeof(t),#t) 358static void checknumsize (LoadState *S, int size, const char *tname) {
359 if (size != loadByte(S))
360 numerror(S, "size", tname);
361}
362
363
364static void checknumformat (LoadState *S, int eq, const char *tname) {
365 if (!eq)
366 numerror(S, "format", tname);
367}
368
369
370#define checknum(S,tvar,value,tname) \
371 { tvar i; checknumsize(S, sizeof(i), tname); \
372 loadVar(S, i); \
373 checknumformat(S, i == value, tname); }
374
355 375
356static void checkHeader (LoadState *S) { 376static void checkHeader (LoadState *S) {
357 /* skip 1st char (already read and checked) */ 377 /* skip 1st char (already read and checked) */
@@ -361,13 +381,10 @@ static void checkHeader (LoadState *S) {
361 if (loadByte(S) != LUAC_FORMAT) 381 if (loadByte(S) != LUAC_FORMAT)
362 error(S, "format mismatch"); 382 error(S, "format mismatch");
363 checkliteral(S, LUAC_DATA, "corrupted chunk"); 383 checkliteral(S, LUAC_DATA, "corrupted chunk");
364 checksize(S, Instruction); 384 checknum(S, int, LUAC_INT, "int");
365 checksize(S, lua_Integer); 385 checknum(S, Instruction, LUAC_INST, "instruction");
366 checksize(S, lua_Number); 386 checknum(S, lua_Integer, LUAC_INT, "Lua integer");
367 if (loadInteger(S) != LUAC_INT) 387 checknum(S, lua_Number, LUAC_NUM, "Lua number");
368 error(S, "integer format mismatch");
369 if (loadNumber(S) != LUAC_NUM)
370 error(S, "float format mismatch");
371} 388}
372 389
373 390
@@ -378,11 +395,10 @@ LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name, int fixed) {
378 LoadState S; 395 LoadState S;
379 LClosure *cl; 396 LClosure *cl;
380 if (*name == '@' || *name == '=') 397 if (*name == '@' || *name == '=')
381 S.name = name + 1; 398 name = name + 1;
382 else if (*name == LUA_SIGNATURE[0]) 399 else if (*name == LUA_SIGNATURE[0])
383 S.name = "binary string"; 400 name = "binary string";
384 else 401 S.name = name;
385 S.name = name;
386 S.L = L; 402 S.L = L;
387 S.Z = Z; 403 S.Z = Z;
388 S.fixed = cast_byte(fixed); 404 S.fixed = cast_byte(fixed);
@@ -398,7 +414,8 @@ LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name, int fixed) {
398 cl->p = luaF_newproto(L); 414 cl->p = luaF_newproto(L);
399 luaC_objbarrier(L, cl, cl->p); 415 luaC_objbarrier(L, cl, cl->p);
400 loadFunction(&S, cl->p); 416 loadFunction(&S, cl->p);
401 lua_assert(cl->nupvalues == cl->p->sizeupvalues); 417 if (cl->nupvalues != cl->p->sizeupvalues)
418 error(&S, "corrupted chunk");
402 luai_verifycode(L, cl->p); 419 luai_verifycode(L, cl->p);
403 L->top.p--; /* pop table */ 420 L->top.p--; /* pop table */
404 return cl; 421 return cl;