diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-06-22 12:26:53 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-06-22 12:26:53 +0000 |
commit | abb8fd86e78c57461f6729faafec5ea35ccd18a9 (patch) | |
tree | c262a150967152852cb015ddcd12a08530aedf7f /crawl-ref/source | |
parent | 609ccd171cbe8473c0a03c47392a12e72de2baaa (diff) | |
download | crawl-ref-abb8fd86e78c57461f6729faafec5ea35ccd18a9.tar.gz crawl-ref-abb8fd86e78c57461f6729faafec5ea35ccd18a9.zip |
Pull c_macro out of the code and into clua/macro.lua.
User-script dofile and loadfile check for "clua" anywhere in the file name and
refuse to load the file in that case; only core Crawl code can load Lua files
from clua/*.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1622 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/clua.cc | 40 | ||||
-rw-r--r-- | crawl-ref/source/clua.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/dat/clua/macro.lua | 39 | ||||
-rw-r--r-- | crawl-ref/source/files.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/files.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/makefile.mgw | 2 | ||||
-rw-r--r-- | crawl-ref/source/makefile.unix | 12 |
7 files changed, 67 insertions, 42 deletions
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc index 5953355df2..2f21d7db44 100644 --- a/crawl-ref/source/clua.cc +++ b/crawl-ref/source/clua.cc @@ -216,17 +216,19 @@ int CLua::execstring(const char *s, const char *context) return err; } -bool CLua::is_path_safe(const char *s) +bool CLua::is_path_safe(std::string s, bool trusted) { - return (!strstr(s, "..") && shell_safe(s)); + lowercase(s); + return (s.find("..") == std::string::npos && shell_safe(s.c_str()) + && (trusted || s.find("clua") == std::string::npos)); } -int CLua::loadfile(lua_State *ls, const char *filename) +int CLua::loadfile(lua_State *ls, const char *filename, bool trusted) { if (!ls) return (-1); - if (!is_path_safe(filename)) + if (!is_path_safe(filename, trusted)) { lua_pushstring( ls, @@ -238,7 +240,7 @@ int CLua::loadfile(lua_State *ls, const char *filename) return (luaL_loadfile(ls, file.c_str())); } -int CLua::execfile(const char *filename) +int CLua::execfile(const char *filename, bool trusted) { if (sourced_files.find(filename) != sourced_files.end()) return 0; @@ -246,7 +248,7 @@ int CLua::execfile(const char *filename) sourced_files.insert(filename); lua_State *ls = state(); - int err = loadfile(ls, filename); + int err = loadfile(ls, filename, trusted); lua_call_throttle strangler(this); if (!err) err = lua_pcall(ls, 0, 0, 0); @@ -600,31 +602,7 @@ void CLua::load_chooks() void CLua::load_cmacro() { - static const char *c_macro = - "function c_macro(fn)" - " if fn == nil then" - " if c_macro_coroutine ~= nil then" - " local coret, mret" - " coret, mret = coroutine.resume(c_macro_coroutine)" - " if not coret or not mret then" - " c_macro_coroutine = nil" - " c_macro_name = nil" - " end" - " if not coret and mret then" - " error(mret)" - " end" - " return (coret and mret)" - " end" - " return false" - " end" - " if _G[fn] == nil or type(_G[fn]) ~= 'function' then" - " return false" - " end" - " c_macro_name = fn" - " c_macro_coroutine = coroutine.create(_G[fn]) " - " return c_macro() " - "end"; - execstring(c_macro, "base"); + execfile("clua/macro.lua", true); } ///////////////////////////////////////////////////////////////////// diff --git a/crawl-ref/source/clua.h b/crawl-ref/source/clua.h index 419d34c908..0ec9723544 100644 --- a/crawl-ref/source/clua.h +++ b/crawl-ref/source/clua.h @@ -64,7 +64,7 @@ public: void getregistry(const char *name); int execstring(const char *str, const char *context = "init.txt"); - int execfile(const char *filename); + int execfile(const char *filename, bool trusted = false); bool callbooleanfn(bool defval, const char *fn, const char *params, ...); bool callfn(const char *fn, int nargs, int nret = 1); @@ -73,8 +73,8 @@ public: bool runhook(const char *hook, const char *params, ...); static int file_write(lua_State *ls); - static int loadfile(lua_State *ls, const char *file); - static bool is_path_safe(const char *file); + static int loadfile(lua_State *ls, const char *file, bool trusted = false); + static bool is_path_safe(std::string file, bool trusted = false); public: std::string error; diff --git a/crawl-ref/source/dat/clua/macro.lua b/crawl-ref/source/dat/clua/macro.lua new file mode 100644 index 0000000000..b624ed0292 --- /dev/null +++ b/crawl-ref/source/dat/clua/macro.lua @@ -0,0 +1,39 @@ +------------------------------------------------------------------ +-- macro.lua: +-- Crawl macro framework for Lua. +-- +-- Macros are called as Lua coroutines. If the macro yields false, the +-- coroutine is discarded (assuming an error). If the macro yields +-- true, Crawl will start a macro delay for the macro and call the +-- coroutine again next turn. If the macro just returns, the coroutine +-- is assumed to be done. +-- +-- Why coroutines: Macros may need to perform actions that take +-- multiple turns, which requires control to return to Crawl to +-- perform world updates between actions. Coroutines are the simplest +-- way to pass control back and forth without losing the macro's +-- state. +------------------------------------------------------------------ +function c_macro(fn) + if fn == nil then + if c_macro_coroutine ~= nil then + local coret, mret + coret, mret = coroutine.resume(c_macro_coroutine) + if not coret or not mret then + c_macro_coroutine = nil + c_macro_name = nil + end + if not coret and mret then + error(mret) + end + return (coret and mret) + end + return false + end + if _G[fn] == nil or type(_G[fn]) ~= 'function' then + return false + end + c_macro_name = fn + c_macro_coroutine = coroutine.create(_G[fn]) + return c_macro() +end
\ No newline at end of file diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 68dc9424b2..114a3f23a2 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -285,10 +285,14 @@ static bool create_dirs(const std::string &dir) return (true); } -std::string datafile_path(const std::string &basename, +std::string datafile_path(std::string basename, bool croak_on_fail, bool test_base_path) { +#if FILE_SEPARATOR != '/' + basename = replace_all_of(basename, "/", std::string(1, FILE_SEPARATOR)); +#endif + if (test_base_path && file_exists(basename)) return (basename); @@ -305,7 +309,7 @@ std::string datafile_path(const std::string &basename, const std::string prefixes[] = { std::string("dat") + FILE_SEPARATOR, std::string("docs") + FILE_SEPARATOR, - std::string("..")+FILE_SEPARATOR+std::string("docs")+FILE_SEPARATOR, + std::string("..") + FILE_SEPARATOR + "docs" + FILE_SEPARATOR, std::string("..") + FILE_SEPARATOR, std::string(".") + FILE_SEPARATOR, "", diff --git a/crawl-ref/source/files.h b/crawl-ref/source/files.h index 112e8e620f..c32cc52561 100644 --- a/crawl-ref/source/files.h +++ b/crawl-ref/source/files.h @@ -26,7 +26,7 @@ // referenced in files - newgame - ouch: extern FixedArray<bool, MAX_LEVELS, NUM_BRANCHES> tmp_file_pairs; -std::string datafile_path(const std::string &basename, +std::string datafile_path(std::string basename, bool croak_on_fail = true, bool test_base_path = false); std::string get_parent_directory(const std::string &filename); diff --git a/crawl-ref/source/makefile.mgw b/crawl-ref/source/makefile.mgw index d0056cd958..a9c3fbe381 100644 --- a/crawl-ref/source/makefile.mgw +++ b/crawl-ref/source/makefile.mgw @@ -125,8 +125,10 @@ ifneq ($(OPATH),$(INSTALLDIR)) $(COPY) $(APPNAME) ${INSTALLDIR} endif mkdir $(INSTALLDIR)\dat 2>nul || echo "" >nul + mkdir $(INSTALLDIR)\dat\clua 2>null || echo "">nul copy /y dat\*.des $(INSTALLDIR)\dat copy /y dat\*.txt $(INSTALLDIR)\dat + copy /y dat\clua\*.lua $(INSTALLDIR)\dat\clua copy /y ..\init.txt $(INSTALLDIR) clean: diff --git a/crawl-ref/source/makefile.unix b/crawl-ref/source/makefile.unix index 298e249f6a..9a6ed5998f 100644 --- a/crawl-ref/source/makefile.unix +++ b/crawl-ref/source/makefile.unix @@ -33,14 +33,14 @@ MCHMOD_SAVEDIR := 775 # The user:group to install the game as. INSTALL_UGRP := games:games -INSTALLDIR := /usr/games +INSTALLDIR := /usr/games/crawl # If you're installing Crawl for multiple users, you *must* set this to a # valid path before building Crawl. This is not necessary if you are building # Crawl for a single user. -# SAVEDIR := /usr/games/crawl-saves/ -# DATADIR := /usr/games/crawl-data/ +# SAVEDIR := /usr/games/crawl/saves/ +# DATADIR := /usr/games/crawl/data/ LEX := flex YACC := bison -y @@ -210,15 +210,16 @@ endif install: $(GAME) [ -d $(INSTALLDIR) ] || mkdir -p $(INSTALLDIR) - $(COPY) $(GAME) ${INSTALLDIR} + $(COPY) $(GAME) $(INSTALLDIR) chown $(INSTALL_UGRP) $(INSTALLDIR)/$(GAME) chmod ${MCHMOD} ${INSTALLDIR}/$(GAME) ifeq ($(DATADIR),) $(error DATADIR not set! Set DATADIR and run make clean install again) endif - mkdir -p $(DATADIR)/dat + mkdir -p $(DATADIR)/dat/clua cp dat/*.des $(DATADIR)/dat cp dat/*.txt $(DATADIR)/dat + cp dat/clua/*.lua $(DATADIR)/dat/clua cp -r lua $(DATADIR)/dat mkdir -p $(DATADIR)/docs cp ../docs/*.txt $(DATADIR)/docs @@ -228,6 +229,7 @@ ifneq ($(SAVEDIR),) chown $(INSTALL_UGRP) $(SAVEDIR) chmod $(MCHMOD_SAVEDIR) $(SAVEDIR) endif + ln -s $(INSTALLDIR)/$(GAME) /usr/local/bin/ clean: $(DELETE) *.o |