Mon Apr 17 21:17:58 2023 UTC ()
lua: apply upstream bugfix for "Loading a corrupted binary file can segfault."


(nikita)
diff -r1.10 -r1.11 src/external/mit/lua/dist/src/ldump.c
diff -r1.9 -r1.10 src/external/mit/lua/dist/src/lundump.c

cvs diff -r1.10 -r1.11 src/external/mit/lua/dist/src/ldump.c (switch to unified diff)

--- src/external/mit/lua/dist/src/ldump.c 2023/04/16 20:46:17 1.10
+++ src/external/mit/lua/dist/src/ldump.c 2023/04/17 21:17:57 1.11
@@ -1,232 +1,242 @@ @@ -1,232 +1,242 @@
1/* $NetBSD: ldump.c,v 1.10 2023/04/16 20:46:17 nikita Exp $ */ 1/* $NetBSD: ldump.c,v 1.11 2023/04/17 21:17:57 nikita Exp $ */
2 2
3/* 3/*
4** Id: ldump.c  4** Id: ldump.c
5** save precompiled Lua chunks 5** save precompiled Lua chunks
6** See Copyright Notice in lua.h 6** See Copyright Notice in lua.h
7*/ 7*/
8 8
9#define ldump_c 9#define ldump_c
10#define LUA_CORE 10#define LUA_CORE
11 11
12#include "lprefix.h" 12#include "lprefix.h"
13 13
14 14
15#ifndef _KERNEL 15#ifndef _KERNEL
16#include <stddef.h> 16#include <stddef.h>
 17#include <limits.h>
17#endif /* _KERNEL */ 18#endif /* _KERNEL */
18 19
19#include "lua.h" 20#include "lua.h"
20 21
21#include "lobject.h" 22#include "lobject.h"
22#include "lstate.h" 23#include "lstate.h"
23#include "lundump.h" 24#include "lundump.h"
24 25
25 26
26typedef struct { 27typedef struct {
27 lua_State *L; 28 lua_State *L;
28 lua_Writer writer; 29 lua_Writer writer;
29 void *data; 30 void *data;
30 int strip; 31 int strip;
31 int status; 32 int status;
32} DumpState; 33} DumpState;
33 34
34 35
35/* 36/*
36** All high-level dumps go through dumpVector; you can change it to 37** All high-level dumps go through dumpVector; you can change it to
37** change the endianness of the result 38** change the endianness of the result
38*/ 39*/
39#define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0])) 40#define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0]))
40 41
41#define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) 42#define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char))
42 43
43 44
44static void dumpBlock (DumpState *D, const void *b, size_t size) { 45static void dumpBlock (DumpState *D, const void *b, size_t size) {
45 if (D->status == 0 && size > 0) { 46 if (D->status == 0 && size > 0) {
46 lua_unlock(D->L); 47 lua_unlock(D->L);
47 D->status = (*D->writer)(D->L, b, size, D->data); 48 D->status = (*D->writer)(D->L, b, size, D->data);
48 lua_lock(D->L); 49 lua_lock(D->L);
49 } 50 }
50} 51}
51 52
52 53
53#define dumpVar(D,x) dumpVector(D,&x,1) 54#define dumpVar(D,x) dumpVector(D,&x,1)
54 55
55 56
56static void dumpByte (DumpState *D, int y) { 57static void dumpByte (DumpState *D, int y) {
57 lu_byte x = (lu_byte)y; 58 lu_byte x = (lu_byte)y;
58 dumpVar(D, x); 59 dumpVar(D, x);
59} 60}
60 61
61 62
 63#ifdef _KERNEL
62/* dumpInt Buff Size */ 64/* dumpInt Buff Size */
63#define DIBS ((sizeof(size_t) * 8 / 7) + 1) 65#define DIBS ((sizeof(size_t) * 8 / 7) + 1)
 66#endif /* _KERNEL */
 67#ifndef _KERNEL
 68/*
 69** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6"
 70** rounds up the division.)
 71*/
 72#define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7)
 73#endif /* _KERNEL */
64 74
65static void dumpSize (DumpState *D, size_t x) { 75static void dumpSize (DumpState *D, size_t x) {
66 lu_byte buff[DIBS]; 76 lu_byte buff[DIBS];
67 int n = 0; 77 int n = 0;
68 do { 78 do {
69 buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ 79 buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */
70 x >>= 7; 80 x >>= 7;
71 } while (x != 0); 81 } while (x != 0);
72 buff[DIBS - 1] |= 0x80; /* mark last byte */ 82 buff[DIBS - 1] |= 0x80; /* mark last byte */
73 dumpVector(D, buff + DIBS - n, n); 83 dumpVector(D, buff + DIBS - n, n);
74} 84}
75 85
76 86
77static void dumpInt (DumpState *D, int x) { 87static void dumpInt (DumpState *D, int x) {
78 dumpSize(D, x); 88 dumpSize(D, x);
79} 89}
80 90
81 91
82static void dumpNumber (DumpState *D, lua_Number x) { 92static void dumpNumber (DumpState *D, lua_Number x) {
83 dumpVar(D, x); 93 dumpVar(D, x);
84} 94}
85 95
86 96
87static void dumpInteger (DumpState *D, lua_Integer x) { 97static void dumpInteger (DumpState *D, lua_Integer x) {
88 dumpVar(D, x); 98 dumpVar(D, x);
89} 99}
90 100
91 101
92static void dumpString (DumpState *D, const TString *s) { 102static void dumpString (DumpState *D, const TString *s) {
93 if (s == NULL) 103 if (s == NULL)
94 dumpSize(D, 0); 104 dumpSize(D, 0);
95 else { 105 else {
96 size_t size = tsslen(s); 106 size_t size = tsslen(s);
97 const char *str = getstr(s); 107 const char *str = getstr(s);
98 dumpSize(D, size + 1); 108 dumpSize(D, size + 1);
99 dumpVector(D, str, size); 109 dumpVector(D, str, size);
100 } 110 }
101} 111}
102 112
103 113
104static void dumpCode (DumpState *D, const Proto *f) { 114static void dumpCode (DumpState *D, const Proto *f) {
105 dumpInt(D, f->sizecode); 115 dumpInt(D, f->sizecode);
106 dumpVector(D, f->code, f->sizecode); 116 dumpVector(D, f->code, f->sizecode);
107} 117}
108 118
109 119
110static void dumpFunction(DumpState *D, const Proto *f, TString *psource); 120static void dumpFunction(DumpState *D, const Proto *f, TString *psource);
111 121
112static void dumpConstants (DumpState *D, const Proto *f) { 122static void dumpConstants (DumpState *D, const Proto *f) {
113 int i; 123 int i;
114 int n = f->sizek; 124 int n = f->sizek;
115 dumpInt(D, n); 125 dumpInt(D, n);
116 for (i = 0; i < n; i++) { 126 for (i = 0; i < n; i++) {
117 const TValue *o = &f->k[i]; 127 const TValue *o = &f->k[i];
118 int tt = ttypetag(o); 128 int tt = ttypetag(o);
119 dumpByte(D, tt); 129 dumpByte(D, tt);
120 switch (tt) { 130 switch (tt) {
121#ifndef _KERNEL 131#ifndef _KERNEL
122 case LUA_VNUMFLT: 132 case LUA_VNUMFLT:
123 dumpNumber(D, fltvalue(o)); 133 dumpNumber(D, fltvalue(o));
124 break; 134 break;
125#endif /* _KERNEL */ 135#endif /* _KERNEL */
126 case LUA_VNUMINT: 136 case LUA_VNUMINT:
127 dumpInteger(D, ivalue(o)); 137 dumpInteger(D, ivalue(o));
128 break; 138 break;
129 case LUA_VSHRSTR: 139 case LUA_VSHRSTR:
130 case LUA_VLNGSTR: 140 case LUA_VLNGSTR:
131 dumpString(D, tsvalue(o)); 141 dumpString(D, tsvalue(o));
132 break; 142 break;
133 default: 143 default:
134 lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE); 144 lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE);
135 } 145 }
136 } 146 }
137} 147}
138 148
139 149
140static void dumpProtos (DumpState *D, const Proto *f) { 150static void dumpProtos (DumpState *D, const Proto *f) {
141 int i; 151 int i;
142 int n = f->sizep; 152 int n = f->sizep;
143 dumpInt(D, n); 153 dumpInt(D, n);
144 for (i = 0; i < n; i++) 154 for (i = 0; i < n; i++)
145 dumpFunction(D, f->p[i], f->source); 155 dumpFunction(D, f->p[i], f->source);
146} 156}
147 157
148 158
149static void dumpUpvalues (DumpState *D, const Proto *f) { 159static void dumpUpvalues (DumpState *D, const Proto *f) {
150 int i, n = f->sizeupvalues; 160 int i, n = f->sizeupvalues;
151 dumpInt(D, n); 161 dumpInt(D, n);
152 for (i = 0; i < n; i++) { 162 for (i = 0; i < n; i++) {
153 dumpByte(D, f->upvalues[i].instack); 163 dumpByte(D, f->upvalues[i].instack);
154 dumpByte(D, f->upvalues[i].idx); 164 dumpByte(D, f->upvalues[i].idx);
155 dumpByte(D, f->upvalues[i].kind); 165 dumpByte(D, f->upvalues[i].kind);
156 } 166 }
157} 167}
158 168
159 169
160static void dumpDebug (DumpState *D, const Proto *f) { 170static void dumpDebug (DumpState *D, const Proto *f) {
161 int i, n; 171 int i, n;
162 n = (D->strip) ? 0 : f->sizelineinfo; 172 n = (D->strip) ? 0 : f->sizelineinfo;
163 dumpInt(D, n); 173 dumpInt(D, n);
164 dumpVector(D, f->lineinfo, n); 174 dumpVector(D, f->lineinfo, n);
165 n = (D->strip) ? 0 : f->sizeabslineinfo; 175 n = (D->strip) ? 0 : f->sizeabslineinfo;
166 dumpInt(D, n); 176 dumpInt(D, n);
167 for (i = 0; i < n; i++) { 177 for (i = 0; i < n; i++) {
168 dumpInt(D, f->abslineinfo[i].pc); 178 dumpInt(D, f->abslineinfo[i].pc);
169 dumpInt(D, f->abslineinfo[i].line); 179 dumpInt(D, f->abslineinfo[i].line);
170 } 180 }
171 n = (D->strip) ? 0 : f->sizelocvars; 181 n = (D->strip) ? 0 : f->sizelocvars;
172 dumpInt(D, n); 182 dumpInt(D, n);
173 for (i = 0; i < n; i++) { 183 for (i = 0; i < n; i++) {
174 dumpString(D, f->locvars[i].varname); 184 dumpString(D, f->locvars[i].varname);
175 dumpInt(D, f->locvars[i].startpc); 185 dumpInt(D, f->locvars[i].startpc);
176 dumpInt(D, f->locvars[i].endpc); 186 dumpInt(D, f->locvars[i].endpc);
177 } 187 }
178 n = (D->strip) ? 0 : f->sizeupvalues; 188 n = (D->strip) ? 0 : f->sizeupvalues;
179 dumpInt(D, n); 189 dumpInt(D, n);
180 for (i = 0; i < n; i++) 190 for (i = 0; i < n; i++)
181 dumpString(D, f->upvalues[i].name); 191 dumpString(D, f->upvalues[i].name);
182} 192}
183 193
184 194
185static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { 195static void dumpFunction (DumpState *D, const Proto *f, TString *psource) {
186 if (D->strip || f->source == psource) 196 if (D->strip || f->source == psource)
187 dumpString(D, NULL); /* no debug info or same source as its parent */ 197 dumpString(D, NULL); /* no debug info or same source as its parent */
188 else 198 else
189 dumpString(D, f->source); 199 dumpString(D, f->source);
190 dumpInt(D, f->linedefined); 200 dumpInt(D, f->linedefined);
191 dumpInt(D, f->lastlinedefined); 201 dumpInt(D, f->lastlinedefined);
192 dumpByte(D, f->numparams); 202 dumpByte(D, f->numparams);
193 dumpByte(D, f->is_vararg); 203 dumpByte(D, f->is_vararg);
194 dumpByte(D, f->maxstacksize); 204 dumpByte(D, f->maxstacksize);
195 dumpCode(D, f); 205 dumpCode(D, f);
196 dumpConstants(D, f); 206 dumpConstants(D, f);
197 dumpUpvalues(D, f); 207 dumpUpvalues(D, f);
198 dumpProtos(D, f); 208 dumpProtos(D, f);
199 dumpDebug(D, f); 209 dumpDebug(D, f);
200} 210}
201 211
202 212
203static void dumpHeader (DumpState *D) { 213static void dumpHeader (DumpState *D) {
204 dumpLiteral(D, LUA_SIGNATURE); 214 dumpLiteral(D, LUA_SIGNATURE);
205 dumpByte(D, LUAC_VERSION); 215 dumpByte(D, LUAC_VERSION);
206 dumpByte(D, LUAC_FORMAT); 216 dumpByte(D, LUAC_FORMAT);
207 dumpLiteral(D, LUAC_DATA); 217 dumpLiteral(D, LUAC_DATA);
208 dumpByte(D, sizeof(Instruction)); 218 dumpByte(D, sizeof(Instruction));
209 dumpByte(D, sizeof(lua_Integer)); 219 dumpByte(D, sizeof(lua_Integer));
210 dumpByte(D, sizeof(lua_Number)); 220 dumpByte(D, sizeof(lua_Number));
211 dumpInteger(D, LUAC_INT); 221 dumpInteger(D, LUAC_INT);
212 dumpNumber(D, LUAC_NUM); 222 dumpNumber(D, LUAC_NUM);
213} 223}
214 224
215 225
216/* 226/*
217** dump Lua function as precompiled chunk 227** dump Lua function as precompiled chunk
218*/ 228*/
219int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 229int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
220 int strip) { 230 int strip) {
221 DumpState D; 231 DumpState D;
222 D.L = L; 232 D.L = L;
223 D.writer = w; 233 D.writer = w;
224 D.data = data; 234 D.data = data;
225 D.strip = strip; 235 D.strip = strip;
226 D.status = 0; 236 D.status = 0;
227 dumpHeader(&D); 237 dumpHeader(&D);
228 dumpByte(&D, f->sizeupvalues); 238 dumpByte(&D, f->sizeupvalues);
229 dumpFunction(&D, f, NULL); 239 dumpFunction(&D, f, NULL);
230 return D.status; 240 return D.status;
231} 241}
232 242

