Make new raw_parse more robust

This commit is contained in:
luk3yx 2022-02-08 21:22:26 +13:00
parent 8fca50e407
commit 0ba38e041e
2 changed files with 12 additions and 9 deletions

View File

@ -29,6 +29,8 @@
local formspec_ast, minetest = formspec_ast, formspec_ast.minetest local formspec_ast, minetest = formspec_ast, formspec_ast.minetest
local BACKSLASH, SEMICOLON, COMMA, RBRACKET = ('\\;,]'):byte(1, 4)
-- Parse a formspec into a "raw" non-AST state. -- Parse a formspec into a "raw" non-AST state.
-- Input: size[5,2]button[0,0;5,1;name;Label] image[0,1;1,1;air.png] -- Input: size[5,2]button[0,0;5,1;name;Label] image[0,1;1,1;air.png]
-- Output: -- Output:
@ -62,13 +64,11 @@ local function raw_parse(spec)
if esc then if esc then
-- The current character is escaped -- The current character is escaped
esc = false esc = false
start_idx = idx elseif byte == BACKSLASH then
elseif byte == 0x5c then
-- Backslashes
part[#part + 1] = spec:sub(start_idx, idx - 1) part[#part + 1] = spec:sub(start_idx, idx - 1)
start_idx = idx + 1
esc = true esc = true
elseif byte == 0x3b then elseif byte == SEMICOLON then
-- Semicolons
part[#part + 1] = spec:sub(start_idx, idx - 1) part[#part + 1] = spec:sub(start_idx, idx - 1)
start_idx = idx + 1 start_idx = idx + 1
if #inner > 0 then if #inner > 0 then
@ -79,14 +79,12 @@ local function raw_parse(spec)
parts[#parts + 1] = table_concat(part) parts[#parts + 1] = table_concat(part)
end end
part = {} part = {}
elseif byte == 0x2c then elseif byte == COMMA then
-- Commas
part[#part + 1] = spec:sub(start_idx, idx - 1) part[#part + 1] = spec:sub(start_idx, idx - 1)
start_idx = idx + 1 start_idx = idx + 1
inner[#inner + 1] = table_concat(part) inner[#inner + 1] = table_concat(part)
part = {} part = {}
elseif byte == 0x5d then elseif byte == RBRACKET then
-- ]
end_idx = idx end_idx = idx
break break
end end

View File

@ -416,4 +416,9 @@ assert_equal(
-- Ensure invsize[] is converted to size[] -- Ensure invsize[] is converted to size[]
assert_equal(assert(formspec_ast.interpret('invsize[12,34]')), 'size[12,34]') assert_equal(assert(formspec_ast.interpret('invsize[12,34]')), 'size[12,34]')
assert_equal(assert(formspec_ast.interpret('label[1,2;abc\\')),
'label[1,2;abc]')
assert_equal(assert(formspec_ast.interpret('label[1,2;abc\\\\')),
'label[1,2;abc\\\\]')
print('Tests pass') print('Tests pass')