Skip to content

Commit cf3a8a0

Browse files
committed
undump支持lua55
1 parent e542a8b commit cf3a8a0

File tree

1 file changed

+226
-20
lines changed

1 file changed

+226
-20
lines changed

extension/script/backend/worker/undump.lua

Lines changed: 226 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@ local function LoadByte()
1212
return unpack "B"
1313
end
1414

15-
local function LoadInteger()
16-
return unpack "j"
17-
end
18-
1915
local function LoadNumber()
2016
return unpack "n"
2117
end
2218

2319
local function LoadCharN(n)
24-
return unpack("c"..tostring(n))
20+
return unpack("c" .. tostring(n))
2521
end
2622

2723
local undump53; do
2824
local function LoadInt()
2925
return unpack "i"
3026
end
3127

28+
local function LoadInteger()
29+
return unpack "j"
30+
end
31+
3232
local function LoadString()
3333
local size = LoadByte()
3434
if size == 0xFF then
@@ -51,14 +51,17 @@ local undump53; do
5151
end
5252

5353
local function LoadConstants(f)
54-
local LUA_TNIL = 0
54+
local function makevariant(t, v) return t | (v << 4) end
55+
local LUA_TNIL = 0
5556
local LUA_TBOOLEAN = 1
56-
local LUA_TNUMFLT = 3 | (0 << 4)
57-
local LUA_TNUMINT = 3 | (1 << 4)
58-
local LUA_TSHRSTR = 4 | (0 << 4)
59-
local LUA_TLNGSTR = 4 | (1 << 4)
60-
f.sizek = LoadInt()
61-
f.k = {}
57+
local LUA_TNUMBER = 3
58+
local LUA_TSTRING = 4
59+
local LUA_TNUMFLT = makevariant(LUA_TNUMBER, 0)
60+
local LUA_TNUMINT = makevariant(LUA_TNUMBER, 1)
61+
local LUA_TSHRSTR = makevariant(LUA_TSTRING, 0)
62+
local LUA_TLNGSTR = makevariant(LUA_TSTRING, 1)
63+
f.sizek = LoadInt()
64+
f.k = {}
6265
for i = 1, f.sizek do
6366
local t = LoadByte()
6467
if t == LUA_TNIL then
@@ -73,7 +76,7 @@ local undump53; do
7376
elseif t == LUA_TLNGSTR then
7477
f.k[i] = LoadString()
7578
else
76-
error("unknown type: "..t)
79+
error(string.format("unknown constant type: <%d, %d>", t >> 4, t & 0xf))
7780
end
7881
end
7982
end
@@ -112,6 +115,9 @@ local undump53; do
112115
f.locvars[i].endpc = LoadInt()
113116
end
114117
local n = LoadInt()
118+
if n ~= 0 then
119+
n = f.sizeupvalues
120+
end
115121
for i = 1, n do
116122
f.upvalues[i].name = LoadString()
117123
end
@@ -138,8 +144,6 @@ local undump53; do
138144
local function CheckHeader()
139145
local LUAC_INT = 0x5678
140146
local LUAC_NUM = 370.5
141-
assert(LoadByte() == 0)
142-
assert(LoadCharN(6) == "\x19\x93\r\n\x1a\n")
143147
-- int
144148
assert(string.packsize "i" == LoadByte())
145149
-- size_t
@@ -163,13 +167,17 @@ local undump53; do
163167
end
164168

