diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-09-16 16:49:45 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-09-16 16:49:45 -0300 |
| commit | 32a5d96dfc846ccfe63e6272d385fe963e025b61 (patch) | |
| tree | a8db9f8300dca5f951f475d7cad8619460141d07 | |
| parent | 8dae071f42bf036ea3f61468aca825397c8e33e4 (diff) | |
| download | lua-32a5d96dfc846ccfe63e6272d385fe963e025b61.tar.gz lua-32a5d96dfc846ccfe63e6272d385fe963e025b61.tar.bz2 lua-32a5d96dfc846ccfe63e6272d385fe963e025b61.zip | |
`setmetatable' cannot change protected objects
| -rw-r--r-- | lauxlib.c | 11 | ||||
| -rw-r--r-- | lauxlib.h | 3 | ||||
| -rw-r--r-- | lbaselib.c | 14 |
3 files changed, 16 insertions, 12 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.84 2002/08/30 20:00:59 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.85 2002/09/05 19:45:42 roberto Exp roberto $ |
| 3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -147,7 +147,7 @@ LUALIB_API lua_Number luaL_opt_number (lua_State *L, int narg, lua_Number def) { | |||
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | 149 | ||
| 150 | LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { | 150 | LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { |
| 151 | if (!lua_getmetatable(L, obj)) /* no metatable? */ | 151 | if (!lua_getmetatable(L, obj)) /* no metatable? */ |
| 152 | return 0; | 152 | return 0; |
| 153 | lua_pushstring(L, event); | 153 | lua_pushstring(L, event); |
| @@ -156,6 +156,13 @@ LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { | |||
| 156 | lua_pop(L, 2); /* remove metatable and metafield */ | 156 | lua_pop(L, 2); /* remove metatable and metafield */ |
| 157 | return 0; | 157 | return 0; |
| 158 | } | 158 | } |
| 159 | return 1; | ||
| 160 | } | ||
| 161 | |||
| 162 | |||
| 163 | LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { | ||
| 164 | if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ | ||
| 165 | return 0; | ||
| 159 | lua_pushvalue(L, obj); | 166 | lua_pushvalue(L, obj); |
| 160 | lua_call(L, 1, 1); | 167 | lua_call(L, 1, 1); |
| 161 | return 1; | 168 | return 1; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.h,v 1.52 2002/08/08 20:08:41 roberto Exp roberto $ | 2 | ** $Id: lauxlib.h,v 1.53 2002/08/30 20:00:59 roberto Exp roberto $ |
| 3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -30,6 +30,7 @@ typedef struct luaL_reg { | |||
| 30 | LUALIB_API void luaL_openlib (lua_State *L, const luaL_reg *l, int nup); | 30 | LUALIB_API void luaL_openlib (lua_State *L, const luaL_reg *l, int nup); |
| 31 | LUALIB_API void luaL_opennamedlib (lua_State *L, const char *libname, | 31 | LUALIB_API void luaL_opennamedlib (lua_State *L, const char *libname, |
| 32 | const luaL_reg *l, int nup); | 32 | const luaL_reg *l, int nup); |
| 33 | LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *e); | ||
| 33 | LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *e); | 34 | LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *e); |
| 34 | LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname); | 35 | LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname); |
| 35 | LUALIB_API int luaL_argerror (lua_State *L, int numarg, const char *extramsg); | 36 | LUALIB_API int luaL_argerror (lua_State *L, int numarg, const char *extramsg); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.97 2002/08/08 20:08:41 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.98 2002/09/05 19:45:42 roberto Exp roberto $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -109,14 +109,8 @@ static int luaB_getmetatable (lua_State *L) { | |||
| 109 | lua_pushnil(L); | 109 | lua_pushnil(L); |
| 110 | return 1; /* no metatable */ | 110 | return 1; /* no metatable */ |
| 111 | } | 111 | } |
| 112 | else { | 112 | luaL_getmetafield(L, 1, "__metatable"); |
| 113 | lua_pushliteral(L, "__metatable"); | 113 | return 1; /* returns either __metatable field (if present) or metatable */ |
| 114 | lua_rawget(L, -2); | ||
| 115 | if (lua_isnil(L, -1)) | ||
| 116 | lua_pop(L, 1); | ||
| 117 | /* otherwise returns metatable.__metatable */ | ||
| 118 | } | ||
| 119 | return 1; | ||
| 120 | } | 114 | } |
| 121 | 115 | ||
| 122 | 116 | ||
| @@ -125,6 +119,8 @@ static int luaB_setmetatable (lua_State *L) { | |||
| 125 | luaL_check_type(L, 1, LUA_TTABLE); | 119 | luaL_check_type(L, 1, LUA_TTABLE); |
| 126 | luaL_arg_check(L, t == LUA_TNIL || t == LUA_TTABLE, 2, | 120 | luaL_arg_check(L, t == LUA_TNIL || t == LUA_TTABLE, 2, |
| 127 | "nil or table expected"); | 121 | "nil or table expected"); |
| 122 | if (luaL_getmetafield(L, 1, "__metatable")) | ||
| 123 | luaL_error(L, "cannot change a protected metatable"); | ||
| 128 | lua_settop(L, 2); | 124 | lua_settop(L, 2); |
| 129 | lua_setmetatable(L, 1); | 125 | lua_setmetatable(L, 1); |
| 130 | return 1; | 126 | return 1; |