cvs diff -r1.9 -r1.10 src/external/mit/lua/dist/src/lundump.c (switch to unified diff)

--- src/external/mit/lua/dist/src/lundump.c 2023/04/16 20:46:17 1.9
+++ src/external/mit/lua/dist/src/lundump.c 2023/04/17 21:17:57 1.10
@@ -1,339 +1,341 @@ @@ -1,339 +1,341 @@
1/* $NetBSD: lundump.c,v 1.9 2023/04/16 20:46:17 nikita Exp $ */ 1/* $NetBSD: lundump.c,v 1.10 2023/04/17 21:17:57 nikita Exp $ */
2 2
3/* 3/*
4** Id: lundump.c  4** Id: lundump.c
5** load precompiled Lua chunks 5** load precompiled Lua chunks
6** See Copyright Notice in lua.h 6** See Copyright Notice in lua.h
7*/ 7*/
8 8
9#define lundump_c 9#define lundump_c
10#define LUA_CORE 10#define LUA_CORE
11 11
12#include "lprefix.h" 12#include "lprefix.h"
13 13
14 14
15#ifndef _KERNEL 15#ifndef _KERNEL
16#include <limits.h> 16#include <limits.h>
17#include <string.h> 17#include <string.h>
18#endif /* _KERNEL */ 18#endif /* _KERNEL */
19 19
20#include "lua.h" 20#include "lua.h"
21 21
22#include "ldebug.h" 22#include "ldebug.h"
23#include "ldo.h" 23#include "ldo.h"
24#include "lfunc.h" 24#include "lfunc.h"
25#include "lmem.h" 25#include "lmem.h"
26#include "lobject.h" 26#include "lobject.h"
27#include "lstring.h" 27#include "lstring.h"
28#include "lundump.h" 28#include "lundump.h"
29#include "lzio.h" 29#include "lzio.h"
30 30
31 31
32#if !defined(luai_verifycode) 32#if !defined(luai_verifycode)
33#define luai_verifycode(L,f) /* empty */ 33#define luai_verifycode(L,f) /* empty */
34#endif 34#endif
35 35
36 36
37typedef struct { 37typedef struct {
38 lua_State *L; 38 lua_State *L;
39 ZIO *Z; 39 ZIO *Z;
40 const char *name; 40 const char *name;
41} LoadState; 41} LoadState;
42 42
43 43
44static l_noret error (LoadState *S, const char *why) { 44static l_noret error (LoadState *S, const char *why) {
45 luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why); 45 luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why);
46 luaD_throw(S->L, LUA_ERRSYNTAX); 46 luaD_throw(S->L, LUA_ERRSYNTAX);
47} 47}
48 48
49 49
50/* 50/*
51** All high-level loads go through loadVector; you can change it to 51** All high-level loads go through loadVector; you can change it to
52** adapt to the endianness of the input 52** adapt to the endianness of the input
53*/ 53*/
54#define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0])) 54#define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0]))
55 55
56static void loadBlock (LoadState *S, void *b, size_t size) { 56static void loadBlock (LoadState *S, void *b, size_t size) {
57 if (luaZ_read(S->Z, b, size) != 0) 57 if (luaZ_read(S->Z, b, size) != 0)
58 error(S, "truncated chunk"); 58 error(S, "truncated chunk");
59} 59}
60 60
61 61
62#define loadVar(S,x) loadVector(S,&x,1) 62#define loadVar(S,x) loadVector(S,&x,1)
63 63
64 64
65static lu_byte loadByte (LoadState *S) { 65static lu_byte loadByte (LoadState *S) {
66 int b = zgetc(S->Z); 66 int b = zgetc(S->Z);
67 if (b == EOZ) 67 if (b == EOZ)
68 error(S, "truncated chunk"); 68 error(S, "truncated chunk");
69 return cast_byte(b); 69 return cast_byte(b);
70} 70}
71 71
72 72
73static size_t loadUnsigned (LoadState *S, size_t limit) { 73static size_t loadUnsigned (LoadState *S, size_t limit) {
74 size_t x = 0; 74 size_t x = 0;
75 int b; 75 int b;
76 limit >>= 7; 76 limit >>= 7;
77 do { 77 do {
78 b = loadByte(S); 78 b = loadByte(S);
79 if (x >= limit) 79 if (x >= limit)
80 error(S, "integer overflow"); 80 error(S, "integer overflow");
81 x = (x << 7) | (b & 0x7f); 81 x = (x << 7) | (b & 0x7f);
82 } while ((b & 0x80) == 0); 82 } while ((b & 0x80) == 0);
83 return x; 83 return x;
84} 84}
85 85
86 86
87static size_t loadSize (LoadState *S) { 87static size_t loadSize (LoadState *S) {
88 return loadUnsigned(S, ~(size_t)0); 88 return loadUnsigned(S, ~(size_t)0);
89} 89}
90 90
91 91
92static int loadInt (LoadState *S) { 92static int loadInt (LoadState *S) {
93 return cast_int(loadUnsigned(S, INT_MAX)); 93 return cast_int(loadUnsigned(S, INT_MAX));
94} 94}
95 95
96 96
97static lua_Number loadNumber (LoadState *S) { 97static lua_Number loadNumber (LoadState *S) {
98 lua_Number x; 98 lua_Number x;
99 loadVar(S, x); 99 loadVar(S, x);
100 return x; 100 return x;
101} 101}
102 102
103 103
104static lua_Integer loadInteger (LoadState *S) { 104static lua_Integer loadInteger (LoadState *S) {
105 lua_Integer x; 105 lua_Integer x;
106 loadVar(S, x); 106 loadVar(S, x);
107 return x; 107 return x;
108} 108}
109 109
110 110
111/* 111/*
112** Load a nullable string into prototype 'p'. 112** Load a nullable string into prototype 'p'.
113*/ 113*/
114static TString *loadStringN (LoadState *S, Proto *p) { 114static TString *loadStringN (LoadState *S, Proto *p) {
115 lua_State *L = S->L; 115 lua_State *L = S->L;
116 TString *ts; 116 TString *ts;
117 size_t size = loadSize(S); 117 size_t size = loadSize(S);
118 if (size == 0) /* no string? */ 118 if (size == 0) /* no string? */
119 return NULL; 119 return NULL;
120 else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ 120 else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
121 char buff[LUAI_MAXSHORTLEN]; 121 char buff[LUAI_MAXSHORTLEN];
122 loadVector(S, buff, size); /* load string into buffer */ 122 loadVector(S, buff, size); /* load string into buffer */
123 ts = luaS_newlstr(L, buff, size); /* create string */ 123 ts = luaS_newlstr(L, buff, size); /* create string */
124 } 124 }
125 else { /* long string */ 125 else { /* long string */
126 ts = luaS_createlngstrobj(L, size); /* create string */ 126 ts = luaS_createlngstrobj(L, size); /* create string */
127 setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */ 127 setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */
128 luaD_inctop(L); 128 luaD_inctop(L);
129 loadVector(S, getstr(ts), size); /* load directly in final place */ 129 loadVector(S, getstr(ts), size); /* load directly in final place */
130 L->top--; /* pop string */ 130 L->top--; /* pop string */
131 } 131 }
132 luaC_objbarrier(L, p, ts); 132 luaC_objbarrier(L, p, ts);
133 return ts; 133 return ts;
134} 134}
135 135
136 136
137/* 137/*
138** Load a non-nullable string into prototype 'p'. 138** Load a non-nullable string into prototype 'p'.
139*/ 139*/
140static TString *loadString (LoadState *S, Proto *p) { 140static TString *loadString (LoadState *S, Proto *p) {
141 TString *st = loadStringN(S, p); 141 TString *st = loadStringN(S, p);
142 if (st == NULL) 142 if (st == NULL)
143 error(S, "bad format for constant string"); 143 error(S, "bad format for constant string");
144 return st; 144 return st;
145} 145}
146 146
147 147
148static void loadCode (LoadState *S, Proto *f) { 148static void loadCode (LoadState *S, Proto *f) {
149 int n = loadInt(S); 149 int n = loadInt(S);
150 f->code = luaM_newvectorchecked(S->L, n, Instruction); 150 f->code = luaM_newvectorchecked(S->L, n, Instruction);
151 f->sizecode = n; 151 f->sizecode = n;
152 loadVector(S, f->code, n); 152 loadVector(S, f->code, n);
153} 153}
154 154
155 155
156static void loadFunction(LoadState *S, Proto *f, TString *psource); 156static void loadFunction(LoadState *S, Proto *f, TString *psource);
157 157
158 158
159static void loadConstants (LoadState *S, Proto *f) { 159static void loadConstants (LoadState *S, Proto *f) {
160 int i; 160 int i;
161 int n = loadInt(S); 161 int n = loadInt(S);
162 f->k = luaM_newvectorchecked(S->L, n, TValue); 162 f->k = luaM_newvectorchecked(S->L, n, TValue);
163 f->sizek = n; 163 f->sizek = n;
164 for (i = 0; i < n; i++) 164 for (i = 0; i < n; i++)
165 setnilvalue(&f->k[i]); 165 setnilvalue(&f->k[i]);
166 for (i = 0; i < n; i++) { 166 for (i = 0; i < n; i++) {
167 TValue *o = &f->k[i]; 167 TValue *o = &f->k[i];
168 int t = loadByte(S); 168 int t = loadByte(S);
169 switch (t) { 169 switch (t) {
170 case LUA_VNIL: 170 case LUA_VNIL:
171 setnilvalue(o); 171 setnilvalue(o);
172 break; 172 break;
173 case LUA_VFALSE: 173 case LUA_VFALSE:
174 setbfvalue(o); 174 setbfvalue(o);
175 break; 175 break;
176 case LUA_VTRUE: 176 case LUA_VTRUE:
177 setbtvalue(o); 177 setbtvalue(o);
178 break; 178 break;
179#ifndef _KERNEL 179#ifndef _KERNEL
180 case LUA_VNUMFLT: 180 case LUA_VNUMFLT:
181 setfltvalue(o, loadNumber(S)); 181 setfltvalue(o, loadNumber(S));
182 break; 182 break;
183#endif /* _KERNEL */ 183#endif /* _KERNEL */
184 case LUA_VNUMINT: 184 case LUA_VNUMINT:
185 setivalue(o, loadInteger(S)); 185 setivalue(o, loadInteger(S));
186 break; 186 break;
187 case LUA_VSHRSTR: 187 case LUA_VSHRSTR:
188 case LUA_VLNGSTR: 188 case LUA_VLNGSTR:
189 setsvalue2n(S->L, o, loadString(S, f)); 189 setsvalue2n(S->L, o, loadString(S, f));
190 break; 190 break;
191 default: lua_assert(0); 191 default: lua_assert(0);
192 } 192 }
193 } 193 }
194} 194}
195 195
196 196
197static void loadProtos (LoadState *S, Proto *f) { 197static void loadProtos (LoadState *S, Proto *f) {
198 int i; 198 int i;
199 int n = loadInt(S); 199 int n = loadInt(S);
200 f->p = luaM_newvectorchecked(S->L, n, Proto *); 200 f->p = luaM_newvectorchecked(S->L, n, Proto *);
201 f->sizep = n; 201 f->sizep = n;
202 for (i = 0; i < n; i++) 202 for (i = 0; i < n; i++)
203 f->p[i] = NULL; 203 f->p[i] = NULL;
204 for (i = 0; i < n; i++) { 204 for (i = 0; i < n; i++) {
205 f->p[i] = luaF_newproto(S->L); 205 f->p[i] = luaF_newproto(S->L);
206 luaC_objbarrier(S->L, f, f->p[i]); 206 luaC_objbarrier(S->L, f, f->p[i]);
207 loadFunction(S, f->p[i], f->source); 207 loadFunction(S, f->p[i], f->source);
208 } 208 }
209} 209}
210 210
211 211
212/* 212/*
213** Load the upvalues for a function. The names must be filled first, 213** Load the upvalues for a function. The names must be filled first,
214** because the filling of the other fields can raise read errors and 214** because the filling of the other fields can raise read errors and
215** the creation of the error message can call an emergency collection; 215** the creation of the error message can call an emergency collection;
216** in that case all prototypes must be consistent for the GC. 216** in that case all prototypes must be consistent for the GC.
217*/ 217*/
218static void loadUpvalues (LoadState *S, Proto *f) { 218static void loadUpvalues (LoadState *S, Proto *f) {
219 int i, n; 219 int i, n;
220 n = loadInt(S); 220 n = loadInt(S);
221 f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); 221 f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc);
222 f->sizeupvalues = n; 222 f->sizeupvalues = n;
223 for (i = 0; i < n; i++) /* make array valid for GC */ 223 for (i = 0; i < n; i++) /* make array valid for GC */
224 f->upvalues[i].name = NULL; 224 f->upvalues[i].name = NULL;
225 for (i = 0; i < n; i++) { /* following calls can raise errors */ 225 for (i = 0; i < n; i++) { /* following calls can raise errors */
226 f->upvalues[i].instack = loadByte(S); 226 f->upvalues[i].instack = loadByte(S);
227 f->upvalues[i].idx = loadByte(S); 227 f->upvalues[i].idx = loadByte(S);
228 f->upvalues[i].kind = loadByte(S); 228 f->upvalues[i].kind = loadByte(S);
229 } 229 }
230} 230}
231 231
232 232
233static void loadDebug (LoadState *S, Proto *f) { 233static void loadDebug (LoadState *S, Proto *f) {
234 int i, n; 234 int i, n;
235 n = loadInt(S); 235 n = loadInt(S);
236 f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); 236 f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte);
237 f->sizelineinfo = n; 237 f->sizelineinfo = n;
238 loadVector(S, f->lineinfo, n); 238 loadVector(S, f->lineinfo, n);
239 n = loadInt(S); 239 n = loadInt(S);
240 f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); 240 f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo);
241 f->sizeabslineinfo = n; 241 f->sizeabslineinfo = n;
242 for (i = 0; i < n; i++) { 242 for (i = 0; i < n; i++) {
243 f->abslineinfo[i].pc = loadInt(S); 243 f->abslineinfo[i].pc = loadInt(S);
244 f->abslineinfo[i].line = loadInt(S); 244 f->abslineinfo[i].line = loadInt(S);
245 } 245 }
246 n = loadInt(S); 246 n = loadInt(S);
247 f->locvars = luaM_newvectorchecked(S->L, n, LocVar); 247 f->locvars = luaM_newvectorchecked(S->L, n, LocVar);
248 f->sizelocvars = n; 248 f->sizelocvars = n;
249 for (i = 0; i < n; i++) 249 for (i = 0; i < n; i++)
250 f->locvars[i].varname = NULL; 250 f->locvars[i].varname = NULL;
251 for (i = 0; i < n; i++) { 251 for (i = 0; i < n; i++) {
252 f->locvars[i].varname = loadStringN(S, f); 252 f->locvars[i].varname = loadStringN(S, f);
253 f->locvars[i].startpc = loadInt(S); 253 f->locvars[i].startpc = loadInt(S);
254 f->locvars[i].endpc = loadInt(S); 254 f->locvars[i].endpc = loadInt(S);
255 } 255 }
256 n = loadInt(S); 256 n = loadInt(S);
 257 if (n != 0) /* does it have debug information? */
 258 n = f->sizeupvalues; /* must be this many */
