Skip to content
Permalink
Browse files

- made setting actor TID more explicit

Now it's no longer possible to manipulate TID hash from arbitrary location
For example, this prevents linking of destroyed object into the hash
TID member is still public but writing to it is limited to a few very specific cases like serialization and player traveling between levels

https://forum.zdoom.org/viewtopic.php?t=64476
  • Loading branch information...
alexey-lysiuk authored and madame-rachelle committed May 10, 2019
1 parent d00ff65 commit 850529b51bebba3fc1f658fab8f85693524995ee
Showing with 42 additions and 38 deletions.
  1. +4 −2 src/actor.h
  2. +1 −2 src/d_net.cpp
  3. +4 −2 src/g_level.cpp
  4. +1 −2 src/maploader/maploader.cpp
  5. +4 −9 src/p_acs.cpp
  6. +3 −10 src/p_lnspec.cpp
  7. +20 −2 src/p_mobj.cpp
  8. +2 −4 src/p_things.cpp
  9. +3 −5 src/scripting/vmthunks_actors.cpp
@@ -1180,12 +1180,14 @@ class AActor : public DThinker


// ThingIDs
void SetTID (int newTID);

private:
void AddToHash ();
void RemoveFromHash ();


private:
static inline int TIDHASH (int key) { return key & 127; }

public:
static FSharedStringArena mStringPropertyData;
private:
@@ -2400,12 +2400,11 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
if (type >= DEM_SUMMON2 && type <= DEM_SUMMONFOE2)
{
spawned->Angles.Yaw = source->Angles.Yaw - angle;
spawned->tid = tid;
spawned->special = special;
for(i = 0; i < 5; i++) {
spawned->args[i] = args[i];
}
if(tid) spawned->AddToHash();
if(tid) spawned->SetTID(tid);
}
}
}
@@ -1369,7 +1369,7 @@ void FLevelLocals::StartTravel ()
{
pawn->UnlinkFromWorld (nullptr);
int tid = pawn->tid; // Save TID
pawn->RemoveFromHash ();
pawn->SetTID(0);
pawn->tid = tid; // Restore TID (but no longer linked into the hash chain)
pawn->ChangeStatNum (STAT_TRAVELLING);
pawn->DeleteAttachedLights();
@@ -1481,7 +1481,9 @@ int FLevelLocals::FinishTravel ()
}
pawn->LinkToWorld (nullptr);
pawn->ClearInterpolation();
pawn->AddToHash ();
const int tid = pawn->tid; // Save TID (actor isn't linked into the hash chain yet)
pawn->tid = 0; // Reset TID
pawn->SetTID(tid); // Set TID (and link actor into the hash chain)
pawn->SetState(pawn->SpawnState);
pawn->player->SendPitchLimits();

@@ -112,8 +112,7 @@ void MapLoader::TranslateTeleportThings ()
{
if (!Level->SectorHasTags(dest->Sector))
{
dest->tid = 1;
dest->AddToHash ();
dest->SetTID(1);
foundSomething = true;
}
}
@@ -3768,8 +3768,7 @@ int DLevelScript::DoSpawn (int type, const DVector3 &pos, int tid, DAngle angle,
if (force || P_TestMobjLocation (actor))
{
actor->Angles.Yaw = angle;
actor->tid = tid;
actor->AddToHash ();
actor->SetTID(tid);
if (actor->flags & MF_SPECIAL)
actor->flags |= MF_DROPPED; // Don't respawn
actor->flags2 = oldFlags2;
@@ -5856,8 +5855,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
AActor *puff = P_LineAttack(activator, angle, range, pitch, damage, damagetype, pufftype, fhflags);
if (puff != NULL && pufftid != 0)
{
puff->tid = pufftid;
puff->AddToHash();
puff->SetTID(pufftid);
}
}
else
@@ -5870,8 +5868,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
AActor *puff = P_LineAttack(source, angle, range, pitch, damage, damagetype, pufftype, fhflags);
if (puff != NULL && pufftid != 0)
{
puff->tid = pufftid;
puff->AddToHash();
puff->SetTID(pufftid);
}
}
}
@@ -6291,9 +6288,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)

