diff options
Diffstat (limited to 'src/script/lua_api/l_noise.cpp')
-rw-r--r-- | src/script/lua_api/l_noise.cpp | 126 |
1 files changed, 123 insertions, 3 deletions
diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp index c8dc2d2dc..04dc6048f 100644 --- a/src/script/lua_api/l_noise.cpp +++ b/src/script/lua_api/l_noise.cpp @@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common/c_converter.h" #include "common/c_content.h" #include "log.h" +#include "porting.h" +#include "util/numeric.h" /////////////////////////////////////// /* @@ -410,6 +412,7 @@ const luaL_reg LuaPerlinNoiseMap::methods[] = { int LuaPseudoRandom::l_next(lua_State *L) { NO_MAP_LOCK_REQUIRED; + LuaPseudoRandom *o = checkobject(L, 1); int min = 0; int max = 32767; @@ -437,7 +440,9 @@ int LuaPseudoRandom::l_next(lua_State *L) int LuaPseudoRandom::create_object(lua_State *L) { - int seed = luaL_checknumber(L, 1); + NO_MAP_LOCK_REQUIRED; + + u64 seed = luaL_checknumber(L, 1); LuaPseudoRandom *o = new LuaPseudoRandom(seed); *(void **)(lua_newuserdata(L, sizeof(void *))) = o; luaL_getmetatable(L, className); @@ -532,8 +537,10 @@ int LuaPcgRandom::l_rand_normal_dist(lua_State *L) int LuaPcgRandom::create_object(lua_State *L) { - lua_Integer seed = luaL_checknumber(L, 1); - LuaPcgRandom *o = lua_isnumber(L, 2) ? + NO_MAP_LOCK_REQUIRED; + + u64 seed = luaL_checknumber(L, 1); + LuaPcgRandom *o = lua_isnumber(L, 2) ? new LuaPcgRandom(seed, lua_tointeger(L, 2)) : new LuaPcgRandom(seed); *(void **)(lua_newuserdata(L, sizeof(void *))) = o; @@ -595,3 +602,116 @@ const luaL_reg LuaPcgRandom::methods[] = { luamethod(LuaPcgRandom, rand_normal_dist), {0,0} }; + +/////////////////////////////////////// +/* + LuaSecureRandom +*/ + +bool LuaSecureRandom::fillRandBuf() +{ + return porting::secure_rand_fill_buf(m_rand_buf, RAND_BUF_SIZE); +} + +int LuaSecureRandom::l_next_bytes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + LuaSecureRandom *o = checkobject(L, 1); + u32 count = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : 1; + + // Limit count + count = MYMIN(RAND_BUF_SIZE, count); + + // Find out whether we can pass directly from our array, or have to do some gluing + size_t count_remaining = RAND_BUF_SIZE - o->m_rand_idx; + if (count_remaining >= count) { + lua_pushlstring(L, o->m_rand_buf + o->m_rand_idx, count); + o->m_rand_idx += count; + } else { + char output_buf[RAND_BUF_SIZE]; + + // Copy over with what we have left from our current buffer + memcpy(output_buf, o->m_rand_buf + o->m_rand_idx, count_remaining); + + // Refill buffer and copy over the remainder of what was requested + o->fillRandBuf(); + memcpy(output_buf + count_remaining, o->m_rand_buf, count - count_remaining); + + // Update index + o->m_rand_idx = count - count_remaining; + + lua_pushlstring(L, output_buf, count); + } + + return 1; +} + + +int LuaSecureRandom::create_object(lua_State *L) +{ + LuaSecureRandom *o = new LuaSecureRandom(); + + // Fail and return nil if we can't securely fill the buffer + if (!o->fillRandBuf()) { + delete o; + return 0; + } + + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + + +int LuaSecureRandom::gc_object(lua_State *L) +{ + LuaSecureRandom *o = *(LuaSecureRandom **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + + +LuaSecureRandom *LuaSecureRandom::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + return *(LuaSecureRandom **)ud; +} + + +void LuaSecureRandom::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); + + luaL_openlib(L, 0, methods, 0); + lua_pop(L, 1); + + lua_register(L, className, create_object); +} + +const char LuaSecureRandom::className[] = "SecureRandom"; +const luaL_reg LuaSecureRandom::methods[] = { + luamethod(LuaSecureRandom, next_bytes), + {0,0} +}; |