257 for (i = 0; i < n; i++) 259 for (i = 0; i < n; i++)
258 f->upvalues[i].name = loadStringN(S, f); 260 f->upvalues[i].name = loadStringN(S, f);
259} 261}
260 262
261 263
262static void loadFunction (LoadState *S, Proto *f, TString *psource) { 264static void loadFunction (LoadState *S, Proto *f, TString *psource) {
263 f->source = loadStringN(S, f); 265 f->source = loadStringN(S, f);
264 if (f->source == NULL) /* no source in dump? */ 266 if (f->source == NULL) /* no source in dump? */
265 f->source = psource; /* reuse parent's source */ 267 f->source = psource; /* reuse parent's source */
266 f->linedefined = loadInt(S); 268 f->linedefined = loadInt(S);
267 f->lastlinedefined = loadInt(S); 269 f->lastlinedefined = loadInt(S);
268 f->numparams = loadByte(S); 270 f->numparams = loadByte(S);
269 f->is_vararg = loadByte(S); 271 f->is_vararg = loadByte(S);
270 f->maxstacksize = loadByte(S); 272 f->maxstacksize = loadByte(S);
271 loadCode(S, f); 273 loadCode(S, f);
272 loadConstants(S, f); 274 loadConstants(S, f);
273 loadUpvalues(S, f); 275 loadUpvalues(S, f);
274 loadProtos(S, f); 276 loadProtos(S, f);
275 loadDebug(S, f); 277 loadDebug(S, f);
276} 278}
277 279
278 280
279static void checkliteral (LoadState *S, const char *s, const char *msg) { 281static void checkliteral (LoadState *S, const char *s, const char *msg) {
280 char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ 282 char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
281 size_t len = strlen(s); 283 size_t len = strlen(s);
282 loadVector(S, buff, len); 284 loadVector(S, buff, len);
283 if (memcmp(s, buff, len) != 0) 285 if (memcmp(s, buff, len) != 0)
284 error(S, msg); 286 error(S, msg);
285} 287}
286 288
287 289
288static void fchecksize (LoadState *S, size_t size, const char *tname) { 290static void fchecksize (LoadState *S, size_t size, const char *tname) {
289 if (loadByte(S) != size) 291 if (loadByte(S) != size)
290 error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); 292 error(S, luaO_pushfstring(S->L, "%s size mismatch", tname));
291} 293}
292 294
293 295
294#define checksize(S,t) fchecksize(S,sizeof(t),#t) 296#define checksize(S,t) fchecksize(S,sizeof(t),#t)
295 297
296static void checkHeader (LoadState *S) { 298static void checkHeader (LoadState *S) {
297 /* skip 1st char (already read and checked) */ 299 /* skip 1st char (already read and checked) */
298 checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk"); 300 checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk");
299 if (loadByte(S) != LUAC_VERSION) 301 if (loadByte(S) != LUAC_VERSION)
300 error(S, "version mismatch"); 302 error(S, "version mismatch");
301 if (loadByte(S) != LUAC_FORMAT) 303 if (loadByte(S) != LUAC_FORMAT)
302 error(S, "format mismatch"); 304 error(S, "format mismatch");
303 checkliteral(S, LUAC_DATA, "corrupted chunk"); 305 checkliteral(S, LUAC_DATA, "corrupted chunk");
304 checksize(S, Instruction); 306 checksize(S, Instruction);
305 checksize(S, lua_Integer); 307 checksize(S, lua_Integer);
306 checksize(S, lua_Number); 308 checksize(S, lua_Number);
307 if (loadInteger(S) != LUAC_INT) 309 if (loadInteger(S) != LUAC_INT)
308 error(S, "integer format mismatch"); 310 error(S, "integer format mismatch");
309 if (loadNumber(S) != LUAC_NUM) 311 if (loadNumber(S) != LUAC_NUM)
310 error(S, "float format mismatch"); 312 error(S, "float format mismatch");
311} 313}
312 314
313 315
314/* 316/*
315** Load precompiled chunk. 317** Load precompiled chunk.
316*/ 318*/
317LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { 319LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
318 LoadState S; 320 LoadState S;
319 LClosure *cl; 321 LClosure *cl;
320 if (*name == '@' || *name == '=') 322 if (*name == '@' || *name == '=')
321 S.name = name + 1; 323 S.name = name + 1;
322 else if (*name == LUA_SIGNATURE[0]) 324 else if (*name == LUA_SIGNATURE[0])
323 S.name = "binary string"; 325 S.name = "binary string";
324 else 326 else
325 S.name = name; 327 S.name = name;
326 S.L = L; 328 S.L = L;
327 S.Z = Z; 329 S.Z = Z;
328 checkHeader(&S); 330 checkHeader(&S);
329 cl = luaF_newLclosure(L, loadByte(&S)); 331 cl = luaF_newLclosure(L, loadByte(&S));
330 setclLvalue2s(L, L->top, cl); 332 setclLvalue2s(L, L->top, cl);
331 luaD_inctop(L); 333 luaD_inctop(L);
332 cl->p = luaF_newproto(L); 334 cl->p = luaF_newproto(L);
333 luaC_objbarrier(L, cl, cl->p); 335 luaC_objbarrier(L, cl, cl->p);
334 loadFunction(&S, cl->p, NULL); 336 loadFunction(&S, cl->p, NULL);
335 lua_assert(cl->nupvalues == cl->p->sizeupvalues); 337 lua_assert(cl->nupvalues == cl->p->sizeupvalues);
336 luai_verifycode(L, cl->p); 338 luai_verifycode(L, cl->p);
337 return cl; 339 return cl;
338} 340}
339 341