diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-10 15:21:32 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-10 15:21:32 -0300 |
commit | b5b1995f2925b2f9be4a48304ac97a38f8608648 (patch) | |
tree | 6935ced2337eb900029ccb119636185df5037fd8 | |
parent | cb88c1cd5d22fe7c56f4f374ded7c16f7cf14bf3 (diff) | |
download | lua-b5b1995f2925b2f9be4a48304ac97a38f8608648.tar.gz lua-b5b1995f2925b2f9be4a48304ac97a38f8608648.tar.bz2 lua-b5b1995f2925b2f9be4a48304ac97a38f8608648.zip |
Checks for type 'int' added to binary header
The structure 'AbsLineInfo' is hard-dumped into binary chunks, and
it comprises two 'int' fields.
-rw-r--r-- | ldump.c | 13 | ||||
-rw-r--r-- | lundump.c | 38 | ||||
-rw-r--r-- | lundump.h | 5 | ||||
-rw-r--r-- | testes/calls.lua | 47 |
4 files changed, 67 insertions, 36 deletions
@@ -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 | |||
256 | static void dumpHeader (DumpState *D) { | 260 | static 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 | ||
@@ -345,13 +345,29 @@ static void checkliteral (LoadState *S, const char *s, const char *msg) { | |||
345 | } | 345 | } |
346 | 346 | ||
347 | 347 | ||
348 | static void fchecksize (LoadState *S, size_t size, const char *tname) { | 348 | static 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) | 354 | static void checknumsize (LoadState *S, int size, const char *tname) { |
355 | if (size != loadByte(S)) | ||
356 | numerror(S, "size", tname); | ||
357 | } | ||
358 | |||
359 | |||
360 | static 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 | ||
356 | static void checkHeader (LoadState *S) { | 372 | static 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; |
@@ -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 | ||
481 | print("testing binary chunks") | 481 | print("testing binary chunks") |
482 | do | 482 | do |
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 | ||