mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Add LuaSecureRandom
This commit is contained in:
parent
d506d56707
commit
ad5ac39d8d
6 changed files with 201 additions and 1 deletions
|
@ -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"
|
||||
|
||||
///////////////////////////////////////
|
||||
/*
|
||||
|
@ -600,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}
|
||||
};
|
||||
|
|
|
@ -160,4 +160,37 @@ public:
|
|||
static void Register(lua_State *L);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
LuaSecureRandom
|
||||
*/
|
||||
class LuaSecureRandom : public ModApiBase {
|
||||
private:
|
||||
static const size_t RAND_BUF_SIZE = 2048;
|
||||
static const char className[];
|
||||
static const luaL_reg methods[];
|
||||
|
||||
u32 m_rand_idx;
|
||||
char m_rand_buf[RAND_BUF_SIZE];
|
||||
|
||||
// Exported functions
|
||||
|
||||
// garbage collector
|
||||
static int gc_object(lua_State *L);
|
||||
|
||||
// next_bytes(self, count) -> get count many bytes
|
||||
static int l_next_bytes(lua_State *L);
|
||||
|
||||
public:
|
||||
bool fillRandBuf();
|
||||
|
||||
// LuaSecureRandom()
|
||||
// Creates an LuaSecureRandom and leaves it on top of stack
|
||||
static int create_object(lua_State *L);
|
||||
|
||||
static LuaSecureRandom *checkobject(lua_State *L, int narg);
|
||||
|
||||
static void Register(lua_State *L);
|
||||
};
|
||||
|
||||
#endif /* L_NOISE_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue