[10340] Some fixes for recent chat code changes.

* Fixed crash at absent optional literal. Thanks to MysteriousSouL for reproting.
* Converted mode commands use new way parsing functions with fixing posible crash cases.
This commit is contained in:
VladimirMangos 2010-08-11 02:10:37 +04:00
parent a202b33702
commit 8b99ac7298
4 changed files with 115 additions and 153 deletions

View file

@ -2202,33 +2202,40 @@ char* ChatHandler::ExtractLiteralArg(char** args, char const* lit /*= NULL*/)
if (lit) if (lit)
{ {
int diff = strncmp(head, lit, strlen(lit)); int l = strlen(lit);
int diff = strncmp(head, lit, l);
if (diff > 0) if (diff != 0)
return NULL; return NULL;
if (diff < 0 && !head[-diff] && !isWhiteSpace(head[-diff])) if (head[l] && !isWhiteSpace(head[l]))
return NULL; return NULL;
char* arg = head; char* arg = head;
if (head[-diff]) if (head[l])
{ {
head[-diff] = '\0'; head[l] = '\0';
head += -diff + 1; head += l + 1;
*args = head; *args = head;
} }
else else
*args = NULL; *args = head + l;
SkipWhiteSpaces(args); SkipWhiteSpaces(args);
return arg; return arg;
} }
char* name = strtok(head, " "); char* name = strtok(head, " ");
*args = strtok(NULL, "");
char* tail = strtok(NULL, "");
*args = tail ? tail : (char*)""; // *args don't must be NULL
SkipWhiteSpaces(args);
return name; return name;
} }
@ -2255,7 +2262,8 @@ char* ChatHandler::ExtractQuotedArg( char** args )
char* str = strtok((*args)+1, guard); // skip start guard symbol char* str = strtok((*args)+1, guard); // skip start guard symbol
*args = strtok(NULL, ""); char* tail = strtok(NULL, "");
*args = tail ? tail : (char*)""; // *args don't must be NULL
SkipWhiteSpaces(args); SkipWhiteSpaces(args);
@ -2522,7 +2530,7 @@ char* ChatHandler::ExtractOptNotLastArg(char** args)
return arg; return arg;
// optional name not found // optional name not found
*args = arg; *args = arg ? arg : (char*)""; // *args don't must be NULL
return NULL; return NULL;
} }

View file

