From be73f72fcc944a8ebae2c60d2ce84139acb011b9 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 18 Jun 2019 16:52:22 -0300 Subject: New function 'setCstacklimit' Added new functions to dynamically set the C-stack limit ('lua_setCstacklimit' in the C-API, 'debug.setCstacklimit' in Lua). --- testes/cstack.lua | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ testes/errors.lua | 16 ++++++++++------ 2 files changed, 58 insertions(+), 6 deletions(-) (limited to 'testes') diff --git a/testes/cstack.lua b/testes/cstack.lua index 3cb1e4ce..c7aa740f 100644 --- a/testes/cstack.lua +++ b/testes/cstack.lua @@ -1,8 +1,14 @@ -- $Id: testes/cstack.lua $ -- See Copyright Notice in file all.lua +local debug = require "debug" + print"testing C-stack overflow detection" +local origlimit = debug.setCstacklimit(400) +print("current stack limit: " .. origlimit) +debug.setCstacklimit(origlimit) + -- Segmentation faults in these tests probably result from a C-stack -- overflow. To avoid these errors, recompile Lua with a smaller -- value for the constant 'LUAI_MAXCCALLS' or else ensure a larger @@ -79,4 +85,46 @@ do print("testing stack-overflow in recursive 'gsub'") print("\tfinal count: ", count) end + +do print("testing changes in C-stack limit") + + assert(not debug.setCstacklimit(0)) -- limit too small + assert(not debug.setCstacklimit(50000)) -- limit too large + local co = coroutine.wrap (function () + return debug.setCstacklimit(400) + end) + assert(co() == false) -- cannot change C stack inside coroutine + + local n + local function foo () n = n + 1; foo () end + + local function check () + n = 0 + pcall(foo) + return n + end + + assert(debug.setCstacklimit(400) == origlimit) + local lim400 = check() + -- a very low limit (given that the several calls to arive here) + local lowlimit = 38 + assert(debug.setCstacklimit(lowlimit) == 400) + assert(check() < lowlimit - 30) + assert(debug.setCstacklimit(600) == lowlimit) + local lim600 = check() + assert(lim600 == lim400 + 200) + + + -- 'setCstacklimit' works inside protected calls. (The new stack + -- limit is kept when 'pcall' returns.) + assert(pcall(function () + assert(debug.setCstacklimit(400) == 600) + assert(check() <= lim400) + end)) + + assert(check() == lim400) + assert(debug.setCstacklimit(origlimit) == 400) -- restore original limit +end + + print'OK' diff --git a/testes/errors.lua b/testes/errors.lua index 0b12410e..6e7b8004 100644 --- a/testes/errors.lua +++ b/testes/errors.lua @@ -523,9 +523,13 @@ end -- testing syntax limits -local function testrep (init, rep, close, repc) +local function testrep (init, rep, close, repc, finalresult) local s = init .. string.rep(rep, 100) .. close .. string.rep(repc, 100) - assert(load(s)) -- 100 levels is OK + local res, msg = load(s) + assert(res) -- 100 levels is OK + if (finalresult) then + assert(res() == finalresult) + end s = init .. string.rep(rep, 10000) local res, msg = load(s) -- 10000 levels not ok assert(not res and (string.find(msg, "too many registers") or @@ -534,14 +538,14 @@ end testrep("local a; a", ",a", "= 1", ",1") -- multiple assignment testrep("local a; a=", "{", "0", "}") -testrep("local a; a=", "(", "2", ")") -testrep("local a; ", "a(", "2", ")") +testrep("return ", "(", "2", ")", 2) +testrep("local function a (x) return x end; return ", "a(", "2.2", ")", 2.2) testrep("", "do ", "", " end") testrep("", "while a do ", "", " end") testrep("local a; ", "if a then else ", "", " end") testrep("", "function foo () ", "", " end") -testrep("local a; a=", "a..", "a", "") -testrep("local a; a=", "a^", "a", "") +testrep("local a = ''; return ", "a..", "'a'", "", "a") +testrep("local a = 1; return ", "a^", "a", "", 1) checkmessage("a = f(x" .. string.rep(",x", 260) .. ")", "too many registers") -- cgit v1.2.3-55-g6feb