#pragma once #include #include #include // Forward declare lua_State to avoid including lua.h in header struct lua_State; struct lua_Debug; namespace mosis { // Resource limits for sandbox struct SandboxLimits { size_t memory_bytes = 16 * 1024 * 1024; // 16 MB default size_t max_string_size = 1 * 1024 * 1024; // 1 MB max string size_t max_table_entries = 100000; // Prevent hash DoS uint64_t instructions_per_call = 1000000; // ~10ms execution int stack_depth = 200; // Recursion limit }; // Context for sandbox (app identity, permissions, etc.) struct SandboxContext { std::string app_id; std::string app_path; std::vector permissions; bool is_system_app = false; }; // Isolated Lua execution environment class LuaSandbox { public: explicit LuaSandbox(const SandboxContext& context, const SandboxLimits& limits = {}); ~LuaSandbox(); // Non-copyable, non-movable LuaSandbox(const LuaSandbox&) = delete; LuaSandbox& operator=(const LuaSandbox&) = delete; LuaSandbox(LuaSandbox&&) = delete; LuaSandbox& operator=(LuaSandbox&&) = delete; // Load and execute Lua code (text only, bytecode rejected) bool LoadString(const std::string& code, const std::string& chunk_name = "chunk"); bool LoadFile(const std::string& path); // State access lua_State* GetState() const { return m_L; } const std::string& GetLastError() const { return m_last_error; } // Resource usage size_t GetMemoryUsed() const { return m_memory_used; } uint64_t GetInstructionsUsed() const { return m_instructions_used; } // Context access const SandboxContext& GetContext() const { return m_context; } const SandboxLimits& GetLimits() const { return m_limits; } const std::string& app_id() const { return m_context.app_id; } // Reset instruction counter (call before each event handler) void ResetInstructionCount(); // Check if sandbox is in valid state bool IsValid() const { return m_L != nullptr; } private: // Setup functions void SetupSandbox(); void RemoveDangerousGlobals(); void ProtectBuiltinTables(); void SetupInstructionHook(); void SetupSafeGlobals(); void SetupSafeRequire(); // Allocator callback (static for C compatibility) static void* SandboxAlloc(void* ud, void* ptr, size_t osize, size_t nsize); // Instruction hook callback (static for C compatibility) static void InstructionHook(lua_State* L, lua_Debug* ar); // Safe print function static int SafePrint(lua_State* L); // Safe require function static int SafeRequire(lua_State* L); lua_State* m_L = nullptr; SandboxContext m_context; SandboxLimits m_limits; size_t m_memory_used = 0; uint64_t m_instructions_used = 0; std::string m_last_error; }; } // namespace mosis // Convenience alias for tests using SandboxContext = mosis::SandboxContext; using SandboxLimits = mosis::SandboxLimits; using LuaSandbox = mosis::LuaSandbox;