Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions Client/mods/deathmatch/logic/lua/CLuaArgument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ bool CLuaArgument::CompareRecursive(const CLuaArgument& Argument, std::set<CLuaA
return true;
}

void CLuaArgument::Read(lua_State* luaVM, int iArgument, CFastHashMap<const void*, CLuaArguments*>* pKnownTables)
bool CLuaArgument::Read(lua_State* luaVM, int iArgument, CFastHashMap<const void*, CLuaArguments*>* pKnownTables, unsigned int uiDepth)
{
// Store debug data for later retrieval
#ifdef MTA_DEBUG
Expand Down Expand Up @@ -250,9 +250,20 @@ void CLuaArgument::Read(lua_State* luaVM, int iArgument, CFastHashMap<const void
}
else
{
if (uiDepth >= CLuaArguments::MaxLuaTableReadDepth)
{
m_iType = LUA_TNIL;
return false;
}

m_pTableData = new CLuaArguments();
m_pTableData->ReadTable(luaVM, iArgument, pKnownTables);
m_bWeakTableRef = false;
if (!m_pTableData->ReadTable(luaVM, iArgument, pKnownTables, uiDepth))
{
DeleteTableData();
m_iType = LUA_TNIL;
return false;
}
}
break;
}
Expand Down Expand Up @@ -306,6 +317,8 @@ void CLuaArgument::Read(lua_State* luaVM, int iArgument, CFastHashMap<const void
}
}
}

return true;
}

void CLuaArgument::ReadBool(bool bBool)
Expand Down
2 changes: 1 addition & 1 deletion Client/mods/deathmatch/logic/lua/CLuaArgument.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class CLuaArgument
bool operator==(const CLuaArgument& Argument);
bool operator!=(const CLuaArgument& Argument);

void Read(lua_State* luaVM, int iArgument, CFastHashMap<const void*, CLuaArguments*>* pKnownTables = NULL);
bool Read(lua_State* luaVM, int iArgument, CFastHashMap<const void*, CLuaArguments*>* pKnownTables = NULL, unsigned int uiDepth = 0);
void ReadBool(bool bBool);
void ReadNumber(double dNumber);
void ReadString(const std::string& string);
Expand Down
61 changes: 52 additions & 9 deletions Client/mods/deathmatch/logic/lua/CLuaArguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ void CLuaArguments::CopyRecursive(const CLuaArguments& Arguments, CFastHashMap<C
delete pKnownTables;
}

void CLuaArguments::ReadArguments(lua_State* luaVM, signed int uiIndexBegin)
bool CLuaArguments::ReadArguments(lua_State* luaVM, signed int uiIndexBegin)
{
// Delete the previous arguments if any
DeleteArguments();
Expand All @@ -85,39 +85,74 @@ void CLuaArguments::ReadArguments(lua_State* luaVM, signed int uiIndexBegin)
while (lua_type(luaVM, uiIndexBegin) != LUA_TNONE)
{
// Create an argument, let it read out the argument and add it to our vector
CLuaArgument* pArgument = new CLuaArgument(luaVM, uiIndexBegin++, &knownTables);
CLuaArgument* pArgument = new CLuaArgument();
if (!pArgument->Read(luaVM, uiIndexBegin++, &knownTables))
{
delete pArgument;
DeleteArguments();
return false;
}
m_Arguments.push_back(pArgument);

knownTables.clear();
}

return true;
}

