diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-02-27 13:56:20 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-02-27 13:56:20 -0300 |
commit | 054179c2ffb108eb0c6535bed6288f70217c96ab (patch) | |
tree | ec291d2ac795f75e29fc37df07d33689bb399be6 /lundump.c | |
parent | 986c11daa66b6f0004f878bcbb9deaf5edbe15ee (diff) | |
download | lua-054179c2ffb108eb0c6535bed6288f70217c96ab.tar.gz lua-054179c2ffb108eb0c6535bed6288f70217c96ab.tar.bz2 lua-054179c2ffb108eb0c6535bed6288f70217c96ab.zip |
more explicit handling of headers for binary chunks
Diffstat (limited to 'lundump.c')
-rw-r--r-- | lundump.c | 74 |
1 files changed, 29 insertions, 45 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lundump.c,v 2.24 2013/08/16 18:55:49 roberto Exp roberto $ | 2 | ** $Id: lundump.c,v 2.25 2014/02/13 12:11:34 roberto Exp roberto $ |
3 | ** load precompiled Lua chunks | 3 | ** load precompiled Lua chunks |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -84,11 +84,9 @@ static TString* LoadString(LoadState* S) | |||
84 | return NULL; | 84 | return NULL; |
85 | else | 85 | else |
86 | { | 86 | { |
87 | TString* ts; | ||
88 | char* s=luaZ_openspace(S->L,S->b,size); | 87 | char* s=luaZ_openspace(S->L,S->b,size); |
89 | LoadBlock(S,s,size*sizeof(char)); | 88 | LoadBlock(S,s,size*sizeof(char)); |
90 | ts = luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ | 89 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ |
91 | return ts; | ||
92 | } | 90 | } |
93 | } | 91 | } |
94 | 92 | ||
@@ -193,23 +191,34 @@ static void LoadFunction(LoadState* S, Proto* f) | |||
193 | LoadDebug(S,f); | 191 | LoadDebug(S,f); |
194 | } | 192 | } |
195 | 193 | ||
196 | /* the code below must be consistent with the code in luaU_header */ | 194 | static void checkstring(LoadState *S, const char *s, const char *msg) |
197 | #define N0 LUAC_HEADERSIZE | 195 | { |
198 | #define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) | 196 | char buff[sizeof(LUA_SIGNATURE)+sizeof(LUAC_DATA)]; /* larger than each */ |
199 | #define N2 N1+2 | 197 | LoadMem(S,buff,strlen(s)+1,sizeof(char)); |
200 | #define N3 N2+6 | 198 | if (strcmp(s,buff)!=0) error(S,msg); |
199 | } | ||
200 | |||
201 | static void fchecksize(LoadState *S, size_t size, const char *tname) | ||
202 | { | ||
203 | if (LoadByte(S) != size) | ||
204 | error(S,luaO_pushfstring(S->L,"%s size mismatch in",tname)); | ||
205 | } | ||
206 | |||
207 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) | ||
201 | 208 | ||
202 | static void LoadHeader(LoadState* S) | 209 | static void checkHeader(LoadState* S) |
203 | { | 210 | { |
204 | lu_byte h[LUAC_HEADERSIZE]; | 211 | checkstring(S,LUA_SIGNATURE+1,"not a"); |
205 | lu_byte s[LUAC_HEADERSIZE]; | 212 | checkstring(S,LUAC_DATA,"corrupted"); |
206 | luaU_header(h); | 213 | if (LoadByte(S) != LUAC_VERSION) error(S,"version mismatch in"); |
207 | memcpy(s,h,sizeof(char)); /* first char already read */ | 214 | if (LoadByte(S) != LUAC_FORMAT) error(S,"format mismatch in"); |
208 | LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); | 215 | checksize(S,int); |
209 | if (memcmp(h,s,N0)==0) return; | 216 | checksize(S,size_t); |
210 | if (memcmp(h,s,N1)!=0) error(S,"not a"); | 217 | checksize(S,Instruction); |
211 | if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); | 218 | checksize(S,lua_Integer); |
212 | if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); | 219 | checksize(S,lua_Number); |
220 | if (LoadInteger(S) != LUAC_INT) error(S,"endianess mismatch in"); | ||
221 | if (LoadNumber(S) != LUAC_NUM) error(S,"float format mismatch in"); | ||
213 | } | 222 | } |
214 | 223 | ||
215 | /* | 224 | /* |
@@ -228,7 +237,7 @@ Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) | |||
228 | S.L=L; | 237 | S.L=L; |
229 | S.Z=Z; | 238 | S.Z=Z; |
230 | S.b=buff; | 239 | S.b=buff; |
231 | LoadHeader(&S); | 240 | checkHeader(&S); |
232 | cl=luaF_newLclosure(L,1); | 241 | cl=luaF_newLclosure(L,1); |
233 | setclLvalue(L,L->top,cl); incr_top(L); | 242 | setclLvalue(L,L->top,cl); incr_top(L); |
234 | cl->l.p=luaF_newproto(L); | 243 | cl->l.p=luaF_newproto(L); |
@@ -243,28 +252,3 @@ Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) | |||
243 | luai_verifycode(L,buff,cl->l.p); | 252 | luai_verifycode(L,buff,cl->l.p); |
244 | return cl; | 253 | return cl; |
245 | } | 254 | } |
246 | |||
247 | #define MYINT(s) (s[0]-'0') | ||
248 | #define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) | ||
249 | #define FORMAT 0 /* this is the official format */ | ||
250 | |||
251 | /* | ||
252 | * make header for precompiled chunks | ||
253 | * if you change the code below be sure to update LoadHeader and FORMAT above | ||
254 | * and LUAC_HEADERSIZE in lundump.h | ||
255 | */ | ||
256 | void luaU_header (lu_byte* h) | ||
257 | { | ||
258 | int x=1; | ||
259 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); | ||
260 | h+=sizeof(LUA_SIGNATURE)-sizeof(char); | ||
261 | *h++=cast_byte(VERSION); | ||
262 | *h++=cast_byte(FORMAT); | ||
263 | *h++=cast_byte(*(char*)&x); /* endianness */ | ||
264 | *h++=cast_byte(sizeof(int)); | ||
265 | *h++=cast_byte(sizeof(size_t)); | ||
266 | *h++=cast_byte(sizeof(Instruction)); | ||
267 | *h++=cast_byte(sizeof(lua_Number)); | ||
268 | *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ | ||
269 | memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); | ||
270 | } | ||