Skip to content

Commit

Permalink
Fixed: Dynamically spawned boss brain targets could result in an out …
Browse files Browse the repository at this point in the history
…of bounds write to the brain targets list upon loading a saved game.
  • Loading branch information
danij-deng committed Feb 12, 2011
1 parent 70ac7c5 commit e6f8256
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 39 deletions.
12 changes: 5 additions & 7 deletions doomsday/plugins/common/src/p_mapsetup.c
@@ -1,10 +1,10 @@
/**\file
/**\file p_setup.c
*\section License
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
*
*\author Copyright © 2003-2009 Jaakko Keränen <jaakko.keranen@iki.fi>
*\author Copyright © 2005-2009 Daniel Swanson <danij@dengine.net>
*\author Copyright © 2003-2011 Jaakko Keränen <jaakko.keranen@iki.fi>
*\author Copyright © 2005-2011 Daniel Swanson <danij@dengine.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -23,7 +23,7 @@
*/

/**
* p_setup.c: Common map setup routines.
* Common map setup routines.
*
* Management of extended map data objects (eg xlines) is done here
*/
Expand Down Expand Up @@ -872,10 +872,8 @@ static void P_ResetWorldState(void)

#if __JDOOM__
// Brain info
brain.numTargets = 0;
brain.maxTargets = -1;
brain.targetOn = 0;
brain.easy = 0; // Always init easy to 0.
P_ClearBrainTargets();
#endif

#if __JHERETIC__
Expand Down
16 changes: 8 additions & 8 deletions doomsday/plugins/common/src/p_saveg.c
Expand Up @@ -4333,31 +4333,31 @@ static void P_ArchiveBrain(void)

static void P_UnArchiveBrain(void)
{
int i, ver = 0;
int i, numTargets, ver = 0;

if(hdr.version < 3)
return; // No brain data before version 3.

if(hdr.version >= 8)
ver = SV_ReadByte();

P_ClearBrainTargets();
if(ver >= 1)
{
brain.numTargets = SV_ReadShort();
numTargets = SV_ReadShort();
brain.targetOn = SV_ReadShort();
brain.easy = SV_ReadByte()!=0? true : false;
}
else
{
brain.numTargets = SV_ReadByte();
numTargets = SV_ReadByte();
brain.targetOn = SV_ReadByte();
brain.easy = false;
}

for(i = 0; i < brain.numTargets; ++i)
for(i = 0; i < numTargets; ++i)
{
brain.targets[i] = (mobj_t*) (int) SV_ReadShort();
brain.targets[i] = SV_GetArchiveThing((int) brain.targets[i], NULL);
P_AddMobjToBrainTargets(SV_GetArchiveThing((int) SV_ReadShort(), 0));
}
}
#endif
Expand Down Expand Up @@ -4596,7 +4596,7 @@ static void P_UnArchiveGlobalScriptData(void)
else
{ // Old format.
acsstore_t tempStore[20];

ACSStoreSize = 0;
for(i = 0; i < 20; ++i)
{
Expand Down Expand Up @@ -5174,7 +5174,7 @@ static boolean SV_LoadGame2(void)
// Create and populate the MaterialArchive.
materialArchive = P_CreateEmptyMaterialArchive();


P_UnArchivePlayerHeader();
// Read the player structures
SV_AssertSegment(ASEG_PLAYERS);
Expand Down
14 changes: 8 additions & 6 deletions doomsday/plugins/jdoom/include/p_enemy.h
@@ -1,9 +1,9 @@
/**\file
/**\file p_enemy.h
*\section License
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
*
*\author Copyright © 2009 Daniel Swanson <danij@dengine.net>
*\author Copyright © 2009-2011 Daniel Swanson <danij@dengine.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -22,11 +22,11 @@
*/

/**
* p_enemy.h: Enemy thinking, AI (jDoom-specific).
* Enemy thinking, AI (jDoom-specific).
*/

#ifndef __P_ENEMY_H__
#define __P_ENEMY_H__
#ifndef LIBDOOM_P_ENEMY_H
#define LIBDOOM_P_ENEMY_H

#ifndef __JDOOM__
# error "Using jDoom headers without __JDOOM__"
Expand All @@ -47,7 +47,9 @@ extern braindata_t brain;

extern boolean bossKilled;

void P_ClearBrainTargets(void);
void P_AddMobjToBrainTargets(mobj_t* mo);
void P_NoiseAlert(mobj_t *target, mobj_t *emmiter);
int P_Massacre(void);

#endif
#endif /* LIBDOOM_ENEMY_H */
27 changes: 27 additions & 0 deletions doomsday/plugins/jdoom/src/p_enemy.c
Expand Up @@ -1768,6 +1768,33 @@ void C_DECL A_BabyMetal(mobj_t *mo)
A_Chase(mo);
}

void P_ClearBrainTargets(void)
{
brain.numTargets = 0;
brain.maxTargets = -1;
brain.targetOn = 0;
}

void P_AddMobjToBrainTargets(mobj_t* mo)
{
if(brain.numTargets >= brain.maxTargets)
{
// Do we need to alloc more targets?
if(brain.numTargets == brain.maxTargets)
{
brain.maxTargets *= 2;
brain.targets = Z_Realloc(brain.targets, brain.maxTargets * sizeof(*brain.targets), PU_MAP);
}
else
{
brain.maxTargets = 32;
brain.targets = Z_Malloc(brain.maxTargets * sizeof(*brain.targets), PU_MAP, NULL);
}
}

brain.targets[brain.numTargets++] = mo;
}

void C_DECL A_BrainAwake(mobj_t* mo)
{
S_StartSound(SFX_BOSSIT, NULL);
Expand Down
19 changes: 1 addition & 18 deletions doomsday/plugins/jdoom/src/p_mobj.c
Expand Up @@ -944,24 +944,7 @@ mobj_t* P_SpawnMobj3f(mobjtype_t type, float x, float y, float z,
}

if(type == MT_BOSSTARGET)
{
if(brain.numTargets >= brain.maxTargets)
{
// Do we need to alloc more targets?
if(brain.numTargets == brain.maxTargets)
{
brain.maxTargets *= 2;
brain.targets = Z_Realloc(brain.targets, brain.maxTargets * sizeof(*brain.targets), PU_MAP);
}
else
{
brain.maxTargets = 32;
brain.targets = Z_Malloc(brain.maxTargets * sizeof(*brain.targets), PU_MAP, NULL);
}
}

brain.targets[brain.numTargets++] = mo;
}
P_AddMobjToBrainTargets(mo);

// Copy spawn attributes to the new mobj.
mo->spawnSpot.pos[VX] = x;
Expand Down

0 comments on commit e6f8256

Please sign in to comment.