Skip to content

Commit 3ca03de

Browse files
authored
fix(aiupdate): Fix XFER and CRC of AIUpdateInterface::m_guardTargetType (TheSuperHackers#2662)
1 parent 2896c82 commit 3ca03de

2 files changed

Lines changed: 54 additions & 8 deletions

File tree

  • GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update
  • Generals/Code/GameEngine/Source/GameLogic/Object/Update

Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4808,12 +4808,21 @@ void AIUpdateInterface::crc( Xfer *x )
48084808
// ------------------------------------------------------------------------------------------------
48094809
/** Xfer method
48104810
* Version Info:
4811-
* 1: Initial version */
4811+
* 1: Initial version, contains specific surrender and demoralize variables
4812+
* 2: Added m_demoralizedFramesLeft (behind ALLOW_DEMORALIZE)
4813+
* 3: Removed lastFrameMoved and repulsorCountdown; removed surrender and demoralize variables
4814+
* 4: Read m_curLocomotorSet from ini
4815+
* 5: TheSuperHackers @fix Fixed out-of-bounds xfer of m_guardTargetType
4816+
*/
48124817
// ------------------------------------------------------------------------------------------------
48134818
void AIUpdateInterface::xfer( Xfer *xfer )
48144819
{
48154820
// version
4816-
const XferVersion currentVersion = 4;
4821+
#if RETAIL_COMPATIBLE_CRC || RETAIL_COMPATIBLE_XFER_SAVE
4822+
const XferVersion currentVersion = 4;
4823+
#else
4824+
const XferVersion currentVersion = 5;
4825+
#endif
48174826
XferVersion version = currentVersion;
48184827
xfer->xferVersion( &version, currentVersion );
48194828

@@ -4830,8 +4839,22 @@ void AIUpdateInterface::xfer( Xfer *xfer )
48304839
xfer->xferObjectID(&m_currentVictimID);
48314840
xfer->xferReal(&m_desiredSpeed);
48324841
xfer->xferUser(&m_lastCommandSource, sizeof(m_lastCommandSource));
4833-
xfer->xferUser(&m_guardTargetType[0], sizeof(m_guardTargetType));
4834-
xfer->xferUser(&m_guardTargetType[1], sizeof(m_guardTargetType));
4842+
4843+
if (version < 5)
4844+
{
4845+
// TheSuperHackers @fix The original code effectively accessed m_guardTargetType[0], [1], [1], [2].
4846+
// The last one is out-of-bounds and points to m_locationToGuard.
4847+
static_assert(sizeof(m_locationToGuard) >= sizeof(m_guardTargetType[2]), "Xfer size must not exceed variable size");
4848+
4849+
xfer->xferUser(&m_guardTargetType[0], sizeof(m_guardTargetType));
4850+
xfer->xferUser(&m_guardTargetType[1], sizeof(m_guardTargetType[1]));
4851+
xfer->xferUser(&m_locationToGuard, sizeof(m_guardTargetType[2]));
4852+
}
4853+
else
4854+
{
4855+
xfer->xferUser(m_guardTargetType, sizeof(m_guardTargetType));
4856+
}
4857+
48354858
xfer->xferCoord3D(&m_locationToGuard);
48364859

48374860
xfer->xferObjectID(&m_objectToGuard);

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5056,12 +5056,21 @@ void AIUpdateInterface::crc( Xfer *x )
50565056
// ------------------------------------------------------------------------------------------------
50575057
/** Xfer method
50585058
* Version Info:
5059-
* 1: Initial version */
5059+
* 1: Initial version, contains specific surrender and demoralize variables
5060+
* 2: Added m_demoralizedFramesLeft (behind ALLOW_DEMORALIZE)
5061+
* 3: Removed lastFrameMoved and repulsorCountdown; removed surrender and demoralize variables
5062+
* 4: Read m_curLocomotorSet from ini
5063+
* 5: TheSuperHackers @fix Fixed out-of-bounds xfer of m_guardTargetType
5064+
*/
50605065
// ------------------------------------------------------------------------------------------------
50615066
void AIUpdateInterface::xfer( Xfer *xfer )
50625067
{
50635068
// version
5064-
const XferVersion currentVersion = 4;
5069+
#if RETAIL_COMPATIBLE_CRC || RETAIL_COMPATIBLE_XFER_SAVE
5070+
const XferVersion currentVersion = 4;
5071+
#else
5072+
const XferVersion currentVersion = 5;
5073+
#endif
50655074
XferVersion version = currentVersion;
50665075
xfer->xferVersion( &version, currentVersion );
50675076

@@ -5078,8 +5087,22 @@ void AIUpdateInterface::xfer( Xfer *xfer )
50785087
xfer->xferObjectID(&m_currentVictimID);
50795088
xfer->xferReal(&m_desiredSpeed);
50805089
xfer->xferUser(&m_lastCommandSource, sizeof(m_lastCommandSource));
5081-
xfer->xferUser(&m_guardTargetType[0], sizeof(m_guardTargetType));
5082-
xfer->xferUser(&m_guardTargetType[1], sizeof(m_guardTargetType));
5090+
5091+
if (version < 5)
5092+
{
5093+
// TheSuperHackers @fix The original code effectively accessed m_guardTargetType[0], [1], [1], [2].
5094+
// The last one is out-of-bounds and points to m_locationToGuard.
5095+
static_assert(sizeof(m_locationToGuard) >= sizeof(m_guardTargetType[2]), "Xfer size must not exceed variable size");
5096+
5097+
xfer->xferUser(&m_guardTargetType[0], sizeof(m_guardTargetType));
5098+
xfer->xferUser(&m_guardTargetType[1], sizeof(m_guardTargetType[1]));
5099+
xfer->xferUser(&m_locationToGuard, sizeof(m_guardTargetType[2]));
5100+
}
5101+
else
5102+
{
5103+
xfer->xferUser(m_guardTargetType, sizeof(m_guardTargetType));
5104+
}
5105+
50835106
xfer->xferCoord3D(&m_locationToGuard);
50845107

50855108
xfer->xferObjectID(&m_objectToGuard);

0 commit comments

Comments
 (0)