Skip to content

Commit f6557b1

Browse files
helmutbuhlerxezon
authored andcommitted
Fix replay header memory corruption on VS22
1 parent 933e1de commit f6557b1

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,17 @@ Int REPLAY_CRC_INTERVAL = 100;
5656
const char *replayExtention = ".rep";
5757
const char *lastReplayFileName = "00000000"; // a name the user is unlikely to ever type, but won't cause panic & confusion
5858

59+
// TheSuperHackers @tweak helmutbuhler 25/04/2025
60+
// The replay header contains two time elements startTime and endTime of type time_t.
61+
// On VC6 this was 32-bit, but on newer compilers it's 64-bit. In order to remain compatible
62+
// we need to load and save them as 32-bit and use this type for that.
63+
// Note that this will overflow on January 18, 2038.
64+
typedef int32_t replay_time_t;
65+
5966
static time_t startTime;
6067
static const UnsignedInt startTimeOffset = 6;
61-
static const UnsignedInt endTimeOffset = startTimeOffset + sizeof(time_t);
62-
static const UnsignedInt framesOffset = endTimeOffset + sizeof(time_t);
68+
static const UnsignedInt endTimeOffset = startTimeOffset + sizeof(replay_time_t);
69+
static const UnsignedInt framesOffset = endTimeOffset + sizeof(replay_time_t);
6370
static const UnsignedInt desyncOffset = framesOffset + sizeof(UnsignedInt);
6471
static const UnsignedInt quitEarlyOffset = desyncOffset + sizeof(Bool);
6572
static const UnsignedInt disconOffset = quitEarlyOffset + sizeof(Bool);
@@ -75,7 +82,8 @@ void RecorderClass::logGameStart(AsciiString options)
7582
if (!fseek(m_file, startTimeOffset, SEEK_SET))
7683
{
7784
// save off start time
78-
fwrite(&startTime, sizeof(time_t), 1, m_file);
85+
replay_time_t tmp = (replay_time_t)startTime;
86+
fwrite(&tmp, sizeof(replay_time_t), 1, m_file);
7987
}
8088
// move back to end of stream
8189
#ifdef DEBUG_CRASHING
@@ -229,7 +237,8 @@ void RecorderClass::logGameEnd( void )
229237
if (!fseek(m_file, endTimeOffset, SEEK_SET))
230238
{
231239
// save off end time
232-
fwrite(&t, sizeof(time_t), 1, m_file);
240+
replay_time_t tmp = (replay_time_t)t;
241+
fwrite(&tmp, sizeof(replay_time_t), 1, m_file);
233242
}
234243
// move to appropriate offset
235244
if (!fseek(m_file, framesOffset, SEEK_SET))
@@ -557,9 +566,9 @@ void RecorderClass::startRecording(GameDifficulty diff, Int originalGameMode, In
557566
//
558567
// **** if this changes, change the LAN code above ****
559568
//
560-
time_t t = 0;
561-
fwrite(&t, sizeof(time_t), 1, m_file); // reserve space for start time
562-
fwrite(&t, sizeof(time_t), 1, m_file); // reserve space for end time
569+
replay_time_t t = 0;
570+
fwrite(&t, sizeof(replay_time_t), 1, m_file); // reserve space for start time
571+
fwrite(&t, sizeof(replay_time_t), 1, m_file); // reserve space for end time
563572

564573
UnsignedInt frames = 0;
565574
fwrite(&frames, sizeof(UnsignedInt), 1, m_file); // reserve space for duration in frames
@@ -836,8 +845,11 @@ Bool RecorderClass::readReplayHeader(ReplayHeader& header)
836845
}
837846

838847
// read in some stats
839-
fread(&header.startTime, sizeof(time_t), 1, m_file);
840-
fread(&header.endTime, sizeof(time_t), 1, m_file);
848+
replay_time_t tmp;
849+
fread(&tmp, sizeof(replay_time_t), 1, m_file);
850+
header.startTime = tmp;
851+
fread(&tmp, sizeof(replay_time_t), 1, m_file);
852+
header.endTime = tmp;
841853

842854
fread(&header.frameDuration, sizeof(UnsignedInt), 1, m_file);
843855

0 commit comments

Comments
 (0)