Răsfoiți Sursa

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'.
Roberto Ierusalimschy 5 ani în urmă
părinte
comite
6bc0f13505
2 a modificat fișierele cu 18 adăugiri și 1 ștergeri
  1. 3 0
      lundump.c
  2. 15 1
      testes/calls.lua

+ 3 - 0
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;

+ 15 - 1
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)