165169
local undump54; do
170+
local function LoadInteger()
171+
return unpack "j"
172+
end
173+
166174
local function LoadUnsigned(limit)
167175
local b
168176
local x = 0
169177
limit = limit >> 7
170178
repeat
171179
b = LoadByte()
172-
if x >= limit then
180+
if x > limit then
173181
error("integer overflow")
174182
end
175183
x = (x << 7) | (b & 0x7f)
@@ -228,7 +236,7 @@ local undump54; do
228236
elseif t == LUA_VSHRSTR or t == LUA_VLNGSTR then
229237
f.k[i] = LoadString()
230238
else
231-
error("unknown type: "..t)
239+
error(string.format("unknown constant type: <%d, %d>", t >> 4, t & 0xf))
232240
end
233241
end
234242
end
@@ -275,6 +283,9 @@ local undump54; do
275283
f.locvars[i].endpc = LoadInt()
276284
end
277285
local n = LoadInt()
286+
if n ~= 0 then
287+
n = f.sizeupvalues
288+
end
278289
for i = 1, n do
279290
f.upvalues[i].name = LoadString()
280291
end
@@ -301,8 +312,6 @@ local undump54; do
301312
local function CheckHeader()
302313
local LUAC_INT = 0x5678
303314
local LUAC_NUM = 370.5
304-
assert(LoadByte() == 0)
305-
assert(LoadCharN(6) == "\x19\x93\r\n\x1a\n")
306315
-- Instruction
307316
assert(string.packsize "i4" == LoadByte())
308317
-- lua_Integer
@@ -321,16 +330,213 @@ local undump54; do
321330
end
322331
end
323332

