diff options
Diffstat (limited to 'lundump.c')
-rw-r--r-- | lundump.c | 38 |
1 files changed, 23 insertions, 15 deletions
@@ -10,6 +10,7 @@ | |||
10 | #include "lprefix.h" | 10 | #include "lprefix.h" |
11 | 11 | ||
12 | 12 | ||
13 | #include <limits.h> | ||
13 | #include <string.h> | 14 | #include <string.h> |
14 | 15 | ||
15 | #include "lua.h" | 16 | #include "lua.h" |
@@ -37,7 +38,7 @@ typedef struct { | |||
37 | 38 | ||
38 | 39 | ||
39 | static l_noret error (LoadState *S, const char *why) { | 40 | static l_noret error (LoadState *S, const char *why) { |
40 | luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); | 41 | luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why); |
41 | luaD_throw(S->L, LUA_ERRSYNTAX); | 42 | luaD_throw(S->L, LUA_ERRSYNTAX); |
42 | } | 43 | } |
43 | 44 | ||
@@ -50,7 +51,7 @@ static l_noret error (LoadState *S, const char *why) { | |||
50 | 51 | ||
51 | static void LoadBlock (LoadState *S, void *b, size_t size) { | 52 | static void LoadBlock (LoadState *S, void *b, size_t size) { |
52 | if (luaZ_read(S->Z, b, size) != 0) | 53 | if (luaZ_read(S->Z, b, size) != 0) |
53 | error(S, "truncated"); | 54 | error(S, "truncated chunk"); |
54 | } | 55 | } |
55 | 56 | ||
56 | 57 | ||
@@ -60,24 +61,32 @@ static void LoadBlock (LoadState *S, void *b, size_t size) { | |||
60 | static lu_byte LoadByte (LoadState *S) { | 61 | static lu_byte LoadByte (LoadState *S) { |
61 | int b = zgetc(S->Z); | 62 | int b = zgetc(S->Z); |
62 | if (b == EOZ) | 63 | if (b == EOZ) |
63 | error(S, "truncated"); | 64 | error(S, "truncated chunk"); |
64 | return cast_byte(b); | 65 | return cast_byte(b); |
65 | } | 66 | } |
66 | 67 | ||
67 | 68 | ||
68 | static size_t LoadSize (LoadState *S) { | 69 | static size_t LoadUnsigned (LoadState *S, size_t limit) { |
69 | size_t x = 0; | 70 | size_t x = 0; |
70 | int b; | 71 | int b; |
72 | limit >>= 7; | ||
71 | do { | 73 | do { |
72 | b = LoadByte(S); | 74 | b = LoadByte(S); |
75 | if (x >= limit) | ||
76 | error(S, "integer overflow"); | ||
73 | x = (x << 7) | (b & 0x7f); | 77 | x = (x << 7) | (b & 0x7f); |
74 | } while ((b & 0x80) == 0); | 78 | } while ((b & 0x80) == 0); |
75 | return x; | 79 | return x; |
76 | } | 80 | } |
77 | 81 | ||
78 | 82 | ||
83 | static size_t LoadSize (LoadState *S) { | ||
84 | return LoadUnsigned(S, ~(size_t)0); | ||
85 | } | ||
86 | |||
87 | |||
79 | static int LoadInt (LoadState *S) { | 88 | static int LoadInt (LoadState *S) { |
80 | return cast_int(LoadSize(S)); | 89 | return cast_int(LoadUnsigned(S, INT_MAX)); |
81 | } | 90 | } |
82 | 91 | ||
83 | 92 | ||
@@ -255,28 +264,27 @@ static void checkliteral (LoadState *S, const char *s, const char *msg) { | |||
255 | 264 | ||
256 | static void fchecksize (LoadState *S, size_t size, const char *tname) { | 265 | static void fchecksize (LoadState *S, size_t size, const char *tname) { |
257 | if (LoadByte(S) != size) | 266 | if (LoadByte(S) != size) |
258 | error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname)); | 267 | error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); |
259 | } | 268 | } |
260 | 269 | ||
261 | 270 | ||
262 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) | 271 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) |
263 | 272 | ||
264 | static void checkHeader (LoadState *S) { | 273 | static void checkHeader (LoadState *S) { |
265 | checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */ | 274 | /* 1st char already checked */ |
266 | if (LoadByte(S) != LUAC_VERSION) | 275 | checkliteral(S, LUA_SIGNATURE + 1, "not a binary chunk"); |
267 | error(S, "version mismatch in"); | 276 | if (LoadInt(S) != LUAC_VERSION) |
277 | error(S, "version mismatch"); | ||
268 | if (LoadByte(S) != LUAC_FORMAT) | 278 | if (LoadByte(S) != LUAC_FORMAT) |
269 | error(S, "format mismatch in"); | 279 | error(S, "format mismatch"); |
270 | checkliteral(S, LUAC_DATA, "corrupted"); | 280 | checkliteral(S, LUAC_DATA, "corrupted chunk"); |
271 | checksize(S, int); | ||
272 | checksize(S, size_t); | ||
273 | checksize(S, Instruction); | 281 | checksize(S, Instruction); |
274 | checksize(S, lua_Integer); | 282 | checksize(S, lua_Integer); |
275 | checksize(S, lua_Number); | 283 | checksize(S, lua_Number); |
276 | if (LoadInteger(S) != LUAC_INT) | 284 | if (LoadInteger(S) != LUAC_INT) |
277 | error(S, "endianness mismatch in"); | 285 | error(S, "integer format mismatch"); |
278 | if (LoadNumber(S) != LUAC_NUM) | 286 | if (LoadNumber(S) != LUAC_NUM) |
279 | error(S, "float format mismatch in"); | 287 | error(S, "float format mismatch"); |
280 | } | 288 | } |
281 | 289 | ||
282 | 290 | ||