Opened 8 years ago
Closed 8 years ago
#10935 closed enhancement (fixed)
lua-5.3.5
| Reported by: | Bruce Dubbs | Owned by: | Douglas R. Reno |
|---|---|---|---|
| Priority: | normal | Milestone: | 8.3 |
| Component: | BOOK | Version: | SVN |
| Severity: | medium | Keywords: | |
| Cc: |
Description
New point version.
Change History (3)
comment:1 by , 8 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:2 by , 8 years ago
Note:
See TracTickets
for help on using tickets.

Wrong code generated for a 'goto' followed by a label inside an 'if'. reported by 云风 on 13 Apr 2017. existed since 5.2. Example: -- should print 32323232..., but prints only '3' if true then goto LBL ::loop:: print(2) ::LBL:: print(3) goto loop end Patch: lparser.c: @@ -1392,7 +1392,7 @@ luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ enterblock(fs, &bl, 0); /* must enter block before 'goto' */ gotostat(ls, v.t); /* handle goto/break */ - skipnoopstat(ls); /* skip other no-op statements */ + while (testnext(ls, ';')) {} /* skip semicolons */ if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ leaveblock(fs); return; /* and that is it */ Lua crashes when building sequences with more than 2^30 elements. reported by Viacheslav Usov on 11 May 2017. Example: -- crashes if machine has enough memory local t = {} for i = 1, 0x7fffffff do t[i] = i end Patch: ltable.c: @@ -223,7 +223,9 @@ unsigned int na = 0; /* number of elements to go to array part */ unsigned int optimal = 0; /* optimal size for array part */ /* loop while keys can fill more than half of total size */ - for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) { + for (i = 0, twotoi = 1; + twotoi > 0 && *pna > twotoi / 2; + i++, twotoi *= 2) { if (nums[i] > 0) { a += nums[i]; if (a > twotoi/2) { /* more than half elements present? */ Table length computation overflows for sequences larger than 2^31 elements. reported by Viacheslav Usov on 12 May 2017. Example: -- on a machine with enough memory local t = {} for i = 1, 2147483681 do t[i] = i end print(#t) Patch: ltable.h: @@ -56,3 +56,3 @@ LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); -LUAI_FUNC int luaH_getn (Table *t); +LUAI_FUNC lua_Unsigned luaH_getn (Table *t); ltable.c: @@ -614,4 +614,4 @@ -static int unbound_search (Table *t, unsigned int j) { - unsigned int i = j; /* i is zero or a present index */ +static lua_Unsigned unbound_search (Table *t, lua_Unsigned j) { + lua_Unsigned i = j; /* i is zero or a present index */ j++; @@ -620,3 +620,3 @@ i = j; - if (j > cast(unsigned int, MAX_INT)/2) { /* overflow? */ + if (j > l_castS2U(LUA_MAXINTEGER) / 2) { /* overflow? */ /* table was built with bad purposes: resort to linear search */ @@ -630,3 +630,3 @@ while (j - i > 1) { - unsigned int m = (i+j)/2; + lua_Unsigned m = (i+j)/2; if (ttisnil(luaH_getint(t, m))) j = m; @@ -642,3 +642,3 @@ */ -int luaH_getn (Table *t) { +lua_Unsigned luaH_getn (Table *t) { unsigned int j = t->sizearray; Lua does not check GC when creating error messages. reported by Viacheslav Usov on 06 Jul 2017. existed since 5.3.2. Example: function test() bob.joe.larry = 23 end -- memory will grow steadly for i = 1, math.huge do pcall(test) if i % 100000 == 0 then io.write(collectgarbage'count'*1024, "\n") end end Patch: ldebug.c: @@ -653,6 +653,7 @@ CallInfo *ci = L->ci; const char *msg; va_list argp; + luaC_checkGC(L); /* error message uses memory */ va_start(argp, fmt); msg = luaO_pushvfstring(L, fmt, argp); /* format message */ va_end(argp); Dead keys with nil values can stay in weak tables. reported by 云风 Cloud Wu on 15 Aug 2017. existed since 5.2. Example: -- The following chunk, under a memory checker like valgrind, produces a memory access violation. local a = setmetatable({}, {__mode = 'kv'}) a['ABCDEFGHIJKLMNOPQRSTUVWXYZ' .. 'abcdefghijklmnopqrstuvwxyz'] = {} a[next(a)] = nil collectgarbage() print(a['BCDEFGHIJKLMNOPQRSTUVWXYZ' .. 'abcdefghijklmnopqrstuvwxyz']) Patch: lgc.c: @@ -643,8 +643,9 @@ for (n = gnode(h, 0); n < limit; n++) { if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { setnilvalue(gval(n)); /* remove value ... */ - removeentry(n); /* and remove entry from table */ } + if (ttisnil(gval(n))) /* is entry empty? */ + removeentry(n); /* remove entry from table */ } } } lua_pushcclosure should not call the garbage collector when n is zero. reported by Andrew Gierth on 05 Dec 2017. existed since 5.3.3. Patch: lapi.c: @@ -533,6 +533,7 @@ lua_lock(L); if (n == 0) { setfvalue(L->top, fn); + api_incr_top(L); } else { CClosure *cl; @@ -546,9 +547,9 @@ /* does not need barrier because closure is white */ } setclCvalue(L, L->top, cl); + api_incr_top(L); + luaC_checkGC(L); } - api_incr_top(L); - luaC_checkGC(L); lua_unlock(L); } Memory-allocation error when resizing a table can leave it in an inconsistent state.. reported by Roberto on 08 Dec 2017. existed since 5.0. Example: local a = {x = 1, y = 1, z = 1} a[1] = 10 -- goes to the hash part (which has 4 slots) print(a[1]) --> 10 -- assume that the 2nd memory allocation from now fails pcall(rawset, a, 2, 20) -- forces a rehash -- a[1] now exists both in the array part (because the array part -- grew) and in the hash part (because the allocation of the hash -- part failed, keeping it as it was). -- This makes the following traversal goes forever... for k,v in pairs(a) do print(k,v) end Patch: ltable.c: @@ -332,17 +332,34 @@ } +typedef struct { + Table *t; + unsigned int nhsize; +} AuxsetnodeT; + + +static void auxsetnode (lua_State *L, void *ud) { + AuxsetnodeT *asn = cast(AuxsetnodeT *, ud); + setnodevector(L, asn->t, asn->nhsize); +} + + void luaH_resize (lua_State *L, Table *t, unsigned int nasize, unsigned int nhsize) { unsigned int i; int j; + AuxsetnodeT asn; unsigned int oldasize = t->sizearray; int oldhsize = allocsizenode(t); Node *nold = t->node; /* save old hash ... */ if (nasize > oldasize) /* array part must grow? */ setarrayvector(L, t, nasize); /* create new hash part with appropriate size */ - setnodevector(L, t, nhsize); + asn.t = t; asn.nhsize = nhsize; + if (luaD_rawrunprotected(L, auxsetnode, &asn) != LUA_OK) { /* mem. error? */ + setarrayvector(L, t, oldasize); /* array back to its original size */ + luaD_throw(L, LUA_ERRMEM); /* rethrow memory error */ + } if (nasize < oldasize) { /* array part must shrink? */ t->sizearray = nasize; /* re-insert elements from vanishing slice */