diff options
author | red-001 <red-001@outlook.ie> | 2017-06-30 19:14:39 +0100 |
---|---|---|
committer | Loïc Blot <nerzhul@users.noreply.github.com> | 2017-06-30 20:14:39 +0200 |
commit | f3ad75691aea30d2d68aab19fbfa9031409c39d7 (patch) | |
tree | b73109f1d3d14af91b3593dc80645a1bb70274a8 /src/client.cpp | |
parent | 2e53801fc0d9ba13afec6c1ddb5e3999f68b96bd (diff) | |
download | minetest-f3ad75691aea30d2d68aab19fbfa9031409c39d7.tar.gz minetest-f3ad75691aea30d2d68aab19fbfa9031409c39d7.tar.bz2 minetest-f3ad75691aea30d2d68aab19fbfa9031409c39d7.zip |
Create a filesystem abstraction layer for CSM and only allow accessing files that are scanned into it. (#5965)
* Load client-side mods into memory before executing them.
This removes the remaining filesystem access that client-sided mods had and it will hopefully make then more secure.
* Lua Virtual filesystem: don't load the files into memory just scan the filenames into memory.
* Fix the issues with backtrace
* fix most of the issues
* fix code style.
* add a comment
Diffstat (limited to 'src/client.cpp')
-rw-r--r-- | src/client.cpp | 67 |
1 files changed, 51 insertions, 16 deletions
diff --git a/src/client.cpp b/src/client.cpp index 5681c3ddb..0f689a714 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -104,17 +104,17 @@ Client::Client( m_script->setEnv(&m_env); } -void Client::initMods() +void Client::loadMods() { - m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME); + // Load builtin + scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath()); // If modding is not enabled, don't load mods, just builtin if (!m_modding_enabled) { return; } - ClientModConfiguration modconf(getClientModsLuaPath()); - std::vector<ModSpec> mods = modconf.getMods(); + m_mods = modconf.getMods(); std::vector<ModSpec> unsatisfied_mods = modconf.getUnsatisfiedMods(); // complain about mods with unsatisfied dependencies if (!modconf.isConsistent()) { @@ -123,28 +123,52 @@ void Client::initMods() // Print mods infostream << "Client Loading mods: "; - for (std::vector<ModSpec>::const_iterator i = mods.begin(); - i != mods.end(); ++i) { - infostream << (*i).name << " "; - } - + for (const ModSpec &mod : m_mods) + infostream << mod.name << " "; infostream << std::endl; + // Load and run "mod" scripts - for (std::vector<ModSpec>::const_iterator it = mods.begin(); - it != mods.end(); ++it) { - const ModSpec &mod = *it; + for (const ModSpec &mod : m_mods) { if (!string_allowed(mod.name, MODNAME_ALLOWED_CHARS)) { throw ModError("Error loading mod \"" + mod.name + "\": Mod name does not follow naming conventions: " "Only characters [a-z0-9_] are allowed."); } - std::string script_path = mod.path + DIR_DELIM + "init.lua"; - infostream << " [" << padStringRight(mod.name, 12) << "] [\"" - << script_path << "\"]" << std::endl; - m_script->loadMod(script_path, mod.name); + scanModIntoMemory(mod.name, mod.path); + } +} + +void Client::scanModSubfolder(const std::string &mod_name, const std::string &mod_path, + std::string mod_subpath) +{ + std::string full_path = mod_path + DIR_DELIM + mod_subpath; + std::vector<fs::DirListNode> mod = fs::GetDirListing(full_path); + for (unsigned int j=0; j < mod.size(); j++){ + std::string filename = mod[j].name; + if (mod[j].dir) { + scanModSubfolder(mod_name, mod_path, mod_subpath + + filename + DIR_DELIM); + continue; + } + std::replace( mod_subpath.begin(), mod_subpath.end(), DIR_DELIM_CHAR, '/'); + m_mod_files[mod_name + ":" + mod_subpath + filename] = full_path + filename; } } +void Client::initMods() +{ + m_script->loadModFromMemory(BUILTIN_MOD_NAME); + + // If modding is not enabled, don't load mods, just builtin + if (!m_modding_enabled) { + return; + } + + // Load and run "mod" scripts + for (const ModSpec &mod : m_mods) + m_script->loadModFromMemory(mod.name); +} + const std::string &Client::getBuiltinLuaPath() { static const std::string builtin_dir = porting::path_share + DIR_DELIM + "builtin"; @@ -1898,6 +1922,17 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename) return mesh; } +const std::string* Client::getModFile(const std::string &filename) +{ + StringMap::const_iterator it = m_mod_files.find(filename); + if (it == m_mod_files.end()) { + errorstream << "Client::getModFile(): File not found: \"" << filename + << "\"" << std::endl; + return NULL; + } + return &it->second; +} + bool Client::registerModStorage(ModMetadata *storage) { if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) { |