1 #include "AppHdr.h"
2
3 #include "clua.h"
4
5 #include <algorithm>
6
7 #include "cluautil.h"
8 #include "dlua.h"
9 #include "end.h"
10 #include "files.h"
11 #include "libutil.h"
12 #include "l-libs.h"
13 #include "maybe-bool.h"
14 #include "misc.h" // erase_val
15 #include "options.h"
16 #include "state.h"
17 #include "stringutil.h"
18 #include "syscalls.h"
19 #include "unicode.h"
20 #include "version.h"
21
22 #define BUGGY_PCALL_ERROR "667: Malformed response to guarded pcall."
23 #define BUGGY_SCRIPT_ERROR "666: Killing badly-behaved Lua script."
24
25 // 64-bit luajit does not support custom allocators. Only checking
26 // TARGET_CPU_X64 because luajit doesn't support other 64-bit archs.
27 #if defined(USE_LUAJIT) && defined(TARGET_CPU_X64)
28 #define NO_CUSTOM_ALLOCATOR
29 #endif
30
31 static int _clua_panic(lua_State *);
32 static void _clua_throttle_hook(lua_State *, lua_Debug *);
33 #ifndef NO_CUSTOM_ALLOCATOR
34 static void *_clua_allocator(void *ud, void *ptr, size_t osize, size_t nsize);
35 #endif
36 static int _clua_guarded_pcall(lua_State *);
37 static int _clua_require(lua_State *);
38 static int _clua_dofile(lua_State *);
39 static int _clua_loadfile(lua_State *);
40 static string _get_persist_file();
41
CLua(bool managed)42 CLua::CLua(bool managed)
43 : error(), managed_vm(managed), shutting_down(false),
44 throttle_unit_lines(50000),
45 throttle_sleep_ms(0), throttle_sleep_start(2),
46 throttle_sleep_end(800), n_throttle_sleeps(0), mixed_call_depth(0),
47 lua_call_depth(0), max_mixed_call_depth(8),
48 max_lua_call_depth(100), memory_used(0),
49 _state(nullptr), sourced_files(), uniqindex(0)
50 {
51 }
52
~CLua()53 CLua::~CLua()
54 {
55 // Copy the listener vector, because listeners may remove
56 // themselves from the listener list when we notify them of a
57 // shutdown.
58 const vector<lua_shutdown_listener*> slisteners = shutdown_listeners;
59 for (lua_shutdown_listener *listener : slisteners)
60 listener->shutdown(*this);
61 shutting_down = true;
62 if (_state)
63 lua_close(_state);
64 }
65
state()66 lua_State *CLua::state()
67 {
68 if (!_state)
69 init_lua();
70 return _state;
71 }
72
setglobal(const char * name)73 void CLua::setglobal(const char *name)
74 {
75 lua_setglobal(state(), name);
76 }
77
getglobal(const char * name)78 void CLua::getglobal(const char *name)
79 {
80 lua_getglobal(state(), name);
81 }
82
setuniqregistry()83 string CLua::setuniqregistry()
84 {
85 char name[100];
86 snprintf(name, sizeof name, "__cru%u", uniqindex++);
87 lua_pushstring(state(), name);
88 lua_insert(state(), -2);
89 lua_settable(state(), LUA_REGISTRYINDEX);
90
91 return name;
92 }
93
setregistry(const char * name)94 void CLua::setregistry(const char *name)
95 {
96 lua_pushstring(state(), name);
97 // Slide name round before the value
98 lua_insert(state(), -2);
99 lua_settable(state(), LUA_REGISTRYINDEX);
100 }
101
_getregistry(lua_State * ls,const char * name)102 void CLua::_getregistry(lua_State *ls, const char *name)
103 {
104 lua_pushstring(ls, name);
105 lua_gettable(ls, LUA_REGISTRYINDEX);
106 }
107
getregistry(const char * name)108 void CLua::getregistry(const char *name)
109 {
110 _getregistry(state(), name);
111 }
112
gc()113 void CLua::gc()
114 {
115 lua_gc(state(), LUA_GCCOLLECT, 0);
116 }
117
save(writer & outf)118 void CLua::save(writer &outf)
119 {
120 if (!_state)
121 return;
122
123 string res;
124 callfn("c_save", ">s", &res);
125 outf.write(res.c_str(), res.size());
126 }
127
save_persist()128 void CLua::save_persist()
129 {
130 string persist;
131 // We load persist.lua immediately before calling c_save_persist so
132 // that we know that it hasn't been overwritten by a player version.
133 execfile("dlua/persist.lua", true, true);
134 callfn("c_save_persist", ">s", &persist);
135 if (Options.no_save)
136 return;
137
138 FILE *f;
139 const string persistfile = _get_persist_file();
140
141 // Don't create the file if there's no need to do so.
142 if (persist.empty() && !file_exists(persistfile))
143 return;
144
145 f = fopen_u(persistfile.c_str(), "w");
146 if (!f)
147 {
148 mprf(MSGCH_ERROR, "Couldn't open %s for writing!", persistfile.c_str());
149 return;
150 }
151
152 fprintf(f, "-- %s %s persistent clua file\n"
153 "-- WARNING: This file is entirely auto-generated.\n"
154 "\n",
155 OUTS(CRAWL), // ok, localizing the game name is not likely
156 OUTS(Version::Long)); // nor the version string
157 fprintf(f, "%s", persist.c_str());
158 fclose(f);
159 }
160
load_persist()161 void CLua::load_persist()
162 {
163 if (Options.no_save)
164 return;
165 string persistfile = _get_persist_file();
166 if (!file_exists(persistfile))
167 return;
168 FileLineInput f(persistfile.c_str());
169 string script;
170 while (!f.eof())
171 script += f.get_line() + "\n";
172 execstring(script.c_str());
173 }
174
file_write(lua_State * ls)175 int CLua::file_write(lua_State *ls)
176 {
177 if (!lua_islightuserdata(ls, 1))
178 {
179 luaL_argerror(ls, 1, "Expected filehandle at arg 1");
180 return 0;
181 }
182 CLuaSave *sf = static_cast<CLuaSave *>(lua_touserdata(ls, 1));
183 if (!sf)
184 return 0;
185
186 FILE *f = sf->get_file();
187 if (!f)
188 return 0;
189
190 const char *text = luaL_checkstring(ls, 2);
191 if (text)
192 fprintf(f, "%s", text);
193 return 0;
194 }
195
get_file()196 FILE *CLua::CLuaSave::get_file()
197 {
198 if (!handle)
199 handle = fopen_u(filename, "w");
200
201 return handle;
202 }
203
set_error(int err,lua_State * ls)204 void CLua::set_error(int err, lua_State *ls)
205 {
206 if (!err)
207 {
208 error.clear();
209 return;
210 }
211 if (!ls && !(ls = _state))
212 {
213 error = "<LUA not initialised>";
214 return;
215 }
216 const char *serr = lua_tostring(ls, -1);
217 lua_pop(ls, 1);
218 error = serr? serr : "<Unknown error>";
219 }
220
init_throttle()221 void CLua::init_throttle()
222 {
223 if (!managed_vm)
224 return;
225
226 if (!crawl_state.throttle)
227 return;
228
229 if (throttle_unit_lines <= 0)
230 throttle_unit_lines = 500;
231
232 if (throttle_sleep_start < 1)
233 throttle_sleep_start = 1;
234
235 if (throttle_sleep_end < throttle_sleep_start)
236 throttle_sleep_end = throttle_sleep_start;
237
238 if (!mixed_call_depth)
239 {
240 lua_sethook(_state, _clua_throttle_hook,
241 LUA_MASKCOUNT, throttle_unit_lines);
242 throttle_sleep_ms = 0;
243 n_throttle_sleeps = 0;
244 }
245 }
246
loadbuffer(const char * buf,size_t size,const char * context)247 int CLua::loadbuffer(const char *buf, size_t size, const char *context)
248 {
249 const int err = luaL_loadbuffer(state(), buf, size, context);
250 set_error(err, state());
251 return err;
252 }
253
loadstring(const char * s,const char * context)254 int CLua::loadstring(const char *s, const char *context)
255 {
256 return loadbuffer(s, strlen(s), context);
257 }
258
execstring(const char * s,const char * context,int nresults)259 int CLua::execstring(const char *s, const char *context, int nresults)
260 {
261 int err = 0;
262 if ((err = loadstring(s, context)))
263 return err;
264
265 lua_State *ls = state();
266 lua_call_throttle strangler(this);
267 err = lua_pcall(ls, 0, nresults, 0);
268 set_error(err, ls);
269 return err;
270 }
271
is_path_safe(string s,bool trusted)272 bool CLua::is_path_safe(string s, bool trusted)
273 {
274 lowercase(s);
275 return s.find("..") == string::npos && shell_safe(s.c_str())
276 // loading dlua stuff would spew tons of error messages
277 && (trusted || s.find("dlua") != 0);
278 }
279
loadfile(lua_State * ls,const char * filename,bool trusted,bool die_on_fail)280 int CLua::loadfile(lua_State *ls, const char *filename, bool trusted,
281 bool die_on_fail)
282 {
283 if (!ls)
284 return -1;
285
286 if (!is_path_safe(filename, trusted))
287 {
288 lua_pushstring(
289 ls,
290 make_stringf("invalid filename: %s", filename).c_str());
291 return -1;
292 }
293
294 string file = datafile_path(filename, die_on_fail);
295 if (file.empty())
296 {
297 lua_pushstring(ls,
298 make_stringf("Can't find \"%s\"", filename).c_str());
299 return -1;
300 }
301
302 FileLineInput f(file.c_str());
303 string script;
304 while (!f.eof())
305 script += f.get_line() + "\n";
306
307 if (script[0] == 0x1b)
308 abort();
309
310 // prefixing with @ stops lua from adding [string "%s"]
311 return luaL_loadbuffer(ls, &script[0], script.length(),
312 ("@" + file).c_str());
313 }
314
execfile(const char * filename,bool trusted,bool die_on_fail,bool force)315 int CLua::execfile(const char *filename, bool trusted, bool die_on_fail,
316 bool force)
317 {
318 if (!force && sourced_files.count(filename))
319 return 0;
320
321 lua_State *ls = state();
322 int err = loadfile(ls, filename, trusted || !managed_vm, die_on_fail);
323 lua_call_throttle strangler(this);
324 if (!err)
325 err = lua_pcall(ls, 0, 0, 0);
326 if (!err)
327 sourced_files.insert(filename);
328 set_error(err);
329 if (die_on_fail && !error.empty())
330 {
331 end(1, false, "Lua execfile error (%s): %s",
332 filename, error.c_str());
333 }
334 return err;
335 }
336
runhook(const char * hook,const char * params,...)337 bool CLua::runhook(const char *hook, const char *params, ...)
338 {
339 error.clear();
340
341 lua_State *ls = state();
342 if (!ls)
343 return false;
344
345 lua_stack_cleaner clean(ls);
346
347 pushglobal(hook);
348 if (!lua_istable(ls, -1))
349 return false;
350 for (int i = 1; ; ++i)
351 {
352 lua_stack_cleaner clean2(ls);
353
354 lua_rawgeti(ls, -1, i);
355 if (!lua_isfunction(ls, -1))
356 {
357 lua_pop(ls, 1);
358 break;
359 }
360
361 // So what's on top *is* a function. Call it with the args we have.
362 va_list args;
363 va_start(args, params);
364 calltopfn(ls, params, args);
365 va_end(args);
366 }
367 return true;
368 }
369
fnreturns(const char * format,...)370 void CLua::fnreturns(const char *format, ...)
371 {
372 lua_State *ls = _state;
373
374 if (!format || !ls)
375 return;
376
377 va_list args;
378 va_start(args, format);
379 vfnreturns(format, args);
380 va_end(args);
381 }
382
vfnreturns(const char * format,va_list args)383 void CLua::vfnreturns(const char *format, va_list args)
384 {
385 lua_State *ls = _state;
386 int nrets = return_count(ls, format);
387 int sp = -nrets - 1;
388
389 const char *gs = strchr(format, '>');
390 if (gs)
391 format = gs + 1;
392 else if ((gs = strchr(format, ':')))
393 format = gs + 1;
394
395 for (const char *run = format; *run; ++run)
396 {
397 char argtype = *run;
398 ++sp;
399 switch (argtype)
400 {
401 case 'u':
402 if (lua_islightuserdata(ls, sp))
403 *(va_arg(args, void**)) = lua_touserdata(ls, sp);
404 break;
405 case 'd':
406 if (lua_isnumber(ls, sp))
407 *(va_arg(args, int*)) = luaL_safe_checkint(ls, sp);
408 break;
409 case 'b':
410 *(va_arg(args, bool *)) = lua_toboolean(ls, sp);
411 break;
412 case 's':
413 {
414 const char *s = lua_tostring(ls, sp);
415 if (s)
416 *(va_arg(args, string *)) = s;
417 break;
418 }
419 default:
420 break;
421 }
422
423 }
424 // Pop args off the stack
425 lua_pop(ls, nrets);
426 }
427
push_args(lua_State * ls,const char * format,va_list args,va_list * targ)428 int CLua::push_args(lua_State *ls, const char *format, va_list args,
429 va_list *targ)
430 {
431 if (!format)
432 {
433 if (targ)
434 va_copy(*targ, args);
435 return 0;
436 }
437
438 const char *cs = strchr(format, ':');
439 if (cs)
440 format = cs + 1;
441
442 int argc = 0;
443 for (const char *run = format; *run; run++)
444 {
445 if (*run == '>')
446 break;
447
448 char argtype = *run;
449 ++argc;
450 switch (argtype)
451 {
452 case 'u': // Light userdata
453 lua_pushlightuserdata(ls, va_arg(args, void*));
454 break;
455 case 'i':
456 clua_push_item(ls, va_arg(args, item_def*));
457 break;
458 case 's': // String
459 {
460 const char *s = va_arg(args, const char *);
461 if (s)
462 lua_pushstring(ls, s);
463 else
464 lua_pushnil(ls);
465 break;
466 }
467 case 'd': // Integer
468 lua_pushnumber(ls, va_arg(args, int));
469 break;
470 case 'L':
471 die("ambiguous long in Lua push_args");
472 lua_pushnumber(ls, va_arg(args, long));
473 break;
474 case 'b':
475 lua_pushboolean(ls, va_arg(args, int));
476 break;
477 case 'D':
478 clua_push_dgn_event(ls, va_arg(args, const dgn_event *));
479 break;
480 case 'm':
481 clua_push_map(ls, va_arg(args, map_def *));
482 break;
483 case 'M':
484 push_monster(ls, va_arg(args, monster*));
485 break;
486 case 'I':
487 lua_push_moninf(ls, va_arg(args, monster_info *));
488 break;
489 case 'A':
490 argc += push_activity_interrupt(
491 ls, va_arg(args, activity_interrupt_data *));
492 break;
493 default:
494 --argc;
495 break;
496 }
497 }
498 if (targ)
499 va_copy(*targ, args);
500 return argc;
501 }
502
return_count(lua_State * ls,const char * format)503 int CLua::return_count(lua_State *ls, const char *format)
504 {
505 UNUSED(ls);
506
507 if (!format)
508 return 0;
509
510 const char *gs = strchr(format, '>');
511 if (gs)
512 return strlen(gs + 1);
513
514 const char *cs = strchr(format, ':');
515 if (cs && isdigit(*format))
516 {
517 char *es = nullptr;
518 int ci = strtol(format, &es, 10);
519 // We're capping return at 10 here, which is arbitrary, but avoids
520 // blowing the stack.
521 if (ci < 0)
522 ci = 0;
523 else if (ci > 10)
524 ci = 10;
525 return ci;
526 }
527 return 0;
528 }
529
calltopfn(lua_State * ls,const char * params,va_list args,int retc,va_list * copyto)530 bool CLua::calltopfn(lua_State *ls, const char *params, va_list args,
531 int retc, va_list *copyto)
532 {
533 // We guarantee to remove the function from the stack
534 int argc = push_args(ls, params, args, copyto);
535 if (retc == -1)
536 retc = return_count(ls, params);
537 lua_call_throttle strangler(this);
538 int err = lua_pcall(ls, argc, retc, 0);
539 set_error(err, ls);
540 return !err;
541 }
542
callmbooleanfn(const char * fn,const char * params,va_list args)543 maybe_bool CLua::callmbooleanfn(const char *fn, const char *params,
544 va_list args)
545 {
546 error.clear();
547 lua_State *ls = state();
548 if (!ls)
549 return MB_MAYBE;
550
551 lua_stack_cleaner clean(ls);
552
553 pushglobal(fn);
554 if (!lua_isfunction(ls, -1))
555 return MB_MAYBE;
556
557 bool ret = calltopfn(ls, params, args, 1);
558 if (!ret)
559 return MB_MAYBE;
560
561 return frombool(lua_toboolean(ls, -1));
562 }
563
callmbooleanfn(const char * fn,const char * params,...)564 maybe_bool CLua::callmbooleanfn(const char *fn, const char *params, ...)
565 {
566 va_list args;
567 va_start(args, params);
568 maybe_bool r = callmbooleanfn(fn, params, args);
569 va_end(args);
570 return r;
571 }
572
callmaybefn(const char * fn,const char * params,va_list args)573 maybe_bool CLua::callmaybefn(const char *fn, const char *params, va_list args)
574 {
575 error.clear();
576 lua_State *ls = state();
577 if (!ls)
578 return MB_MAYBE;
579
580 lua_stack_cleaner clean(ls);
581
582 pushglobal(fn);
583 if (!lua_isfunction(ls, -1))
584 return MB_MAYBE;
585
586 bool ret = calltopfn(ls, params, args, 1);
587 if (!ret)
588 return MB_MAYBE;
589
590 return lua_isboolean(ls, -1) ? frombool(lua_toboolean(ls, -1)) : MB_MAYBE;
591 }
592
callmaybefn(const char * fn,const char * params,...)593 maybe_bool CLua::callmaybefn(const char *fn, const char *params, ...)
594 {
595 va_list args;
596 va_start(args, params);
597 maybe_bool r = callmaybefn(fn, params, args);
598 va_end(args);
599 return r;
600 }
601
callbooleanfn(bool def,const char * fn,const char * params,...)602 bool CLua::callbooleanfn(bool def, const char *fn, const char *params, ...)
603 {
604 va_list args;
605 va_start(args, params);
606 maybe_bool r = callmbooleanfn(fn, params, args);
607 va_end(args);
608 return tobool(r, def);
609 }
610
proc_returns(const char * par) const611 bool CLua::proc_returns(const char *par) const
612 {
613 return strchr(par, '>') != nullptr;
614 }
615
616 // Identical to lua_getglobal for simple names, but will look up
617 // "a.b.c" names in tables, so you can pushglobal("dgn.point") and get
618 // _G['dgn']['point'], as expected.
619 //
620 // Guarantees to push exactly one value onto the stack.
621 //
pushglobal(const string & name)622 void CLua::pushglobal(const string &name)
623 {
624 vector<string> pieces = split_string(".", name);
625 lua_State *ls(state());
626
627 if (pieces.empty())
628 lua_pushnil(ls);
629
630 for (unsigned i = 0, size = pieces.size(); i < size; ++i)
631 {
632 if (!i)
633 lua_getglobal(ls, pieces[i].c_str());
634 else
635 {
636 if (lua_istable(ls, -1))
637 {
638 lua_pushstring(ls, pieces[i].c_str());
639 lua_gettable(ls, -2);
640 // Swap the value we just found with the table itself.
641 lua_insert(ls, -2);
642 // And remove the table.
643 lua_pop(ls, 1);
644 }
645 else
646 {
647 // We expected a table here, but got something else. Fail.
648 lua_pop(ls, 1);
649 lua_pushnil(ls);
650 break;
651 }
652 }
653 }
654 }
655
callfn(const char * fn,const char * params,...)656 bool CLua::callfn(const char *fn, const char *params, ...)
657 {
658 error.clear();
659 lua_State *ls = state();
660 if (!ls)
661 return false;
662
663 pushglobal(fn);
664 if (!lua_isfunction(ls, -1))
665 {
666 lua_pop(ls, 1);
667 return false;
668 }
669
670 va_list args;
671 va_list fnret;
672 va_start(args, params);
673 bool ret = calltopfn(ls, params, args, -1, &fnret);
674 if (ret)
675 {
676 // If we have a > in format, gather return params now.
677 if (proc_returns(params))
678 vfnreturns(params, fnret);
679 }
680 va_end(args);
681 va_end(fnret);
682 return ret;
683 }
684
callfn(const char * fn,int nargs,int nret)685 bool CLua::callfn(const char *fn, int nargs, int nret)
686 {
687 error.clear();
688 lua_State *ls = state();
689 if (!ls)
690 return false;
691
692 // If a function is not provided on the stack, get the named function.
693 if (fn)
694 {
695 pushglobal(fn);
696 if (!lua_isfunction(ls, -1))
697 {
698 lua_settop(ls, -nargs - 2);
699 return false;
700 }
701
702 // Slide the function in front of its args and call it.
703 if (nargs)
704 lua_insert(ls, -nargs - 1);
705 }
706
707 lua_call_throttle strangler(this);
708 int err = lua_pcall(ls, nargs, nret, 0);
709 set_error(err, ls);
710 return !err;
711 }
712
init_lua()713 void CLua::init_lua()
714 {
715 if (_state)
716 return;
717
718 #ifdef NO_CUSTOM_ALLOCATOR
719 // If this is likely to be used as a server, warn the builder.
720 // NOTE: #warning doesn't work on MSVC, so this will be fatal there
721 // (not that webtiles or dgamelaunch are supported on Windows anyway).
722 # if defined(USE_TILE_WEB) || defined(DGAMELAUNCH)
723 # warning Detected 64-bit Luajit, disabling CLua memory throttling.
724 # endif
725 _state = luaL_newstate();
726 #else
727 // Throttle memory usage in managed (clua) VMs
728 _state = managed_vm? lua_newstate(_clua_allocator, this) : luaL_newstate();
729 #endif
730 if (!_state)
731 end(1, false, "Unable to create Lua state.");
732
733 lua_stack_cleaner clean(_state);
734
735 lua_atpanic(_state, _clua_panic);
736
737 #ifdef CLUA_UNRESTRICTED_LIBS
738 // open all libs -- this is not safe for public servers or releases!
739 // Intended for people writing bots and the like.
740 luaL_openlibs(_state);
741 #else
742 // Selectively load some, but not all Lua core libraries.
743 //
744 // In Lua 5.1, these library setup calls are not supposed to be called
745 // directly from C. If the lua version changes, this may need to be changed:
746 // recommended practice is (apparently) checking the lua version's linit.cc
747 // and seeing how that does the full library setup.
748 //
749 // This doesn't seem to *obviously* impact the libraries we use by default,
750 // but some of the libraries we don't use will panic if not called
751 // correctly; since someone writing a bot (for example) might want to
752 // expand this, do things "correctly". The core lua libraries in 5.1 we are
753 // not loading are:
754 //
755 // {LUA_LOADLIBNAME, luaopen_package}, // (require etc)
756 // {LUA_IOLIBNAME, luaopen_io}, //
757 // {LUA_OSLIBNAME, luaopen_os},
758 // {LUA_DBLIBNAME, luaopen_debug},
759 const vector<pair<string, lua_CFunction>> lua_core_libs =
760 {
761 {"", luaopen_base}, // XX: why no name? but this is how linit.cc does it
762 {LUA_TABLIBNAME, luaopen_table},
763 {LUA_STRLIBNAME, luaopen_string},
764 {LUA_MATHLIBNAME, luaopen_math},
765 };
766
767 for (auto l : lua_core_libs)
768 {
769 lua_pushcfunction(_state, l.second);
770 lua_pushstring(_state, l.first.c_str());
771 lua_call(_state, 1, 0);
772 }
773 #endif
774
775 lua_pushboolean(_state, managed_vm);
776 setregistry("lua_vm_is_managed");
777
778 lua_pushlightuserdata(_state, this);
779 setregistry("__clua");
780 }
781
lua_loadstring(lua_State * ls)782 static int lua_loadstring(lua_State *ls)
783 {
784 const auto lua = luaL_checkstring(ls, 1);
785 if (lua[0] == 0x1b)
786 abort();
787 lua_settop(ls, 0);
788 if (luaL_loadstring(ls, lua))
789 {
790 lua_pushnil(ls);
791 lua_insert(ls, 1);
792 }
793 return lua_gettop(ls);
794 }
795
init_libraries()796 void CLua::init_libraries()
797 {
798 lua_stack_cleaner clean(state());
799
800 lua_pushcfunction(_state, lua_loadstring);
801 lua_setglobal(_state, "loadstring");
802 lua_pushnil(_state);
803 lua_setglobal(_state, "load");
804
805 // Open Crawl bindings
806 cluaopen_kills(_state);
807 cluaopen_you(_state);
808 cluaopen_item(_state);
809 cluaopen_crawl(_state);
810 cluaopen_file(_state);
811 cluaopen_moninf(_state);
812 cluaopen_options(_state);
813 cluaopen_travel(_state);
814 cluaopen_view(_state);
815 cluaopen_spells(_state);
816
817 cluaopen_globals(_state);
818
819 execfile("dlua/macro.lua", true, true);
820
821 // All hook names must be chk_????
822 execstring("chk_startgame = { }", "base");
823
824 lua_register(_state, "loadfile", _clua_loadfile);
825 lua_register(_state, "dofile", _clua_dofile);
826
827 lua_register(_state, "crawl_require", _clua_require);
828
829 execfile("dlua/util.lua", true, true);
830 execfile("dlua/iter.lua", true, true);
831 execfile("dlua/tags.lua", true, true);
832 execfile("dlua/init.lua", true, true);
833
834 if (managed_vm)
835 {
836 lua_register(_state, "pcall", _clua_guarded_pcall);
837 execfile("dlua/userbase.lua", true, true);
838 execfile("dlua/persist.lua", true, true);
839 }
840 }
841
get_vm(lua_State * ls)842 CLua &CLua::get_vm(lua_State *ls)
843 {
844 lua_stack_cleaner clean(ls);
845 _getregistry(ls, "__clua");
846 CLua *vm = clua_get_lightuserdata<CLua>(ls, -1);
847 if (!vm)
848 luaL_error(ls, "Could not find matching clua for lua state");
849 return *vm;
850 }
851
is_managed_vm(lua_State * ls)852 bool CLua::is_managed_vm(lua_State *ls)
853 {
854 lua_stack_cleaner clean(ls);
855 lua_pushstring(ls, "lua_vm_is_managed");
856 lua_gettable(ls, LUA_REGISTRYINDEX);
857 return lua_toboolean(ls, -1);
858 }
859
add_shutdown_listener(lua_shutdown_listener * listener)860 void CLua::add_shutdown_listener(lua_shutdown_listener *listener)
861 {
862 if (find(shutdown_listeners.begin(), shutdown_listeners.end(), listener)
863 == shutdown_listeners.end())
864 {
865 shutdown_listeners.push_back(listener);
866 }
867 }
868
remove_shutdown_listener(lua_shutdown_listener * listener)869 void CLua::remove_shutdown_listener(lua_shutdown_listener *listener)
870 {
871 erase_val(shutdown_listeners, listener);
872 }
873
874 // Can be called from within a debugger to look at the current Lua
875 // call stack. (Borrowed from ToME 3)
print_stack()876 void CLua::print_stack()
877 {
878 struct lua_Debug dbg;
879 int i = 0;
880 lua_State *L = state();
881
882 fprintf(stderr, "\n");
883 while (lua_getstack(L, i++, &dbg) == 1)
884 {
885 lua_getinfo(L, "lnuS", &dbg);
886
887 char* file = strrchr(dbg.short_src, '/');
888 if (file == nullptr)
889 file = dbg.short_src;
890 else
891 file++;
892
893 fprintf(stderr, "%s, function %s, line %d\n", file,
894 dbg.name, dbg.currentline);
895 }
896
897 fprintf(stderr, "\n");
898 }
899
900 // //////////////////////////////////////////////////////////////////////
901 // lua_text_pattern
902
903 // We could simplify this a great deal by just using lex and yacc, but I
904 // don't know if we want to introduce them.
905
906 struct lua_pat_op
907 {
908 const char *token;
909 const char *luatok;
910
911 bool pretext; // Does this follow a pattern?
912 bool posttext; // Is this followed by a pattern?
913 };
914
915 static lua_pat_op pat_ops[] =
916 {
917 { "<<", " ( ", false, true },
918 { ">>", " ) ", true, false },
919 { "!!", " not ", false, true },
920 { "==", " == ", true, true },
921 { "^^", " ~= ", true, true },
922 { "&&", " and ", true, true },
923 { "||", " or ", true, true },
924 };
925
926 unsigned int lua_text_pattern::lfndx = 0;
927
is_lua_pattern(const string & s)928 bool lua_text_pattern::is_lua_pattern(const string &s)
929 {
930 return any_of(begin(pat_ops), end(pat_ops),
931 [&s] (const lua_pat_op &op)
932 { return s.find(op.token) != string::npos; });
933 }
934
lua_text_pattern(const string & _pattern)935 lua_text_pattern::lua_text_pattern(const string &_pattern)
936 : translated(false), isvalid(true), pattern(_pattern),
937 lua_fn_name(new_fn_name())
938 {
939 }
940
~lua_text_pattern()941 lua_text_pattern::~lua_text_pattern()
942 {
943 if (translated && !lua_fn_name.empty())
944 {
945 lua_State *ls = clua;
946 if (ls)
947 {
948 lua_pushnil(ls);
949 clua.setglobal(lua_fn_name.c_str());
950 }
951 }
952 }
953
valid() const954 bool lua_text_pattern::valid() const
955 {
956 return translated? isvalid : translate();
957 }
958
matches(const string & s) const959 bool lua_text_pattern::matches(const string &s) const
960 {
961 if (isvalid && !translated)
962 translate();
963
964 if (!isvalid)
965 return false;
966
967 return clua.callbooleanfn(false, lua_fn_name.c_str(), "s", s.c_str());
968 }
969
match_location(const string & s) const970 pattern_match lua_text_pattern::match_location(const string &s) const
971 {
972 // lua_text_pattern is only used if a special non-regex op is detected (^F
973 // for "armour && ego", for instance), and in those situations, it's
974 // unclear what exactly to use for the matched text here (especially in
975 // more complicated expressions that include things like <<>>, !!, etc).
976 return matches(s)
977 ? pattern_match::succeeded(s)
978 : pattern_match::failed(s);
979 }
980
pre_pattern(string & pat,string & fn) const981 void lua_text_pattern::pre_pattern(string &pat, string &fn) const
982 {
983 // Trim trailing spaces
984 pat.erase(pat.find_last_not_of(" \t\n\r") + 1);
985
986 fn += " pmatch([[";
987 fn += pat;
988 fn += "]], text, false) ";
989
990 pat.clear();
991 }
992
post_pattern(string & pat,string & fn) const993 void lua_text_pattern::post_pattern(string &pat, string &fn) const
994 {
995 pat.erase(0, pat.find_first_not_of(" \t\n\r"));
996
997 fn += " pmatch([[";
998 fn += pat;
999 fn += "]], text, false) ";
1000
1001 pat.clear();
1002 }
1003
new_fn_name()1004 string lua_text_pattern::new_fn_name()
1005 {
1006 return make_stringf("__ch_stash_search_%u", lfndx++);
1007 }
1008
translate() const1009 bool lua_text_pattern::translate() const
1010 {
1011 if (translated || !isvalid)
1012 return false;
1013
1014 if (pattern.find("]]") != string::npos || pattern.find("[[") != string::npos)
1015 return false;
1016
1017 string textp;
1018 string luafn;
1019 const lua_pat_op *currop = nullptr;
1020 for (string::size_type i = 0; i < pattern.length(); ++i)
1021 {
1022 bool match = false;
1023 for (unsigned p = 0; p < ARRAYSZ(pat_ops); ++p)
1024 {
1025 const lua_pat_op &lop = pat_ops[p];
1026 if (pattern.find(lop.token, i) == i)
1027 {
1028 match = true;
1029 if (lop.pretext && (!currop || currop->posttext))
1030 {
1031 if (currop)
1032 textp.erase(0, textp.find_first_not_of(" \r\n\t"));
1033 pre_pattern(textp, luafn);
1034 }
1035
1036 currop = &lop;
1037 luafn += lop.luatok;
1038
1039 i += strlen(lop.token) - 1;
1040
1041 break;
1042 }
1043 }
1044
1045 if (match)
1046 continue;
1047
1048 textp += pattern[i];
1049 }
1050
1051 if (currop && currop->posttext)
1052 post_pattern(textp, luafn);
1053
1054 luafn = "function " + lua_fn_name + "(text) return " + luafn + " end";
1055
1056 const_cast<lua_text_pattern *>(this)->translated = true;
1057
1058 int err = clua.execstring(luafn.c_str(), "stash-search");
1059 if (err)
1060 {
1061 lua_text_pattern *self = const_cast<lua_text_pattern *>(this);
1062 self->isvalid = self->translated = false;
1063 }
1064
1065 return translated;
1066 }
1067
1068 // ////////////////////////////////////////////////////////////////////////
1069
1070 lua_call_throttle::lua_clua_map lua_call_throttle::lua_map;
1071
1072 // A panic function for the Lua interpreter, usually called when it
1073 // runs out of memory when trying to load a file or a chunk of Lua from
1074 // an unprotected Lua op. The only cases of unprotected Lua loads are
1075 // loads of Lua code from .crawlrc, which is read at start of game.
1076 //
1077 // If there's an inordinately large .crawlrc (we're talking seriously
1078 // massive here) that wants more memory than we're willing to give
1079 // Lua, then the game will save and exit until the .crawlrc is fixed.
1080 //
1081 // Lua can also run out of memory during protected script execution,
1082 // such as when running a macro or some other game hook, but in such
1083 // cases the Lua interpreter will throw an exception instead of
1084 // panicking.
1085 //
_clua_panic(lua_State * ls)1086 static int _clua_panic(lua_State *ls)
1087 {
1088 UNUSED(ls);
1089 if (crawl_state.need_save && !crawl_state.saving_game
1090 && !crawl_state.updating_scores)
1091 {
1092 save_game(true);
1093 }
1094 return 0;
1095 }
1096
1097 #ifndef NO_CUSTOM_ALLOCATOR
_clua_allocator(void * ud,void * ptr,size_t osize,size_t nsize)1098 static void *_clua_allocator(void *ud, void *ptr, size_t osize, size_t nsize)
1099 {
1100 CLua *cl = static_cast<CLua *>(ud);
1101 cl->memory_used += nsize - osize;
1102
1103 if (nsize > osize && cl->memory_used >= CLUA_MAX_MEMORY_USE * 1024
1104 && cl->mixed_call_depth)
1105 {
1106 return nullptr;
1107 }
1108
1109 if (!nsize)
1110 {
1111 free(ptr);
1112 return nullptr;
1113 }
1114 else
1115 return realloc(ptr, nsize);
1116 }
1117 #endif
1118
_clua_throttle_hook(lua_State * ls,lua_Debug * dbg)1119 static void _clua_throttle_hook(lua_State *ls, lua_Debug *dbg)
1120 {
1121 UNUSED(dbg);
1122
1123 CLua *lua = lua_call_throttle::find_clua(ls);
1124
1125 // Co-routines can create a new Lua state; in such cases, we must
1126 // fudge it.
1127 if (!lua)
1128 lua = &clua;
1129
1130 if (lua)
1131 {
1132 if (!lua->throttle_sleep_ms)
1133 lua->throttle_sleep_ms = lua->throttle_sleep_start;
1134 else if (lua->throttle_sleep_ms < lua->throttle_sleep_end)
1135 lua->throttle_sleep_ms *= 2;
1136
1137 ++lua->n_throttle_sleeps;
1138
1139 delay(lua->throttle_sleep_ms);
1140
1141 // Try to kill the annoying script.
1142 if (lua->n_throttle_sleeps > CLua::MAX_THROTTLE_SLEEPS)
1143 {
1144 lua->n_throttle_sleeps = CLua::MAX_THROTTLE_SLEEPS;
1145 luaL_error(ls, BUGGY_SCRIPT_ERROR);
1146 }
1147 }
1148 }
1149
lua_call_throttle(CLua * _lua)1150 lua_call_throttle::lua_call_throttle(CLua *_lua)
1151 : lua(_lua)
1152 {
1153 lua->init_throttle();
1154 if (!lua->mixed_call_depth++)
1155 lua_map[lua->state()] = lua;
1156 }
1157
~lua_call_throttle()1158 lua_call_throttle::~lua_call_throttle()
1159 {
1160 if (!--lua->mixed_call_depth)
1161 lua_map.erase(lua->state());
1162 }
1163
find_clua(lua_State * ls)1164 CLua *lua_call_throttle::find_clua(lua_State *ls)
1165 {
1166 return lookup(lua_map, ls, nullptr);
1167 }
1168
1169 // This function is a replacement for Lua's in-built pcall function. It behaves
1170 // like pcall in all respects (as documented in the Lua 5.1 reference manual),
1171 // but does not allow the Lua chunk/script to catch errors thrown by the
1172 // Lua-throttling code. This is necessary so that we can interrupt scripts that
1173 // are hogging CPU.
1174 //
1175 // If we did not intercept pcall, the script could do the equivalent
1176 // of this:
1177 //
1178 // while true do
1179 // pcall(function () while true do end end)
1180 // end
1181 //
1182 // And there's a good chance we wouldn't be able to interrupt the
1183 // deadloop because our errors would get caught by the pcall (more
1184 // levels of nesting would just increase the chance of the script
1185 // beating our throttling).
1186 //
_clua_guarded_pcall(lua_State * ls)1187 static int _clua_guarded_pcall(lua_State *ls)
1188 {
1189 const int nargs = lua_gettop(ls);
1190 const int err = lua_pcall(ls, nargs - 1, LUA_MULTRET, 0);
1191
1192 if (err)
1193 {
1194 const char *errs = lua_tostring(ls, 1);
1195 if (!errs || strstr(errs, BUGGY_SCRIPT_ERROR))
1196 luaL_error(ls, errs? errs : BUGGY_PCALL_ERROR);
1197 }
1198
1199 lua_pushboolean(ls, !err);
1200 lua_insert(ls, 1);
1201
1202 return lua_gettop(ls);
1203 }
1204
1205 // Document clua globals here, as they're bound by the interpreter object
1206
1207 /*** Pre-defined globals.
1208 *
1209 * *Note:* this is not a real module. All names described here are defined in
1210 * the global clua namespace.
1211 * @module Globals
1212 */
1213
1214 /*** Load the named lua file as a chunk.
1215 * @tparam string filename
1216 * @return function chunk or nil,error
1217 * @function loadfile
1218 */
_clua_loadfile(lua_State * ls)1219 static int _clua_loadfile(lua_State *ls)
1220 {
1221 const char *file = luaL_checkstring(ls, 1);
1222 if (!file)
1223 return 0;
1224
1225 const int err = CLua::loadfile(ls, file, !CLua::is_managed_vm(ls));
1226 if (err)
1227 {
1228 const int place = lua_gettop(ls);
1229 lua_pushnil(ls);
1230 lua_insert(ls, place);
1231 return 2;
1232 }
1233 return 1;
1234 }
1235
1236 /*** Load and execute the named lua file.
1237 * Differs from @{dofile} in that the file is run for its side effects.
1238 * If the execution has an error we raise that error and exit.
1239 * @tparam string filename
1240 * @treturn boolean|nil
1241 * @function require
1242 */
_clua_require(lua_State * ls)1243 static int _clua_require(lua_State *ls)
1244 {
1245 const char *file = luaL_checkstring(ls, 1);
1246 if (!file)
1247 return 0;
1248
1249 CLua &vm(CLua::get_vm(ls));
1250 if (vm.execfile(file, false, false) != 0)
1251 luaL_error(ls, vm.error.c_str());
1252
1253 lua_pushboolean(ls, true);
1254 return 1;
1255 }
1256
1257 /*** Load and execute the named luafile, returning the result.
1258 * Differs from @{require} in that the file is run for a result. Errors
1259 * come back on the lua stack and can be handled by the caller.
1260 * @tparam string filename
1261 * @return whatever is left on the lua stack by filename
1262 * @function dofile
1263 */
_clua_dofile(lua_State * ls)1264 static int _clua_dofile(lua_State *ls)
1265 {
1266 const char *file = luaL_checkstring(ls, 1);
1267 if (!file)
1268 return 0;
1269
1270 const int err = CLua::loadfile(ls, file, !CLua::is_managed_vm(ls));
1271 if (err)
1272 return lua_error(ls);
1273
1274 lua_call(ls, 0, LUA_MULTRET);
1275 return lua_gettop(ls);
1276 }
1277
quote_lua_string(const string & s)1278 string quote_lua_string(const string &s)
1279 {
1280 return replace_all_of(replace_all_of(s, "\\", "\\\\"), "\"", "\\\"");
1281 }
1282
_get_persist_file()1283 static string _get_persist_file()
1284 {
1285 return Options.filename + ".persist";
1286 }
1287
1288 // ///////////////////////////////////////////////////////////////////
1289
~lua_shutdown_listener()1290 lua_shutdown_listener::~lua_shutdown_listener()
1291 {
1292 }
1293
lua_datum(CLua & _lua,int stackpos,bool pop)1294 lua_datum::lua_datum(CLua &_lua, int stackpos, bool pop)
1295 : lua(_lua), need_cleanup(true)
1296 {
1297 // Store the datum in the registry indexed by "this".
1298 lua_pushvalue(lua, stackpos);
1299 lua_pushlightuserdata(lua, this);
1300 // Move the key (this) before the value.
1301 lua_insert(lua, -2);
1302 lua_settable(lua, LUA_REGISTRYINDEX);
1303
1304 if (pop && stackpos < 0)
1305 lua_pop(lua, -stackpos);
1306
1307 lua.add_shutdown_listener(this);
1308 }
1309
lua_datum(const lua_datum & o)1310 lua_datum::lua_datum(const lua_datum &o)
1311 : lua(o.lua), need_cleanup(true)
1312 {
1313 set_from(o);
1314 }
1315
set_from(const lua_datum & o)1316 void lua_datum::set_from(const lua_datum &o)
1317 {
1318 lua_pushlightuserdata(lua, this);
1319 o.push();
1320 lua_settable(lua, LUA_REGISTRYINDEX);
1321 lua.add_shutdown_listener(this);
1322 need_cleanup = true;
1323 }
1324
operator =(const lua_datum & o)1325 const lua_datum &lua_datum::operator = (const lua_datum &o)
1326 {
1327 if (this != &o)
1328 {
1329 cleanup();
1330 set_from(o);
1331 }
1332 return *this;
1333 }
1334
push() const1335 void lua_datum::push() const
1336 {
1337 lua_pushlightuserdata(lua, const_cast<lua_datum*>(this));
1338 lua_gettable(lua, LUA_REGISTRYINDEX);
1339
1340 // The value we saved is now on top of the Lua stack.
1341 }
1342
~lua_datum()1343 lua_datum::~lua_datum()
1344 {
1345 cleanup();
1346 }
1347
shutdown(CLua &)1348 void lua_datum::shutdown(CLua &)
1349 {
1350 cleanup();
1351 }
1352
cleanup()1353 void lua_datum::cleanup()
1354 {
1355 if (need_cleanup)
1356 {
1357 need_cleanup = false;
1358 lua.remove_shutdown_listener(this);
1359
1360 lua_pushlightuserdata(lua, this);
1361 lua_pushnil(lua);
1362 lua_settable(lua, LUA_REGISTRYINDEX);
1363 }
1364 }
1365
1366 #define LUA_CHECK_TYPE(check) \
1367 lua_stack_cleaner clean(lua); \
1368 push(); \
1369 return check(lua, -1)
1370
is_table() const1371 bool lua_datum::is_table() const
1372 {
1373 LUA_CHECK_TYPE(lua_istable);
1374 }
1375
is_function() const1376 bool lua_datum::is_function() const
1377 {
1378 LUA_CHECK_TYPE(lua_isfunction);
1379 }
1380
is_number() const1381 bool lua_datum::is_number() const
1382 {
1383 LUA_CHECK_TYPE(lua_isnumber);
1384 }
1385
is_string() const1386 bool lua_datum::is_string() const
1387 {
1388 LUA_CHECK_TYPE(lua_isstring);
1389 }
1390
is_udata() const1391 bool lua_datum::is_udata() const
1392 {
1393 LUA_CHECK_TYPE(lua_isuserdata);
1394 }
1395