Currently, it is assumed that the following operators may be chained while omitting parentheses: ["..", "and", "or", "+", "", "&", "|"].
However, this becomes an issue when a metatable that has special operator functions is operated on. For example, consider this piece of code:
`local ret = 4 + (setmetatable({}, {
_add = function(, val)
return val 2;
end
}) + 64)
return ret`
Here, the metatable will be operated on with the + operator and the number 64 FIRST, and then 4 will be added to the result, however these semantics are thrown out after parsing the script, leaving us with this result:
local ret = 4 + setmetatable({}, {__add=function(_, val) return val * 2; end}) + 64; return ret;
Now, because the parentheses were omitted, the behavior has changed, and no longer will the metatable function be called with 64 first.
Proposed solution: Consider adding a check to make sure that each member of the binary operator chain is a number, before assuming parentheses are safe to remove.
Currently, it is assumed that the following operators may be chained while omitting parentheses: ["..", "and", "or", "+", "", "&", "|"]. However, this becomes an issue when a metatable that has special operator functions is operated on. For example, consider this piece of code: `local ret = 4 + (setmetatable({}, { _add = function(, val) return val 2; end }) + 64) return ret`
Here, the metatable will be operated on with the + operator and the number 64 FIRST, and then 4 will be added to the result, however these semantics are thrown out after parsing the script, leaving us with this result:
local ret = 4 + setmetatable({}, {__add=function(_, val) return val * 2; end}) + 64; return ret;
Now, because the parentheses were omitted, the behavior has changed, and no longer will the metatable function be called with 64 first.Proposed solution: Consider adding a check to make sure that each member of the binary operator chain is a number, before assuming parentheses are safe to remove.