@ -4459,14 +4459,15 @@ bool ChatHandler::HandleLearnAllRecipesCommand(char* args)
bool ChatHandler::HandleLookupAccountEmailCommand(char* args) bool ChatHandler::HandleLookupAccountEmailCommand(char* args)
{ {
char* emailStr = ExtractQuotedOrLiteralArg(&args);
if (!*args) if (!emailStr)
return false; return false;
std::string email = strtok(args, " "); uint32 limit;
char* limit_str = strtok(NULL, " "); if (!ExtractOptUInt32(&args, limit, 100))
uint32 limit = limit_str ? atoi(limit_str) : 100; return false;
std::string email = emailStr;
LoginDatabase.escape_string(email); LoginDatabase.escape_string(email);
// 0 1 2 3 4 // 0 1 2 3 4
QueryResult *result = LoginDatabase.PQuery("SELECT id, username, last_ip, gmlevel, expansion FROM account WHERE email "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), email.c_str ()); QueryResult *result = LoginDatabase.PQuery("SELECT id, username, last_ip, gmlevel, expansion FROM account WHERE email "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), email.c_str ());
@ -4476,13 +4477,15 @@ bool ChatHandler::HandleLookupAccountEmailCommand(char* args)
bool ChatHandler::HandleLookupAccountIpCommand(char* args) bool ChatHandler::HandleLookupAccountIpCommand(char* args)
{ {
if (!*args) char* ipStr = ExtractQuotedOrLiteralArg(&args);
if (!ipStr)
return false; return false;
std::string ip = strtok(args, " "); uint32 limit;
char* limit_str = strtok(NULL, " "); if (!ExtractOptUInt32(&args, limit, 100))
uint32 limit = limit_str ? atoi(limit_str) : 100; return false;
std::string ip = ipStr;
LoginDatabase.escape_string(ip); LoginDatabase.escape_string(ip);
// 0 1 2 3 4 // 0 1 2 3 4
@ -4493,13 +4496,15 @@ bool ChatHandler::HandleLookupAccountIpCommand(char* args)
bool ChatHandler::HandleLookupAccountNameCommand(char* args) bool ChatHandler::HandleLookupAccountNameCommand(char* args)
{ {
if (!*args) char* accountStr = ExtractQuotedOrLiteralArg(&args);
if (!accountStr)
return false; return false;
std::string account = strtok(args, " "); uint32 limit;
char* limit_str = strtok(NULL, " "); if (!ExtractOptUInt32(&args, limit, 100))
uint32 limit = limit_str ? atoi(limit_str) : 100; return false;
std::string account = accountStr;
if (!AccountMgr::normalizeString(account)) if (!AccountMgr::normalizeString(account))
return false; return false;
@ -4564,13 +4569,15 @@ bool ChatHandler::ShowAccountListHelper(QueryResult* result, uint32* limit, bool
bool ChatHandler::HandleLookupPlayerIpCommand(char* args) bool ChatHandler::HandleLookupPlayerIpCommand(char* args)
{ {
if (!*args) char* ipStr = ExtractQuotedOrLiteralArg(&args);
if (!ipStr)
return false; return false;
std::string ip = strtok(args, " "); uint32 limit;
char* limit_str = strtok(NULL, " "); if (!ExtractOptUInt32(&args, limit, 100))
uint32 limit = limit_str ? atoi(limit_str) : 100; return false;
std::string ip = ipStr;
LoginDatabase.escape_string(ip); LoginDatabase.escape_string(ip);
QueryResult* result = LoginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), ip.c_str ()); QueryResult* result = LoginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), ip.c_str ());
@ -4580,13 +4587,15 @@ bool ChatHandler::HandleLookupPlayerIpCommand(char* args)
bool ChatHandler::HandleLookupPlayerAccountCommand(char* args) bool ChatHandler::HandleLookupPlayerAccountCommand(char* args)
{ {
if (!*args) char* accountStr = ExtractQuotedOrLiteralArg(&args);
if (!accountStr)
return false; return false;
std::string account = strtok(args, " "); uint32 limit;
char* limit_str = strtok(NULL, " "); if (!ExtractOptUInt32(&args, limit, 100))
uint32 limit = limit_str ? atoi(limit_str) : 100; return false;
std::string account = accountStr;
if (!AccountMgr::normalizeString(account)) if (!AccountMgr::normalizeString(account))
return false; return false;
@ -4599,13 +4608,15 @@ bool ChatHandler::HandleLookupPlayerAccountCommand(char* args)
bool ChatHandler::HandleLookupPlayerEmailCommand(char* args) bool ChatHandler::HandleLookupPlayerEmailCommand(char* args)
{ {
if (!*args) char* emailStr = ExtractQuotedOrLiteralArg(&args);
if (!emailStr)
return false; return false;
std::string email = strtok(args, " "); uint32 limit;
char* limit_str = strtok(NULL, " "); if (!ExtractOptUInt32(&args, limit, 100))
uint32 limit = limit_str ? atoi(limit_str) : 100; return false;
std::string email = emailStr;
LoginDatabase.escape_string(email); LoginDatabase.escape_string(email);
QueryResult* result = LoginDatabase.PQuery("SELECT id,username FROM account WHERE email "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), email.c_str ()); QueryResult* result = LoginDatabase.PQuery("SELECT id,username FROM account WHERE email "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), email.c_str ());

View file

@ -4168,9 +4168,6 @@ bool ChatHandler::HandleStableCommand(char* /*args*/)
bool ChatHandler::HandleChangeWeatherCommand(char* args) bool ChatHandler::HandleChangeWeatherCommand(char* args)
{ {
if (!*args)
return false;
//Weather is OFF //Weather is OFF
if (!sWorld.getConfig(CONFIG_BOOL_WEATHER)) if (!sWorld.getConfig(CONFIG_BOOL_WEATHER))
{ {
@ -4179,16 +4176,22 @@ bool ChatHandler::HandleChangeWeatherCommand(char* args)
return false; return false;
} }
//*Change the weather of a cell uint32 type;
char* px = strtok(args, " "); if (!ExtractUInt32(&args, type))
char* py = strtok(NULL, " "); return false;
if (!px || !py) //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
return false; if (type > 3)
return false;
uint32 type = (uint32)atoi(px); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand
float grade = (float)atof(py); //0 to 1, sending -1 is instand good weather float grade;
if (!ExtractFloat(&args, grade))
return false;
//0 to 1, sending -1 is instand good weather
if (grade < 0.0f || grade > 1.0f)
return false;
Player *player = m_session->GetPlayer(); Player *player = m_session->GetPlayer();
uint32 zoneid = player->GetZoneId(); uint32 zoneid = player->GetZoneId();
@ -4659,141 +4662,81 @@ bool ChatHandler::HandleServerShutDownCancelCommand(char* /*args*/)
bool ChatHandler::HandleServerShutDownCommand(char* args) bool ChatHandler::HandleServerShutDownCommand(char* args)
{ {
if (!*args) uint32 delay;
if (!ExtractUInt32(&args, delay))
return false; return false;
char* time_str = strtok(args, " "); uint32 exitcode;
char* exitcode_str = strtok(NULL, ""); if (!ExtractOptUInt32(&args, exitcode, SHUTDOWN_EXIT_CODE))
int32 time = atoi(time_str);
///- Prevent interpret wrong arg value as 0 secs shutdown time
if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
return false; return false;
if (exitcode_str) // Exit code should be in range of 0-125, 126-255 is used
{ // in many shells for their own return codes and code > 255
int32 exitcode = atoi (exitcode_str); // is not supported in many others
if (exitcode < 0 || exitcode > 125)
return false;
// Handle atoi() errors sWorld.ShutdownServ (delay, 0, exitcode);
if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
return false;
// Exit code should be in range of 0-125, 126-255 is used
// in many shells for their own return codes and code > 255
// is not supported in many others
if (exitcode < 0 || exitcode > 125)
return false;
sWorld.ShutdownServ (time, 0, exitcode);
}
else
sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE);
return true; return true;
} }
bool ChatHandler::HandleServerRestartCommand(char* args) bool ChatHandler::HandleServerRestartCommand(char* args)
{ {
if (!*args) uint32 delay;
if (!ExtractUInt32(&args, delay))
return false; return false;
char* time_str = strtok(args, " "); uint32 exitcode;
char* exitcode_str = strtok(NULL, ""); if (!ExtractOptUInt32(&args, exitcode, RESTART_EXIT_CODE))
int32 time = atoi(time_str);
///- Prevent interpret wrong arg value as 0 secs shutdown time
if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
return false; return false;
if (exitcode_str) // Exit code should be in range of 0-125, 126-255 is used
{ // in many shells for their own return codes and code > 255
int32 exitcode = atoi(exitcode_str); // is not supported in many others
if (exitcode < 0 || exitcode > 125)
return false;
// Handle atoi() errors sWorld.ShutdownServ(delay, SHUTDOWN_MASK_RESTART, exitcode);
if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
return false;
// Exit code should be in range of 0-125, 126-255 is used
// in many shells for their own return codes and code > 255
// is not supported in many others
if (exitcode < 0 || exitcode > 125)
return false;
sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, exitcode);
}
else
sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
return true; return true;
} }
bool ChatHandler::HandleServerIdleRestartCommand(char* args) bool ChatHandler::HandleServerIdleRestartCommand(char* args)
{ {
if (!*args) uint32 delay;
if (!ExtractUInt32(&args, delay))
return false; return false;
char* time_str = strtok(args, " "); uint32 exitcode;
char* exitcode_str = strtok(NULL, ""); if (!ExtractOptUInt32(&args, exitcode, RESTART_EXIT_CODE))
int32 time = atoi(time_str);
///- Prevent interpret wrong arg value as 0 secs shutdown time
if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
return false; return false;
if (exitcode_str) // Exit code should be in range of 0-125, 126-255 is used
{ // in many shells for their own return codes and code > 255
int32 exitcode = atoi(exitcode_str); // is not supported in many others
if (exitcode < 0 || exitcode > 125)
return false;
// Handle atoi() errors sWorld.ShutdownServ(delay, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
return false;
// Exit code should be in range of 0-125, 126-255 is used
// in many shells for their own return codes and code > 255
// is not supported in many others
if (exitcode < 0 || exitcode > 125)
return false;
sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
}
else
sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE);
return true; return true;
} }
bool ChatHandler::HandleServerIdleShutDownCommand(char* args) bool ChatHandler::HandleServerIdleShutDownCommand(char* args)
{ {
if (!*args) uint32 delay;
if (!ExtractUInt32(&args, delay))
return false; return false;
char* time_str = strtok(args, " "); uint32 exitcode;
char* exitcode_str = strtok(NULL, ""); if (!ExtractOptUInt32(&args, exitcode, SHUTDOWN_EXIT_CODE))
int32 time = atoi(time_str);
///- Prevent interpret wrong arg value as 0 secs shutdown time
if ((time == 0 && (time_str[0]!='0' || time_str[1]!='\0')) || time < 0)
return false; return false;
if (exitcode_str) // Exit code should be in range of 0-125, 126-255 is used
{ // in many shells for their own return codes and code > 255
int32 exitcode = atoi(exitcode_str); // is not supported in many others
if (exitcode < 0 || exitcode > 125)
return false;
// Handle atoi() errors sWorld.ShutdownServ(delay, SHUTDOWN_MASK_IDLE, exitcode);
if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
return false;
// Exit code should be in range of 0-125, 126-255 is used
// in many shells for their own return codes and code > 255
// is not supported in many others
if (exitcode < 0 || exitcode > 125)
return false;
sWorld.ShutdownServ(time, SHUTDOWN_MASK_IDLE, exitcode);
}
else
sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE);
return true; return true;
} }
@ -5197,7 +5140,7 @@ bool ChatHandler::HandleBanInfoIPCommand(char* args)
if (!*args) if (!*args)
return false; return false;
char* cIP = strtok (args, ""); char* cIP = ExtractQuotedOrLiteralArg(&args);
if(!cIP) if(!cIP)
return false; return false;
@ -5227,7 +5170,7 @@ bool ChatHandler::HandleBanListCharacterCommand(char* args)
{ {
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
char* cFilter = strtok (args, " "); char* cFilter = ExtractLiteralArg(&args);
if(!cFilter) if(!cFilter)
return false; return false;
@ -5247,7 +5190,7 @@ bool ChatHandler::HandleBanListAccountCommand(char* args)
{ {
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
char* cFilter = strtok(args, " "); char* cFilter = ExtractLiteralArg(&args);
std::string filter = cFilter ? cFilter : ""; std::string filter = cFilter ? cFilter : "";
LoginDatabase.escape_string(filter); LoginDatabase.escape_string(filter);
@ -5356,7 +5299,7 @@ bool ChatHandler::HandleBanListIPCommand(char* args)
{ {
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
char* cFilter = strtok(args, " "); char* cFilter = ExtractLiteralArg(&args);
std::string filter = cFilter ? cFilter : ""; std::string filter = cFilter ? cFilter : "";
LoginDatabase.escape_string(filter); LoginDatabase.escape_string(filter);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "10339" #define REVISION_NR "10340"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__