about summary refs log tree commit diff
diff options
context:
space:
mode:
authoroy <Tom_Adams@web.de>2010-10-25 18:30:35 +0200
committeroy <Tom_Adams@web.de>2010-10-25 18:30:35 +0200
commit8ca6a28088f805d8f7599beb0fab0e8dc8bd7d9c (patch)
tree363a5e8f59eb88529434e58882278d8e6e03fd6b
parent12b8b629edb3acfc92851aa301f15bc9827d812d (diff)
downloadzcatch-8ca6a28088f805d8f7599beb0fab0e8dc8bd7d9c.tar.gz
zcatch-8ca6a28088f805d8f7599beb0fab0e8dc8bd7d9c.zip
parse line on addvote and skip invalid ones
-rw-r--r--src/engine/console.h1
-rw-r--r--src/engine/shared/console.cpp51
-rw-r--r--src/engine/shared/console.h1
-rw-r--r--src/game/server/gamecontext.cpp9
4 files changed, 61 insertions, 1 deletions
diff --git a/src/engine/console.h b/src/engine/console.h
index 80a995c3..8a01a312 100644
--- a/src/engine/console.h
+++ b/src/engine/console.h
@@ -53,6 +53,7 @@ public:
 	virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser) = 0;
 	virtual void StoreCommands(bool Store) = 0;
 	
+	virtual bool LineIsValid(const char *pStr) = 0;
 	virtual void ExecuteLine(const char *Sptr) = 0;
 	virtual void ExecuteLineStroked(int Stroke, const char *pStr) = 0;
 	virtual void ExecuteFile(const char *pFilename) = 0;
diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp
index ff9b0cd8..87554678 100644
--- a/src/engine/shared/console.cpp
+++ b/src/engine/shared/console.cpp
@@ -160,7 +160,7 @@ void CConsole::RegisterPrintCallback(FPrintCallback pfnPrintCallback, void *pUse
 void CConsole::Print(int Level, const char *pFrom, const char *pStr)
 {
 	dbg_msg(pFrom ,"%s", pStr);
-	if (Level <= g_Config.m_ConsoleOutputLevel && m_pfnPrintCallback)
+	if(Level <= g_Config.m_ConsoleOutputLevel && m_pfnPrintCallback)
 	{
 		char aBuf[1024];
 		str_format(aBuf, sizeof(aBuf), "[%s]: %s", pFrom, pStr);
@@ -168,6 +168,55 @@ void CConsole::Print(int Level, const char *pFrom, const char *pStr)
 	}
 }
 
+bool CConsole::LineIsValid(const char *pStr)
+{
+	if(!pStr || *pStr == 0)
+		return false;
+	
+	do
+	{
+		CResult Result;
+		const char *pEnd = pStr;
+		const char *pNextPart = 0;
+		int InString = 0;
+		
+		while(*pEnd)
+		{
+			if(*pEnd == '"')
+				InString ^= 1;
+			else if(*pEnd == '\\') // escape sequences
+			{
+				if(pEnd[1] == '"')
+					pEnd++;
+			}
+			else if(!InString)
+			{
+				if(*pEnd == ';')  // command separator
+				{
+					pNextPart = pEnd+1;
+					break;
+				}
+				else if(*pEnd == '#')  // comment, no need to do anything more
+					break;
+			}
+			
+			pEnd++;
+		}
+		
+		if(ParseStart(&Result, pStr, (pEnd-pStr) + 1) != 0)
+			return false;
+
+		CCommand *pCommand = FindCommand(Result.m_pCommand, m_FlagMask);
+		if(!pCommand || ParseArgs(&Result, pCommand->m_pParams))
+			return false;
+		
+		pStr = pNextPart;
+	}
+	while(pStr && *pStr);
+
+	return true;
+}
+
 void CConsole::ExecuteLineStroked(int Stroke, const char *pStr)
 {	
 	while(pStr && *pStr)
diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h
index 87df6dea..e0435c34 100644
--- a/src/engine/shared/console.h
+++ b/src/engine/shared/console.h
@@ -119,6 +119,7 @@ public:
 	virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser);
 	virtual void StoreCommands(bool Store);
 	
+	virtual bool LineIsValid(const char *pStr);
 	virtual void ExecuteLine(const char *pStr);
 	virtual void ExecuteFile(const char *pFilename);
 
diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp
index ce3be58f..4d19dd53 100644
--- a/src/game/server/gamecontext.cpp
+++ b/src/game/server/gamecontext.cpp
@@ -905,6 +905,15 @@ void CGameContext::ConSetTeam(IConsole::IResult *pResult, void *pUserData)
 void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData)
 {
 	CGameContext *pSelf = (CGameContext *)pUserData;
+	// check for valid option
+	if(!pSelf->Console()->LineIsValid(pResult->GetString(0)))
+	{
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf), "skipped invalid option '%s'", pResult->GetString(0));
+		pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
+		return;
+	}
+
 	int Len = str_length(pResult->GetString(0));
 	
 	CGameContext::CVoteOption *pOption = (CGameContext::CVoteOption *)pSelf->m_pVoteOptionHeap->Allocate(sizeof(CGameContext::CVoteOption) + Len);