Is there a way to convert a string into a function?

Hi, is this someway even possible to achieve on Corona SDK?

You can create a table with strings as the keys and functions as the values. Then you can just call myTable"key" to run the function.

So something like this?

local myFunctions = {
“print” = function() print(“hello world”) end
}

I was wonder if it is possible to achieve something like:

local myString = "print("Hello")"

and then somehow…

local function runIt(function)     --Some black magic here...     return myString end

later on…

runIt(myString)

Any idea on how to achieve this?  :huh:

I found it!

loadstring is there

Are you producing dynamic code or something? Might be helpful to know what the use case is.

I meant something like this:

[lua]

local doSomethingCode = function ()

  print (“Doing something…”)

end

local doSomethingElseCode = function ()

  print (“Doing something else…”)

end

local functionsTable = {doSomething = doSomethingCode, doSomethingElse = doSomethingElseCode}

local runIt = function (functionName)

  return functionsTablefunctionName

end

runIt(“doSomething”)

local usingVariable = “doSomethingElse”

runIt(usingVariable)

[/lua]

Just like Nick said, it’d be important to know why you need to do that. loadstring() does exactly what you’ve described, but performance-wise I wouldn’t touch it if there were some simpler alternatives available. loadstring() is a powerful feature, but you need to be careful with it.

Is this feature a performance killer or something?

What do I need to be worry about?

is it about globals maybe?  :huh:

Nohak

@Nick

What I was showing you was just an example that came to mind, I didn’t to try it on simulator.

Nohak

performance won’t be an issue for such simple input.  you need to worry about “where” that code is coming from, and what it could do to your main program’s environment.

consider:

local s = "loadstring = nil" local f,err = loadstring(s) local v,err = pcall(f)

that would execute successfully once, then all code after fails (loadstring no longer exists)

or:

local s = "display = nil" local f,err = loadstring(s) local v,err = pcall(f)

now your main program has no access to Corona’s display library

or, if you want to be truly malicious, how about:

local s = "setfenv(0,{})" local f,err = loadstring(s) local v,err = pcall(f)

or, lock up the main program with an infinite loop:

local s = "while(true) do end" local f,err = loadstring(s) local v,err = pcall(f)

etc

Hey @davebollinger now I understand what are you meaning to  :smiley:

I  don’t know if I am wrong but I think I see a way to create a system to prevent this kind of malicious code:

local function run(code) if (code == "enter malicious code lines here") then print("Bad guy, duh") else local thisCode, error = loadstring(code) end end

Is this a “cracker-avoider” solution?

Is there a way to remove the loadstring global function and to make it availbale loacally only in the “run” function?

Does this action make something worse?

Thanks in advance,

Nohak

@nosoyhackercodigo, loadstring always compiles its strings in a global environment. If your users cannot write any code themselves that your app would load, then you don’t need to worry about what they might do. On the other hand, if you allow your users to write code and you run that using loadstring, then there is no surefire way to catch or even predict all potentially malicious or even accidentally harmful code such as broken or infinite loops, etc.

Take @davebollinger’s example of the display library. There are infinite ways of messing it up, here’s just a few:

local s = "display = nil" loadstring(s)() local s = "\_G.display = nil" loadstring(s)() local s = "display = 1" loadstring(s)()

In any of these cases, you’ve lost the display library. The only way to prevent this would be to first search the string for any mention of display, but even then there’d be ways around it.

You’d also need to worry about what people might download using loadstring. Here’s an example of me loading an apple touch icon from my company’s website using loadstring:

local s = 'display.loadRemoteImage( "https://www.spyric.com/code/media/apple-touch-icon.png", "GET", nil, "icon.png", system.TemporaryDirectory, display.contentCenterX, display.contentCenterY )' loadstring(s)()

That’s a tiny and a harmless image, but what else could be downloaded?

no, because there are thousands of such things you’d have to blacklist, fe did you think of this one?:

local s = "os.exit()" local f,err = loadstring(s) local v,err = pcall(f)

that’s a pretty fatal one.  so odds are you’d never think of them all.  and even if you had a reasonably complete blacklist, it wouldn’t take much to circumvent it:

local s = [[\_G[string.reverse(table.concat({"y","a","l","p","s","i","d"}))]=\_]] local f,err = loadstring(s) local v,err = pcall(f) -- again display library is wiped

odds are you didn’t blacklist THAT specific wording, yet it does same thing as earlier.  (and i could easily reword it in yet another hundred different ways!)

google for “lua” and “_env” and “sandbox” and you might get close to a solution for that issue.

but that still won’t catch infinite loops and such.  (and probably nothing short of full semantic analysis would)

this is actually kinda fun in a twisted sort of way :smiley:

i’ll stop posting the “host code” and just post the “s” source, here’s a fun one:

local f f=function() Runtime:addEventListener("enterFrame",function() f() end) end f()

(bonus points if you can see what it does without actually running it)

Audio is not great, but here’s a talk from Peter Cawley a few years back:

[media]https://www.youtube.com/watch?v=OSMOTDLrBCQ[/media]

See also this thread.

I didn’t notice how difficult could be with my method. That thing would take millions of hours searching for all kind of strings.

I’m currently making a simulation of an “OS” with a custom desktop environment.5

It’s meant to be a tool for developers only so it’s just for experimental use and don’t see nothing wrong with that.

It’s not meant for the average user (at least not for now), so I think that this could be an experimental tool.

I’m in a place where there is too much noise and I don’t have headphones so I’ll see the video later.

@davebollinger

That code executes an anonymous function of itself running forever at 60 fps

I didn’t try it myself but it seems like a Runtime-function based loop.

You can create a table with strings as the keys and functions as the values. Then you can just call myTable"key" to run the function.

So something like this?

local myFunctions = {
“print” = function() print(“hello world”) end
}

I was wonder if it is possible to achieve something like:

local myString = "print("Hello")"

and then somehow…

local function runIt(function)     --Some black magic here...     return myString end

later on…

runIt(myString)

Any idea on how to achieve this?  :huh: