diff --git a/Client/mods/deathmatch/logic/lua/CLuaArgument.cpp b/Client/mods/deathmatch/logic/lua/CLuaArgument.cpp index 819e0854f83..366a03cc705 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArgument.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaArgument.cpp @@ -468,7 +468,7 @@ void CLuaArgument::Push(lua_State* luaVM, CFastHashMap* pKn } // Can't use bitStream.Version() here as it is sometimes not set -bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables) +bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables, unsigned int uiDepth) { DeleteTableData(); m_iType = LUA_TNIL; @@ -530,7 +530,7 @@ bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vect case LUA_TTABLE: { m_pTableData = new CLuaArguments(); - if (!m_pTableData->ReadFromBitStream(bitStream, pKnownTables)) + if (!m_pTableData->ReadFromBitStream(bitStream, pKnownTables, uiDepth + 1)) { DeleteTableData(); return false; diff --git a/Client/mods/deathmatch/logic/lua/CLuaArgument.h b/Client/mods/deathmatch/logic/lua/CLuaArgument.h index c861cb57a80..2ddae3661c1 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArgument.h +++ b/Client/mods/deathmatch/logic/lua/CLuaArgument.h @@ -62,7 +62,7 @@ class CLuaArgument CLuaArguments* GetTable() const { return m_pTableData; } CClientEntity* GetElement() const; - bool ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables = NULL); + bool ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables = NULL, unsigned int uiDepth = 0); bool WriteToBitStream(NetBitStreamInterface& bitStream, CFastHashMap* pKnownTables = NULL) const; json_object* WriteToJSONObject(bool bSerialize = false, CFastHashMap* pKnownTables = NULL); bool ReadFromJSONObject(json_object* object, std::vector* pKnownTables = NULL); diff --git a/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp b/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp index 911eef27d94..232b34629c3 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp @@ -460,8 +460,11 @@ void CLuaArguments::ValidateTableKeys() } } -bool CLuaArguments::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables) +bool CLuaArguments::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables, unsigned int uiDepth) { + if (uiDepth > MaxBitStreamTableReadDepth) + return false; + bool bKnownTablesCreated = false; if (!pKnownTables) { diff --git a/Client/mods/deathmatch/logic/lua/CLuaArguments.h b/Client/mods/deathmatch/logic/lua/CLuaArguments.h index c6a7df10b9f..bda0ca27245 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArguments.h +++ b/Client/mods/deathmatch/logic/lua/CLuaArguments.h @@ -32,6 +32,8 @@ class CLuaArguments; class CLuaArguments { public: + static constexpr unsigned int MaxBitStreamTableReadDepth = 64; + CLuaArguments() {} CLuaArguments(const CLuaArguments& Arguments, CFastHashMap* pKnownTables = NULL); CLuaArguments(NetBitStreamInterface& bitStream, std::vector* pKnownTables = NULL); @@ -67,7 +69,7 @@ class CLuaArguments void DeleteArguments(); void Pop(); - bool ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables = NULL); + bool ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables = NULL, unsigned int uiDepth = 0); bool WriteToBitStream(NetBitStreamInterface& bitStream, CFastHashMap* pKnownTables = NULL) const; void ValidateTableKeys(); bool ReadFromJSONString(const char* szJSON); diff --git a/Server/mods/deathmatch/logic/lua/CLuaArgument.cpp b/Server/mods/deathmatch/logic/lua/CLuaArgument.cpp index 80721720057..de36740c68c 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArgument.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaArgument.cpp @@ -435,7 +435,7 @@ bool CLuaArgument::GetAsString(SString& strBuffer) } // Can't use bitStream.Version() here as it is sometimes not set -bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables) +bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables, unsigned int uiDepth) { DeleteTableData(); m_iType = LUA_TNIL; @@ -494,7 +494,7 @@ bool CLuaArgument::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vect case LUA_TTABLE: { m_pTableData = new CLuaArguments(); - if (!m_pTableData->ReadFromBitStream(bitStream, pKnownTables)) + if (!m_pTableData->ReadFromBitStream(bitStream, pKnownTables, uiDepth + 1)) { DeleteTableData(); return false; diff --git a/Server/mods/deathmatch/logic/lua/CLuaArgument.h b/Server/mods/deathmatch/logic/lua/CLuaArgument.h index 2ecf4114d48..040b433a361 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArgument.h +++ b/Server/mods/deathmatch/logic/lua/CLuaArgument.h @@ -62,7 +62,7 @@ class CLuaArgument CElement* GetElement() const; bool GetAsString(SString& strBuffer); - bool ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables = NULL); + bool ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables = NULL, unsigned int uiDepth = 0); bool WriteToBitStream(NetBitStreamInterface& bitStream, CFastHashMap* pKnownTables = NULL) const; json_object* WriteToJSONObject(bool bSerialize = false, CFastHashMap* pKnownTables = NULL); bool ReadFromJSONObject(json_object* object, std::vector* pKnownTables = NULL); diff --git a/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp b/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp index 0cf0fd73d08..b94e075df54 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp @@ -528,8 +528,11 @@ void CLuaArguments::ValidateTableKeys() } } -bool CLuaArguments::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables) +bool CLuaArguments::ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables, unsigned int uiDepth) { + if (uiDepth > MaxBitStreamTableReadDepth) + return false; + bool bKnownTablesCreated = false; if (!pKnownTables) { diff --git a/Server/mods/deathmatch/logic/lua/CLuaArguments.h b/Server/mods/deathmatch/logic/lua/CLuaArguments.h index 3c550799d26..97ea0bf2b26 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArguments.h +++ b/Server/mods/deathmatch/logic/lua/CLuaArguments.h @@ -44,6 +44,8 @@ class CLuaArguments; class CLuaArguments { public: + static constexpr unsigned int MaxBitStreamTableReadDepth = 64; + CLuaArguments() {} CLuaArguments(const CLuaArguments& Arguments, CFastHashMap* pKnownTables = NULL); @@ -89,7 +91,7 @@ class CLuaArguments void ValidateTableKeys(); void Pop(); - bool ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables = NULL); + bool ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector* pKnownTables = NULL, unsigned int uiDepth = 0); bool ReadFromJSONString(const char* szJSON); bool WriteToBitStream(NetBitStreamInterface& bitStream, CFastHashMap* pKnownTables = NULL) const; bool WriteToJSONString(std::string& strJSON, bool bSerialize = false, int flags = JSON_C_TO_STRING_PLAIN);