diff --git a/bugs b/bugs index e9ea6b73..c2ebe2c1 100644 --- a/bugs +++ b/bugs @@ -839,3 +839,41 @@ patch = [[ } + +Bug{ +what = [[luaL_checkudata may produce wrong error message]], + +report = [[Greg Falcon, 21/03/2006]], + +example = [[ +getmetatable(io.stdin).__gc() + --> bad argument #1 to '__gc' (FILE* expected, got table) +]], + +patch = [[ +* lauxlib.c: +@@ -123,11 +123,17 @@ + + LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); +- lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ +- if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2)) +- luaL_typerror(L, ud, tname); +- lua_pop(L, 2); /* remove both metatables */ +- return p; ++ if (p != NULL) { /* value is a userdata? */ ++ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ ++ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ ++ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ ++ lua_pop(L, 2); /* remove both metatables */ ++ return p; ++ } ++ } ++ } ++ luaL_typerror(L, ud, tname); /* else error */ ++ return NULL; /* to avoid warnings */ + } +]] + +} + diff --git a/lauxlib.c b/lauxlib.c index 8aff27ca..402dcd80 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.157 2005/12/29 15:32:11 roberto Exp roberto $ +** $Id: lauxlib.c,v 1.158 2006/01/16 12:42:21 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -123,11 +123,17 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { void *p = lua_touserdata(L, ud); - lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ - if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2)) - luaL_typerror(L, ud, tname); - lua_pop(L, 2); /* remove both metatables */ - return p; + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ + if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + } + luaL_typerror(L, ud, tname); /* else error */ + return NULL; /* to avoid warnings */ }