- Code: Select all
`--does string math`

--acceptable values:

--numbers .+-*/^ ()

--math library functions

--this function does this validation so that you can be certain it cant execute arbitrary lua code.

--vars array is optional, if you pass in an array of variables and values they will be substituted before calculation

--********************************

function string_math(str,vars)

for k,v in pairs(vars) do

str=string.gsub(str,k,v)

end --for

end --if

--now all variables have been substituted, test if string is math ONLY

--(do not allow arbitrary lua code execution)

--is there a reason to define this array globaly or external to the function?

local allowed={"math%.abs","math%.acos","math%.asin","math%.atan","math%.ceil",

"math%.cos","math%.deg","math%.exp","math%.floor","math%.fmod","math%.huge",

"math%.log","math%.max","math%.maxinteger","math%.min","math%.mininteger",

"math%.modf","math%.pi","math%.rad","math%.random","math%.randomseed",

"math%.sin","math%.sqrt","math%.tan","math%.tointeger","math%.type","math%.ult",

"1","2","3","4","5","6","7","8","9","%.","+","-","*","/","%^","%(","%)",","," "}

local test=str

for k,v in pairs(allowed) do

test=string.gsub(test,v,"0") --change EVERYTHING that is allowed into 0

end --for a

--so why change everything to 0 instead of just ""? paranoia, it means

--something like mathmath.pi.floor cant slip through, although I am not

--certain what someone could do with that anyway

--math.pi3 CAN slip through, but again, I'm not certain what someone could

--do with that.

test=string.gsub(test,"0","") --remove all zeros

local rslt=""

if test=="" then --if the string was good, it should now be empty

rslt=loadstring("return "..str.."+0")()

else

rslt="Invalid String"

end --if test==""

return rslt

end --string_math

---example call:

- Code: Select all
`local vars={clowns=3,monkeys=5,ringmasters=1}`

str="math.floor((clowns+monkeys)/(ringmasters*math.pi))" --this would probably be read in from a settings file

circus=string_math(str,vars)

and now circus=2

So, what is the purpose of this?

I'm using it to allow values as formulas to be put into a settings file instead of having to be coded into the init.lua

So the user can say in the setting file:

tentsize=(monkeys*clowns)/ringmasters

and my lua can read that in and calculate the result on the fly.

I think a settings file is a bit more accessible for many users.

PLUS, it has the advantage that updating the code does not wipe out all of the users settings/preferences.

I just needed a way to be able to do MATH on the settings with variables so the user could enter formulas. But I'm paranoid and wanted to try and limit arbitrary lua code execution