- SW: added some null checks to the SO interpolation code.

It looks like this was able to access deleted sprites - by only checking for the index this never registered as a problem, but with pointers it does.
This commit is contained in:
Christoph Oelckers 2021-12-13 13:57:54 +01:00
parent a23d2ae656
commit a4ff7e5bd4
2 changed files with 35 additions and 18 deletions

View file

@ -278,18 +278,24 @@ void so_updateinterpolations(void) // Stick at beginning of domovethings
bool skip = !SyncInput() && (sop->track == SO_TURRET);
if (SO_EMPTY(sop) || skip)
continue;
if (interp->tic < interp->lasttic)
interp->tic += synctics;
for (i = 0, data = interp->data; i < interp->numinterpolations; i++, data++)
{
if (data->curelement == soi_sprang)
{
USERp u = data->actorofang->u();
if (u)
u->oangdiff = 0;
if (!interpolating)
data->lastangdiff = 0;
data->oldipos = data->actorofang->s().ang;
auto actorofang = data->actorofang;
if (actorofang)
{
USERp u = actorofang->u();
if (u)
u->oangdiff = 0;
if (!interpolating)
data->lastangdiff = 0;
data->oldipos = actorofang->s().ang;
}
}
else
data->oldipos = getvalue(*data, false);
@ -318,11 +324,17 @@ void so_dointerpolations(int32_t smoothratio) // Stick at b
if (SO_EMPTY(sop) || skip)
continue;
for (i = 0; i < interp->numinterpolations; i++)
interp->data[i].bakipos = (interp->data[i].curelement == soi_sprang) ?
interp->data[i].actorofang->s().ang :
getvalue(interp->data[i], false);
for (i = 0; i < interp->numinterpolations; i++)
{
auto actorofang = interp->data[i].actorofang;
if (interp->data[i].curelement >= soi_sprx && actorofang == nullptr)
continue; // target went poof.
interp->data[i].bakipos = (interp->data[i].curelement == soi_sprang) ?
actorofang->s().ang :
getvalue(interp->data[i], false);
}
if (interp->tic == 0) // Only if the SO has just moved
{
for (i = 0, data = interp->data; i < interp->numinterpolations; i++, data++)
@ -331,8 +343,12 @@ void so_dointerpolations(int32_t smoothratio) // Stick at b
data->lastoldipos = data->oldipos;
if (data->curelement == soi_sprang)
{
USERp u = data->actorofang->u();
data->lastangdiff = u ? u->oangdiff : 0;
auto actorofang = data->actorofang;
if (actorofang)
{
USERp u = actorofang->u();
data->lastangdiff = u ? u->oangdiff : 0;
}
}
}
}
@ -412,7 +428,10 @@ void so_restoreinterpolations(void) // Stick at end of drawscree
for (i = 0, data = interp->data; i < interp->numinterpolations; i++, data++)
if (data->curelement == soi_sprang)
data->actorofang->s().ang = data->bakipos;
{
auto actorofang = interp->data[i].actorofang;
if (actorofang) actorofang->s().ang = data->bakipos;
}
else
getvalue(*data, true) = data->bakipos;
}

View file

@ -630,7 +630,7 @@ void KillActor(DSWActor* actor)
if (u)
{
PLAYERp pp;
short pnum;
int pnum;
// doing a MissileSetPos - don't allow killing
if (TEST(u->Flags, SPR_SET_POS_DONT_KILL))
@ -645,7 +645,7 @@ void KillActor(DSWActor* actor)
if (TEST(u->Flags, SPR_SO_ATTACHED))
{
SECTOR_OBJECTp sop;
short sn, FoundSpriteNdx = -1;
int sn, FoundSpriteNdx = -1;
for (sop = SectorObject; sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++)
{
@ -672,8 +672,6 @@ void KillActor(DSWActor* actor)
break;
}
}
ASSERT(FoundSpriteNdx >= 0);
}
// if a player is dead and watching this sprite
@ -706,7 +704,7 @@ void KillActor(DSWActor* actor)
if (TEST(sp->extra, SPRX_PLAYER_OR_ENEMY))
{
USERp mu;
static short MissileStats[] = {STAT_MISSILE, STAT_MISSILE_SKIP4};
static int8_t MissileStats[] = {STAT_MISSILE, STAT_MISSILE_SKIP4};
for (stat = 0; stat < SIZ(MissileStats); stat++)
{