Share to
funky custom variable names aren't handled gracefully.
emptyrivers opened this issue ยท 0 comments
Describe the bug
To Reproduce
The easy way: Import this aura, observe.
From scratch:
- Create any non-group aura, go to Trigger Tab.
- Create a TSU trigger.
- Add a custom variable with state key that starts with a number, contains a space, semicolon, parenthesis, or any other format that would require writing the key in quotes with brackets.
- Create a condition which checks the variable you created. Notice the compile error reported in the print stream.
Additional Info
The error looks to be sourced here - note that every use of condition.variable
in the generated code uses dot notation, when to be fully general it should use bracket notation:
WeakAuras2/WeakAuras/Conditions.lua
Lines 127 to 245 in 3834c27
local function CreateTestForCondition(uid, input, allConditionsTemplate, usedStates) | |
local trigger = input and input.trigger; | |
local variable = input and input.variable; | |
local op = input and input.op; | |
local value = input and input.value; | |
local check = nil; | |
local recheckCode = nil; | |
if (variable == "AND" or variable == "OR") then | |
local test = {}; | |
if (input.checks) then | |
for i, subcheck in ipairs(input.checks) do | |
local subtest, subrecheckCode = CreateTestForCondition(uid, subcheck, allConditionsTemplate, usedStates); | |
if (subtest) then | |
tinsert(test, "(" .. subtest .. ")"); | |
end | |
if (subrecheckCode) then | |
recheckCode = recheckCode or ""; | |
recheckCode = recheckCode .. subrecheckCode; | |
end | |
end | |
end | |
if (next(test)) then | |
if (variable == "AND") then | |
check = table.concat(test, " and "); | |
else | |
check = table.concat(test, " or "); | |
end | |
end | |
end | |
if (trigger and variable) then | |
usedStates[trigger] = true; | |
local conditionTemplate = allConditionsTemplate[trigger] and allConditionsTemplate[trigger][variable]; | |
local cType = conditionTemplate and conditionTemplate.type; | |
local test = conditionTemplate and conditionTemplate.test; | |
local preamble = conditionTemplate and conditionTemplate.preamble; | |
local stateCheck = "state[" .. trigger .. "] and state[" .. trigger .. "].show and "; | |
local stateVariableCheck = "state[" .. trigger .. "]." .. variable .. "~= nil and "; | |
local preambleString | |
if preamble then | |
WeakAuras.conditionHelpers[uid] = WeakAuras.conditionHelpers[uid] or {} | |
WeakAuras.conditionHelpers[uid].preambles = WeakAuras.conditionHelpers[uid].preambles or {} | |
tinsert(WeakAuras.conditionHelpers[uid].preambles, preamble(value)); | |
local preambleNumber = #WeakAuras.conditionHelpers[uid].preambles | |
preambleString = string.format("WeakAuras.conditionHelpers[%q].preambles[%s]", uid, preambleNumber) | |
end | |
if (test) then | |
if (value) then | |
WeakAuras.conditionHelpers[uid] = WeakAuras.conditionHelpers[uid] or {} | |
WeakAuras.conditionHelpers[uid].customTestFunctions = WeakAuras.conditionHelpers[uid].customTestFunctions or {} | |
tinsert(WeakAuras.conditionHelpers[uid].customTestFunctions, test); | |
local testFunctionNumber = #(WeakAuras.conditionHelpers[uid].customTestFunctions); | |
local valueString = type(value) == "string" and string.format("%q", value) or value; | |
local opString = type(op) == "string" and string.format("%q", op) or op; | |
check = string.format("state and WeakAuras.CallCustomConditionTest(%q, %s, state[%s], %s, %s, %s)", | |
uid, testFunctionNumber, trigger, valueString, (opString or "nil"), preambleString or "nil"); | |
end | |
elseif (cType == "customcheck") then | |
if value then | |
local customCheck = WeakAuras.LoadFunction("return " .. value, "custom check") | |
if customCheck then | |
WeakAuras.conditionHelpers[uid] = WeakAuras.conditionHelpers[uid] or {} | |
WeakAuras.conditionHelpers[uid].customTestFunctions = WeakAuras.conditionHelpers[uid].customTestFunctions or {} | |
tinsert(WeakAuras.conditionHelpers[uid].customTestFunctions, customCheck); | |
local testFunctionNumber = #(WeakAuras.conditionHelpers[uid].customTestFunctions); | |
check = string.format("state and WeakAuras.CallCustomConditionTest(%q, %s, state)", | |
uid, testFunctionNumber, trigger); | |
end | |
end | |
elseif cType == "alwaystrue" then | |
check = "true" | |
elseif (cType == "number" and value and op) then | |
local v = tonumber(value) | |
if (v) then | |
check = stateCheck .. stateVariableCheck .. "state[" .. trigger .. "]." .. variable .. op .. v; | |
end | |
elseif (cType == "timer" and value and op) then | |
if (op == "==") then | |
check = stateCheck .. stateVariableCheck .. "abs(state[" .. trigger .. "]." ..variable .. "- now -" .. value .. ") < 0.05"; | |
else | |
check = stateCheck .. stateVariableCheck .. "state[" .. trigger .. "]." .. variable .. "- now" .. op .. value; | |
end | |
elseif (cType == "select" and value and op) then | |
if (tonumber(value)) then | |
check = stateCheck .. stateVariableCheck .. "state[" .. trigger .. "]." .. variable .. op .. tonumber(value); | |
else | |
check = stateCheck .. stateVariableCheck .. "state[" .. trigger .. "]." .. variable .. op .. "'" .. value .. "'"; | |
end | |
elseif (cType == "bool" and value) then | |
local rightSide = value == 0 and "false" or "true"; | |
check = stateCheck .. stateVariableCheck .. "state[" .. trigger .. "]." .. variable .. "==" .. rightSide | |
elseif (cType == "string" and value) then | |
if(op == "==") then | |
check = stateCheck .. stateVariableCheck .. "state[" .. trigger .. "]." .. variable .. " == [[" .. value .. "]]"; | |
elseif (op == "find('%s')") then | |
check = stateCheck .. stateVariableCheck .. "state[" .. trigger .. "]." .. variable .. ":find([[" .. value .. "]], 1, true)"; | |
elseif (op == "match('%s')") then | |
check = stateCheck .. stateVariableCheck .. "state[" .. trigger .. "]." .. variable .. ":match([[" .. value .. "]], 1, true)"; | |
end | |
end | |
if (cType == "timer" and value) then | |
recheckCode = " nextTime = state[" .. trigger .. "] and state[" .. trigger .. "]." .. variable .. " and (state[" .. trigger .. "]." .. variable .. " -" .. value .. ")\n"; | |
recheckCode = recheckCode .. " if (nextTime and (not recheckTime or nextTime < recheckTime) and nextTime >= now) then\n" | |
recheckCode = recheckCode .. " recheckTime = nextTime\n"; | |
recheckCode = recheckCode .. " end\n" | |
end | |
end | |
return check, recheckCode; | |
end |