diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 970280861..f2fe2946f 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -61,7 +61,7 @@ // |color|Htaxinode:id|h[name]|h|r // |color|Htele: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; @@ -1530,7 +1530,7 @@ valid examples: { char c; reader >> c; - if(!c) + if (!c) { DEBUG_LOG("ChatHandler::isValidChatMessage got \\0 while reading color in |c command"); return false; @@ -1538,12 +1538,12 @@ valid examples: color <<= 4; // check for hex char - if(c >= '0' && c <='9') + if (c >= '0' && c <='9') { color |= c-'0'; continue; } - if(c >= 'a' && c <='f') + if (c >= 'a' && c <='f') { color |= 10+c-'a'; continue; @@ -1555,11 +1555,15 @@ valid examples: case 'H': // read chars up to colon = link type reader.getline(buffer, 256, ':'); + if (reader.eof()) // : must be + return false; if (strcmp(buffer, "item") == 0) { // read item entry reader.getline(buffer, 256, ':'); + if (reader.eof()) // : must be + return false; linkedItem = ObjectMgr::GetItemPrototype(atoi(buffer)); if(!linkedItem) @@ -1583,13 +1587,13 @@ valid examples: int32 propertyId = 0; bool negativeNumber = false; char c; - for(uint8 i=0; i='0' && c<='9') + if (c >='0' && c<='9') { propertyId*=10; propertyId += c-'0'; @@ -1608,7 +1612,7 @@ valid examples: if (!itemProperty) return false; } - else if(propertyId < 0) + else if (propertyId < 0) { itemSuffix = sItemRandomSuffixStore.LookupEntry(-propertyId); if (!itemSuffix) @@ -1622,7 +1626,7 @@ valid examples: 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 uint32 questid= 0; @@ -1638,18 +1642,41 @@ valid examples: linkedQuest = sObjectMgr.GetQuestTemplate(questid); - if(!linkedQuest) + if (!linkedQuest) { DEBUG_LOG("ChatHandler::isValidChatMessage Questtemplate %u not found", questid); return false; } + + if (c !=':') + { + DEBUG_LOG("ChatHandler::isValidChatMessage Invalid quest link structure"); + return false; + } + + reader.ignore(1); c = reader.peek(); // level - while(c !='|' && c!='\0') + 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) { @@ -1658,8 +1685,11 @@ valid examples: // read spell entry reader.getline(buffer, 256, ':'); + if (reader.eof()) // : must be + return false; + linkedSpell = sSpellStore.LookupEntry(atoi(buffer)); - if(!linkedSpell) + if (!linkedSpell) return false; char c = reader.peek(); @@ -1678,12 +1708,15 @@ valid examples: // read talent entry reader.getline(buffer, 256, ':'); + if (reader.eof()) // : must be + return false; + TalentEntry const *talentInfo = sTalentStore.LookupEntry(atoi(buffer)); - if(!talentInfo) + if (!talentInfo) return false; linkedSpell = sSpellStore.LookupEntry(talentInfo->RankID[0]); - if(!linkedSpell) + if (!linkedSpell) return false; char c = reader.peek(); @@ -1696,7 +1729,7 @@ valid examples: } else if(strcmp(buffer, "spell") == 0) { - if(color != CHAT_LINK_COLOR_SPELL) + if (color != CHAT_LINK_COLOR_SPELL) return false; uint32 spellid = 0; @@ -1710,12 +1743,12 @@ valid examples: c = reader.peek(); } linkedSpell = sSpellStore.LookupEntry(spellid); - if(!linkedSpell) + if (!linkedSpell) return false; } else if(strcmp(buffer, "enchant") == 0) { - if(color != CHAT_LINK_COLOR_ENCHANT) + if (color != CHAT_LINK_COLOR_ENCHANT) return false; uint32 spellid = 0; @@ -1729,23 +1762,27 @@ valid examples: c = reader.peek(); } linkedSpell = sSpellStore.LookupEntry(spellid); - if(!linkedSpell) + if (!linkedSpell) return false; } else if(strcmp(buffer, "achievement") == 0) { - if(color != CHAT_LINK_COLOR_ACHIEVEMENT) + if (color != CHAT_LINK_COLOR_ACHIEVEMENT) return false; + reader.getline(buffer, 256, ':'); + if (reader.eof()) // : must be + return false; + uint32 achievementId = atoi(buffer); linkedAchievement = sAchievementStore.LookupEntry(achievementId); - if(!linkedAchievement) + if (!linkedAchievement) return false; char c = reader.peek(); // skip progress - while(c !='|' && c!='\0') + while(c !='|' && c != '\0') { reader.ignore(1); c = reader.peek(); @@ -1758,6 +1795,9 @@ valid examples: // first id is slot, drop it reader.getline(buffer, 256, ':'); + if (reader.eof()) // : must be + return false; + uint32 glyphId = 0; char c = reader.peek(); while(c>='0' && c <='9') @@ -1793,6 +1833,8 @@ valid examples: return false; } reader.getline(buffer, 256, ']'); + if (reader.eof()) // ] must be + return false; // verify the link name if (linkedSpell) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 314c4ca35..ac3eff20b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11320" + #define REVISION_NR "11321" #endif // __REVISION_NR_H__