void CLuaArguments::ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<const void*, CLuaArguments*>* pKnownTables)
bool CLuaArguments::ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<const void*, CLuaArguments*>* pKnownTables, unsigned int uiDepth)
{
const int iStackTop = lua_gettop(luaVM);
if (!LUA_CHECKSTACK(luaVM, 2))
{
DeleteArguments();
return false;
}

bool bKnownTablesCreated = false;
if (!pKnownTables)
{
pKnownTables = new CFastHashMap<const void*, CLuaArguments*>();
bKnownTablesCreated = true;
}

pKnownTables->insert(std::make_pair(lua_topointer(luaVM, iIndexBegin), this));
const void* pTablePointer = lua_topointer(luaVM, iIndexBegin);
pKnownTables->insert(std::make_pair(pTablePointer, this));

// Delete the previous arguments if any
DeleteArguments();

LUA_CHECKSTACK(luaVM, 2);
lua_pushnil(luaVM); /* first key */
if (iIndexBegin < 0)
iIndexBegin--;

while (lua_next(luaVM, iIndexBegin) != 0)
{
/* uses 'key' (at index -2) and 'value' (at index -1) */
CLuaArgument* pArgument = new CLuaArgument(luaVM, -2, pKnownTables);
CLuaArgument* pArgument = new CLuaArgument();
if (!pArgument->Read(luaVM, -2, pKnownTables, uiDepth + 1))
{
delete pArgument;
lua_settop(luaVM, iStackTop);
DeleteArguments();
pKnownTables->erase(pTablePointer);
if (bKnownTablesCreated)
delete pKnownTables;
return false;
}
m_Arguments.push_back(pArgument); // push the key first

pArgument = new CLuaArgument(luaVM, -1, pKnownTables);
pArgument = new CLuaArgument();
if (!pArgument->Read(luaVM, -1, pKnownTables, uiDepth + 1))
{
delete pArgument;
lua_settop(luaVM, iStackTop);
DeleteArguments();
pKnownTables->erase(pTablePointer);
if (bKnownTablesCreated)
delete pKnownTables;
return false;
}
m_Arguments.push_back(pArgument); // then the value

/* removes 'value'; keeps 'key' for next iteration */
Expand All @@ -126,12 +161,20 @@ void CLuaArguments::ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<co

if (bKnownTablesCreated)
delete pKnownTables;

return true;
}

void CLuaArguments::ReadArgument(lua_State* luaVM, int iIndex)
bool CLuaArguments::ReadArgument(lua_State* luaVM, int iIndex)
{
CLuaArgument* pArgument = new CLuaArgument(luaVM, iIndex);
CLuaArgument* pArgument = new CLuaArgument();
if (!pArgument->Read(luaVM, iIndex))
{
delete pArgument;
return false;
}
m_Arguments.push_back(pArgument);
return true;
}

void CLuaArguments::PushArguments(lua_State* luaVM) const
Expand Down
14 changes: 9 additions & 5 deletions Client/mods/deathmatch/logic/lua/CLuaArguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ extern "C"
#include <vector>
#include "CLuaFunctionRef.h"

inline void LUA_CHECKSTACK(lua_State* L, int size)
inline bool LUA_CHECKSTACK(lua_State* L, int size)
{
if (lua_getstackgap(L) < size + 5)
lua_checkstack(L, (size + 2) * 3 + 4);
return lua_checkstack(L, (size + 2) * 3 + 4) != 0;

return true;
}

class CLuaArguments;
Expand All @@ -33,6 +35,8 @@ class CLuaArguments
{
public:
static constexpr unsigned int MaxBitStreamTableReadDepth = 64;
// Bound recursive copies before they can exhaust the Lua or native stack.
static constexpr unsigned int MaxLuaTableReadDepth = 64;

CLuaArguments() {}
CLuaArguments(const CLuaArguments& Arguments, CFastHashMap<CLuaArguments*, CLuaArguments*>* pKnownTables = NULL);
Expand All @@ -44,14 +48,14 @@ class CLuaArguments
const CLuaArguments& operator=(const CLuaArguments& Arguments);
CLuaArgument* operator[](const unsigned int uiPosition) const;

void ReadArgument(lua_State* luaVM, signed int uiIndex);
void ReadArguments(lua_State* luaVM, signed int uiIndexBegin = 1);
bool ReadArgument(lua_State* luaVM, signed int uiIndex);
bool ReadArguments(lua_State* luaVM, signed int uiIndexBegin = 1);
void PushArguments(lua_State* luaVM) const;
void PushArguments(const CLuaArguments& Arguments);
bool Call(class CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction, CLuaArguments* returnValues = NULL) const;
bool CallGlobal(class CLuaMain* pLuaMain, const char* szFunction, CLuaArguments* returnValues = NULL) const;

void ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<const void*, CLuaArguments*>* pKnownTables = NULL);
bool ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<const void*, CLuaArguments*>* pKnownTables = NULL, unsigned int uiDepth = 0);
void PushAsTable(lua_State* luaVM, CFastHashMap<CLuaArguments*, int>* pKnownTables = nullptr) const;

CLuaArgument* PushNil();
Expand Down
17 changes: 15 additions & 2 deletions Server/mods/deathmatch/logic/lua/CLuaArgument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bool CLuaArgument::operator!=(const CLuaArgument& Argument) const
return !IsEqualTo(Argument, &knownTables);
}

void CLuaArgument::Read(lua_State* luaVM, int iArgument, CFastHashMap<const void*, CLuaArguments*>* pKnownTables)
bool CLuaArgument::Read(lua_State* luaVM, int iArgument, CFastHashMap<const void*, CLuaArguments*>* pKnownTables, unsigned int uiDepth)
{
#ifdef MTA_DEBUG
// Store debug data for later retrieval
Expand Down Expand Up @@ -181,9 +181,20 @@ void CLuaArgument::Read(lua_State* luaVM, int iArgument, CFastHashMap<const void
}
else
{
if (uiDepth >= CLuaArguments::MaxLuaTableReadDepth)
{
m_iType = LUA_TNIL;
return false;
}

m_pTableData = new CLuaArguments();
m_pTableData->ReadTable(luaVM, iArgument, pKnownTables);
m_bWeakTableRef = false;
if (!m_pTableData->ReadTable(luaVM, iArgument, pKnownTables, uiDepth))
{
DeleteTableData();
m_iType = LUA_TNIL;
return false;
}
}
break;
}
Expand Down Expand Up @@ -237,6 +248,8 @@ void CLuaArgument::Read(lua_State* luaVM, int iArgument, CFastHashMap<const void
}
}
}

return true;
}

