All natives that use a recipient filter now actually validate the clients passed to them.
All natives that use a recipient filter now actually validate the clients passed to them.
This includes StartMessage(), StartMessageEx() from Core as well as EmitSound(), EmitSentence(), and TE_Send() from SDKTools
(Warning: This may potentially cause a minor compatibility problem with plugins that don't check client validity before passing to these natives)
1.1 --- a/core/sm_stringutil.cpp Mon Jun 09 22:17:09 2008 +0000
1.2 +++ b/core/sm_stringutil.cpp Wed Jun 11 08:07:17 2008 +0000
1.3 @@ -1385,7 +1385,7 @@
1.4 * NOTE: Do not edit this for the love of god unless you have
1.5 * read the test cases and understand the code behind each one.
1.6 * While I don't guarantee there aren't mistakes, I do guarantee
1.7 - * that plugins will end up relying on tiny idiosyncracies of this
1.8 + * that plugins will end up relying on tiny idiosyncrasies of this
1.9 * function, just like they did with AMX Mod X.
1.10 *
1.11 * There are explicitly more cases than the AMX Mod X version because
2.1 --- a/core/smn_usermsgs.cpp Mon Jun 09 22:17:09 2008 +0000
2.2 +++ b/core/smn_usermsgs.cpp Wed Jun 11 08:07:17 2008 +0000
2.3 @@ -32,6 +32,7 @@
2.4 #include "HandleSys.h"
2.5 #include "PluginSys.h"
2.6 #include "UserMessages.h"
2.7 +#include "PlayerManager.h"
2.8 #include "smn_usermsgs.h"
2.9
2.10 HandleType_t g_WrBitBufType;
2.11 @@ -349,8 +350,11 @@
2.12 {
2.13 char *msgname;
2.14 cell_t *cl_array;
2.15 + unsigned int numClients;
2.16 int msgid;
2.17 bf_write *pBitBuf;
2.18 + int client;
2.19 + CPlayer *pPlayer = NULL;
2.20
2.21 if (g_IsMsgInExec)
2.22 {
2.23 @@ -366,7 +370,23 @@
2.24
2.25 pCtx->LocalToPhysAddr(params[2], &cl_array);
2.26
2.27 - pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, params[3], params[4]);
2.28 + numClients = params[3];
2.29 +
2.30 + /* Client validation */
2.31 + for (unsigned int i = 0; i < numClients; i++)
2.32 + {
2.33 + client = cl_array[i];
2.34 + pPlayer = g_Players.GetPlayerByIndex(client);
2.35 +
2.36 + if (!pPlayer)
2.37 + {
2.38 + return pCtx->ThrowNativeError("Client index %d is invalid", client);
2.39 + } else if (!pPlayer->IsConnected()) {
2.40 + return pCtx->ThrowNativeError("Client %d is not connected", client);
2.41 + }
2.42 + }
2.43 +
2.44 + pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, numClients, params[4]);
2.45 if (!pBitBuf)
2.46 {
2.47 return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
2.48 @@ -381,7 +401,10 @@
2.49 static cell_t smn_StartMessageEx(IPluginContext *pCtx, const cell_t *params)
2.50 {
2.51 cell_t *cl_array;
2.52 + unsigned int numClients;
2.53 bf_write *pBitBuf;
2.54 + int client;
2.55 + CPlayer *pPlayer = NULL;
2.56 int msgid = params[1];
2.57
2.58 if (g_IsMsgInExec)
2.59 @@ -396,7 +419,23 @@
2.60
2.61 pCtx->LocalToPhysAddr(params[2], &cl_array);
2.62
2.63 - pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, params[3], params[4]);
2.64 + numClients = params[3];
2.65 +
2.66 + /* Client validation */
2.67 + for (unsigned int i = 0; i < numClients; i++)
2.68 + {
2.69 + client = cl_array[i];
2.70 + pPlayer = g_Players.GetPlayerByIndex(client);
2.71 +
2.72 + if (!pPlayer)
2.73 + {
2.74 + return pCtx->ThrowNativeError("Client index %d is invalid", client);
2.75 + } else if (!pPlayer->IsConnected()) {
2.76 + return pCtx->ThrowNativeError("Client %d is not connected", client);
2.77 + }
2.78 + }
2.79 +
2.80 + pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, numClients, params[4]);
2.81 if (!pBitBuf)
2.82 {
2.83 return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
3.1 --- a/extensions/sdktools/tenatives.cpp Mon Jun 09 22:17:09 2008 +0000
3.2 +++ b/extensions/sdktools/tenatives.cpp Wed Jun 11 08:07:17 2008 +0000
3.3 @@ -445,10 +445,29 @@
3.4 }
3.5
3.6 cell_t *cl_array;
3.7 + unsigned int numClients;
3.8 + int client;
3.9 + IGamePlayer *pPlayer = NULL;
3.10 +
3.11 pContext->LocalToPhysAddr(params[1], &cl_array);
3.12 + numClients = params[2];
3.13 +
3.14 + /* Client validation */
3.15 + for (unsigned int i = 0; i < numClients; i++)
3.16 + {
3.17 + client = cl_array[i];
3.18 + pPlayer = playerhelpers->GetGamePlayer(client);
3.19 +
3.20 + if (!pPlayer)
3.21 + {
3.22 + return pContext->ThrowNativeError("Client index %d is invalid", client);
3.23 + } else if (!pPlayer->IsInGame()) {
3.24 + return pContext->ThrowNativeError("Client %d is not connected", client);
3.25 + }
3.26 + }
3.27
3.28 g_TERecFilter.Reset();
3.29 - g_TERecFilter.Initialize(cl_array, params[2]);
3.30 + g_TERecFilter.Initialize(cl_array, numClients);
3.31
3.32 g_CurrentTE->Send(g_TERecFilter, sp_ctof(params[3]));
3.33 g_CurrentTE = NULL;
4.1 --- a/extensions/sdktools/vsound.cpp Mon Jun 09 22:17:09 2008 +0000
4.2 +++ b/extensions/sdktools/vsound.cpp Wed Jun 11 08:07:17 2008 +0000
4.3 @@ -449,11 +449,30 @@
4.4
4.5 static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
4.6 {
4.7 - cell_t *addr, *pl_addr;
4.8 -
4.9 + cell_t *addr, *cl_array;
4.10 CellRecipientFilter crf;
4.11 - pContext->LocalToPhysAddr(params[1], &pl_addr);
4.12 - crf.Initialize(pl_addr, params[2]);
4.13 + unsigned int numClients;
4.14 + int client;
4.15 + IGamePlayer *pPlayer = NULL;
4.16 +
4.17 + pContext->LocalToPhysAddr(params[1], &cl_array);
4.18 + numClients = params[2];
4.19 +
4.20 + /* Client validation */
4.21 + for (unsigned int i = 0; i < numClients; i++)
4.22 + {
4.23 + client = cl_array[i];
4.24 + pPlayer = playerhelpers->GetGamePlayer(client);
4.25 +
4.26 + if (!pPlayer)
4.27 + {
4.28 + return pContext->ThrowNativeError("Client index %d is invalid", client);
4.29 + } else if (!pPlayer->IsInGame()) {
4.30 + return pContext->ThrowNativeError("Client %d is not connected", client);
4.31 + }
4.32 + }
4.33 +
4.34 + crf.Initialize(cl_array, numClients);
4.35
4.36 char *sample;
4.37 pContext->LocalToString(params[3], &sample);
4.38 @@ -512,10 +531,10 @@
4.39
4.40 if (entity == -2 && engine->IsDedicatedServer())
4.41 {
4.42 - for (cell_t i=0; i<params[2]; i++)
4.43 + for (unsigned int i = 0; i < numClients; i++)
4.44 {
4.45 cell_t player[1];
4.46 - player[0] = pl_addr[i];
4.47 + player[0] = cl_array[i];
4.48 crf.Reset();
4.49 crf.Initialize(player, 1);
4.50 if (g_InSoundHook)
4.51 @@ -604,10 +623,29 @@
4.52 static cell_t EmitSentence(IPluginContext *pContext, const cell_t *params)
4.53 {
4.54 cell_t *addr;
4.55 + CellRecipientFilter crf;
4.56 + unsigned int numClients;
4.57 + int client;
4.58 + IGamePlayer *pPlayer = NULL;
4.59
4.60 - CellRecipientFilter crf;
4.61 pContext->LocalToPhysAddr(params[1], &addr);
4.62 - crf.Initialize(addr, params[2]);
4.63 + numClients = params[2];
4.64 +
4.65 + /* Client validation */
4.66 + for (unsigned int i = 0; i < numClients; i++)
4.67 + {
4.68 + client = addr[i];
4.69 + pPlayer = playerhelpers->GetGamePlayer(client);
4.70 +
4.71 + if (!pPlayer)
4.72 + {
4.73 + return pContext->ThrowNativeError("Client index %d is invalid", client);
4.74 + } else if (!pPlayer->IsInGame()) {
4.75 + return pContext->ThrowNativeError("Client %d is not connected", client);
4.76 + }
4.77 + }
4.78 +
4.79 + crf.Initialize(addr, numClients);
4.80
4.81 int sentence = params[3];
4.82 int entity = params[4];
5.1 --- a/plugins/include/usermessages.inc Mon Jun 09 22:17:09 2008 +0000
5.2 +++ b/plugins/include/usermessages.inc Wed Jun 11 08:07:17 2008 +0000
5.3 @@ -83,7 +83,8 @@
5.4 * @param flags Optional flags to set.
5.5 * @return A handle to a bf_write bit packing structure, or
5.6 * INVALID_HANDLE on failure.
5.7 - * @error Invalid message name or unable to start a message.
5.8 + * @error Invalid message name, unable to start a message, invalid client,
5.9 + * or client not connected.
5.10 */
5.11 native Handle:StartMessage(String:msgname[], clients[], numClients, flags=0);
5.12
5.13 @@ -98,7 +99,8 @@
5.14 * @param flags Optional flags to set.
5.15 * @return A handle to a bf_write bit packing structure, or
5.16 * INVALID_HANDLE on failure.
5.17 - * @error Invalid message name or unable to start a message.
5.18 + * @error Invalid message name, unable to start a message, invalid client,
5.19 + * or client not connected.
5.20 */
5.21 native Handle:StartMessageEx(UserMsg:msg, clients[], numClients, flags=0);
5.22