lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


lua_error function is supposed to be called from a protected call, and
all luaL_check* functions call it. Instead you can check the stack
safely with calls to lua_is* and other similar functions. That way you
don't have to add an additionnal pcall layer. Example:

int main()
{
   lua_State* L = luaL_newstate();
   luaL_openlibs(L);
   lua_pushcfunction(L, foo);
   if (lua_pcall(L, 0, 1, 0)==0)
   {
       if (lua_isstring(L, -1)) /* <-- This call is entirely safe,
whatever foo returned */
       {
           /* Process returned string */
       }
   }
}

2006/10/14, David Burgess <dburgess@gmail.com>:
> So really, the whole sequence above should be protected itself by
> another level of lua_pcall, like I described. Am I right?

Right.

Refer to the usage of lua_cpcall() in lua.c.

Also if you are using in a Windows GUI app. you might want to
change the default panic function using lua_atpanic() to
a routine that uses MessageBox() (or whatever). The default
function uses fprintf()/fputs().

db

On 10/15/06, Nick Gammon <nick@gammon.com.au> wrote:
> After recent questions about is it "safe" to use Lua, and a couple of
> application crashes of my own, I am starting to wonder if I have been
> doing it 100% correctly.
>
> There is an example in the PIL book (Listing 24.1) along these lines
> (I have slightly simplified it):
>
> ---------------
> #include "lua.h"
> #include "lauxlib.h"
>
> char buff [] = "print 'hi'";
>
> int main (void)
>    {
>    lua_State * L = luaL_newstate ();
>    luaL_openlibs (L);
>    int error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
>                  lua_pcall(L, 0, 0, 0);
>    return 0;
>    } // end of main
> ---------------
>
> Isn't there a problem here? What if luaL_loadbuffer fails? For
> example, out of memory? We can simulate a failure with this example
> program, which in essence does what caused my application to crash
> recently:
>
> ---------------
> #include "lua.h"
> #include "lauxlib.h"
> #include <stdio.h>
>
> int main (void)
>    {
>    lua_State * L = luaL_newstate ();
>    lua_pushnil (L);
>    luaL_checkstring (L, -1);   --> error, string not on stack
>    printf ("Hello, world\n");
>    return 0;
>    } // end of main
> ---------------
>
> If I run this at the command-line I get this message:
>
> PANIC: unprotected error in call to Lua API (bad argument #-1 (string
> expected, got nil))
>
>
> If I run the equivalent code in my (Windows GUI) application it
> crashes the application with some sort of error in Lua5.1.dll.
>
>
> Would the correct method be to always wrap any attempts to use the
> Lua functions into a protected environment? - like in this example:
>
> ---------------
> #include "lua.h"
> #include "lauxlib.h"
> #include <stdio.h>
>
> // do things here that might fail
> int stub(lua_State *L)
>    {
>    lua_pushnil (L);
>    luaL_checkstring (L, -1);
>    }
>
> int main (void)
>    {
>    lua_State * L = luaL_newstate ();
>    lua_pushcfunction (L, stub);
>    int error = lua_pcall (L, 0, 0, 0);
>    printf ("stub returned %i\n", error);
>    printf ("Hello, world\n");
>    return 0;
>    } // end of main
> ---------------
>
>
> I am familiar with doing lua_pcall to run the code that I ultimately
> want to run in a safe way, but I usually did something like this:
>
> lua_getglobal (L, "somefunction");  --> get some function
> lua_pushstring (L, "blah blah");  --> push arguments to function
> lua_pcall (L, 1, 1, 0);  --> call the function
> const char * p = lua_checkstring (L, -1);  --> oops! this might fail
>
>
> So really, the whole sequence above should be protected itself by
> another level of lua_pcall, like I described. Am I right?
>
> - Nick
>