void CLuaArgument::Push(lua_State* luaVM, CFastHashMap<CLuaArguments*, int>* pKnownTables) const
Expand Down
2 changes: 1 addition & 1 deletion Server/mods/deathmatch/logic/lua/CLuaArgument.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class CLuaArgument
bool operator==(const CLuaArgument& Argument) const;
bool operator!=(const CLuaArgument& Argument) const;

void Read(lua_State* luaVM, int iArgument, CFastHashMap<const void*, CLuaArguments*>* pKnownTables = NULL);
bool Read(lua_State* luaVM, int iArgument, CFastHashMap<const void*, CLuaArguments*>* pKnownTables = NULL, unsigned int uiDepth = 0);
void Push(lua_State* luaVM, CFastHashMap<CLuaArguments*, int>* pKnownTables = NULL) const;

void ReadBool(bool bBool);
Expand Down
61 changes: 52 additions & 9 deletions Server/mods/deathmatch/logic/lua/CLuaArguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void CLuaArguments::CopyRecursive(const CLuaArguments& Arguments, CFastHashMap<C
delete pKnownTables;
}

void CLuaArguments::ReadArguments(lua_State* luaVM, signed int uiIndexBegin)
bool CLuaArguments::ReadArguments(lua_State* luaVM, signed int uiIndexBegin)
{
// Delete the previous arguments if any
DeleteArguments();
Expand All @@ -90,39 +90,74 @@ void CLuaArguments::ReadArguments(lua_State* luaVM, signed int uiIndexBegin)
while (lua_type(luaVM, uiIndexBegin) != LUA_TNONE)
{
// Create an argument, let it read out the argument and add it to our vector
CLuaArgument* pArgument = new CLuaArgument(luaVM, uiIndexBegin++, &knownTables);
CLuaArgument* pArgument = new CLuaArgument();
if (!pArgument->Read(luaVM, uiIndexBegin++, &knownTables))
{
delete pArgument;
DeleteArguments();
return false;
}
m_Arguments.push_back(pArgument);

knownTables.clear();
}

return true;
}

void CLuaArguments::ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<const void*, CLuaArguments*>* pKnownTables)
bool CLuaArguments::ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<const void*, CLuaArguments*>* pKnownTables, unsigned int uiDepth)
{
const int iStackTop = lua_gettop(luaVM);
if (!LUA_CHECKSTACK(luaVM, 2))
{
DeleteArguments();
return false;
}

bool bKnownTablesCreated = false;
if (!pKnownTables)
{
pKnownTables = new CFastHashMap<const void*, CLuaArguments*>();
bKnownTablesCreated = true;
}

pKnownTables->insert(std::make_pair(lua_topointer(luaVM, iIndexBegin), this));
const void* pTablePointer = lua_topointer(luaVM, iIndexBegin);
pKnownTables->insert(std::make_pair(pTablePointer, this));

// Delete the previous arguments if any
DeleteArguments();

LUA_CHECKSTACK(luaVM, 2);
lua_pushnil(luaVM); /* first key */
if (iIndexBegin < 0)
iIndexBegin--;

while (lua_next(luaVM, iIndexBegin) != 0)
{
/* uses 'key' (at index -2) and 'value' (at index -1) */
CLuaArgument* pArgument = new CLuaArgument(luaVM, -2, pKnownTables);
CLuaArgument* pArgument = new CLuaArgument();
if (!pArgument->Read(luaVM, -2, pKnownTables, uiDepth + 1))
{
delete pArgument;
lua_settop(luaVM, iStackTop);
DeleteArguments();
pKnownTables->erase(pTablePointer);
if (bKnownTablesCreated)
delete pKnownTables;
return false;
}
m_Arguments.push_back(pArgument); // push the key first

pArgument = new CLuaArgument(luaVM, -1, pKnownTables);
pArgument = new CLuaArgument();
if (!pArgument->Read(luaVM, -1, pKnownTables, uiDepth + 1))
{
delete pArgument;
lua_settop(luaVM, iStackTop);
DeleteArguments();
pKnownTables->erase(pTablePointer);
if (bKnownTablesCreated)
delete pKnownTables;
return false;
}
m_Arguments.push_back(pArgument); // then the value

/* removes 'value'; keeps 'key' for next iteration */
Expand All @@ -131,12 +166,20 @@ void CLuaArguments::ReadTable(lua_State* luaVM, int iIndexBegin, CFastHashMap<co

if (bKnownTablesCreated)
delete pKnownTables;

return true;
}

void CLuaArguments::ReadArgument(lua_State* luaVM, int iIndex)
bool CLuaArguments::ReadArgument(lua_State* luaVM, int iIndex)
{
CLuaArgument* pArgument = new CLuaArgument(luaVM, iIndex);
CLuaArgument* pArgument = new CLuaArgument();
if (!pArgument->Read(luaVM, iIndex))
{
delete pArgument;
return false;
}
m_Arguments.push_back(pArgument);
return true;
}

void CLuaArguments::PushArguments(lua_State* luaVM) const
Expand Down
Loading