fix edge case when lua keywords are used as keys

This commit is contained in:
tour 2024-09-14 20:42:42 +02:00
parent 9c723301ec
commit 9b440f279e
4 changed files with 84 additions and 7 deletions

View File

@ -44,11 +44,36 @@ local function stringToTable(str)
end
end
local lua_keywords = {
["and"] = true,
["break"] = true,
["do"] = true,
["else"] = true,
["elseif"] = true,
["end"] = true,
["false"] = true,
["for"] = true,
["function"] = true,
["goto"] = true,
["if"] = true,
["in"] = true,
["local"] = true,
["nil"] = true,
["not"] = true,
["or"] = true,
["repeat"] = true,
["return"] = true,
["then"] = true,
["true"] = true,
["until"] = true,
["while"] = true,
}
local function parseKey(s, i)
s = s:match("^%s*(.-)%s*$", i) -- Trim leading/trailing spaces
if s:find("^[%a_]") then
local key = s:match("^[%a%d_]*")
if key ~= "true" and key ~= "false" and key ~= "nil" then
if not lua_keywords[key] then
return key, #key
end
end

View File

@ -41,15 +41,41 @@ local function codedStringToTable(str)
end
end
local lua_keywords = {
["and"] = true,
["break"] = true,
["do"] = true,
["else"] = true,
["elseif"] = true,
["end"] = true,
["false"] = true,
["for"] = true,
["function"] = true,
["goto"] = true,
["if"] = true,
["in"] = true,
["local"] = true,
["nil"] = true,
["not"] = true,
["or"] = true,
["repeat"] = true,
["return"] = true,
["then"] = true,
["true"] = true,
["until"] = true,
["while"] = true,
}
local function parseKey(s)
s = s:match("^%s*(.-)%s*$") -- trim whitespace
if s:match("^%[(.*)%]$") then
return parseValue(s:match("^%[(.*)%]$"))
elseif s:find("^[%a_][%a%d_]*$") then -- make sure the string is a valid lua identifier
return s
else
error("Unrecognized key: " .. s)
end
s = s:match("^[%a_][%a%d_]*$") -- make sure the string is a valid lua identifier
if s and not lua_keywords[s] then
return s
end
error("Unrecognized key: " .. s)
end
local tbl = {}

View File

@ -38,6 +38,31 @@ local function parse_value(str)
return false, string.format("unable to parse '%s'", str)
end
local lua_keywords = {
["and"] = true,
["break"] = true,
["do"] = true,
["else"] = true,
["elseif"] = true,
["end"] = true,
["false"] = true,
["for"] = true,
["function"] = true,
["goto"] = true,
["if"] = true,
["in"] = true,
["local"] = true,
["nil"] = true,
["not"] = true,
["or"] = true,
["repeat"] = true,
["return"] = true,
["then"] = true,
["true"] = true,
["until"] = true,
["while"] = true,
}
local function parse_key(str)
if str:find("^%[.*%]$") then
-- if in brackets, we can threat it like a value
@ -51,7 +76,7 @@ local function parse_key(str)
return true, key
end
-- make sure the key is a valid identifier
if str:find("^[%a_][%a%d_]*$") then
if str:find("^[%a_][%a%d_]*$") and not lua_keywords[str] then
return true, str
end
return false, string.format("'%s' is not a valid key", str)

View File

@ -26,6 +26,7 @@ local tests = {
"{a = 1",
"{'unclosed string\\'}",
"{invalid key = 3}",
"{false = 2}", -- invalid key
"{1 = 2}", -- invalid key
"{,}",
"{[nil] = 1}"
@ -44,7 +45,7 @@ local function test(alg)
end
local t2 = minetest.get_us_time()
minetest.log("action",alg .. " = " .. (t2-t1))
print(dump(outcome))
-- print(dump(outcome))
end
test("s2t1")