aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldump.c13
-rw-r--r--lundump.c38
-rw-r--r--lundump.h5
-rw-r--r--testes/calls.lua47
4 files changed, 67 insertions, 36 deletions
diff --git a/ldump.c b/ldump.c
index 71d9a5b1..54f96674 100644
--- a/ldump.c
+++ b/ldump.c
@@ -253,16 +253,19 @@ static void dumpFunction (DumpState *D, const Proto *f) {
253} 253}
254 254
255 255
256#define dumpNumInfo(D, tvar, value) \
257 { tvar i = value; dumpByte(D, sizeof(tvar)); dumpVar(D, i); }
258
259
256static void dumpHeader (DumpState *D) { 260static void dumpHeader (DumpState *D) {
257 dumpLiteral(D, LUA_SIGNATURE); 261 dumpLiteral(D, LUA_SIGNATURE);
258 dumpByte(D, LUAC_VERSION); 262 dumpByte(D, LUAC_VERSION);
259 dumpByte(D, LUAC_FORMAT); 263 dumpByte(D, LUAC_FORMAT);
260 dumpLiteral(D, LUAC_DATA); 264 dumpLiteral(D, LUAC_DATA);
261 dumpByte(D, sizeof(Instruction)); 265 dumpNumInfo(D, int, LUAC_INT);
262 dumpByte(D, sizeof(lua_Integer)); 266 dumpNumInfo(D, Instruction, LUAC_INST);
263 dumpByte(D, sizeof(lua_Number)); 267 dumpNumInfo(D, lua_Integer, LUAC_INT);
264 dumpInteger(D, LUAC_INT); 268 dumpNumInfo(D, lua_Number, LUAC_NUM);
265 dumpNumber(D, LUAC_NUM);
266} 269}
267 270
268 271
diff --git a/lundump.c b/lundump.c
index d074a073..d53bfc9a 100644
--- a/lundump.c
+++ b/lundump.c
@@ -345,13 +345,29 @@ static void checkliteral (LoadState *S, const char *s, const char *msg) {
345} 345}
346 346
347 347
348static void fchecksize (LoadState *S, size_t size, const char *tname) { 348static l_noret numerror (LoadState *S, const char *what, const char *tname) {
349 if (loadByte(S) != size) 349 const char *msg = luaO_pushfstring(S->L, "%s %s mismatch", tname, what);
350 error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); 350 error(S, msg);
351} 351}
352 352
353 353
354#define checksize(S,t) fchecksize(S,sizeof(t),#t) 354static void checknumsize (LoadState *S, int size, const char *tname) {
355 if (size != loadByte(S))
356 numerror(S, "size", tname);
357}
358
359
360static void checknumformat (LoadState *S, int eq, const char *tname) {
361 if (!eq)
362 numerror(S, "format", tname);
363}
364
365
366#define checknum(S,tvar,value,tname) \
367 { tvar i; checknumsize(S, sizeof(i), tname); \
368 loadVar(S, i); \
369 checknumformat(S, i == value, tname); }
370
355 371
356static void checkHeader (LoadState *S) { 372static void checkHeader (LoadState *S) {
357 /* skip 1st char (already read and checked) */ 373 /* skip 1st char (already read and checked) */
@@ -361,13 +377,10 @@ static void checkHeader (LoadState *S) {
361 if (loadByte(S) != LUAC_FORMAT) 377 if (loadByte(S) != LUAC_FORMAT)
362 error(S, "format mismatch"); 378 error(S, "format mismatch");
363 checkliteral(S, LUAC_DATA, "corrupted chunk"); 379 checkliteral(S, LUAC_DATA, "corrupted chunk");
364 checksize(S, Instruction); 380 checknum(S, int, LUAC_INT, "int");
365 checksize(S, lua_Integer); 381 checknum(S, Instruction, LUAC_INST, "instruction");
366 checksize(S, lua_Number); 382 checknum(S, lua_Integer, LUAC_INT, "Lua integer");
367 if (loadInteger(S) != LUAC_INT) 383 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} 384}
372 385
373 386
@@ -398,7 +411,8 @@ LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name, int fixed) {
398 cl->p = luaF_newproto(L); 411 cl->p = luaF_newproto(L);
399 luaC_objbarrier(L, cl, cl->p); 412 luaC_objbarrier(L, cl, cl->p);
400 loadFunction(&S, cl->p); 413 loadFunction(&S, cl->p);
401 lua_assert(cl->nupvalues == cl->p->sizeupvalues); 414 if (cl->nupvalues != cl->p->sizeupvalues)
415 error(&S, "corrupted chunk");
402 luai_verifycode(L, cl->p); 416 luai_verifycode(L, cl->p);
403 L->top.p--; /* pop table */ 417 L->top.p--; /* pop table */
404 return cl; 418 return cl;
diff --git a/lundump.h b/lundump.h
index 1d6e50ea..c4e06f9e 100644
--- a/lundump.h
+++ b/lundump.h
@@ -17,8 +17,9 @@
17/* data to catch conversion errors */ 17/* data to catch conversion errors */
18#define LUAC_DATA "\x19\x93\r\n\x1a\n" 18#define LUAC_DATA "\x19\x93\r\n\x1a\n"
19 19
20#define LUAC_INT 0x5678 20#define LUAC_INT -0x5678
21#define LUAC_NUM cast_num(370.5) 21#define LUAC_INST 0x12345678
22#define LUAC_NUM cast_num(-370.5)
22 23
23/* 24/*
24** Encode major-minor version in one byte, one nibble for each 25** Encode major-minor version in one byte, one nibble for each
diff --git a/testes/calls.lua b/testes/calls.lua
index 31028215..8b355957 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -480,15 +480,22 @@ assert((function (a) return a end)() == nil)
480 480
481print("testing binary chunks") 481print("testing binary chunks")
482do 482do
483 local header = string.pack("c4BBc6BBB", 483 local headformat = "c4BBc6BiBI4BjBn"
484 "\27Lua", -- signature 484 local header = { -- header components
485 0x55, -- version 5.5 (0x55) 485 "\27Lua", -- signature
486 0, -- format 486 0x55, -- version 5.5 (0x55)
487 "\x19\x93\r\n\x1a\n", -- data 487 0, -- format
488 4, -- size of instruction 488 "\x19\x93\r\n\x1a\n", -- a binary string
489 string.packsize("j"), -- sizeof(lua integer) 489 string.packsize("i"), -- size of an int
490 string.packsize("n") -- sizeof(lua number) 490 -0x5678, -- an int
491 ) 491 4, -- size of an instruction
492 0x12345678, -- an instruction (4 bytes)
493 string.packsize("j"), -- size of a Lua integer
494 -0x5678, -- a Lua integer
495 string.packsize("n"), -- size of a Lua float
496 -370.5, -- a Lua float
497 }
498
492 local c = string.dump(function () 499 local c = string.dump(function ()
493 local a = 1; local b = 3; 500 local a = 1; local b = 3;
494 local f = function () return a + b + _ENV.c; end -- upvalues 501 local f = function () return a + b + _ENV.c; end -- upvalues
@@ -500,17 +507,23 @@ do
500 assert(assert(load(c))() == 10) 507 assert(assert(load(c))() == 10)
501 508
502 -- check header 509 -- check header
503 assert(string.sub(c, 1, #header) == header) 510 local t = {string.unpack(headformat, c)}
504 -- check LUAC_INT and LUAC_NUM
505 local ci, cn = string.unpack("jn", c, #header + 1)
506 assert(ci == 0x5678 and cn == 370.5)
507
508 -- corrupted header
509 for i = 1, #header do 511 for i = 1, #header do
512 assert(t[i] == header[i])
513 end
514
515 -- Testing corrupted header.
516 -- A single wrong byte in the head invalidates the chunk,
517 -- except for the Lua float check. (If numbers are long double,
518 -- the representation may need padding, and changing that padding
519 -- will not invalidate the chunk.)
520 local headlen = string.packsize(headformat)
521 headlen = headlen - string.packsize("n") -- remove float check
522 for i = 1, headlen do
510 local s = string.sub(c, 1, i - 1) .. 523 local s = string.sub(c, 1, i - 1) ..
511 string.char(string.byte(string.sub(c, i, i)) + 1) .. 524 string.char((string.byte(string.sub(c, i, i)) + 1) & 0xFF) ..
512 string.sub(c, i + 1, -1) 525 string.sub(c, i + 1, -1)
513 assert(#s == #c) 526 assert(#s == #c and s ~= c)
514 assert(not load(s)) 527 assert(not load(s))
515 end 528 end
516 529