## lua string math and loadstring

### lua string math and loadstring

in a project I'm working on, I end up with a string that is a mathematical equation. like:
local equation="8+5"
there should be NOTHING but numbers and mathematical operators in the string, and I can, of course, verify that in the code.
but I need to convert that equation into an actual number.
I had a fancy schmancy Java routine that would handle all kinds of string math. I'm trying to determine how to do this in lua.
It looks like I could accomplish this using loadstring?

BUT, loadstring looks like a very risky thing to implement. With sufficient code checks to ensure there will be no arbitrary lua code execution, is loadstring considered acceptable in minetest mods?

Is there some other built in way to convert string equations into actual numerical results?
Kilarin
Member

Posts: 717
Joined: Mon Mar 10, 2014 12:36 am

### Re: lua string math and loadstring

Never mind. I think I worked out a nice routine with a good whitest that should handle the problem. Will post if anyone wishes to critique it.
Kilarin
Member

Posts: 717
Joined: Mon Mar 10, 2014 12:36 am

### Re: lua string math and loadstring

Please do let us view the code.
Member

Posts: 272
Joined: Mon Dec 29, 2014 8:07 am

### Re: lua string math and loadstring

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 rsltend  --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 filecircus=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
Kilarin
Member

Posts: 717
Joined: Mon Mar 10, 2014 12:36 am

### Re: lua string math and loadstring

Thanks for posting.

Try the str_helpers mod. Might be useful for breaking apart strings, or show you how to code something else.
Member

Posts: 272
Joined: Mon Dec 29, 2014 8:07 am

### Re: lua string math and loadstring

Manually parsing strings like that is insecure and really not a good idea.

Use a sandbox instead, see how mesecon's lua controller does it: https://github.com/minetest-mods/meseco ... #L436-L553
rubenwardy
Moderator

Posts: 5717
Joined: Tue Jun 12, 2012 6:11 pm
GitHub: rubenwardy
In-game: rubenwardy

### Re: lua string math and loadstring

THAT is exactly what I came here for.   White listing is certainly better than Black listing, but it still left my nerves on edge.  This will be a better solution.

THANK YOU!
Kilarin
Member

Posts: 717
Joined: Mon Mar 10, 2014 12:36 am

### Re: lua string math and loadstring

Is this properly implemented sandboxing?

Code: Select all
`--********************************function luautils.string_math(str,vars)  if vars~=nil then --substitute variables    for k,v in pairs(vars) do      str=string.gsub(str,k,v)    end --for    end --if    --sandbox for security (do not allow arbitrary lua code execution)    local env = {loadstring=loadstring, math = {    abs = math.abs,    acos = math.acos,    asin = math.asin,    atan = math.atan,    atan2 = math.atan2,    ceil = math.ceil,    cos = math.cos,    cosh = math.cosh,    deg = math.deg,    exp = math.exp,    floor = math.floor,    fmod = math.fmod,    frexp = math.frexp,    huge = math.huge,    ldexp = math.ldexp,    log = math.log,    log10 = math.log10,    max = math.max,    min = math.min,    modf = math.modf,    pi = math.pi,    pow = math.pow,    rad = math.rad,    random = math.random,    sin = math.sin,    sinh = math.sinh,    sqrt = math.sqrt,    tan = math.tan,    tanh = math.tanh,    }}         local f=function() return loadstring("return "..str.."+0")() end  setfenv(f,env)  local rslt=f()    return rsltend  --string_math`
Kilarin
Member

Posts: 717
Joined: Mon Mar 10, 2014 12:36 am