From 78fb7896313f2074fa814309901e30d4a4f218e2 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Nov 2014 15:16:52 +0100 Subject: Fixed a security problem with signs. --- src/Bindings/ManualBindings.cpp | 2 +- src/ClientHandle.cpp | 9 +++++++-- src/ClientHandle.h | 6 ++++++ src/World.cpp | 12 +++--------- src/World.h | 5 +---- 5 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 3d10e2abb..e259e2e91 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1038,7 +1038,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) } #endif { - bool res = self->UpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player); + bool res = self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player); tolua_pushboolean(tolua_S, res ? 1 : 0); } } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 94bace43a..9bf4875e2 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -93,6 +93,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_UniqueID(0), m_HasSentPlayerChunk(false), m_Locale("en_GB"), + m_LastPlacedBlock(0, -1, 0), m_ProtocolVersion(0) { m_Protocol = new cProtocolRecognizer(this); @@ -1500,6 +1501,8 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e { m_Player->GetInventory().RemoveOneEquippedItem(); } + m_LastPlacedBlock.Set(a_BlockX, a_BlockY, a_BlockZ); + cChunkInterface ChunkInterface(World->GetChunkMap()); NewBlock->OnPlacedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); @@ -1677,8 +1680,10 @@ void cClientHandle::HandleUpdateSign( const AString & a_Line3, const AString & a_Line4 ) { - cWorld * World = m_Player->GetWorld(); - World->UpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, m_Player); + if (m_LastPlacedBlock.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + m_Player->GetWorld()->SetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, m_Player); + } } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 082ed2fcc..a0dd4ff7a 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -125,6 +125,9 @@ public: inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); } + /** Returns the positions from the last block that the player placed. */ + const Vector3i & GetLastPlacedBlock(void) const { return m_LastPlacedBlock; } // tolua_export + /** Called while the client is being ticked from the world via its cPlayer object */ void Tick(float a_Dt); @@ -432,6 +435,9 @@ private: /** Client Settings */ AString m_Locale; + + /** The positions from the last block that the player placed. It's needed to verify the sign text change. */ + Vector3i m_LastPlacedBlock; /** The plugin channels that the client has registered. */ cChannels m_PluginChannels; diff --git a/src/World.cpp b/src/World.cpp index 68855e617..3178d41a6 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2926,25 +2926,19 @@ bool cWorld::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AStrin AString Line2(a_Line2); AString Line3(a_Line3); AString Line4(a_Line4); + if (cRoot::Get()->GetPluginManager()->CallHookUpdatingSign(*this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player)) { return false; } + if (m_ChunkMap->SetSignLines(a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4)) { cRoot::Get()->GetPluginManager()->CallHookUpdatedSign(*this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player); return true; } - return false; -} - - - - -bool cWorld::UpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) -{ - return SetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player); + return false; } diff --git a/src/World.h b/src/World.h index 1a9f60a5c..b209f71a7 100644 --- a/src/World.h +++ b/src/World.h @@ -377,11 +377,8 @@ public: /** Marks the chunk as failed-to-load: */ void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ); - /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. Same as UpdateSign() */ + /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. */ bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp - - /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. Same as SetSignLines() */ - bool UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp /** Sets the command block command. Returns true if command changed. */ bool SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command); // tolua_export -- cgit v1.2.3 From 277151582fbb0652dcf4e15f67d41f90e08bdeeb Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Nov 2014 22:36:31 +0100 Subject: Use LastPlacedSign instead of LastPlacedBlock. --- src/ClientHandle.cpp | 7 ++++--- src/ClientHandle.h | 7 ++----- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 9bf4875e2..83fb283b6 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -93,7 +93,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_UniqueID(0), m_HasSentPlayerChunk(false), m_Locale("en_GB"), - m_LastPlacedBlock(0, -1, 0), + m_LastPlacedSign(0, -1, 0), m_ProtocolVersion(0) { m_Protocol = new cProtocolRecognizer(this); @@ -1501,7 +1501,6 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e { m_Player->GetInventory().RemoveOneEquippedItem(); } - m_LastPlacedBlock.Set(a_BlockX, a_BlockY, a_BlockZ); cChunkInterface ChunkInterface(World->GetChunkMap()); NewBlock->OnPlacedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); @@ -1680,8 +1679,9 @@ void cClientHandle::HandleUpdateSign( const AString & a_Line3, const AString & a_Line4 ) { - if (m_LastPlacedBlock.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + if (m_LastPlacedSign.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { + m_LastPlacedSign.Set(0, -1, 0); m_Player->GetWorld()->SetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, m_Player); } } @@ -2262,6 +2262,7 @@ void cClientHandle::SendDisconnect(const AString & a_Reason) void cClientHandle::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) { + m_LastPlacedSign.Set(a_BlockX, a_BlockY, a_BlockZ); m_Protocol->SendEditSign(a_BlockX, a_BlockY, a_BlockZ); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index a0dd4ff7a..d8cc3c643 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -125,9 +125,6 @@ public: inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); } - /** Returns the positions from the last block that the player placed. */ - const Vector3i & GetLastPlacedBlock(void) const { return m_LastPlacedBlock; } // tolua_export - /** Called while the client is being ticked from the world via its cPlayer object */ void Tick(float a_Dt); @@ -436,8 +433,8 @@ private: /** Client Settings */ AString m_Locale; - /** The positions from the last block that the player placed. It's needed to verify the sign text change. */ - Vector3i m_LastPlacedBlock; + /** The positions from the last sign that the player placed. It's needed to verify the sign text change. */ + Vector3i m_LastPlacedSign; /** The plugin channels that the client has registered. */ cChannels m_PluginChannels; -- cgit v1.2.3 From 0e491273c1e942b73adc78db03a71d76d529b009 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 17 Nov 2014 14:57:24 +0100 Subject: Added UpdateSign() method to DeprecatedBindings.cpp --- src/Bindings/DeprecatedBindings.cpp | 86 +++++++++++++++++++++++++++++++++++++ src/Bindings/ManualBindings.cpp | 5 +-- 2 files changed, 88 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index ded7a0142..442d9add5 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -7,6 +7,33 @@ #include "../BlockInfo.h" +#include "../World.h" +#include "../Entities/Player.h" + + + + + +static void lua_do_warning(lua_State* L, const char * a_pFormat, ...) +{ + // Retrieve current function name + lua_Debug entry; + VERIFY(lua_getstack(L, 0, &entry)); + VERIFY(lua_getinfo(L, "n", &entry)); + + // Insert function name into error msg + AString msg(a_pFormat); + ReplaceString(msg, "#funcname#", entry.name?entry.name:"?"); + + // Copied from luaL_error and modified + va_list argp; + va_start(argp, a_pFormat); + luaL_where(L, 1); + lua_pushvfstring(L, msg.c_str(), argp); + va_end(argp); + lua_concat(L, 2); + lua_error(L); +} @@ -222,6 +249,61 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) +/** function: cWorld:SetSignLines */ +static int tolua_cWorld_SetSignLines(lua_State * tolua_S) +{ + #ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype (tolua_S, 1, "cWorld", 0, &tolua_err) || + !tolua_isnumber (tolua_S, 2, 0, &tolua_err) || + !tolua_isnumber (tolua_S, 3, 0, &tolua_err) || + !tolua_isnumber (tolua_S, 4, 0, &tolua_err) || + !tolua_iscppstring(tolua_S, 5, 0, &tolua_err) || + !tolua_iscppstring(tolua_S, 6, 0, &tolua_err) || + !tolua_iscppstring(tolua_S, 7, 0, &tolua_err) || + !tolua_iscppstring(tolua_S, 8, 0, &tolua_err) || + !tolua_isusertype (tolua_S, 9, "cPlayer", 1, &tolua_err) || + !tolua_isnoobj (tolua_S, 10, &tolua_err) + ) + goto tolua_lerror; + else + #endif + { + cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr); + int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); + int BlockY = (int) tolua_tonumber (tolua_S, 3, 0); + int BlockZ = (int) tolua_tonumber (tolua_S, 4, 0); + const AString Line1 = tolua_tocppstring(tolua_S, 5, 0); + const AString Line2 = tolua_tocppstring(tolua_S, 6, 0); + const AString Line3 = tolua_tocppstring(tolua_S, 7, 0); + const AString Line4 = tolua_tocppstring(tolua_S, 8, 0); + cPlayer * Player = (cPlayer *)tolua_tousertype (tolua_S, 9, nullptr); + #ifndef TOLUA_RELEASE + if (self == nullptr) + { + tolua_error(tolua_S, "invalid 'self' in function 'UpdateSign'", nullptr); + } + #endif + { + bool res = self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player); + tolua_pushboolean(tolua_S, res ? 1 : 0); + } + } + lua_do_warning(tolua_S, "Warning in function call '#funcname#': UpdateSign() is deprecated. Please use SetSignLines()"); + return 1; + + #ifndef TOLUA_RELEASE +tolua_lerror: + tolua_error(tolua_S, "#ferror in function 'UpdateSign'.", &tolua_err); + return 0; + #endif +} + + + + + void DeprecatedBindings::Bind(lua_State * tolua_S) { tolua_beginmodule(tolua_S, nullptr); @@ -235,6 +317,10 @@ void DeprecatedBindings::Bind(lua_State * tolua_S) tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, nullptr); tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, nullptr); + tolua_beginmodule(tolua_S, "cWorld"); + tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); + tolua_endmodule(tolua_S); + tolua_endmodule(tolua_S); } diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index e259e2e91..750f7c65a 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1034,7 +1034,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) #ifndef TOLUA_RELEASE if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'SetSignLines' / 'UpdateSign'", nullptr); + tolua_error(tolua_S, "invalid 'self' in function 'SetSignLines'", nullptr); } #endif { @@ -1046,7 +1046,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S, "#ferror in function 'SetSignLines' / 'UpdateSign'.", &tolua_err); + tolua_error(tolua_S, "#ferror in function 'SetSignLines'.", &tolua_err); return 0; #endif } @@ -3405,7 +3405,6 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "ScheduleTask", tolua_cWorld_ScheduleTask); tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines); tolua_function(tolua_S, "TryGetHeight", tolua_cWorld_TryGetHeight); - tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cMapManager"); -- cgit v1.2.3 From d7efece5f2efcbaa93c36f26c325fea66f3700f1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 17 Nov 2014 18:01:56 +0100 Subject: Use cLuaState's stack trace. --- src/Bindings/DeprecatedBindings.cpp | 75 +++++++++++++------------------------ 1 file changed, 27 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 442d9add5..345ab2a07 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -9,31 +9,7 @@ #include "../BlockInfo.h" #include "../World.h" #include "../Entities/Player.h" - - - - - -static void lua_do_warning(lua_State* L, const char * a_pFormat, ...) -{ - // Retrieve current function name - lua_Debug entry; - VERIFY(lua_getstack(L, 0, &entry)); - VERIFY(lua_getinfo(L, "n", &entry)); - - // Insert function name into error msg - AString msg(a_pFormat); - ReplaceString(msg, "#funcname#", entry.name?entry.name:"?"); - - // Copied from luaL_error and modified - va_list argp; - va_start(argp, a_pFormat); - luaL_where(L, 1); - lua_pushvfstring(L, msg.c_str(), argp); - va_end(argp); - lua_concat(L, 2); - lua_error(L); -} +#include "LuaState.h" @@ -252,50 +228,53 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) /** function: cWorld:SetSignLines */ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) { + cLuaState LuaState(tolua_S); + #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype (tolua_S, 1, "cWorld", 0, &tolua_err) || - !tolua_isnumber (tolua_S, 2, 0, &tolua_err) || - !tolua_isnumber (tolua_S, 3, 0, &tolua_err) || - !tolua_isnumber (tolua_S, 4, 0, &tolua_err) || - !tolua_iscppstring(tolua_S, 5, 0, &tolua_err) || - !tolua_iscppstring(tolua_S, 6, 0, &tolua_err) || - !tolua_iscppstring(tolua_S, 7, 0, &tolua_err) || - !tolua_iscppstring(tolua_S, 8, 0, &tolua_err) || - !tolua_isusertype (tolua_S, 9, "cPlayer", 1, &tolua_err) || - !tolua_isnoobj (tolua_S, 10, &tolua_err) + !tolua_isusertype (LuaState, 1, "cWorld", 0, &tolua_err) || + !tolua_isnumber (LuaState, 2, 0, &tolua_err) || + !tolua_isnumber (LuaState, 3, 0, &tolua_err) || + !tolua_isnumber (LuaState, 4, 0, &tolua_err) || + !tolua_iscppstring(LuaState, 5, 0, &tolua_err) || + !tolua_iscppstring(LuaState, 6, 0, &tolua_err) || + !tolua_iscppstring(LuaState, 7, 0, &tolua_err) || + !tolua_iscppstring(LuaState, 8, 0, &tolua_err) || + !tolua_isusertype (LuaState, 9, "cPlayer", 1, &tolua_err) || + !tolua_isnoobj (LuaState, 10, &tolua_err) ) goto tolua_lerror; else #endif { - cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, nullptr); - int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); - int BlockY = (int) tolua_tonumber (tolua_S, 3, 0); - int BlockZ = (int) tolua_tonumber (tolua_S, 4, 0); - const AString Line1 = tolua_tocppstring(tolua_S, 5, 0); - const AString Line2 = tolua_tocppstring(tolua_S, 6, 0); - const AString Line3 = tolua_tocppstring(tolua_S, 7, 0); - const AString Line4 = tolua_tocppstring(tolua_S, 8, 0); - cPlayer * Player = (cPlayer *)tolua_tousertype (tolua_S, 9, nullptr); + cWorld * self = (cWorld *) tolua_tousertype (LuaState, 1, nullptr); + int BlockX = (int) tolua_tonumber (LuaState, 2, 0); + int BlockY = (int) tolua_tonumber (LuaState, 3, 0); + int BlockZ = (int) tolua_tonumber (LuaState, 4, 0); + const AString Line1 = tolua_tocppstring(LuaState, 5, 0); + const AString Line2 = tolua_tocppstring(LuaState, 6, 0); + const AString Line3 = tolua_tocppstring(LuaState, 7, 0); + const AString Line4 = tolua_tocppstring(LuaState, 8, 0); + cPlayer * Player = (cPlayer *)tolua_tousertype (LuaState, 9, nullptr); #ifndef TOLUA_RELEASE if (self == nullptr) { - tolua_error(tolua_S, "invalid 'self' in function 'UpdateSign'", nullptr); + tolua_error(LuaState, "invalid 'self' in function 'UpdateSign'", nullptr); } #endif { bool res = self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player); - tolua_pushboolean(tolua_S, res ? 1 : 0); + tolua_pushboolean(LuaState, res ? 1 : 0); } } - lua_do_warning(tolua_S, "Warning in function call '#funcname#': UpdateSign() is deprecated. Please use SetSignLines()"); + LOGWARNING("Warning in function call 'UpdateSign': UpdateSign() is deprecated. Please use SetSignLines()"); + LuaState.LogStackTrace(0); return 1; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S, "#ferror in function 'UpdateSign'.", &tolua_err); + tolua_error(LuaState, "#ferror in function 'UpdateSign'.", &tolua_err); return 0; #endif } -- cgit v1.2.3