libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

lundump.c (6444B)


      1 /*
      2 ** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $
      3 ** load precompiled Lua chunks
      4 ** See Copyright Notice in lua.h
      5 */
      6 
      7 #define lundump_c
      8 #define LUA_CORE
      9 
     10 #include "lprefix.h"
     11 
     12 
     13 #include <string.h>
     14 
     15 #include "lua.h"
     16 
     17 #include "ldebug.h"
     18 #include "ldo.h"
     19 #include "lfunc.h"
     20 #include "lmem.h"
     21 #include "lobject.h"
     22 #include "lstring.h"
     23 #include "lundump.h"
     24 #include "lzio.h"
     25 
     26 
     27 #if !defined(luai_verifycode)
     28 #define luai_verifycode(L,b,f)  /* empty */
     29 #endif
     30 
     31 
     32 typedef struct {
     33   lua_State *L;
     34   ZIO *Z;
     35   const char *name;
     36 } LoadState;
     37 
     38 
     39 static l_noret error(LoadState *S, const char *why) {
     40   luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why);
     41   luaD_throw(S->L, LUA_ERRSYNTAX);
     42 }
     43 
     44 
     45 /*
     46 ** All high-level loads go through LoadVector; you can change it to
     47 ** adapt to the endianness of the input
     48 */
     49 #define LoadVector(S,b,n)	LoadBlock(S,b,(n)*sizeof((b)[0]))
     50 
     51 static void LoadBlock (LoadState *S, void *b, size_t size) {
     52   if (luaZ_read(S->Z, b, size) != 0)
     53     error(S, "truncated");
     54 }
     55 
     56 
     57 #define LoadVar(S,x)		LoadVector(S,&x,1)
     58 
     59 
     60 static lu_byte LoadByte (LoadState *S) {
     61   lu_byte x;
     62   LoadVar(S, x);
     63   return x;
     64 }
     65 
     66 
     67 static int LoadInt (LoadState *S) {
     68   int x;
     69   LoadVar(S, x);
     70   return x;
     71 }
     72 
     73 
     74 static lua_Number LoadNumber (LoadState *S) {
     75   lua_Number x;
     76   LoadVar(S, x);
     77   return x;
     78 }
     79 
     80 
     81 static lua_Integer LoadInteger (LoadState *S) {
     82   lua_Integer x;
     83   LoadVar(S, x);
     84   return x;
     85 }
     86 
     87 
     88 static TString *LoadString (LoadState *S, Proto *p) {
     89   lua_State *L = S->L;
     90   size_t size = LoadByte(S);
     91   TString *ts;
     92   if (size == 0xFF)
     93     LoadVar(S, size);
     94   if (size == 0)
     95     return NULL;
     96   else if (--size <= LUAI_MAXSHORTLEN) {  /* short string? */
     97     char buff[LUAI_MAXSHORTLEN];
     98     LoadVector(S, buff, size);
     99     ts = luaS_newlstr(L, buff, size);
    100   }
    101   else {  /* long string */
    102     ts = luaS_createlngstrobj(L, size);
    103     setsvalue2s(L, L->top, ts);  /* anchor it ('loadVector' can GC) */
    104     luaD_inctop(L);
    105     LoadVector(S, getstr(ts), size);  /* load directly in final place */
    106     L->top--;  /* pop string */
    107   }
    108   luaC_objbarrier(L, p, ts);
    109   return ts;
    110 }
    111 
    112 
    113 static void LoadCode (LoadState *S, Proto *f) {
    114   int n = LoadInt(S);
    115   f->code = luaM_newvector(S->L, n, Instruction);
    116   f->sizecode = n;
    117   LoadVector(S, f->code, n);
    118 }
    119 
    120 
    121 static void LoadFunction(LoadState *S, Proto *f, TString *psource);
    122 
    123 
    124 static void LoadConstants (LoadState *S, Proto *f) {
    125   int i;
    126   int n = LoadInt(S);
    127   f->k = luaM_newvector(S->L, n, TValue);
    128   f->sizek = n;
    129   for (i = 0; i < n; i++)
    130     setnilvalue(&f->k[i]);
    131   for (i = 0; i < n; i++) {
    132     TValue *o = &f->k[i];
    133     int t = LoadByte(S);
    134     switch (t) {
    135     case LUA_TNIL:
    136       setnilvalue(o);
    137       break;
    138     case LUA_TBOOLEAN:
    139       setbvalue(o, LoadByte(S));
    140       break;
    141     case LUA_TNUMFLT:
    142       setfltvalue(o, LoadNumber(S));
    143       break;
    144     case LUA_TNUMINT:
    145       setivalue(o, LoadInteger(S));
    146       break;
    147     case LUA_TSHRSTR:
    148     case LUA_TLNGSTR:
    149       setsvalue2n(S->L, o, LoadString(S, f));
    150       break;
    151     default:
    152       lua_assert(0);
    153     }
    154   }
    155 }
    156 
    157 
    158 static void LoadProtos (LoadState *S, Proto *f) {
    159   int i;
    160   int n = LoadInt(S);
    161   f->p = luaM_newvector(S->L, n, Proto *);
    162   f->sizep = n;
    163   for (i = 0; i < n; i++)
    164     f->p[i] = NULL;
    165   for (i = 0; i < n; i++) {
    166     f->p[i] = luaF_newproto(S->L);
    167     luaC_objbarrier(S->L, f, f->p[i]);
    168     LoadFunction(S, f->p[i], f->source);
    169   }
    170 }
    171 
    172 
    173 static void LoadUpvalues (LoadState *S, Proto *f) {
    174   int i, n;
    175   n = LoadInt(S);
    176   f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
    177   f->sizeupvalues = n;
    178   for (i = 0; i < n; i++)
    179     f->upvalues[i].name = NULL;
    180   for (i = 0; i < n; i++) {
    181     f->upvalues[i].instack = LoadByte(S);
    182     f->upvalues[i].idx = LoadByte(S);
    183   }
    184 }
    185 
    186 
    187 static void LoadDebug (LoadState *S, Proto *f) {
    188   int i, n;
    189   n = LoadInt(S);
    190   f->lineinfo = luaM_newvector(S->L, n, int);
    191   f->sizelineinfo = n;
    192   LoadVector(S, f->lineinfo, n);
    193   n = LoadInt(S);
    194   f->locvars = luaM_newvector(S->L, n, LocVar);
    195   f->sizelocvars = n;
    196   for (i = 0; i < n; i++)
    197     f->locvars[i].varname = NULL;
    198   for (i = 0; i < n; i++) {
    199     f->locvars[i].varname = LoadString(S, f);
    200     f->locvars[i].startpc = LoadInt(S);
    201     f->locvars[i].endpc = LoadInt(S);
    202   }
    203   n = LoadInt(S);
    204   for (i = 0; i < n; i++)
    205     f->upvalues[i].name = LoadString(S, f);
    206 }
    207 
    208 
    209 static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
    210   f->source = LoadString(S, f);
    211   if (f->source == NULL)  /* no source in dump? */
    212     f->source = psource;  /* reuse parent's source */
    213   f->linedefined = LoadInt(S);
    214   f->lastlinedefined = LoadInt(S);
    215   f->numparams = LoadByte(S);
    216   f->is_vararg = LoadByte(S);
    217   f->maxstacksize = LoadByte(S);
    218   LoadCode(S, f);
    219   LoadConstants(S, f);
    220   LoadUpvalues(S, f);
    221   LoadProtos(S, f);
    222   LoadDebug(S, f);
    223 }
    224 
    225 
    226 static void checkliteral (LoadState *S, const char *s, const char *msg) {
    227   char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
    228   size_t len = strlen(s);
    229   LoadVector(S, buff, len);
    230   if (memcmp(s, buff, len) != 0)
    231     error(S, msg);
    232 }
    233 
    234 
    235 static void fchecksize (LoadState *S, size_t size, const char *tname) {
    236   if (LoadByte(S) != size)
    237     error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
    238 }
    239 
    240 
    241 #define checksize(S,t)	fchecksize(S,sizeof(t),#t)
    242 
    243 static void checkHeader (LoadState *S) {
    244   checkliteral(S, LUA_SIGNATURE + 1, "not a");  /* 1st char already checked */
    245   if (LoadByte(S) != LUAC_VERSION)
    246     error(S, "version mismatch in");
    247   if (LoadByte(S) != LUAC_FORMAT)
    248     error(S, "format mismatch in");
    249   checkliteral(S, LUAC_DATA, "corrupted");
    250   checksize(S, int);
    251   checksize(S, size_t);
    252   checksize(S, Instruction);
    253   checksize(S, lua_Integer);
    254   checksize(S, lua_Number);
    255   if (LoadInteger(S) != LUAC_INT)
    256     error(S, "endianness mismatch in");
    257   if (LoadNumber(S) != LUAC_NUM)
    258     error(S, "float format mismatch in");
    259 }
    260 
    261 
    262 /*
    263 ** load precompiled chunk
    264 */
    265 LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
    266   LoadState S;
    267   LClosure *cl;
    268   if (*name == '@' || *name == '=')
    269     S.name = name + 1;
    270   else if (*name == LUA_SIGNATURE[0])
    271     S.name = "binary string";
    272   else
    273     S.name = name;
    274   S.L = L;
    275   S.Z = Z;
    276   checkHeader(&S);
    277   cl = luaF_newLclosure(L, LoadByte(&S));
    278   setclLvalue(L, L->top, cl);
    279   luaD_inctop(L);
    280   cl->p = luaF_newproto(L);
    281   luaC_objbarrier(L, cl, cl->p);
    282   LoadFunction(&S, cl->p, NULL);
    283   lua_assert(cl->nupvalues == cl->p->sizeupvalues);
    284   luai_verifycode(L, buff, cl->p);
    285   return cl;
    286 }
    287