324-
return function (bytes)
333+
local undump55; do
334+
local cached = {}
335+
336+
local function LoadAlign(align)
337+
local padding = align - (unpack_pos - 1) % align
338+
if padding < align then
339+
unpack_pos = unpack_pos + padding
340+
assert((unpack_pos - 1) % align == 0)
341+
end
342+
end
343+
344+
local function LoadUnsigned(limit)
345+
local b
346+
local x = 0
347+
limit = limit >> 7
348+
repeat
349+
b = LoadByte()
350+
if x > limit then
351+
error("integer overflow")
352+
end
353+
x = (x << 7) | (b & 0x7f)
354+
until ((b & 0x80) == 0)
355+
return x
356+
end
357+
358+
local function LoadInteger()
359+
local cx = LoadUnsigned(math.maxinteger)
360+
if (cx & 1) ~= 0 then
361+
return ~(cx >> 1)
362+
else
363+
return cx >> 1
364+
end
365+
end
366+
367+
local function LoadInt()
368+
return LoadUnsigned(0x7fffffff)
369+
end
370+
371+
local function LoadString()
372+
local size = LoadUnsigned(math.maxinteger)
373+
if size == 0 then
374+
return nil
375+
end
376+
if size == 1 then
377+
local idx = LoadUnsigned(math.maxinteger)
378+
if not cached[idx] then
379+
error("invalid string index")
380+
end
381+
return cached[idx]
382+
end
383+
local str = LoadCharN(size - 1)
384+
cached[#cached + 1] = str
385+
return str
386+
end
387+
388+
local LoadFunction
389+
390+
local function LoadCode(f)
391+
f.sizecode = LoadInt()
392+
LoadAlign(4)
393+
f.code = {}
394+
for i = 1, f.sizecode do
395+
f.code[i] = unpack "i4"
396+
end
397+
end
398+
399+
local function LoadConstants(f)
400+
local function makevariant(t, v) return t | (v << 4) end
401+
local LUA_TNIL = 0
402+
local LUA_TBOOLEAN = 1
403+
local LUA_TNUMBER = 3
404+
local LUA_TSTRING = 4
405+
local LUA_VNIL = makevariant(LUA_TNIL, 0)
406+
local LUA_VFALSE = makevariant(LUA_TBOOLEAN, 0)
407+
local LUA_VTRUE = makevariant(LUA_TBOOLEAN, 1)
408+
local LUA_VNUMINT = makevariant(LUA_TNUMBER, 0)
409+
local LUA_VNUMFLT = makevariant(LUA_TNUMBER, 1)
410+
local LUA_VSHRSTR = makevariant(LUA_TSTRING, 0)
411+
local LUA_VLNGSTR = makevariant(LUA_TSTRING, 1)
412+
f.sizek = LoadInt()
413+
f.k = {}
414+
for i = 1, f.sizek do
415+
local t = LoadByte()
416+
if t == LUA_VNIL then
417+
elseif t == LUA_VTRUE then
418+
f.k[i] = true
419+
elseif t == LUA_VFALSE then
420+
f.k[i] = false
421+
elseif t == LUA_VNUMFLT then
422+
f.k[i] = LoadNumber()
423+
elseif t == LUA_VNUMINT then
424+
f.k[i] = LoadInteger()
425+
elseif t == LUA_VSHRSTR or t == LUA_VLNGSTR then
426+
f.k[i] = LoadString()
427+
else
428+
error(string.format("unknown constant type: <%d, %d>", t >> 4, t & 0xf))
429+
end
430+
end
431+
end
432+
433+
local function LoadUpvalues(f)
434+
f.sizeupvalues = LoadInt()
435+
f.upvalues = {}
436+
for i = 1, f.sizeupvalues do
437+
f.upvalues[i] = {}
438+
f.upvalues[i].instack = LoadByte()
439+
f.upvalues[i].idx = LoadByte()
440+
f.upvalues[i].kind = LoadByte()
441+
end
442+
end
443+
444+
local function LoadProtos(f)
445+
f.sizep = LoadInt()
446+
f.p = {}
447+
for i = 1, f.sizep do
448+
f.p[i] = {}
449+
LoadFunction(f.p[i], f.source)
450+
end
451+
end
452+
453+
local function LoadDebug(f)
454+
f.sizelineinfo = LoadInt()
455+
f.lineinfo = {}
456+
for i = 1, f.sizelineinfo do
457+
f.lineinfo[i] = unpack "b"
458+
end
459+
f.sizeabslineinfo = LoadInt()
460+
f.abslineinfo = {}
461+
if f.sizeabslineinfo > 0 then
462+
LoadAlign(4)
463+
for i = 1, f.sizeabslineinfo do
464+
f.abslineinfo[i] = {}
465+
f.abslineinfo[i].pc = unpack "i"
466+
f.abslineinfo[i].line = unpack "i"
467+
end
468+
end
469+
f.sizelocvars = LoadInt()
470+
f.locvars = {}
471+
for i = 1, f.sizelocvars do
472+
f.locvars[i] = {}
473+
f.locvars[i].varname = LoadString()
474+
f.locvars[i].startpc = LoadInt()
475+
f.locvars[i].endpc = LoadInt()
476+
end
477+
local n = LoadInt()
478+
if n ~= 0 then
479+
n = f.sizeupvalues
480+
end
481+
for i = 1, n do
482+
f.upvalues[i].name = LoadString()
483+
end
484+
end
485+
486+
function LoadFunction(f, psource)
487+
f.linedefined = LoadInt()
488+
f.lastlinedefined = LoadInt()
489+
f.numparams = LoadByte()
490+
f.is_vararg = LoadByte() & 1
491+
f.maxstacksize = LoadByte()
492+
LoadCode(f)
493+
LoadConstants(f)
494+
LoadUpvalues(f)
495+
LoadProtos(f)
496+
f.source = LoadString()
497+
if not f.source then
498+
f.source = psource
499+
end
500+
LoadDebug(f)
501+
return f
502+
end
503+
504+
local function CheckHeader()
505+
local LUAC_INT = -0x5678
506+
local LUAC_INST = 0x12345678
507+
local LUAC_NUM = -370.5
508+
assert(string.packsize "i" == LoadByte())
509+
assert(unpack "i" == LUAC_INT)
510+
assert(string.packsize "i4" == LoadByte())
511+
assert(unpack "i4" == LUAC_INST)
512+
assert(string.packsize "j" == LoadByte())
513+
assert(unpack "j" == LUAC_INT)
514+
assert(string.packsize "n" == LoadByte())
515+
assert(unpack "n" == LUAC_NUM)
516+
end
517+
518+
function undump55(cl)
519+
CheckHeader()
520+
cl.nupvalues = LoadByte()
521+
cl.f = {}
522+
LoadFunction(cl.f, nil)
523+
end
524+
end
525+
526+
return function(bytes)
325527
unpack_pos = 1
326528
unpack_buf = bytes
327529
assert(LoadCharN(4) == "\x1bLua")
328530
local Version = LoadByte()
531+
assert(LoadByte() == 0)
532+
assert(LoadCharN(6) == "\x19\x93\r\n\x1a\n")
329533
local cl = {}
330534
if Version == 0x53 then
331535
undump53(cl)
332536
elseif Version == 0x54 then
333537
undump54(cl)
538+
elseif Version == 0x55 then
539+
undump55(cl)
334540
else
335541
error(("unknown lua version: 0x%x"):format(Version))
336542
end

0 commit comments

Comments
 (0)