diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-06-30 15:36:26 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-06-30 15:36:26 -0300 |
commit | 422ce50d2e8856ed789d1359c673122dbb0088ea (patch) | |
tree | 163c566c322915b12d13e4b1d1966d5658e19086 /lundump.c | |
parent | c33b1728aeb7dfeec4013562660e07d32697aa6b (diff) | |
download | lua-422ce50d2e8856ed789d1359c673122dbb0088ea.tar.gz lua-422ce50d2e8856ed789d1359c673122dbb0088ea.tar.bz2 lua-422ce50d2e8856ed789d1359c673122dbb0088ea.zip |
Fixed detail in 'loadUpvalues'
In 'lundump.c', when loading the upvalues of a function, there can be
a read error if the chunk is truncated. In that case, the creation
of the error message can trigger an emergency collection while the
prototype is still anchored. So, the prototype must be GC consistent
before loading the upvales, which implies that it the 'name' fields
must be filled with NULL before the reading.
Diffstat (limited to 'lundump.c')
-rw-r--r-- | lundump.c | 9 |
1 files changed, 8 insertions, 1 deletions
@@ -200,13 +200,20 @@ static void loadProtos (LoadState *S, Proto *f) { | |||
200 | } | 200 | } |
201 | 201 | ||
202 | 202 | ||
203 | /* | ||
204 | ** Load the upvalues for a function. The names must be filled first, | ||
205 | ** because the filling of the other fields can raise read errors and | ||
206 | ** the creation of the error message can call an emergency collection; | ||
207 | ** in that case all prototypes must be consistent for the GC. | ||
208 | */ | ||
203 | static void loadUpvalues (LoadState *S, Proto *f) { | 209 | static void loadUpvalues (LoadState *S, Proto *f) { |
204 | int i, n; | 210 | int i, n; |
205 | n = loadInt(S); | 211 | n = loadInt(S); |
206 | f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); | 212 | f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); |
207 | f->sizeupvalues = n; | 213 | f->sizeupvalues = n; |
208 | for (i = 0; i < n; i++) { | 214 | for (i = 0; i < n; i++) /* make array valid for GC */ |
209 | f->upvalues[i].name = NULL; | 215 | f->upvalues[i].name = NULL; |
216 | for (i = 0; i < n; i++) { /* following calls can raise errors */ | ||
210 | f->upvalues[i].instack = loadByte(S); | 217 | f->upvalues[i].instack = loadByte(S); |
211 | f->upvalues[i].idx = loadByte(S); | 218 | f->upvalues[i].idx = loadByte(S); |
212 | f->upvalues[i].kind = loadByte(S); | 219 | f->upvalues[i].kind = loadByte(S); |