mirror of
https://github.com/lua/lua
synced 2024-11-25 06:09:36 +03:00
2258f3133b
This file is not part of the regular tests. It tests error conditions that demand too much memory or too much time to create: * string with too many characters * control structure with body too large * chunk with too many lines * identifier with too many characters * chunks with too many instructions * function with too many constants * too many strings internalized * table with too many entries In machines with limited memory (less than 150 GB), many tests run up to a "not enough memory" error. We need some memory (~256 GB) to run all tests up to their intrinsic limits.
174 lines
4.4 KiB
Lua
174 lines
4.4 KiB
Lua
-- $Id: heavy.lua,v 1.7 2017/12/29 15:42:15 roberto Exp $
|
|
-- See Copyright Notice in file all.lua
|
|
|
|
local function teststring ()
|
|
print("creating a string too long")
|
|
do
|
|
local a = "x"
|
|
local st, msg = pcall(function ()
|
|
while true do
|
|
a = a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
.. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
.. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
.. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
.. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
.. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
.. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
.. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
.. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
.. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
|
|
print(string.format("string with %d bytes", #a))
|
|
end
|
|
end)
|
|
assert(not st and
|
|
(string.find(msg, "string length overflow") or
|
|
string.find(msg, "not enough memory")))
|
|
print("string length overflow with " .. #a * 100)
|
|
end
|
|
print('+')
|
|
end
|
|
|
|
local function loadrep (x, what)
|
|
local p = 1<<20
|
|
local s = string.rep(x, p)
|
|
local count = 0
|
|
local function f()
|
|
count = count + p
|
|
if count % (0x80*p) == 0 then
|
|
io.stderr:write("(", count // 2^20, " M)")
|
|
end
|
|
return s
|
|
end
|
|
local st, msg = load(f, "=big")
|
|
print("\nmemory: ", collectgarbage'count' * 1024)
|
|
msg = string.match(msg, "^[^\n]+") -- get only first line
|
|
print(string.format("total: 0x%x %s ('%s')", count, what, msg))
|
|
return st, msg
|
|
end
|
|
|
|
|
|
function controlstruct ()
|
|
print("control structure too long")
|
|
local lim = ((1 << 24) - 2) // 3
|
|
local s = string.rep("a = a + 1\n", lim)
|
|
s = "while true do " .. s .. "end"
|
|
assert(load(s))
|
|
print("ok with " .. lim .. " lines")
|
|
lim = lim + 3
|
|
s = string.rep("a = a + 1\n", lim)
|
|
s = "while true do " .. s .. "end"
|
|
local st, msg = load(s)
|
|
assert(not st and string.find(msg, "too long"))
|
|
print(msg)
|
|
end
|
|
|
|
|
|
function manylines ()
|
|
print("loading chunk with too many lines")
|
|
local st, msg = loadrep("\n", "lines")
|
|
assert(not st and string.find(msg, "too many lines"))
|
|
print('+')
|
|
end
|
|
|
|
|
|
function hugeid ()
|
|
print("loading chunk with huge identifier")
|
|
local st, msg = loadrep("a", "chars")
|
|
assert(not st and
|
|
(string.find(msg, "lexical element too long") or
|
|
string.find(msg, "not enough memory")))
|
|
print('+')
|
|
end
|
|
|
|
function toomanyinst ()
|
|
print("loading chunk with too many instructions")
|
|
local st, msg = loadrep("a = 10; ", "instructions")
|
|
print('+')
|
|
end
|
|
|
|
|
|
local function loadrepfunc (prefix, f)
|
|
local count = -1
|
|
local function aux ()
|
|
count = count + 1
|
|
if count == 0 then
|
|
return prefix
|
|
else
|
|
if count % (0x100000) == 0 then
|
|
io.stderr:write("(", count // 2^20, " M)")
|
|
end
|
|
return f(count)
|
|
end
|
|
end
|
|
local st, msg = load(aux, "k")
|
|
print("\nmemory: ", collectgarbage'count' * 1024)
|
|
msg = string.match(msg, "^[^\n]+") -- get only first line
|
|
print("expected error: ", msg)
|
|
end
|
|
|
|
|
|
function toomanyconst ()
|
|
print("loading function with too many constants")
|
|
loadrepfunc("function foo () return {0,",
|
|
function (n)
|
|
-- convert 'n' to a string in the format [["...",]],
|
|
-- where '...' is a kind of number in base 128
|
|
-- (in a range that does not include either the double quote
|
|
-- and the escape.)
|
|
return string.char(34,
|
|
((n // 128^0) & 127) + 128,
|
|
((n // 128^1) & 127) + 128,
|
|
((n // 128^2) & 127) + 128,
|
|
((n // 128^3) & 127) + 128,
|
|
((n // 128^4) & 127) + 128,
|
|
34, 44)
|
|
end)
|
|
end
|
|
|
|
|
|
function toomanystr ()
|
|
local a = {}
|
|
local st, msg = pcall(function ()
|
|
for i = 1, math.huge do
|
|
if i % (0x100000) == 0 then
|
|
io.stderr:write("(", i // 2^20, " M)")
|
|
end
|
|
a[i] = string.pack("I", i)
|
|
end
|
|
end)
|
|
local size = #a
|
|
a = collectgarbage'count'
|
|
print("\nmemory:", a * 1024)
|
|
print("expected error:", msg)
|
|
print("size:", size)
|
|
end
|
|
|
|
|
|
function toomanyidx ()
|
|
local a = {}
|
|
local st, msg = pcall(function ()
|
|
for i = 1, math.huge do
|
|
if i % (0x100000) == 0 then
|
|
io.stderr:write("(", i // 2^20, " M)")
|
|
end
|
|
a[i] = i
|
|
end
|
|
end)
|
|
print("\nmemory: ", collectgarbage'count' * 1024)
|
|
print("expected error: ", msg)
|
|
print("size:", #a)
|
|
end
|
|
|
|
|
|
|
|
-- teststring()
|
|
-- controlstruct()
|
|
-- manylines()
|
|
-- hugeid()
|
|
-- toomanyinst()
|
|
-- toomanyconst()
|
|
-- toomanystr()
|
|
toomanyidx()
|
|
|
|
print "OK"
|