From 5e657c65047c3f1e6546bc908f816c49ab02938d Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Sun, 22 Oct 2017 11:55:05 +0200 Subject: [PATCH] More robust `super_tostring`. --- analyze_structure.lua | 8 ++++++-- test/test_resilience.lua | 9 +++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/analyze_structure.lua b/analyze_structure.lua index 3799b9a..56075dd 100644 --- a/analyze_structure.lua +++ b/analyze_structure.lua @@ -42,6 +42,8 @@ local LEAF_VALUE_TYPES = { local SHORT_STRING_MAX_LEN = 7 local MINIMUM_NUMBER_OF_SET_ELEMENTS = 2 +local RECURSIVE_TOSTRING_TIMEOUT = 10 + -------------------------------------------------------------------------------- local function is_identifier(s) @@ -226,12 +228,14 @@ local function super_tostring (t) -- function cannot find a string. local seen = { [t] = true } - while true do - local nt = tostring(t) + for i = 1, RECURSIVE_TOSTRING_TIMEOUT do + local success, nt = pcall(tostring, t) + if not success then return 'error on tostring: '..tostring(nt) end if type(nt) == 'string' or nt == nil then return tostring(nt) end if seen[nt] then return nil end seen[nt], t = true, nt end + return nil end -------------------------------------------------------------------------------- diff --git a/test/test_resilience.lua b/test/test_resilience.lua index 3e72b52..d4c0e10 100644 --- a/test/test_resilience.lua +++ b/test/test_resilience.lua @@ -161,13 +161,10 @@ end -------------------------------------------------------------------------------- -- Strange metatable -SUITE:addTest('Metatable: Error on %s operator', function (op) - pretty( setmetatable( { a = 2, b = 4, 1, 2, 3 } , {['__'..op] = function() error 'This should be unreachable!' end}) ) +SUITE:addTest('Metatable: Error on operator', function (op) + pretty( setmetatable( { a = 2, b = 4, 1, 2, 3 } , {[op] = function() error 'This should be unreachable!' end}) ) assert(true) -end, { data = { - {'add'}, {'sub'}, {'mul'}, {'div'}, {'mod'},{'pow'}, {'unm'}, {'concat'}, - {'len'}, {'eq'}, {'lt'}, {'le'}, {'index'}, {'newindex'}, {'call'} } -}) +end, { data = { '__add', '__sub', '__mul', '__div', '__mod', '__pow', '__unm', '__concat','__len', '__eq', '__lt', '__le', '__index', '__newindex', '__call', '__tostring' } }) SUITE:addTest('Metatable: # returns bogus length', function () assert_equal('{ 1, 2, 3, 4 }', pretty( setmetatable({ 1, 2, 3, 4 }, {__len = function() return 2 end})))