From 7433d27da57655e3eb5b33b1c2b3ddb02810dce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Sat, 27 Nov 2021 13:10:36 +0100 Subject: [PATCH] Don't expose private event fields to user in choices --- interpreter/interpreter.lua | 22 ++++++++++++++++------ test/run.lua | 16 ---------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/interpreter/interpreter.lua b/interpreter/interpreter.lua index be284d5..25bcd37 100644 --- a/interpreter/interpreter.lua +++ b/interpreter/interpreter.lua @@ -125,16 +125,25 @@ local events = { state.interpreter.event_type = nil state.interpreter.event_buffer = nil state.interpreter.skip_choices_until_flush = nil - -- yield + -- extract some needed state data for each choice block + local choices + if type == "choice" then + choices = {} + for _, c in ipairs(buffer) do + table.insert(choices, c._state) + c._state = nil + end + end + -- yield event coroutine.yield(type, buffer) -- run choice if type == "choice" then local sel = state.interpreter.choice_selected state.interpreter.choice_selected = nil - if not sel or sel < 1 or sel > #buffer then + if not sel or sel < 1 or sel > #choices then return nil, "invalid choice" else - local choice = buffer[sel]._d + local choice = choices[sel] -- execute in expected tag & event capture state local capture_state = state.interpreter.event_capture_stack state.interpreter.event_capture_stack = {} @@ -184,14 +193,15 @@ run_line = function(state, line) local v, e = events:make_space_for(state, "choice") if not v then return v, ("%s; in automatic event flush at %s"):format(e, line.source) end local currentTags = tags:current(state) - v, e = events:append(state, "choice", { _d = { tags = currentTags, block = line.child }}) -- new choice + local choice_block_state = { tags = currentTags, block = line.child } + v, e = events:append(state, "choice", { _state = choice_block_state }) -- new choice if not v then return v, e end events:push_capture(state, "text", function(event) - local v2, e2 = events:append_in_last(state, "choice", event, { _d = { tags = currentTags, block = line.child }}) + local v2, e2 = events:append_in_last(state, "choice", event, { _state = choice_block_state }) if not v2 then return v2, e2 end end) v, e = eval_text_callback(state, line.text, function(text) - local v2, e2 = events:append_in_last(state, "choice", { text = text, tags = currentTags }, { _d = { tags = currentTags, block = line.child }}) + local v2, e2 = events:append_in_last(state, "choice", { text = text, tags = currentTags }, { _state = choice_block_state }) if not v2 then return v2, e2 end end) events:pop_capture(state, "text") diff --git a/test/run.lua b/test/run.lua index 3f208b4..edca515 100644 --- a/test/run.lua +++ b/test/run.lua @@ -21,20 +21,6 @@ local function format_text(t) return r end ---- remove unneeded things from a result table (namely private fields) -local function strip(t, visited) - visited = visited or {} - for k, v in pairs(t) do - if type(k) == "string" and k:match("^_") then - t[k] = nil - end - if type(v) == "table" and not visited[v] then - visited[v] = true - strip(v, visited) - end - end -end - local function compare(a, b) if type(a) == "table" and type(b) == "table" then for k, v in pairs(a) do @@ -214,8 +200,6 @@ else table.insert(result, { "error", err }) end - strip(result) - if args["write-all"] then write_result(filebase, result) else