s_base.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "cpp_api/s_base.h"
  17. #include "cpp_api/s_internal.h"
  18. #include "cpp_api/s_security.h"
  19. #include "lua_api/l_object.h"
  20. #include "common/c_converter.h"
  21. #include "server/player_sao.h"
  22. #include "filesys.h"
  23. #include "content/mods.h"
  24. #include "porting.h"
  25. #include "util/string.h"
  26. #include "server.h"
  27. #ifndef SERVER
  28. #include "client/client.h"
  29. #endif
  30. extern "C" {
  31. #include "lualib.h"
  32. #if USE_LUAJIT
  33. #include "luajit.h"
  34. #else
  35. #include "bit.h"
  36. #endif
  37. }
  38. #include <cstdio>
  39. #include <cstdarg>
  40. #include "script/common/c_content.h"
  41. #include <sstream>
  42. class ModNameStorer
  43. {
  44. private:
  45. lua_State *L;
  46. public:
  47. ModNameStorer(lua_State *L_, const std::string &mod_name):
  48. L(L_)
  49. {
  50. // Store current mod name in registry
  51. lua_pushstring(L, mod_name.c_str());
  52. lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
  53. }
  54. ~ModNameStorer()
  55. {
  56. // Clear current mod name from registry
  57. lua_pushnil(L);
  58. lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
  59. }
  60. };
  61. /*
  62. ScriptApiBase
  63. */
  64. ScriptApiBase::ScriptApiBase(ScriptingType type):
  65. m_type(type)
  66. {
  67. #ifdef SCRIPTAPI_LOCK_DEBUG
  68. m_lock_recursion_count = 0;
  69. #endif
  70. m_luastack = luaL_newstate();
  71. FATAL_ERROR_IF(!m_luastack, "luaL_newstate() failed");
  72. lua_atpanic(m_luastack, &luaPanic);
  73. if (m_type == ScriptingType::Client)
  74. clientOpenLibs(m_luastack);
  75. else
  76. luaL_openlibs(m_luastack);
  77. // Load bit library
  78. lua_pushcfunction(m_luastack, luaopen_bit);
  79. lua_pushstring(m_luastack, LUA_BITLIBNAME);
  80. lua_call(m_luastack, 1, 0);
  81. // Make the ScriptApiBase* accessible to ModApiBase
  82. #if INDIRECT_SCRIPTAPI_RIDX
  83. *(void **)(lua_newuserdata(m_luastack, sizeof(void *))) = this;
  84. #else
  85. lua_pushlightuserdata(m_luastack, this);
  86. #endif
  87. lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
  88. lua_pushcfunction(m_luastack, script_error_handler);
  89. lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER);
  90. // Add a C++ wrapper function to catch exceptions thrown in Lua -> C++ calls
  91. #if USE_LUAJIT
  92. lua_pushlightuserdata(m_luastack, (void*) script_exception_wrapper);
  93. luaJIT_setmode(m_luastack, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
  94. lua_pop(m_luastack, 1);
  95. #else
  96. // (This is a custom API from the bundled Lua.)
  97. lua_atccall(m_luastack, script_exception_wrapper);
  98. #endif
  99. // Add basic globals
  100. // "core" table:
  101. lua_newtable(m_luastack);
  102. // Populate with some internal functions which will be removed in Lua:
  103. lua_pushcfunction(m_luastack, [](lua_State *L) -> int {
  104. lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_VECTOR);
  105. return 0;
  106. });
  107. lua_setfield(m_luastack, -2, "set_read_vector");
  108. lua_pushcfunction(m_luastack, [](lua_State *L) -> int {
  109. lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_VECTOR);
  110. return 0;
  111. });
  112. lua_setfield(m_luastack, -2, "set_push_vector");
  113. lua_pushcfunction(m_luastack, [](lua_State *L) -> int {
  114. lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_NODE);
  115. return 0;
  116. });
  117. lua_setfield(m_luastack, -2, "set_read_node");
  118. lua_pushcfunction(m_luastack, [](lua_State *L) -> int {
  119. lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_NODE);
  120. return 0;
  121. });
  122. lua_setfield(m_luastack, -2, "set_push_node");
  123. // Finally, put the table into the global environment:
  124. lua_setglobal(m_luastack, "core");
  125. if (m_type == ScriptingType::Client)
  126. lua_pushstring(m_luastack, "/");
  127. else
  128. lua_pushstring(m_luastack, DIR_DELIM);
  129. lua_setglobal(m_luastack, "DIR_DELIM");
  130. lua_pushstring(m_luastack, porting::getPlatformName());
  131. lua_setglobal(m_luastack, "PLATFORM");
  132. // Make sure Lua uses the right locale
  133. setlocale(LC_NUMERIC, "C");
  134. }
  135. ScriptApiBase::~ScriptApiBase()
  136. {
  137. lua_close(m_luastack);
  138. }
  139. int ScriptApiBase::luaPanic(lua_State *L)
  140. {
  141. std::ostringstream oss;
  142. oss << "LUA PANIC: unprotected error in call to Lua API ("
  143. << readParam<std::string>(L, -1) << ")";
  144. FATAL_ERROR(oss.str().c_str());
  145. // NOTREACHED
  146. return 0;
  147. }
  148. #ifndef SERVER
  149. void ScriptApiBase::clientOpenLibs(lua_State *L)
  150. {
  151. static const std::vector<std::pair<std::string, lua_CFunction>> m_libs = {
  152. { "", luaopen_base },
  153. { LUA_TABLIBNAME, luaopen_table },
  154. { LUA_OSLIBNAME, luaopen_os },
  155. { LUA_STRLIBNAME, luaopen_string },
  156. { LUA_MATHLIBNAME, luaopen_math },
  157. { LUA_DBLIBNAME, luaopen_debug },
  158. #if USE_LUAJIT
  159. { LUA_JITLIBNAME, luaopen_jit },
  160. #endif
  161. };
  162. for (const auto &lib : m_libs) {
  163. lua_pushcfunction(L, lib.second);
  164. lua_pushstring(L, lib.first.c_str());
  165. lua_call(L, 1, 0);
  166. }
  167. }
  168. #endif
  169. void ScriptApiBase::checkSetByBuiltin()
  170. {
  171. lua_State *L = getStack();
  172. if (m_gamedef) {
  173. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_VECTOR);
  174. FATAL_ERROR_IF(lua_type(L, -1) != LUA_TFUNCTION, "missing read_vector");
  175. lua_pop(L, 1);
  176. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_VECTOR);
  177. FATAL_ERROR_IF(lua_type(L, -1) != LUA_TFUNCTION, "missing push_vector");
  178. lua_pop(L, 1);
  179. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_NODE);
  180. FATAL_ERROR_IF(lua_type(L, -1) != LUA_TFUNCTION, "missing read_node");
  181. lua_pop(L, 1);
  182. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_NODE);
  183. FATAL_ERROR_IF(lua_type(L, -1) != LUA_TFUNCTION, "missing push_node");
  184. lua_pop(L, 1);
  185. }
  186. }
  187. std::string ScriptApiBase::getCurrentModNameInsecure(lua_State *L)
  188. {
  189. lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
  190. auto ret = lua_isstring(L, -1) ? readParam<std::string>(L, -1) : "";
  191. lua_pop(L, 1);
  192. return ret;
  193. }
  194. std::string ScriptApiBase::getCurrentModName(lua_State *L)
  195. {
  196. auto script = ModApiBase::getScriptApiBase(L);
  197. if (script->getType() == ScriptingType::Async ||
  198. script->getType() == ScriptingType::Emerge)
  199. {
  200. // As a precaution never return a "secure" mod name in the async and
  201. // emerge environment, because these currently do not track mod origins
  202. // in a spoof-safe way (see l_register_async_dofile and l_register_mapgen_script).
  203. return "";
  204. }
  205. // We have to make sure that this function is being called directly by
  206. // a mod, otherwise a malicious mod could override a function and
  207. // steal its return value. (e.g. request_insecure_environment)
  208. lua_Debug info;
  209. // Make sure there's only one item below this function on the stack...
  210. if (lua_getstack(L, 2, &info))
  211. return "";
  212. FATAL_ERROR_IF(!lua_getstack(L, 1, &info), "lua_getstack() failed");
  213. FATAL_ERROR_IF(!lua_getinfo(L, "S", &info), "lua_getinfo() failed");
  214. // ...and that that item is the main file scope.
  215. if (strcmp(info.what, "main") != 0)
  216. return "";
  217. // at this point we can trust this value:
  218. return getCurrentModNameInsecure(L);
  219. }
  220. void ScriptApiBase::loadMod(const std::string &script_path,
  221. const std::string &mod_name)
  222. {
  223. ModNameStorer mod_name_storer(getStack(), mod_name);
  224. loadScript(script_path);
  225. }
  226. void ScriptApiBase::loadScript(const std::string &script_path)
  227. {
  228. verbosestream << "Loading and running script from " << script_path << std::endl;
  229. lua_State *L = getStack();
  230. int error_handler = PUSH_ERROR_HANDLER(L);
  231. bool ok;
  232. if (m_secure) {
  233. ok = ScriptApiSecurity::safeLoadFile(L, script_path.c_str());
  234. } else {
  235. ok = !luaL_loadfile(L, script_path.c_str());
  236. }
  237. ok = ok && !lua_pcall(L, 0, 0, error_handler);
  238. if (!ok) {
  239. const char *error_msg = lua_tostring(L, -1);
  240. if (!error_msg)
  241. error_msg = "(error object is not a string)";
  242. lua_pop(L, 2); // Pop error message and error handler
  243. throw ModError("Failed to load and run script from " +
  244. script_path + ":\n" + error_msg);
  245. }
  246. lua_pop(L, 1); // Pop error handler
  247. }
  248. #ifndef SERVER
  249. void ScriptApiBase::loadModFromMemory(const std::string &mod_name)
  250. {
  251. ModNameStorer mod_name_storer(getStack(), mod_name);
  252. sanity_check(m_type == ScriptingType::Client);
  253. const std::string init_filename = mod_name + ":init.lua";
  254. const std::string chunk_name = "@" + init_filename;
  255. const std::string *contents = getClient()->getModFile(init_filename);
  256. if (!contents)
  257. throw ModError("Mod \"" + mod_name + "\" lacks init.lua");
  258. verbosestream << "Loading and running script " << chunk_name << std::endl;
  259. lua_State *L = getStack();
  260. int error_handler = PUSH_ERROR_HANDLER(L);
  261. bool ok = ScriptApiSecurity::safeLoadString(L, *contents, chunk_name.c_str());
  262. if (ok)
  263. ok = !lua_pcall(L, 0, 0, error_handler);
  264. if (!ok) {
  265. const char *error_msg = lua_tostring(L, -1);
  266. if (!error_msg)
  267. error_msg = "(error object is not a string)";
  268. lua_pop(L, 2); // Pop error message and error handler
  269. throw ModError("Failed to load and run mod \"" +
  270. mod_name + "\":\n" + error_msg);
  271. }
  272. lua_pop(L, 1); // Pop error handler
  273. }
  274. #endif
  275. // Push the list of callbacks (a lua table).
  276. // Then push nargs arguments.
  277. // Then call this function, which
  278. // - runs the callbacks
  279. // - replaces the table and arguments with the return value,
  280. // computed depending on mode
  281. // This function must only be called with scriptlock held (i.e. inside of a
  282. // code block with SCRIPTAPI_PRECHECKHEADER declared)
  283. void ScriptApiBase::runCallbacksRaw(int nargs,
  284. RunCallbacksMode mode, const char *fxn)
  285. {
  286. #ifndef SERVER
  287. // Hard fail for bad guarded callbacks
  288. // Only run callbacks when the scripting enviroment is loaded
  289. FATAL_ERROR_IF(m_type == ScriptingType::Client &&
  290. !getClient()->modsLoaded(), fxn);
  291. #endif
  292. #ifdef SCRIPTAPI_LOCK_DEBUG
  293. assert(m_lock_recursion_count > 0);
  294. #endif
  295. lua_State *L = getStack();
  296. FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments");
  297. // Insert error handler
  298. PUSH_ERROR_HANDLER(L);
  299. int error_handler = lua_gettop(L) - nargs - 1;
  300. lua_insert(L, error_handler);
  301. // Insert run_callbacks between error handler and table
  302. lua_getglobal(L, "core");
  303. lua_getfield(L, -1, "run_callbacks");
  304. lua_remove(L, -2);
  305. lua_insert(L, error_handler + 1);
  306. // Insert mode after table
  307. lua_pushnumber(L, (int)mode);
  308. lua_insert(L, error_handler + 3);
  309. // Stack now looks like this:
  310. // ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n>
  311. int result = lua_pcall(L, nargs + 2, 1, error_handler);
  312. if (result != 0)
  313. scriptError(result, fxn);
  314. lua_remove(L, error_handler);
  315. }
  316. void ScriptApiBase::realityCheck()
  317. {
  318. int top = lua_gettop(m_luastack);
  319. if (top >= 30) {
  320. dstream << "Stack is over 30:" << std::endl;
  321. stackDump(dstream);
  322. std::string traceback = script_get_backtrace(m_luastack);
  323. throw LuaError("Stack is over 30 (reality check)\n" + traceback);
  324. }
  325. }
  326. void ScriptApiBase::scriptError(int result, const char *fxn)
  327. {
  328. script_error(getStack(), result, m_last_run_mod.c_str(), fxn);
  329. }
  330. void ScriptApiBase::stackDump(std::ostream &o)
  331. {
  332. int top = lua_gettop(m_luastack);
  333. for (int i = 1; i <= top; i++) { /* repeat for each level */
  334. int t = lua_type(m_luastack, i);
  335. switch (t) {
  336. case LUA_TSTRING: /* strings */
  337. o << "\"" << readParam<std::string>(m_luastack, i) << "\"";
  338. break;
  339. case LUA_TBOOLEAN: /* booleans */
  340. o << (readParam<bool>(m_luastack, i) ? "true" : "false");
  341. break;
  342. case LUA_TNUMBER: /* numbers */ {
  343. char buf[10];
  344. porting::mt_snprintf(buf, sizeof(buf), "%lf", lua_tonumber(m_luastack, i));
  345. o << buf;
  346. break;
  347. }
  348. default: /* other values */
  349. o << lua_typename(m_luastack, t);
  350. break;
  351. }
  352. o << " ";
  353. }
  354. o << std::endl;
  355. }
  356. void ScriptApiBase::setOriginDirect(const char *origin)
  357. {
  358. m_last_run_mod = origin ? origin : "??";
  359. }
  360. void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn)
  361. {
  362. lua_State *L = getStack();
  363. m_last_run_mod = lua_istable(L, index) ?
  364. getstringfield_default(L, index, "mod_origin", "") : "";
  365. }
  366. /*
  367. * How ObjectRefs are handled in Lua:
  368. * When an active object is created, an ObjectRef is created on the Lua side
  369. * and stored in core.object_refs[id].
  370. * Methods that require an ObjectRef to a certain object retrieve it from that
  371. * table instead of creating their own.(*)
  372. * When an active object is removed, the existing ObjectRef is invalidated
  373. * using ::set_null() and removed from the core.object_refs table.
  374. * (*) An exception to this are NULL ObjectRefs and anonymous ObjectRefs
  375. * for objects without ID.
  376. * It's unclear what the latter are needed for and their use is problematic
  377. * since we lose control over the ref and the contained pointer.
  378. */
  379. void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
  380. {
  381. SCRIPTAPI_PRECHECKHEADER
  382. assert(getType() == ScriptingType::Server);
  383. // Create object on stack
  384. ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
  385. int object = lua_gettop(L);
  386. // Get core.object_refs table
  387. lua_getglobal(L, "core");
  388. lua_getfield(L, -1, "object_refs");
  389. luaL_checktype(L, -1, LUA_TTABLE);
  390. int objectstable = lua_gettop(L);
  391. // object_refs[id] = object
  392. lua_pushnumber(L, cobj->getId()); // Push id
  393. lua_pushvalue(L, object); // Copy object to top of stack
  394. lua_settable(L, objectstable);
  395. }
  396. void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
  397. {
  398. SCRIPTAPI_PRECHECKHEADER
  399. assert(getType() == ScriptingType::Server);
  400. // Get core.object_refs table
  401. lua_getglobal(L, "core");
  402. lua_getfield(L, -1, "object_refs");
  403. luaL_checktype(L, -1, LUA_TTABLE);
  404. int objectstable = lua_gettop(L);
  405. // Get object_refs[id]
  406. lua_pushnumber(L, cobj->getId()); // Push id
  407. lua_gettable(L, objectstable);
  408. // Set object reference to NULL
  409. ObjectRef::set_null(L);
  410. lua_pop(L, 1); // pop object
  411. // Set object_refs[id] = nil
  412. lua_pushnumber(L, cobj->getId()); // Push id
  413. lua_pushnil(L);
  414. lua_settable(L, objectstable);
  415. }
  416. // Creates a new anonymous reference if cobj=NULL or id=0
  417. void ScriptApiBase::objectrefGetOrCreate(lua_State *L,
  418. ServerActiveObject *cobj)
  419. {
  420. assert(getType() == ScriptingType::Server);
  421. if (cobj == NULL || cobj->getId() == 0) {
  422. ObjectRef::create(L, cobj);
  423. } else {
  424. push_objectRef(L, cobj->getId());
  425. if (cobj->isGone())
  426. warningstream << "ScriptApiBase::objectrefGetOrCreate(): "
  427. << "Pushing ObjectRef to removed/deactivated object"
  428. << ", this is probably a bug." << std::endl;
  429. }
  430. }
  431. void ScriptApiBase::pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason &reason)
  432. {
  433. assert(getType() == ScriptingType::Server);
  434. if (reason.hasLuaReference())
  435. lua_rawgeti(L, LUA_REGISTRYINDEX, reason.lua_reference);
  436. else
  437. lua_newtable(L);
  438. lua_getfield(L, -1, "type");
  439. bool has_type = (bool)lua_isstring(L, -1);
  440. lua_pop(L, 1);
  441. if (!has_type) {
  442. lua_pushstring(L, reason.getTypeAsString().c_str());
  443. lua_setfield(L, -2, "type");
  444. }
  445. lua_pushstring(L, reason.from_mod ? "mod" : "engine");
  446. lua_setfield(L, -2, "from");
  447. if (reason.object) {
  448. objectrefGetOrCreate(L, reason.object);
  449. lua_setfield(L, -2, "object");
  450. }
  451. if (!reason.node.empty()) {
  452. lua_pushstring(L, reason.node.c_str());
  453. lua_setfield(L, -2, "node");
  454. push_v3s16(L, reason.node_pos);
  455. lua_setfield(L, -2, "node_pos");
  456. }
  457. }
  458. Server* ScriptApiBase::getServer()
  459. {
  460. // Since the gamedef is the server it's still possible to retrieve it in
  461. // e.g. the async environment, but this isn't meant to happen.
  462. // TODO: still needs work
  463. //assert(getType() == ScriptingType::Server);
  464. return dynamic_cast<Server *>(m_gamedef);
  465. }
  466. #ifndef SERVER
  467. Client* ScriptApiBase::getClient()
  468. {
  469. return dynamic_cast<Client *>(m_gamedef);
  470. }
  471. #endif