Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

loadstring

BortelsBortels Mod
edited November 2011 in Suggestions Posts: 1,557

Was trying to import:

http://lua-users.org/wiki/DataDumper

And it looks like "loadstring" isn't supported. Eep! My concept of serialize-as-code is in jeopardy.

Having said that - there's a good chance I really don't know what I'm doing. Is loadstring supported?

Comments

  • SimeonSimeon Admin Mod
    Posts: 5,054

    loadstring was removed as part of the sandboxing, however I've put it back in, as it doesn't seem that dangerous. It won't be available until the update following 1.1.2.

  • Posts: 2,161

    I was just trying the same thing. The new save data stuff looks useful, but it would be nice to be able to easily serialise and unserialise data to be able to save more interesting data. All the unserialising code that I've found uses loadstring.

  • SimeonSimeon Admin Mod
    Posts: 5,054

    loadstring() has been enabled for the next update.

  • BortelsBortels Mod
    Posts: 1,557

    So:

    v=0
    loadstring("v=1")
    print v
    

    returns 0, not the expected 1. This is in the beta. I'm missing something simple, right?

  • BortelsBortels Mod
    Posts: 1,557

    The goal, incidentally, is to make using a font (it's always fonts with him!) as easy as

    loadstring(readGlobalData("HersheyFont"))
    a=HersheyFont()
    a.drawstring("BooYah!")
    

    BooYah!

  • SimeonSimeon Admin Mod
    edited December 2011 Posts: 5,054

    loadstring() loads the string as a "chunk" into the Lua interpreter. You then need to execute it. So your example should be written:

    v = 0
    loadstring("v = 1")() -- note the function call
    print(v)
    

    You can also do:

    v = 0
    chunk = loadstring("v = 1")
    chunk()
    print(v)
    

    And so on.

  • BortelsBortels Mod
    Posts: 1,557

    Heh - I figured it was something simple. Thanks!

  • BortelsBortels Mod
    Posts: 1,557

    Sweet - I have data marshalling/unmarshalling working with the code on this page https://gist.github.com/1255382 - it's a derived version of the code linked above (not mine). More fun - it works unmodified - just load that gist into a blank tab, and

    v={"hello", "world"}
    d=DataDumper(v)
    print(d)
    

    gives

    return { "hello", "world"}
    

    which means I could do

    v = d()
    

    to restore my table. This should work on anything that doesn't have userdata (ie. an image() will break it) - but I've not tested it exhaustively, caveat emptor.

  • Reminds me of the exec() function in python :)

  • BortelsBortels Mod
    Posts: 1,557

    indeed - it's similar to exec() in javascript or perl as well.

  • When does this come in handy?

  • BortelsBortels Mod
    edited December 2011 Posts: 1,557

    the big thing, the reason I asked for it, is marshalling/unmarshalling data structures. A common way to save a complex data structure to persistent memory is to create the code necessary to re-create that data structure, and save the code - the idea being, when you want to load it back in, all you need to do is grab the block of code and execute it. Without that, saving/loading data means you need to write a save routine, and a load routine, specially for each type of data you want to persist.

    An example is spritely - it can save, to persistent memory, the code you need to draw a sprite. That makes it easy for a person to use in their own code - they don't need to include some custom spritely loader, they just load and execute the code.

    Problem is - if you can loadstring() random code, and you can download random code - you can download and execute random code, and apple freaks out about that unless the thing executing the code is their javascript implementation, Sigh. So - the likely scenario is we get loadstring() or sockets - but not both. And given their utility - sockets is way more useful. We can marshall/unmarshall data without loadstring(), it's just a pain. But without sockets - no talking to the world. And - the world is interesting to talk to.

  • DylanDylan Admin Mod
    Posts: 121

    But @Bortels, you could write a lua interpreter in lua, implementing your own loadstring function, thus allowing the executing of downloadable code. WILL THIS MADNESS EVER END?

    I think having the two systems exist independently is probably enough for Apple, though who knows, from our talks with them even they don't really know what is allowed. It seems to be very much up to the individual reviewer and their rules of thumb.

  • BortelsBortels Mod
    Posts: 1,557

    Dylan - you're absolutely correct. Which is why I think this restriction is ultimately futile. I think Apple is coming to its senses, slowly... But too slowly for my tastes.

    I also think you're right in thinking Apple themselves don't know for sure what is allowed and what's not. It's what happens when you throw common sense out the window in favor of strict policy guidelines.

    Anything sufficiently powerful can be abused - punishing the majority of users based on what some might do is a losing strategy, long run.

  • edited December 2011 Posts: 622

    e-mail this to them (prior to 1.2.7), it may help

    --What is Codea Allowed to do
    function setup()
        print("Think of a feature Codea will implement.")
        print("Then, press the red circle to determine if it's allowed")
    end
    
    function draw()
        rect(0,0,1,1)
        background(0, 0, 0)
        fill(255, 0, 0, 255)
        ellipse(WIDTH/2,HEIGHT/2,WIDTH,WIDTH)
        if CurrentTouch.state == BEGAN then
            x = math.random(5)
            if x == 1 then print("Why even ask, of course that's allowed.")
            elseif x == 2 then print("That should be fine.")
            elseif x == 3 then print("Yes, there is another approved app that does this.")
            elseif x == 4 then print("Whoa there, lemme check ... oh ya, no prob")
            elseif x == 5 then print("That may have been an issue with iOS 4 but with 5 your good.")
            end
        end
    end
    
  • Posts: 273

    @ipda41001 Perfect!

  • Posts: 2,820

    Hmm... Sockets + LoadString() + File IO = Mahem. Of only apple would really loses up... X(

  • BortelsBortels Mod
    Posts: 1,557

    You don't really need loadstring() - it just makes it easier.

  • Posts: 2,820

    Ya. But it's nice... But your right.

  • edited February 2012 Posts: 273

    @Bortels Sorry for reviving an old thread but above you mentioned that the DataDumper revised code:

     More fun - it works unmodified - just load that gist into a blank tab, and...
    

    So, as a clueless neophyte, I've just tried pasting said unmodified code into a blank tab and found (before I even tried invoking the function in main) that the code choked on this line:

    if totallen ]] > 80 then
    

    with a -- 'then' expected near ']' -- error.

    Any ideas? Does the DataDumper function still work for you?

    TIA Mr. Bortels!

  • BortelsBortels Mod
    Posts: 1,557

    Hmm - it worked for me when I posted it...

    Looking at the gist, the only line I see that comes close to what you posted above is line 256

                if totallen > 80 then
    

    Only thing I can think is maybe something got funky with the cut and paste? Try it again - the code that's there worked for me.

  • edited February 2012 Posts: 273

    I'll try again... ah thanks!... it now runs... mea culpa, you were right there must have been something funky with my cut and paste... :)

    However... now when I call DataDumper (using your {"hello", "world"} table for testing) Codea protests its confusion concerning getfenv(), a function which, at least according to Mr. Zoyd's recent posts, is under embargo in the sandbox file.

    @Bortels did you not encounter this problem?

    @Simeon is getfenv() dangerous?

    Must I live dangerously to serialize/save tables and functions with up-values?

    Edit: Thinking about this a bit I can imagine the ability to serialize tables and functions might be a giant step beyond loadstring on Apple's slippery slope.

  • BortelsBortels Mod
    Posts: 1,557

    It worked when I posted it; a quick google (all that I have time for right now, I'm on the way to work) suggests this was removed in Lua 5.2? (and I think the Lua Codea uses was upgraded between then and now, although I'm not sure.) I'm also not sure how relevant that call is in the iOS/Codea context anyway - I suspect it could be stubbed out or otherwise dealt with. Keep in mind - I did not write the code in question, I just found/ported it, and as I noted the port was trivial, code being basically unchanged - there's still very deep voodoo in it I won't claim to fully understand.

    I believe - again, based on a quick scan - that this chunk of code only deals with "userdata" - in our case, things like image() and mesh(). If your data structure is a pure lua-element-only table, I suspect this chunk of code could simply be commented out.

  • Posts: 273

    I'm pretty sure that Codea hasn't upgraded to Lua 5.2 yet. But thanks for your reply Mr. B. I'll keep at it!

  • Posts: 2,820

    Confirmation: Codea is only on 5.1 :-(

  • SimeonSimeon Admin Mod
    Posts: 5,054

    Our libraries (vec2, image, mesh, and so on) are not compatible with 5.2. We haven't got around to re-working them.

    @Blanchot getfenv is not dangerous. None of the sandboxed functions are really dangerous — we'll probably expose some more in the next release.

  • BortelsBortels Mod
    Posts: 1,557

    Well - if it's not Lua 5.2, my only other thought is that they must have sandboxed that function at some point, because I promise - the code worked for me when I posted it. Scout's Honor. Or, maybe I just never tried using it on something that triggered that call?

    No idea.

  • edited February 2012 Posts: 273
    we'll probably expose some more in the next release.
    

    @Simeon that would be swell! (hopefully getfenv in 1.3.1?)

    @Bortels the call to getfenv() was triggered using your own {"hello", "world"} example! But hey... no problem. Thank you for all your help. :)

    Edit:

    I believe - again, based on a quick scan - that this chunk of code only deals with "userdata" - in our case, things like image() and mesh(). If your data structure is a pure lua-element-only table, I suspect this chunk of code could simply be commented out.
    

    As far as I can tell (I hope I am not saying something stupid here-- my understanding of all this is rudimentary to the extreme) the chunk of code in question allows the dumping of closures with the up-value preserved -- a feat which string.dump can't do in 5.1. (I believe it is possible in 5.2 but only with a reset up-value.)

  • BortelsBortels Mod
    Posts: 1,557

    What can I say? It worked when I posted it. Codea has changed in some way since then.

  • SimeonSimeon Admin Mod
    Posts: 5,054

    @Bortels is probably right that something has changed.

    However the sandbox has only changed twice — once in 1.1.2 to allow os.time/clock functions and again in 1.2 to allow loadstring().

  • Posts: 2,820

    @Blanchot - You know how to enable getfenv(), right? I did it :-) Just see my discussion on how to enable file io.

  • Posts: 2,820

    And please don't disable LoadString (although I'd rather sockets than LoadString) because I was looking into making a Codea Jr. kind of like Scratch (look it up). You would drag in little chunks of code, and it would execute them when you press run. I'd also integrate a few other librarys out there.

  • edited February 2012 Posts: 273

    @Zoyt thanks I've seen your thread. You might think me crazy but I'd rather keep my system kosher if possible. Especially as a lua/Codea newbie. But again thanks!

  • Posts: 2,820

    Ya, I hack around with Codea a lot... It doesn't seem to affect anything else. I do it for fun... Mainly. And I don't think you're crazy... You might as well call me crazy. :-)

Sign In or Register to comment.