From a301de9769f8c7f352ed7b9ce3ffd1eb1ac1254b Mon Sep 17 00:00:00 2001 From: Thomas Watson <twatson52@icloud.com> Date: Mon, 20 Jan 2025 14:42:46 -0600 Subject: [PATCH] AP_Scripting: patch vendored Lua to 5.3.6 In particular this fixes some exceedingly rare/impossible use-after-frees. Add the new docs from the distribution. To maintain our alterations, the following patches have been applied to the source from upstream's repository (1221e987...75ea9ccb) to bring the source up to date: * Bug: Long brackets with a huge number of '=' causes overflow A long bracket with too many equal signs can overflow the 'int' used for the counting and some arithmetic done on the value. Changing the counter to 'size_t' avoids that. (Because what is counted goes to a buffer, an overflow in the counter will first raise a buffer-overflow error.) * Fixed bug in 'lua_upvaluejoin' Bug-fix: joining an upvalue with itself could cause a use-after-free crash. * Fixed typos in comments * Fixed missing GC barriers in compiler and undump While building a new prototype, the GC needs barriers for every object (strings and nested prototypes) that is attached to the new prototype. * Updated release number and copyright year * Fixed bug: invalid mode can crash 'io.popen' * Fixed bug: Negation overflow in getlocal/setlocal * 'realloc' can fail when shrinking a block According to ISO C, 'realloc' can fail when shrinking a block. If that happens, 'l_alloc' simply ignores the fail and returns the original block. * Fixed bug of long strings in binary chunks When "undumping" a long string, the function 'LoadVector' can call the reader function, which can run the garbage collector, which can collect the string being read. So, the string must be anchored during the call to 'LoadVector'. --- libraries/AP_Scripting/lua/Makefile | 2 +- libraries/AP_Scripting/lua/README | 2 +- libraries/AP_Scripting/lua/doc/contents.html | 37 ++++++++++++++++++-- libraries/AP_Scripting/lua/doc/manual.html | 6 ++-- libraries/AP_Scripting/lua/doc/readme.html | 8 ++--- libraries/AP_Scripting/lua/src/lapi.c | 12 +++---- libraries/AP_Scripting/lua/src/lauxlib.c | 9 +++-- libraries/AP_Scripting/lua/src/lcode.c | 2 +- libraries/AP_Scripting/lua/src/ldebug.c | 7 ++-- libraries/AP_Scripting/lua/src/liolib.c | 2 ++ libraries/AP_Scripting/lua/src/llex.c | 31 ++++++++-------- libraries/AP_Scripting/lua/src/lobject.c | 2 +- libraries/AP_Scripting/lua/src/lparser.c | 3 ++ libraries/AP_Scripting/lua/src/lua.h | 7 ++-- libraries/AP_Scripting/lua/src/lundump.c | 24 ++++++++----- 15 files changed, 103 insertions(+), 51 deletions(-) diff --git a/libraries/AP_Scripting/lua/Makefile b/libraries/AP_Scripting/lua/Makefile index 119110d2f01054..a2820e04fe24ca 100644 --- a/libraries/AP_Scripting/lua/Makefile +++ b/libraries/AP_Scripting/lua/Makefile @@ -46,7 +46,7 @@ TO_MAN= lua.1 luac.1 # Lua version and release. V= 5.3 -R= $V.4 +R= $V.6 # Targets start here. all: $(PLAT) diff --git a/libraries/AP_Scripting/lua/README b/libraries/AP_Scripting/lua/README index ed424defe0255c..f8bdb6f41d0051 100644 --- a/libraries/AP_Scripting/lua/README +++ b/libraries/AP_Scripting/lua/README @@ -1,5 +1,5 @@ -This is Lua 5.3.5, released on 26 Jun 2018. +This is Lua 5.3.6, released on 14 Sep 2020. For installation instructions, license details, and further information about Lua, see doc/readme.html. diff --git a/libraries/AP_Scripting/lua/doc/contents.html b/libraries/AP_Scripting/lua/doc/contents.html index c4eb2677906de9..3a357b1ed65345 100644 --- a/libraries/AP_Scripting/lua/doc/contents.html +++ b/libraries/AP_Scripting/lua/doc/contents.html @@ -32,7 +32,7 @@ <H1> <P> <SMALL> -Copyright © 2015–2018 Lua.org, PUC-Rio. +Copyright © 2015–2020 Lua.org, PUC-Rio. Freely available under the terms of the <A HREF="http://www.lua.org/license.html">Lua license</A>. </SMALL> @@ -318,6 +318,37 @@ <H3> </H3> <A HREF="manual.html#pdf-utf8.len">utf8.len</A><BR> <A HREF="manual.html#pdf-utf8.offset">utf8.offset</A><BR> +<H3><A NAME="metamethods">metamethods</A></H3> +<P> +<A HREF="manual.html#2.4">__add</A><BR> +<A HREF="manual.html#2.4">__band</A><BR> +<A HREF="manual.html#2.4">__bnot</A><BR> +<A HREF="manual.html#2.4">__bor</A><BR> +<A HREF="manual.html#2.4">__bxor</A><BR> +<A HREF="manual.html#2.4">__call</A><BR> +<A HREF="manual.html#2.4">__concat</A><BR> +<A HREF="manual.html#2.4">__div</A><BR> +<A HREF="manual.html#2.4">__eq</A><BR> +<A HREF="manual.html#2.5.1">__gc</A><BR> +<A HREF="manual.html#2.4">__idiv</A><BR> +<A HREF="manual.html#2.4">__index</A><BR> +<A HREF="manual.html#2.4">__le</A><BR> +<A HREF="manual.html#2.4">__len</A><BR> +<A HREF="manual.html#2.4">__lt</A><BR> +<A HREF="manual.html#pdf-getmetatable">__metatable</A><BR> +<A HREF="manual.html#2.4">__mod</A><BR> +<A HREF="manual.html#2.5.2">__mode</A><BR> +<A HREF="manual.html#2.4">__mul</A><BR> +<A HREF="manual.html#luaL_newmetatable">__name</A><BR> +<A HREF="manual.html#2.4">__newindex</A><BR> +<A HREF="manual.html#pdf-pairs">__pairs</A><BR> +<A HREF="manual.html#2.4">__pow</A><BR> +<A HREF="manual.html#2.4">__shl</A><BR> +<A HREF="manual.html#2.4">__shr</A><BR> +<A HREF="manual.html#2.4">__sub</A><BR> +<A HREF="manual.html#pdf-tostring">__tostring</A><BR> +<A HREF="manual.html#2.4">__unm</A><BR> + <H3><A NAME="env">environment<BR>variables</A></H3> <P> <A HREF="manual.html#pdf-LUA_CPATH">LUA_CPATH</A><BR> @@ -609,10 +640,10 @@ <H3><A NAME="constants">constants</A></H3> <P CLASS="footer"> Last update: -Mon Jun 18 22:56:06 -03 2018 +Tue Aug 25 13:45:14 UTC 2020 </P> <!-- -Last change: revised for Lua 5.3.5 +Last change: revised for Lua 5.3.6 --> </BODY> diff --git a/libraries/AP_Scripting/lua/doc/manual.html b/libraries/AP_Scripting/lua/doc/manual.html index 89a642a45d9215..57c778744b7aab 100644 --- a/libraries/AP_Scripting/lua/doc/manual.html +++ b/libraries/AP_Scripting/lua/doc/manual.html @@ -19,7 +19,7 @@ <H1> <P> <SMALL> -Copyright © 2015–2018 Lua.org, PUC-Rio. +Copyright © 2015–2020 Lua.org, PUC-Rio. Freely available under the terms of the <a href="http://www.lua.org/license.html">Lua license</a>. </SMALL> @@ -10972,10 +10972,10 @@ <h1>9 – <a name="9">The Complete Syntax of Lua</a></h1> <P CLASS="footer"> Last update: -Tue Jun 26 13:16:37 -03 2018 +Tue Jul 14 10:32:39 UTC 2020 </P> <!-- -Last change: revised for Lua 5.3.5 +Last change: revised for Lua 5.3.6 --> </body></html> diff --git a/libraries/AP_Scripting/lua/doc/readme.html b/libraries/AP_Scripting/lua/doc/readme.html index b118f7b02d1662..50716f42d0cf42 100644 --- a/libraries/AP_Scripting/lua/doc/readme.html +++ b/libraries/AP_Scripting/lua/doc/readme.html @@ -107,7 +107,7 @@ <H3>Building Lua</H3> <OL> <LI> Open a terminal window and move to -the top-level directory, which is named <TT>lua-5.3.5</TT>. +the top-level directory, which is named <TT>lua-5.3.6</TT>. The <TT>Makefile</TT> there controls both the build process and the installation process. <P> <LI> @@ -328,7 +328,7 @@ <H2><A NAME="license">License</A></H2> <A HREF="http://www.lua.org/license.html">this</A>. <BLOCKQUOTE STYLE="padding-bottom: 0em"> -Copyright © 1994–2017 Lua.org, PUC-Rio. +Copyright © 1994–2020 Lua.org, PUC-Rio. <P> Permission is hereby granted, free of charge, to any person obtaining a copy @@ -355,10 +355,10 @@ <H2><A NAME="license">License</A></H2> <P CLASS="footer"> Last update: -Mon Jun 18 22:57:33 -03 2018 +Tue Jul 14 10:33:01 UTC 2020 </P> <!-- -Last change: revised for Lua 5.3.5 +Last change: revised for Lua 5.3.6 --> </BODY> diff --git a/libraries/AP_Scripting/lua/src/lapi.c b/libraries/AP_Scripting/lua/src/lapi.c index b8cf086fc819ca..48051a0cba017d 100644 --- a/libraries/AP_Scripting/lua/src/lapi.c +++ b/libraries/AP_Scripting/lua/src/lapi.c @@ -1256,13 +1256,12 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { } -static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { +static UpVal **getupvalref (lua_State *L, int fidx, int n) { LClosure *f; StkId fi = index2addr(L, fidx); api_check(L, ttisLclosure(fi), "Lua function expected"); f = clLvalue(fi); api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); - if (pf) *pf = f; return &f->upvals[n - 1]; /* get its upvalue pointer */ } @@ -1271,7 +1270,7 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { StkId fi = index2addr(L, fidx); switch (ttype(fi)) { case LUA_TLCL: { /* lua closure */ - return *getupvalref(L, fidx, n, NULL); + return *getupvalref(L, fidx, n); } case LUA_TCCL: { /* C closure */ CClosure *f = clCvalue(fi); @@ -1288,9 +1287,10 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, int fidx2, int n2) { - LClosure *f1; - UpVal **up1 = getupvalref(L, fidx1, n1, &f1); - UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + UpVal **up1 = getupvalref(L, fidx1, n1); + UpVal **up2 = getupvalref(L, fidx2, n2); + if (*up1 == *up2) + return; luaC_upvdeccount(L, *up1); *up1 = *up2; (*up1)->refcount++; diff --git a/libraries/AP_Scripting/lua/src/lauxlib.c b/libraries/AP_Scripting/lua/src/lauxlib.c index 979b01d9c1dc22..5097c241523417 100644 --- a/libraries/AP_Scripting/lua/src/lauxlib.c +++ b/libraries/AP_Scripting/lua/src/lauxlib.c @@ -1016,8 +1016,13 @@ LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, // free(ptr); // return NULL; // } -// else -// return realloc(ptr, nsize); +// else { /* cannot fail when shrinking a block */ +// void *newptr = realloc(ptr, nsize); +// if (newptr == NULL && ptr != NULL && nsize <= osize) +// return ptr; /* keep the original block */ +// else /* no fail or not shrinking */ +// return newptr; /* use the new block */ +// } // } diff --git a/libraries/AP_Scripting/lua/src/lcode.c b/libraries/AP_Scripting/lua/src/lcode.c index 8a251be7945187..5099b4b7e18fe2 100644 --- a/libraries/AP_Scripting/lua/src/lcode.c +++ b/libraries/AP_Scripting/lua/src/lcode.c @@ -1068,7 +1068,7 @@ static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { /* -** Aplly prefix operation 'op' to expression 'e'. +** Apply prefix operation 'op' to expression 'e'. */ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; diff --git a/libraries/AP_Scripting/lua/src/ldebug.c b/libraries/AP_Scripting/lua/src/ldebug.c index 1de6b0df0ff5ed..3178580f44d782 100644 --- a/libraries/AP_Scripting/lua/src/ldebug.c +++ b/libraries/AP_Scripting/lua/src/ldebug.c @@ -134,10 +134,11 @@ static const char *upvalname (Proto *p, int uv) { static const char *findvararg (CallInfo *ci, int n, StkId *pos) { int nparams = clLvalue(ci->func)->p->numparams; - if (n >= cast_int(ci->u.l.base - ci->func) - nparams) + int nvararg = cast_int(ci->u.l.base - ci->func) - nparams; + if (n <= -nvararg) return NULL; /* no such vararg */ else { - *pos = ci->func + nparams + n; + *pos = ci->func + nparams - n; return "(*vararg)"; /* generic name for any vararg */ } } @@ -149,7 +150,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, StkId base; if (isLua(ci)) { if (n < 0) /* access to vararg values? */ - return findvararg(ci, -n, pos); + return findvararg(ci, n, pos); else { base = ci->u.l.base; name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); diff --git a/libraries/AP_Scripting/lua/src/liolib.c b/libraries/AP_Scripting/lua/src/liolib.c index a6935505e41e19..f2286873df2967 100644 --- a/libraries/AP_Scripting/lua/src/liolib.c +++ b/libraries/AP_Scripting/lua/src/liolib.c @@ -279,6 +279,8 @@ static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); LStream *p = newprefile(L); + luaL_argcheck(L, ((mode[0] == 'r' || mode[0] == 'w') && mode[1] == '\0'), + 2, "invalid mode"); p->f = l_popen(L, filename, mode); p->closef = &io_pclose; return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; diff --git a/libraries/AP_Scripting/lua/src/llex.c b/libraries/AP_Scripting/lua/src/llex.c index afc6f417094445..268a37f51c29cb 100644 --- a/libraries/AP_Scripting/lua/src/llex.c +++ b/libraries/AP_Scripting/lua/src/llex.c @@ -246,12 +246,12 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) { /* -** skip a sequence '[=*[' or ']=*]'; if sequence is well formed, return -** its number of '='s; otherwise, return a negative number (-1 iff there -** are no '='s after initial bracket) +** reads a sequence '[=*[' or ']=*]', leaving the last bracket. +** If sequence is well formed, return its number of '='s + 2; otherwise, +** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...'). */ -static int skip_sep (LexState *ls) { - int count = 0; +static size_t skip_sep (LexState *ls) { + size_t count = 0; int s = ls->current; lua_assert(s == '[' || s == ']'); save_and_next(ls); @@ -259,11 +259,14 @@ static int skip_sep (LexState *ls) { save_and_next(ls); count++; } - return (ls->current == s) ? count : (-count) - 1; + return (ls->current == s) ? count + 2 + : (count == 0) ? 1 + : 0; + } -static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { +static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) { int line = ls->linenumber; /* initial line (for error message) */ save_and_next(ls); /* skip 2nd '[' */ if (currIsNewline(ls)) /* string starts with a newline? */ @@ -297,8 +300,8 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { } } endloop: if (seminfo) - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), - luaZ_bufflen(ls->buff) - 2*(2 + sep)); + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep, + luaZ_bufflen(ls->buff) - 2 * sep); } @@ -446,9 +449,9 @@ static int llex (LexState *ls, SemInfo *seminfo) { /* else is a comment */ next(ls); if (ls->current == '[') { /* long comment? */ - int sep = skip_sep(ls); + size_t sep = skip_sep(ls); luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */ - if (sep >= 0) { + if (sep >= 2) { read_long_string(ls, NULL, sep); /* skip long comment */ luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ break; @@ -460,12 +463,12 @@ static int llex (LexState *ls, SemInfo *seminfo) { break; } case '[': { /* long string or simply '[' */ - int sep = skip_sep(ls); - if (sep >= 0) { + size_t sep = skip_sep(ls); + if (sep >= 2) { read_long_string(ls, seminfo, sep); return TK_STRING; } - else if (sep != -1) /* '[=...' missing second bracket */ + else if (sep == 0) /* '[=...' missing second bracket */ lexerror(ls, "invalid long string delimiter", TK_STRING); return '['; } diff --git a/libraries/AP_Scripting/lua/src/lobject.c b/libraries/AP_Scripting/lua/src/lobject.c index 2218c8cdd771bd..355bf58d637224 100644 --- a/libraries/AP_Scripting/lua/src/lobject.c +++ b/libraries/AP_Scripting/lua/src/lobject.c @@ -266,7 +266,7 @@ static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { ** - 'n'/'N' means 'inf' or 'nan' (which should be rejected) ** - '.' just optimizes the search for the common case (nothing special) ** This function accepts both the current locale or a dot as the radix -** mark. If the convertion fails, it may mean number has a dot but +** mark. If the conversion fails, it may mean number has a dot but ** locale accepts something else. In that case, the code copies 's' ** to a buffer (because 's' is read-only), changes the dot to the ** current locale radix mark, and tries to convert again. diff --git a/libraries/AP_Scripting/lua/src/lparser.c b/libraries/AP_Scripting/lua/src/lparser.c index c41ac657bdbf7a..2dbbb13fd1f9ff 100644 --- a/libraries/AP_Scripting/lua/src/lparser.c +++ b/libraries/AP_Scripting/lua/src/lparser.c @@ -544,6 +544,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { fs->bl = NULL; f = fs->f; f->source = ls->source; + luaC_objbarrier(ls->L, f, f->source); f->maxstacksize = 2; /* registers 0/1 are always valid */ enterblock(fs, bl, 0); } @@ -1616,6 +1617,7 @@ static void mainfunc (LexState *ls, FuncState *fs) { fs->f->is_vararg = 1; /* main function is always declared vararg */ init_exp(&v, VLOCAL, 0); /* create and... */ newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ + luaC_objbarrier(ls->L, fs->f, ls->envn); luaX_next(ls); /* read first token */ statlist(ls); /* parse main body */ check(ls, TK_EOS); @@ -1634,6 +1636,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, sethvalue(L, L->top, lexstate.h); /* anchor it */ luaD_inctop(L); funcstate.f = cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ lexstate.buff = buff; diff --git a/libraries/AP_Scripting/lua/src/lua.h b/libraries/AP_Scripting/lua/src/lua.h index c236e360957949..9394c5ef8fd60f 100644 --- a/libraries/AP_Scripting/lua/src/lua.h +++ b/libraries/AP_Scripting/lua/src/lua.h @@ -1,5 +1,4 @@ /* -** $Id: lua.h,v 1.332.1.2 2018/06/13 16:58:17 roberto Exp $ ** Lua - A Scripting Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -19,11 +18,11 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "3" #define LUA_VERSION_NUM 503 -#define LUA_VERSION_RELEASE "5" +#define LUA_VERSION_RELEASE "6" #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2018 Lua.org, PUC-Rio" +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2020 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" @@ -460,7 +459,7 @@ struct lua_Debug { /****************************************************************************** -* Copyright (C) 1994-2018 Lua.org, PUC-Rio. +* Copyright (C) 1994-2020 Lua.org, PUC-Rio. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/libraries/AP_Scripting/lua/src/lundump.c b/libraries/AP_Scripting/lua/src/lundump.c index 432db3c337210b..d469752edb7823 100644 --- a/libraries/AP_Scripting/lua/src/lundump.c +++ b/libraries/AP_Scripting/lua/src/lundump.c @@ -92,8 +92,10 @@ static lua_Integer LoadInteger (LoadState *S) { } -static TString *LoadString (LoadState *S) { +static TString *LoadString (LoadState *S, Proto *p) { + lua_State *L = S->L; size_t size = LoadByte(S); + TString *ts; if (size == 0xFF) LoadVar(S, size); if (size == 0) @@ -101,13 +103,17 @@ static TString *LoadString (LoadState *S) { else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ char buff[LUAI_MAXSHORTLEN]; LoadVector(S, buff, size); - return luaS_newlstr(S->L, buff, size); + ts = luaS_newlstr(L, buff, size); } else { /* long string */ - TString *ts = luaS_createlngstrobj(S->L, size); + ts = luaS_createlngstrobj(L, size); + setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */ + luaD_inctop(L); LoadVector(S, getstr(ts), size); /* load directly in final place */ - return ts; + L->top--; /* pop string */ } + luaC_objbarrier(L, p, ts); + return ts; } @@ -147,7 +153,7 @@ static void LoadConstants (LoadState *S, Proto *f) { break; case LUA_TSHRSTR: case LUA_TLNGSTR: - setsvalue2n(S->L, o, LoadString(S)); + setsvalue2n(S->L, o, LoadString(S, f)); break; default: lua_assert(0); @@ -165,6 +171,7 @@ static void LoadProtos (LoadState *S, Proto *f) { f->p[i] = NULL; for (i = 0; i < n; i++) { f->p[i] = luaF_newproto(S->L); + luaC_objbarrier(S->L, f, f->p[i]); LoadFunction(S, f->p[i], f->source); } } @@ -196,18 +203,18 @@ static void LoadDebug (LoadState *S, Proto *f) { for (i = 0; i < n; i++) f->locvars[i].varname = NULL; for (i = 0; i < n; i++) { - f->locvars[i].varname = LoadString(S); + f->locvars[i].varname = LoadString(S, f); f->locvars[i].startpc = LoadInt(S); f->locvars[i].endpc = LoadInt(S); } n = LoadInt(S); for (i = 0; i < n; i++) - f->upvalues[i].name = LoadString(S); + f->upvalues[i].name = LoadString(S, f); } static void LoadFunction (LoadState *S, Proto *f, TString *psource) { - f->source = LoadString(S); + f->source = LoadString(S, f); if (f->source == NULL) /* no source in dump? */ f->source = psource; /* reuse parent's source */ f->linedefined = LoadInt(S); @@ -278,6 +285,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { setclLvalue(L, L->top, cl); luaD_inctop(L); cl->p = luaF_newproto(L); + luaC_objbarrier(L, cl, cl->p); LoadFunction(&S, cl->p, NULL); lua_assert(cl->nupvalues == cl->p->sizeupvalues); luai_verifycode(L, buff, cl->p);