Skip to content

Commit 3abeeef

Browse files
Caball009x64-dev
authored andcommitted
bugfix(projectile): Fix out-of-bounds access in DumbProjectile which causes mismatch with very high speed weapons at small hit distances (TheSuperHackers#2087)
1 parent 2752fac commit 3abeeef

1 file changed

Lines changed: 27 additions & 3 deletions

File tree

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,10 @@ Bool DumbProjectileBehavior::calcFlightPath(Bool recalcNumSegments)
446446
Real flightDistance = flightCurve.getApproximateLength();
447447
m_flightPathSegments = ceil( flightDistance / m_flightPathSpeed );
448448
}
449-
flightCurve.getSegmentPoints( m_flightPathSegments, &m_flightPath );
449+
450+
// TheSuperHackers @info The way flight paths are used requires at least two curve points.
451+
// DumbProjectileBehavior::update has been modified to handle cases where the flight path consists of one or zero curve points.
452+
flightCurve.getSegmentPoints(m_flightPathSegments, &m_flightPath);
450453
DEBUG_ASSERTCRASH(m_flightPathSegments == m_flightPath.size(), ("m_flightPathSegments mismatch"));
451454

452455
#if defined(RTS_DEBUG)
@@ -584,6 +587,7 @@ UpdateSleepTime DumbProjectileBehavior::update()
584587
return UPDATE_SLEEP_NONE;
585588
}
586589

590+
// TheSuperHackers @info This check also covers the case where the flight path consists of zero curve points.
587591
if( m_currentFlightPathStep >= m_flightPath.size() )
588592
{
589593
// No more steps to use. Would go out of bounds on vector, so have to do something.
@@ -648,8 +652,28 @@ UpdateSleepTime DumbProjectileBehavior::update()
648652
//long, blurry projectile graphics which look badly oriented on step 0 of the flight path
649653
// so lets orient it the same as if it were on frame 1!
650654
{
651-
Coord3D prevPos = m_flightPath[0];
652-
Coord3D curPos = m_flightPath[1];
655+
// TheSuperHackers @bugfix Caball009 10/01/2026 Check vector size before accessing the second element to prevent out of bounds access.
656+
// The non-deterministic behavior for retail clients cannot be fixed, so this will remain a source of potential mismatches in retail compatibility mode.
657+
// Use the flight path start and end coordinates if needed, so that the behavior is deterministic for patched clients.
658+
Coord3D prevPos;
659+
Coord3D curPos;
660+
661+
if (m_flightPath.size() >= 2)
662+
{
663+
prevPos = m_flightPath[0];
664+
curPos = m_flightPath[1];
665+
}
666+
else
667+
{
668+
#if RETAIL_COMPATIBLE_CRC
669+
DEBUG_CRASH(("A mismatch is likely to happen if this code path is used in a match with unpatched clients."
670+
" Vector is expected to contain two or more elements; check the weapon speed value."));
671+
#endif
672+
673+
prevPos = m_flightPathStart;
674+
curPos = m_flightPathEnd;
675+
flightStep = m_flightPathEnd;
676+
}
653677

654678
Vector3 curDir(curPos.x - prevPos.x, curPos.y - prevPos.y, curPos.z - prevPos.z);
655679
curDir.Normalize(); // buildTransformMatrix wants it this way

0 commit comments

Comments
 (0)