mirror of
https://github.com/mangosfour/server.git
synced 2025-12-17 07:37:03 +00:00
[11321] Fixed client crash at wrong quest shift-link structure.
Protection only work with ChatStrictLinkChecking.Severity = 3 Thanks to Lugia0529 and Micks for provided testing examples. Also fixed server side infinity loops in ChatHandler::isValidChatMessage
This commit is contained in:
parent
f46f4e1b87
commit
28375e295e
2 changed files with 64 additions and 22 deletions
|
|
@ -61,7 +61,7 @@
|
||||||
// |color|Htaxinode:id|h[name]|h|r
|
// |color|Htaxinode:id|h[name]|h|r
|
||||||
// |color|Htele:id|h[name]|h|r
|
// |color|Htele:id|h[name]|h|r
|
||||||
// |color|Htitle:id|h[name]|h|r
|
// |color|Htitle:id|h[name]|h|r
|
||||||
// |color|Htrade:spell_id,cur_value,max_value,unk3int,unk3str|h[name]|h|r - client, spellbook profession icon shift-click
|
// |color|Htrade:spell_id:cur_value:max_value:unk3int:unk3str|h[name]|h|r - client, spellbook profession icon shift-click
|
||||||
|
|
||||||
bool ChatHandler::load_command_table = true;
|
bool ChatHandler::load_command_table = true;
|
||||||
|
|
||||||
|
|
@ -1530,7 +1530,7 @@ valid examples:
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
reader >> c;
|
reader >> c;
|
||||||
if(!c)
|
if (!c)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("ChatHandler::isValidChatMessage got \\0 while reading color in |c command");
|
DEBUG_LOG("ChatHandler::isValidChatMessage got \\0 while reading color in |c command");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1538,12 +1538,12 @@ valid examples:
|
||||||
|
|
||||||
color <<= 4;
|
color <<= 4;
|
||||||
// check for hex char
|
// check for hex char
|
||||||
if(c >= '0' && c <='9')
|
if (c >= '0' && c <='9')
|
||||||
{
|
{
|
||||||
color |= c-'0';
|
color |= c-'0';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(c >= 'a' && c <='f')
|
if (c >= 'a' && c <='f')
|
||||||
{
|
{
|
||||||
color |= 10+c-'a';
|
color |= 10+c-'a';
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1555,11 +1555,15 @@ valid examples:
|
||||||
case 'H':
|
case 'H':
|
||||||
// read chars up to colon = link type
|
// read chars up to colon = link type
|
||||||
reader.getline(buffer, 256, ':');
|
reader.getline(buffer, 256, ':');
|
||||||
|
if (reader.eof()) // : must be
|
||||||
|
return false;
|
||||||
|
|
||||||
if (strcmp(buffer, "item") == 0)
|
if (strcmp(buffer, "item") == 0)
|
||||||
{
|
{
|
||||||
// read item entry
|
// read item entry
|
||||||
reader.getline(buffer, 256, ':');
|
reader.getline(buffer, 256, ':');
|
||||||
|
if (reader.eof()) // : must be
|
||||||
|
return false;
|
||||||
|
|
||||||
linkedItem = ObjectMgr::GetItemPrototype(atoi(buffer));
|
linkedItem = ObjectMgr::GetItemPrototype(atoi(buffer));
|
||||||
if(!linkedItem)
|
if(!linkedItem)
|
||||||
|
|
@ -1583,13 +1587,13 @@ valid examples:
|
||||||
int32 propertyId = 0;
|
int32 propertyId = 0;
|
||||||
bool negativeNumber = false;
|
bool negativeNumber = false;
|
||||||
char c;
|
char c;
|
||||||
for(uint8 i=0; i<randomPropertyPosition; ++i)
|
for(uint8 i=0; i < randomPropertyPosition; ++i)
|
||||||
{
|
{
|
||||||
propertyId = 0;
|
propertyId = 0;
|
||||||
negativeNumber = false;
|
negativeNumber = false;
|
||||||
while((c = reader.get())!=':')
|
while((c = reader.get()) != ':')
|
||||||
{
|
{
|
||||||
if(c >='0' && c<='9')
|
if (c >='0' && c<='9')
|
||||||
{
|
{
|
||||||
propertyId*=10;
|
propertyId*=10;
|
||||||
propertyId += c-'0';
|
propertyId += c-'0';
|
||||||
|
|
@ -1608,7 +1612,7 @@ valid examples:
|
||||||
if (!itemProperty)
|
if (!itemProperty)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(propertyId < 0)
|
else if (propertyId < 0)
|
||||||
{
|
{
|
||||||
itemSuffix = sItemRandomSuffixStore.LookupEntry(-propertyId);
|
itemSuffix = sItemRandomSuffixStore.LookupEntry(-propertyId);
|
||||||
if (!itemSuffix)
|
if (!itemSuffix)
|
||||||
|
|
@ -1622,7 +1626,7 @@ valid examples:
|
||||||
c = reader.peek();
|
c = reader.peek();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(strcmp(buffer, "quest") == 0)
|
else if (strcmp(buffer, "quest") == 0)
|
||||||
{
|
{
|
||||||
// no color check for questlinks, each client will adapt it anyway
|
// no color check for questlinks, each client will adapt it anyway
|
||||||
uint32 questid= 0;
|
uint32 questid= 0;
|
||||||
|
|
@ -1638,17 +1642,40 @@ valid examples:
|
||||||
|
|
||||||
linkedQuest = sObjectMgr.GetQuestTemplate(questid);
|
linkedQuest = sObjectMgr.GetQuestTemplate(questid);
|
||||||
|
|
||||||
if(!linkedQuest)
|
if (!linkedQuest)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("ChatHandler::isValidChatMessage Questtemplate %u not found", questid);
|
DEBUG_LOG("ChatHandler::isValidChatMessage Questtemplate %u not found", questid);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
c = reader.peek();
|
|
||||||
// level
|
if (c !=':')
|
||||||
while(c !='|' && c!='\0')
|
|
||||||
{
|
{
|
||||||
|
DEBUG_LOG("ChatHandler::isValidChatMessage Invalid quest link structure");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
reader.ignore(1);
|
reader.ignore(1);
|
||||||
c = reader.peek();
|
c = reader.peek();
|
||||||
|
// level
|
||||||
|
uint32 questlevel = 0;
|
||||||
|
while(c >='0' && c<='9')
|
||||||
|
{
|
||||||
|
reader.ignore(1);
|
||||||
|
questlevel *= 10;
|
||||||
|
questlevel += c-'0';
|
||||||
|
c = reader.peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (questlevel >= STRONG_MAX_LEVEL)
|
||||||
|
{
|
||||||
|
DEBUG_LOG("ChatHandler::isValidChatMessage Quest level %u too big", questlevel);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c !='|')
|
||||||
|
{
|
||||||
|
DEBUG_LOG("ChatHandler::isValidChatMessage Invalid quest link structure");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(strcmp(buffer, "trade") == 0)
|
else if(strcmp(buffer, "trade") == 0)
|
||||||
|
|
@ -1658,8 +1685,11 @@ valid examples:
|
||||||
|
|
||||||
// read spell entry
|
// read spell entry
|
||||||
reader.getline(buffer, 256, ':');
|
reader.getline(buffer, 256, ':');
|
||||||
|
if (reader.eof()) // : must be
|
||||||
|
return false;
|
||||||
|
|
||||||
linkedSpell = sSpellStore.LookupEntry(atoi(buffer));
|
linkedSpell = sSpellStore.LookupEntry(atoi(buffer));
|
||||||
if(!linkedSpell)
|
if (!linkedSpell)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char c = reader.peek();
|
char c = reader.peek();
|
||||||
|
|
@ -1678,12 +1708,15 @@ valid examples:
|
||||||
|
|
||||||
// read talent entry
|
// read talent entry
|
||||||
reader.getline(buffer, 256, ':');
|
reader.getline(buffer, 256, ':');
|
||||||
|
if (reader.eof()) // : must be
|
||||||
|
return false;
|
||||||
|
|
||||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(atoi(buffer));
|
TalentEntry const *talentInfo = sTalentStore.LookupEntry(atoi(buffer));
|
||||||
if(!talentInfo)
|
if (!talentInfo)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
linkedSpell = sSpellStore.LookupEntry(talentInfo->RankID[0]);
|
linkedSpell = sSpellStore.LookupEntry(talentInfo->RankID[0]);
|
||||||
if(!linkedSpell)
|
if (!linkedSpell)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char c = reader.peek();
|
char c = reader.peek();
|
||||||
|
|
@ -1696,7 +1729,7 @@ valid examples:
|
||||||
}
|
}
|
||||||
else if(strcmp(buffer, "spell") == 0)
|
else if(strcmp(buffer, "spell") == 0)
|
||||||
{
|
{
|
||||||
if(color != CHAT_LINK_COLOR_SPELL)
|
if (color != CHAT_LINK_COLOR_SPELL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 spellid = 0;
|
uint32 spellid = 0;
|
||||||
|
|
@ -1710,12 +1743,12 @@ valid examples:
|
||||||
c = reader.peek();
|
c = reader.peek();
|
||||||
}
|
}
|
||||||
linkedSpell = sSpellStore.LookupEntry(spellid);
|
linkedSpell = sSpellStore.LookupEntry(spellid);
|
||||||
if(!linkedSpell)
|
if (!linkedSpell)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(strcmp(buffer, "enchant") == 0)
|
else if(strcmp(buffer, "enchant") == 0)
|
||||||
{
|
{
|
||||||
if(color != CHAT_LINK_COLOR_ENCHANT)
|
if (color != CHAT_LINK_COLOR_ENCHANT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 spellid = 0;
|
uint32 spellid = 0;
|
||||||
|
|
@ -1729,23 +1762,27 @@ valid examples:
|
||||||
c = reader.peek();
|
c = reader.peek();
|
||||||
}
|
}
|
||||||
linkedSpell = sSpellStore.LookupEntry(spellid);
|
linkedSpell = sSpellStore.LookupEntry(spellid);
|
||||||
if(!linkedSpell)
|
if (!linkedSpell)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(strcmp(buffer, "achievement") == 0)
|
else if(strcmp(buffer, "achievement") == 0)
|
||||||
{
|
{
|
||||||
if(color != CHAT_LINK_COLOR_ACHIEVEMENT)
|
if (color != CHAT_LINK_COLOR_ACHIEVEMENT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
reader.getline(buffer, 256, ':');
|
reader.getline(buffer, 256, ':');
|
||||||
|
if (reader.eof()) // : must be
|
||||||
|
return false;
|
||||||
|
|
||||||
uint32 achievementId = atoi(buffer);
|
uint32 achievementId = atoi(buffer);
|
||||||
linkedAchievement = sAchievementStore.LookupEntry(achievementId);
|
linkedAchievement = sAchievementStore.LookupEntry(achievementId);
|
||||||
|
|
||||||
if(!linkedAchievement)
|
if (!linkedAchievement)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char c = reader.peek();
|
char c = reader.peek();
|
||||||
// skip progress
|
// skip progress
|
||||||
while(c !='|' && c!='\0')
|
while(c !='|' && c != '\0')
|
||||||
{
|
{
|
||||||
reader.ignore(1);
|
reader.ignore(1);
|
||||||
c = reader.peek();
|
c = reader.peek();
|
||||||
|
|
@ -1758,6 +1795,9 @@ valid examples:
|
||||||
|
|
||||||
// first id is slot, drop it
|
// first id is slot, drop it
|
||||||
reader.getline(buffer, 256, ':');
|
reader.getline(buffer, 256, ':');
|
||||||
|
if (reader.eof()) // : must be
|
||||||
|
return false;
|
||||||
|
|
||||||
uint32 glyphId = 0;
|
uint32 glyphId = 0;
|
||||||
char c = reader.peek();
|
char c = reader.peek();
|
||||||
while(c>='0' && c <='9')
|
while(c>='0' && c <='9')
|
||||||
|
|
@ -1793,6 +1833,8 @@ valid examples:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
reader.getline(buffer, 256, ']');
|
reader.getline(buffer, 256, ']');
|
||||||
|
if (reader.eof()) // ] must be
|
||||||
|
return false;
|
||||||
|
|
||||||
// verify the link name
|
// verify the link name
|
||||||
if (linkedSpell)
|
if (linkedSpell)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "11320"
|
#define REVISION_NR "11321"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue