fix(lua): better print function, and override require
This commit is contained in:
parent
99440cc3ee
commit
4bd1110202
2 changed files with 51 additions and 8 deletions
|
@ -39,6 +39,9 @@ Script::~Script() {
|
||||||
void Script::Run() {
|
void Script::Run() {
|
||||||
lua_State* L = dataModel().value()->GetService<ScriptContext>()->state;
|
lua_State* L = dataModel().value()->GetService<ScriptContext>()->state;
|
||||||
|
|
||||||
|
// Initialize script globals
|
||||||
|
|
||||||
|
|
||||||
luaL_loadstring(L, source.c_str());
|
luaL_loadstring(L, source.c_str());
|
||||||
int status = lua_pcall(L, 0, LUA_MULTRET, 0);
|
int status = lua_pcall(L, 0, LUA_MULTRET, 0);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
|
|
|
@ -4,12 +4,18 @@
|
||||||
#include <luajit-2.1/lua.h>
|
#include <luajit-2.1/lua.h>
|
||||||
#include <luajit-2.1/lualib.h>
|
#include <luajit-2.1/lualib.h>
|
||||||
|
|
||||||
static int redirectPrint(lua_State*);
|
static int g_print(lua_State*);
|
||||||
|
static int g_require(lua_State*);
|
||||||
static const struct luaL_Reg luaglobals [] = {
|
static const struct luaL_Reg luaglobals [] = {
|
||||||
{"print", redirectPrint},
|
{"print", g_print},
|
||||||
|
{"require", g_require},
|
||||||
{NULL, NULL} /* end of array */
|
{NULL, NULL} /* end of array */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string unsafe_globals[] = {
|
||||||
|
"loadfile", "loadstring", "load", "dofile", "getfenv", "setfenv"
|
||||||
|
};
|
||||||
|
|
||||||
const InstanceType ScriptContext::TYPE = {
|
const InstanceType ScriptContext::TYPE = {
|
||||||
.super = &Instance::TYPE,
|
.super = &Instance::TYPE,
|
||||||
.className = "ScriptContext",
|
.className = "ScriptContext",
|
||||||
|
@ -34,28 +40,62 @@ void ScriptContext::InitService() {
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
state = luaL_newstate();
|
state = luaL_newstate();
|
||||||
luaL_openlibs(state);
|
luaopen_base(state);
|
||||||
|
luaopen_math(state);
|
||||||
|
luaopen_string(state);
|
||||||
|
luaopen_table(state);
|
||||||
|
// luaopen_io(state);
|
||||||
|
// luaopen_os(state);
|
||||||
|
// luaopen_package(state);
|
||||||
|
// luaopen_debug(state);
|
||||||
|
luaopen_bit(state);
|
||||||
|
|
||||||
|
// TODO: custom os library
|
||||||
|
|
||||||
// Override print
|
// Override print
|
||||||
// https://stackoverflow.com/a/4514193/16255372
|
// https://stackoverflow.com/a/4514193/16255372
|
||||||
|
|
||||||
lua_getglobal(state, "_G");
|
lua_getglobal(state, "_G");
|
||||||
luaL_register(state, NULL, luaglobals);
|
luaL_register(state, NULL, luaglobals);
|
||||||
|
|
||||||
|
// Remove misc dangerous functions
|
||||||
|
for (std::string key : unsafe_globals) {
|
||||||
|
lua_pushstring(state, key.c_str());
|
||||||
|
lua_pushnil(state);
|
||||||
|
lua_rawset(state, -3);
|
||||||
|
}
|
||||||
|
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int redirectPrint(lua_State* L) {
|
// https://www.lua.org/source/5.1/lbaselib.c.html
|
||||||
|
static int g_print(lua_State* L) {
|
||||||
std::string buf;
|
std::string buf;
|
||||||
|
|
||||||
int nargs = lua_gettop(L);
|
int nargs = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_getglobal(L, "tostring");
|
||||||
for (int i=1; i <= nargs; i++) {
|
for (int i=1; i <= nargs; i++) {
|
||||||
std::string arg(lua_tostring(L, -1));
|
lua_pushvalue(L, -1); // push tostring
|
||||||
lua_pop(L, 1);
|
lua_pushvalue(L, i); // push current arg
|
||||||
buf += arg;
|
lua_call(L, 1, 1); // call tostring with current arg (#1 arguments)
|
||||||
|
// lua_call automatically pops function and arguments
|
||||||
|
|
||||||
|
const char* str = lua_tostring(L, -1); // convert result into c-string
|
||||||
|
lua_pop(L, 1); // pop result
|
||||||
|
|
||||||
|
buf += str;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::infof(buf);
|
Logger::info(buf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int g_require(lua_State* L) {
|
||||||
|
int nargs = lua_gettop(L);
|
||||||
|
if (nargs < 1) return luaL_error(L, "expected argument module");
|
||||||
|
|
||||||
|
return luaL_error(L, "require is not yet implemented");
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue