lua-users home
lua-l archive

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


All,

In another message thread (Subject: lua source as config file), PA
posted this function:

function config( aPath )
   local aChunck = setfenv( loadfile( aPath ), {} )
   return getfenv( aChunck, aChunck() )
end

When run with aPath listing a file with a syntax error in it, the
environment for function config() is set. This happens because the first
argument is nil (the return value from loadfile()) and the code in
getfunc() calls luaL_optint(L, 1, 1), resulting in a lax treatment of
the first argument (rather than rejecting it).

Run this to show the error (after loading config() above):

s=config'good.cfg'   -- Containing valid Lua code.
print(getfenv(config))
s=config'bad.cfg'    -- Containing a syntax error.
print(getfenv(config))

Here's a failure case using vanilla 5.1.1:

rogers@rogers-/tmp/lua-5.1.1/src$ /usr/bin/lua
Lua 5.1.1  Copyright (C) 1994-2006 Lua.org, PUC-Rio
> function config( aPath )
>>    local aChunck = setfenv( loadfile( aPath ), {} )
>>    return getfenv( aChunck, aChunck() )
>> end
> s=config'good.cfg'   -- Containing valid Lua code.
> print(getfenv(config))
table: 0x806a450
> s=config'bad.cfg'    -- Containing a syntax error.
stdin:2: attempt to call global 'loadfile' (a nil value)
stack traceback:
        stdin:2: in function 'aChunck'
        stdin:3: in function 'config'
        stdin:1: in main chunk
        [C]: ?
> print(getfenv(config))
table: 0x807e1b0
>


I don't know if it will break other things, but this patch works for me
to correct the problem noted above:

--- lua-5.1.1.orig/src/lbaselib.c       2006-06-02 11:34:00.000000000 -0400
+++ lua-5.1.1/src/lbaselib.c    2007-02-08 17:40:31.000000000 -0500
@@ -118,7 +118,10 @@
   if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
   else {
     lua_Debug ar;
-    int level = luaL_optint(L, 1, 1);
+    int type = lua_type(L, 1);
+    int level;
+    luaL_argcheck(L, type == LUA_TNUMBER, 1, "must be function or number");
+    level = lua_tonumber(L, 1);
     luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
     if (lua_getstack(L, level, &ar) == 0)
       luaL_argerror(L, 1, "invalid level");


Test after the patch is applied:

rogers@rogers-/tmp/lua-5.1.1/src$ ./lua
Lua 5.1.1  Copyright (C) 1994-2006 Lua.org, PUC-Rio
> function config( aPath )
>>    local aChunck = setfenv( loadfile( aPath ), {} )
>>    return getfenv( aChunck, aChunck() )
>> end
> s=config'good.cfg'   -- Containing valid Lua code.
> print(getfenv(config))
table: 0x806a450
> s=config'bad.cfg'    -- Containing a syntax error.
stdin:2: bad argument #1 to 'setfenv' (must be function or number)
stack traceback:
        [C]: in function 'setfenv'
        stdin:2: in function 'config'
        stdin:1: in main chunk
        [C]: ?
> print(getfenv(config))
table: 0x806a450
>

A better solution to the general problem would be to propagate the error
from loadfile(), but I still think this is a bug in setfenv().

Doug

-- 
Innovative Concepts, Inc. www.innocon.com 703-893-2007 x220