1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-12-14 20:20:30 +00:00

Be more rigorous in checking for invalid values in settings.load

If someone had a recursive table (created with an IIFE), then we'd throw
an error inside reserialize. We now catch this error and silently drop
the value.

I'm not thrilled by this behaviour - there's an argument we should
return false instead - but it's consistent with what we currently do.

Closes #1337.
This commit is contained in:
Jonathan Coates 2023-02-17 09:08:19 +00:00
parent a5bda7454a
commit 41c83988a1
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
2 changed files with 11 additions and 5 deletions

View File

@ -74,8 +74,7 @@ function undefine(name)
details[name] = nil details[name] = nil
end end
local function set_value(name, value) local function set_value(name, new)
local new = reserialize(value)
local old = values[name] local old = values[name]
if old == nil then if old == nil then
local opt = details[name] local opt = details[name]
@ -103,7 +102,7 @@ function set(name, value)
local opt = details[name] local opt = details[name]
if opt and opt.type then expect(2, value, opt.type) end if opt and opt.type then expect(2, value, opt.type) end
set_value(name, value) set_value(name, reserialize(value))
end end
--- Get the value of a setting. --- Get the value of a setting.
@ -214,7 +213,9 @@ function load(sPath)
if type(k) == "string" and (ty_v == "string" or ty_v == "number" or ty_v == "boolean" or ty_v == "table") then if type(k) == "string" and (ty_v == "string" or ty_v == "number" or ty_v == "boolean" or ty_v == "table") then
local opt = details[k] local opt = details[k]
if not opt or not opt.type or ty_v == opt.type then if not opt or not opt.type or ty_v == opt.type then
set_value(k, v) -- This may fail if the table is recursive (or otherwise cannot be serialized).
local ok, v = pcall(reserialize, v)
if ok then set_value(k, v) end
end end
end end
end end

View File

@ -189,11 +189,16 @@ describe("The settings library", function()
expect(settings.get("test.defined")):eq(nil) expect(settings.get("test.defined")):eq(nil)
end) end)
it("skips unserializable values", function() it("skips unserializable values (functions)", function()
expect(setup_with "{ test = function() end }"):eq(true) expect(setup_with "{ test = function() end }"):eq(true)
expect(settings.get("test")):eq(nil) expect(settings.get("test")):eq(nil)
end) end)
it("skips unserializable values (recursive tables)", function()
expect(setup_with "{ test = (function() local x = {} x.x = x return x end)() }"):eq(true)
expect(settings.get("test")):eq(nil)
end)
it("skips non-table files", function() it("skips non-table files", function()
expect(setup "not a table"):eq(false) expect(setup "not a table"):eq(false)
end) end)