if ((pickedActor->tid == 0) || (flags & PICKAF_FORCETID))
{
pickedActor->RemoveFromHash();
pickedActor->tid = args[4];
pickedActor->AddToHash();
pickedActor->SetTID(args[4]);
}
if (flags & PICKAF_RETURNTID)
{
@@ -1299,11 +1299,9 @@ FUNC(LS_Thing_ChangeTID)
{
if (arg0 == 0)
{
if (it != NULL && !(it->ObjectFlags & OF_EuthanizeMe))
if (it != nullptr)
{
it->RemoveFromHash ();
it->tid = arg1;
it->AddToHash ();
it->SetTID(arg1);
}
}
else
@@ -1317,12 +1315,7 @@ FUNC(LS_Thing_ChangeTID)
actor = next;
next = iterator.Next ();

if (!(actor->ObjectFlags & OF_EuthanizeMe))
{
actor->RemoveFromHash ();
actor->tid = arg1;
actor->AddToHash ();
}
actor->SetTID(arg1);
}
}
return true;
@@ -2906,6 +2906,8 @@ void P_NightmareRespawn (AActor *mobj)
//
void AActor::AddToHash ()
{
assert(!(ObjectFlags & OF_EuthanizeMe));

if (tid == 0)
{
iprev = NULL;
@@ -2947,6 +2949,23 @@ void AActor::RemoveFromHash ()
tid = 0;
}

void AActor::SetTID (int newTID)
{
RemoveFromHash();

if (ObjectFlags & OF_EuthanizeMe)
{
// Do not assign TID and do not link actor into the hash
// if it was already destroyed and will be freed by GC
return;
}

tid = newTID;

AddToHash();
}


//==========================================================================
//
// P_IsTIDUsed
@@ -5465,8 +5484,7 @@ AActor *FLevelLocals::SpawnMapThing (FMapThing *mthing, int position)
}

// [RH] Add ThingID to mobj and link it in with the others
mobj->tid = mthing->thingid;
mobj->AddToHash ();
mobj->SetTID(mthing->thingid);

mobj->PrevAngles.Yaw = mobj->Angles.Yaw = (double)mthing->angle;

@@ -94,8 +94,7 @@ bool FLevelLocals::EV_Thing_Spawn (int tid, AActor *source, int type, DAngle ang
}
if (mobj->flags & MF_SPECIAL)
mobj->flags |= MF_DROPPED; // Don't respawn
mobj->tid = newtid;
mobj->AddToHash ();
mobj->SetTID(newtid);
mobj->flags2 = oldFlags2;
}
else
@@ -314,8 +313,7 @@ bool FLevelLocals::EV_Thing_Projectile (int tid, AActor *source, int type, const

if (mobj)
{
mobj->tid = newtid;
mobj->AddToHash ();
mobj->SetTID(newtid);
P_PlaySpawnSound(mobj, spot);
if (gravity)
{
@@ -911,21 +911,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, FindUniqueTid, P_FindUniqueTID)

static void RemoveFromHash(AActor *self)
{
self->RemoveFromHash();
self->SetTID(0);
}

DEFINE_ACTION_FUNCTION_NATIVE(AActor, RemoveFromHash, RemoveFromHash)
{
PARAM_SELF_PROLOGUE(AActor);
self->RemoveFromHash();
RemoveFromHash(self);
return 0;
}

static void ChangeTid(AActor *self, int tid)
{
self->RemoveFromHash();
self->tid = tid;
self->AddToHash();
self->SetTID(tid);
}

DEFINE_ACTION_FUNCTION_NATIVE(AActor, ChangeTid, ChangeTid)

0 comments on commit 850529b

Please sign in to comment.
You can’t perform that action at this time.