| 49 | } |
| 50 | |
| 51 | bool State::LoadBuffer(const std::string &name, const char *code, size_t size, const char *sandbox) { |
| 52 | if (size == 0) { |
| 53 | size = strlen(code); |
| 54 | } |
| 55 | |
| 56 | #if 0 |
| 57 | // Remove path |
| 58 | size_t pos = name.find_last_of("/\\"); |
| 59 | if (pos == std::string::npos) { |
| 60 | _name = name; |
| 61 | } else { |
| 62 | _name = name.substr(pos + 1); |
| 63 | } |
| 64 | #else |
| 65 | _name = name; |
| 66 | #endif |
| 67 | // lua_load pushes the compiled chunk as a Lua function on top of the stack. |
| 68 | // Otherwise, it pushes an error message. |
| 69 | int status = luaL_loadbuffer(_l, code, size, _name.c_str()); |
| 70 | if (status != 0) { |
| 71 | if (status == LUA_ERRSYNTAX) { |
| 72 | const char *msg = lua_tostring(_l, -1); |
| 73 | _exception_handler->Handle(status, msg ? msg : _name + ": syntax error"); |
| 74 | } else if (status == LUA_ERRMEM) { |
| 75 | const char *msg = lua_tostring(_l, -1); |
| 76 | _exception_handler->Handle(status, msg ? msg : _name + ": out-of-memory error"); |
| 77 | } |
| 78 | return false; |
| 79 | } |
| 80 | |
| 81 | // Assume that function already pushed on top |
| 82 | assert(lua_type(_l, -1) == LUA_TFUNCTION); |
| 83 | |
| 84 | if (sandbox && sandbox[0]) { |
| 85 | lua_newtable(_l); // Push new environment table for sandboxing (1) |
| 86 | lua_setglobal(_l, sandbox); // Set and pop (0) |
| 87 | lua_getglobal(_l, sandbox); // Push again (1) |
| 88 | lua_newtable(_l); // Push new metatable (2) |
| 89 | lua_getglobal(_l, "_G"); // Push global table (3) |
| 90 | lua_setfield(_l, -2, "__index"); // Do metatable[__index] = _G and pop (2) |
| 91 | lua_setmetatable(_l, -2); // Set metatable of sandbox table and pop (1) |
| 92 | #if LUA_VERSION_NUM >= 502 |
| 93 | lua_setupvalue(_l, -2, 1); // Pop and set sandbox table as the new environment (using upvalue) of the current function (0) |
| 94 | #else |
| 95 | lua_setfenv(_l, -2); // Pop and set sandbox table as the new environment of the current function (0) |
| 96 | #endif |
| 97 | } |
| 98 | |
| 99 | return true; |
| 100 | } |
| 101 | |
| 102 | bool State::Run() { |
| 103 | int status = lua_pcall(_l, 0, LUA_MULTRET, 0); |
no test coverage detected