Bassin d'Arathi : lecture hors limites de BgObjects
Signale par un utilisateur de SylvaniaCore : ses matchs de Bassin
d'Arathi avec pbotbg=1 faisaient tomber le serveur, avec dans le journal
GetBGObject: gameobject (type: 24, ... Entry: 7735234) not found
GetBGObject: gameobject (type: 32, ... Entry: 0) not found
soit des GUID manifestement arbitraires, sur une carte 529 dont le
tableau BgObjects ne compte que 22 cases.
GetNearGameObjectFlag, introduit par le module BG BotFill (a7b1fa78),
indexait BgObjects en node*8+status. Cette disposition -- huit objets
par noeud -- est celle de l'ancien Bassin d'Arathi de TrinityCore. Le
notre n'a qu'UNE banniere par noeud, aux indices 0 a 4 : _ChangeBanner
modifie son visuel selon l'etat au lieu d'echanger huit objets. Le
calcul donnait donc 24 pour le noeud 3 et 32 pour le noeud 4.
Le defaut de fond est ailleurs : huit accesseurs de Battleground.cpp
indexent BgObjects ou BgCreatures avec une valeur fournie par
l'appelant, sans jamais verifier la borne -- AddObject y ECRIT meme.
Une faute de calcul y devient une corruption memoire, et le plantage
survient loin de son origine. Tous sont desormais bornes : ils
journalisent l'indice fautif et renvoient l'echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1560,6 +1560,15 @@ void Battleground::RelocateDeadPlayers(ObjectGuid guideGuid)
|
||||
|
||||
bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 /*respawnTime*/, GOState goState)
|
||||
{
|
||||
// Garde-fou : voir GetBGObject. Ici l'indice sert a une ECRITURE,
|
||||
// BgObjects[type] = go->GetGUID() -- plus grave encore qu'une lecture.
|
||||
if (type >= BgObjects.size())
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: type %u hors limites (%u objets) pour le BG (carte %u, instance %u), entree %u ignoree.",
|
||||
type, uint32(BgObjects.size()), m_MapId, m_InstanceID, entry);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the assert is called, means that BgObjects must be resized!
|
||||
ASSERT(type < BgObjects.size());
|
||||
|
||||
@@ -1629,6 +1638,14 @@ bool Battleground::AddObject(uint32 type, uint32 entry, Position const& pos, flo
|
||||
// It would be nice to correctly implement GO_ACTIVATED state and open/close doors in gameobject code
|
||||
void Battleground::DoorClose(uint32 type)
|
||||
{
|
||||
// Garde-fou : voir GetBGObject.
|
||||
if (type >= BgObjects.size())
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "Battleground::DoorClose: type %u hors limites (%u objets) pour le BG (carte %u, instance %u).",
|
||||
type, uint32(BgObjects.size()), m_MapId, m_InstanceID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameObject* obj = GetBgMap()->GetGameObject(BgObjects[type]))
|
||||
{
|
||||
// If doors are open, close it
|
||||
@@ -1645,6 +1662,14 @@ void Battleground::DoorClose(uint32 type)
|
||||
|
||||
void Battleground::DoorOpen(uint32 type)
|
||||
{
|
||||
// Garde-fou : voir GetBGObject.
|
||||
if (type >= BgObjects.size())
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "Battleground::DoorOpen: type %u hors limites (%u objets) pour le BG (carte %u, instance %u).",
|
||||
type, uint32(BgObjects.size()), m_MapId, m_InstanceID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameObject* obj = GetBgMap()->GetGameObject(BgObjects[type]))
|
||||
{
|
||||
obj->SetLootState(GO_ACTIVATED);
|
||||
@@ -1657,6 +1682,33 @@ void Battleground::DoorOpen(uint32 type)
|
||||
|
||||
GameObject* Battleground::GetBGObject(uint32 type, bool logError)
|
||||
{
|
||||
// =================================================================
|
||||
// SylvaniaCore : refuser les indices hors limites.
|
||||
//
|
||||
// SIGNALE PAR UN UTILISATEUR DE SYLVANIACORE : ses matchs de Bassin
|
||||
// d'Arathi faisaient tomber le serveur, avec dans le journal
|
||||
// GetBGObject: gameobject (type: 24, ... Entry: 7735234) not found
|
||||
// GetBGObject: gameobject (type: 32, ... Entry: 0) not found
|
||||
// Des GUID manifestement arbitraires : BgObjects ne compte que 22
|
||||
// cases pour ce champ de bataille.
|
||||
//
|
||||
// La cause etait une indexation node*8 heritee de l'ancien Bassin
|
||||
// d'Arathi (corrigee dans BattlegroundAB.cpp), mais le defaut de
|
||||
// fond est ici : ces accesseurs indexent un std::vector avec une
|
||||
// valeur fournie par l'appelant, SANS jamais verifier la borne. Une
|
||||
// simple faute de calcul devient alors une corruption memoire, et
|
||||
// le plantage survient loin de son origine.
|
||||
//
|
||||
// On journalise et on renvoie l'echec plutot que de lire n'importe
|
||||
// ou. Meme garde-fou sur les autres accesseurs indexes du fichier.
|
||||
// =================================================================
|
||||
if (type >= BgObjects.size())
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "Battleground::GetBGObject: type %u hors limites (%u objets) pour le BG (carte %u, instance %u).",
|
||||
type, uint32(BgObjects.size()), m_MapId, m_InstanceID);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GameObject* obj = GetBgMap()->GetGameObject(BgObjects[type]);
|
||||
if (!obj)
|
||||
{
|
||||
@@ -1672,6 +1724,14 @@ GameObject* Battleground::GetBGObject(uint32 type, bool logError)
|
||||
|
||||
Creature* Battleground::GetBGCreature(uint32 type, bool logError)
|
||||
{
|
||||
// Garde-fou : voir GetBGObject.
|
||||
if (type >= BgCreatures.size())
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "Battleground::GetBGCreature: type %u hors limites (%u creatures) pour le BG (carte %u, instance %u).",
|
||||
type, uint32(BgCreatures.size()), m_MapId, m_InstanceID);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Creature* creature = GetBgMap()->GetCreature(BgCreatures[type]);
|
||||
if (!creature)
|
||||
{
|
||||
@@ -1687,6 +1747,14 @@ Creature* Battleground::GetBGCreature(uint32 type, bool logError)
|
||||
|
||||
void Battleground::SpawnBGObject(uint32 type, uint32 respawntime)
|
||||
{
|
||||
// Garde-fou : voir GetBGObject.
|
||||
if (type >= BgObjects.size())
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "Battleground::SpawnBGObject: type %u hors limites (%u objets) pour le BG (carte %u, instance %u).",
|
||||
type, uint32(BgObjects.size()), m_MapId, m_InstanceID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Map* map = FindBgMap())
|
||||
if (GameObject* obj = map->GetGameObject(BgObjects[type]))
|
||||
{
|
||||
@@ -1761,6 +1829,14 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, Position const& p
|
||||
|
||||
bool Battleground::DelCreature(uint32 type)
|
||||
{
|
||||
// Garde-fou : voir GetBGObject.
|
||||
if (type >= BgCreatures.size())
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "Battleground::DelCreature: type %u hors limites (%u creatures) pour le BG (carte %u, instance %u).",
|
||||
type, uint32(BgCreatures.size()), m_MapId, m_InstanceID);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!BgCreatures[type])
|
||||
return true;
|
||||
|
||||
@@ -1779,6 +1855,14 @@ bool Battleground::DelCreature(uint32 type)
|
||||
|
||||
bool Battleground::DelObject(uint32 type)
|
||||
{
|
||||
// Garde-fou : voir GetBGObject.
|
||||
if (type >= BgObjects.size())
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "Battleground::DelObject: type %u hors limites (%u objets) pour le BG (carte %u, instance %u).",
|
||||
type, uint32(BgObjects.size()), m_MapId, m_InstanceID);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!BgObjects[type])
|
||||
return true;
|
||||
|
||||
|
||||
@@ -731,9 +731,16 @@ GameObject const* BattlegroundAB::GetNearGameObjectFlag(const Player* player)
|
||||
// cliquable si neutre, ou tenu/conteste par l equipe adverse
|
||||
if (!(status == 0 || teamIndex == status % 2))
|
||||
continue;
|
||||
// BgObjects[node*8 + status] = banniere affichee pour cet etat (0=neutre,
|
||||
// 1/2=contestee A/H, 3/4=occupee A/H)
|
||||
GameObject* flag = GetBgMap()->GetGameObject(BgObjects[node * 8 + status]);
|
||||
// Ce coeur n'a QU'UNE banniere par noeud, aux indices 0 a 4
|
||||
// (BG_AB_OBJECT_BANNER + node) : _ChangeBanner modifie son visuel
|
||||
// selon l'etat au lieu d'echanger huit objets distincts.
|
||||
//
|
||||
// L'indexation node*8+status ecrite ici venait de l'ancien Bassin
|
||||
// d'Arathi de TrinityCore, ou chaque noeud possedait bien huit
|
||||
// objets. Elle donnait 24 pour le noeud 3 et 32 pour le noeud 4,
|
||||
// dans un tableau qui n'en compte que 22 : lecture hors limites,
|
||||
// GUID arbitraires, et plantage selon ce qui suit le tampon.
|
||||
GameObject* flag = GetBGObject(BG_AB_OBJECT_BANNER + node, false);
|
||||
if (!flag || !flag->isSpawned())
|
||||
continue;
|
||||
float dist = player->GetDistance(flag);
|
||||
|
||||
Reference in New Issue
Block a user