From d753c7485897ac077e6a2fb17305be63241afa74 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 11 Oct 2026 22:17:47 +0300 Subject: [PATCH 1/4] update StdfsDevice::resolve, remove, removeAll --- src/io/devices/StdfsDevice.cpp | 46 +++++++++++++++++++++++++++++----- src/io/devices/StdfsDevice.hpp | 1 + 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/io/devices/StdfsDevice.cpp b/src/io/devices/StdfsDevice.cpp index fc0602b52..6f0e37e0e 100644 --- a/src/io/devices/StdfsDevice.cpp +++ b/src/io/devices/StdfsDevice.cpp @@ -20,10 +20,29 @@ StdfsDevice::StdfsDevice(fs::path root, bool createDirectory) << ": " << ec.message(); } } + absoluteRoot = fs::absolute(this->root).lexically_normal(); + if (!absoluteRoot.has_filename() && absoluteRoot.has_relative_path()) { + absoluteRoot = absoluteRoot.parent_path(); + } } fs::path StdfsDevice::resolve(std::string_view path) { - return root / fs::u8path(io::path(std::string(path)).normalized().string()); + if (path.find_first_of(std::string_view("\0\\:", 3)) != std::string_view::npos) { + throw std::runtime_error("invalid path"); + } + fs::path rel = fs::u8path(io::path(std::string(path)).normalized().string()); + if (rel.has_root_name() || rel.has_root_directory()) { + throw std::runtime_error("absolute paths are not allowed"); + } + fs::path full = (absoluteRoot / rel).lexically_normal(); + fs::path inside = full.lexically_relative(absoluteRoot); + if (inside.empty() || *inside.begin() == "..") { + throw std::runtime_error("path escapes device root"); + } + if (inside == ".") { + return absoluteRoot; + } + return full; } std::unique_ptr StdfsDevice::write(std::string_view path) { @@ -90,17 +109,32 @@ bool StdfsDevice::mkdirs(std::string_view path) { bool StdfsDevice::remove(std::string_view path) { auto resolved = resolve(path); - return fs::remove(resolved); + if (resolved == absoluteRoot) { + throw std::runtime_error("unable to remove device root"); + } + std::error_code ec; + bool removed = fs::remove(resolved, ec); + if (ec) { + logger.error() << "error removing " << resolved << ": " << ec.message(); + } + return removed; } uint64_t StdfsDevice::removeAll(std::string_view path) { auto resolved = resolve(path); - if (fs::exists(resolved)) { - logger.info() << "removeAll " << resolved; - return fs::remove_all(resolved); - } else { + if (resolved == absoluteRoot) { + throw std::runtime_error("unable to remove device root"); + } + std::error_code ec; + auto removed = fs::remove_all(resolved, ec); + if (ec) { + logger.error() << "error removing " << resolved << ": " << ec.message(); return 0; } + if (removed > 0) { + logger.info() << "removeAll " << resolved << ": " << removed; + } + return removed; } class StdfsPathsGenerator : public PathsGenerator { diff --git a/src/io/devices/StdfsDevice.hpp b/src/io/devices/StdfsDevice.hpp index 677cad25b..9259a9256 100644 --- a/src/io/devices/StdfsDevice.hpp +++ b/src/io/devices/StdfsDevice.hpp @@ -23,5 +23,6 @@ namespace io { std::unique_ptr list(std::string_view path) override; private: std::filesystem::path root; + std::filesystem::path absoluteRoot; }; } From ab129367adc2f515e9452d4928163df2715e0a04 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 12 Oct 2026 00:15:28 +0300 Subject: [PATCH 2/4] fix registry access in generator scripts --- src/logic/scripting/lua/lua_engine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index 812f67665..1e73ea903 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -196,6 +196,10 @@ void lua::init_state(State* L, StateType stateType) { if (stateType == StateType::GENERATOR) { pushnil(L); setglobal(L, "ffi"); + + static const char* removed_debug[] { + "getregistry", "getupvalue", "setupvalue", "getinfo", nullptr}; + remove_lib_funcs(L, "debug", removed_debug); } } From 6f466d52f263081c72595a61bc2efdf958e4acb9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 12 Oct 2026 00:21:24 +0300 Subject: [PATCH 3/4] fix: missing network.request protocol filter --- src/network/Curl.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/network/Curl.cpp b/src/network/Curl.cpp index 0e08162fb..11afa5ae5 100644 --- a/src/network/Curl.cpp +++ b/src/network/Curl.cpp @@ -113,6 +113,14 @@ public: curl_easy_setopt(curl, CURLOPT_URL, request.url.c_str()); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, request.method.c_str()); + +#if LIBCURL_VERSION_NUM >= 0x075500 + curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, "http,https"); + curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"); +#else + curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); +#endif curl_slist* hs = nullptr; From f246619c6bbc2c144e36475cf7fcc16c3df21b73 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 12 Oct 2026 00:30:49 +0300 Subject: [PATCH 4/4] fix potential fatal errors --- src/coders/vec3.cpp | 3 +++ src/io/io.cpp | 3 +++ src/logic/scripting/lua/libs/libnetwork.cpp | 6 ++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/coders/vec3.cpp b/src/coders/vec3.cpp index e00bdd662..119cbed92 100644 --- a/src/coders/vec3.cpp +++ b/src/coders/vec3.cpp @@ -133,6 +133,9 @@ static model::Mesh load_mesh( if (flags == FLAG_ZLIB) { throw std::runtime_error("compression is not supported yet"); } + if (attributeCount <= 0) { + throw std::runtime_error("mesh must have at least one attribute"); + } std::vector attributes; for (int i = 0; i < attributeCount; i++) { attributes.push_back(load_attribute(reader)); diff --git a/src/io/io.cpp b/src/io/io.cpp index 638108587..d550654e4 100644 --- a/src/io/io.cpp +++ b/src/io/io.cpp @@ -152,6 +152,9 @@ std::vector io::read_bytes(const path& filename) { std::string io::read_string(const path& filename) { size_t size; auto bytes = read_bytes(filename, size); + if (bytes == nullptr) { + throw std::runtime_error("could not read file " + filename.string()); + } return std::string((const char*)bytes.get(), size); } diff --git a/src/logic/scripting/lua/libs/libnetwork.cpp b/src/logic/scripting/lua/libs/libnetwork.cpp index 59d50f075..0d48e4a29 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -266,8 +266,10 @@ static int l_peek(lua::State* L, network::Network& network) { static int l_available(lua::State* L, network::Network& network) { u64id_t id = lua::tointeger(L, 1); - if (auto connection = network.getConnection(id, false)) { - return lua::pushinteger(L, dynamic_cast(connection)->available()); + if (auto connection = dynamic_cast( + network.getConnection(id, false) + )) { + return lua::pushinteger(L, connection->available()); } return 0;