From 6bc0f13505bf5d4f613d725fe008c79e72f83ddf Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 18 Aug 2020 14:42:11 -0300 Subject: [PATCH] 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'. --- lundump.c | 3 +++ testes/calls.lua | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lundump.c b/lundump.c index cb124d6f..5aa55c44 100644 --- a/lundump.c +++ b/lundump.c @@ -120,7 +120,10 @@ static TString *loadStringN (LoadState *S, Proto *p) { } else { /* long string */ ts = luaS_createlngstrobj(L, size); /* create string */ + setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */ + luaD_inctop(L); loadVector(S, getstr(ts), size); /* load directly in final place */ + L->top--; /* pop string */ } luaC_objbarrier(L, p, ts); return ts; diff --git a/testes/calls.lua b/testes/calls.lua index decf4176..ff72d8f6 100644 --- a/testes/calls.lua +++ b/testes/calls.lua @@ -317,6 +317,16 @@ f = load(string.dump(function () return 1 end), nil, "b", {}) assert(type(f) == "function" and f() == 1) +do -- another bug (in 5.4.0) + -- loading a binary long string interrupted by GC cycles + local f = string.dump(function () + return '01234567890123456789012345678901234567890123456789' + end) + f = load(read1(f)) + assert(f() == '01234567890123456789012345678901234567890123456789') +end + + x = string.dump(load("x = 1; return x")) a = assert(load(read1(x), nil, "b")) assert(a() == 1 and _G.x == 1) @@ -358,8 +368,12 @@ x = [[ end end ]] +a = assert(load(read1(x), "read", "t")) +assert(a()(2)(3)(10) == 15) -a = assert(load(read1(x))) +-- repeat the test loading a binary chunk +x = string.dump(a) +a = assert(load(read1(x), "read", "b")) assert(a()(2)(3)(10) == 15)