When both 'int' and 'l_obj' have 32 bits, an unsigned int needs a
cast to be assigned to 'l_obj'. (As long as 'l_obj' can count the
total memory used by the system, these casts should be safe.)
The cast of n (number of repetitions) to size_t may truncate its value,
causing a buffer overflow later. Better to check the buffer size
using lua_Integer, as all string lengths must fit in a lua_Integer and
n already is a lua_Integer. If everything fits in MAX_SIZE, then we can
safely convert n to size_t and compute the buffer size as a size_t.
As a corner case, n can be larger than size_t if the strings being
repeated have length zero, but in this case it will be multiplied by
zero, so an overflow in the cast is irrelevant.
A bad actor could fill only a few entries in a table (power of twos in
decreasing order, see tests) and produce a small table with a huge
length. If your program builds a table with external data and iterates
over its length, this behavior could be an issue.
That complicates a little object equality (and therefore table access
for long strings), but the old behavior was somewhat weird. (Short
strings, a concept otherwise absent from the manual, could not be
external.)
External strings created by DLLs may need the DLL code to be
deallocated. This implies that a DLL can only be unloaded after all
its strings were deallocated, which happen only after the run of all
finalizers. To ensure that order, we create a 'library string' to
represent each DLL and keep it locked. When this string is deallocated
(after the deallocation of any string created by the DLL) it closes its
corresponding DLL.
LUAI_MAXSTACK is limited to INT_MAX/2, so can use INT_MAX/2 to define
pseudo-indices (LUA_REGISTRYINDEX) in 'lua.h'. A change in the maximum
stack size does not need to change the Lua-C ABI.
All-weak tables are not being revisited after being visited during
propagation; if it gets a new metatable after that, the new metatable
may not be marked.
No thread started with pcall (instead of resume) can be closed,
because coroutine.close would not respect the expected number of
results from the protected call.
In a constructor, each field generates at least one opcode, and the
number of opcodes is limited by INT_MAX. Therefore, the counters for
number of fields cannot exceed this limit. (The current limit for
items in the hash part of a table has a limit smaller than INT_MAX.
However, as long as there are no overflows, the logic for table
resizing will handle that limit.)
A goto cannot jump into the scope of any variable declaration,
including 'global *'. To report the error, it needs a "name" for
the scope it is entering.
The parser uses "break" as fake label to compile "break" as "goto
break". To avoid producing this string at each use, it keeps it
available in its state.
In generational collection, objects marked as touched1 stay in gray
lists between collections. This commit fixes a bug introduced in
commit 808976bb59.