Attempt to fix demo buffer overflow crash. Also don't record demos at… #38

Merged
alufolie91 merged 1 commits from dont-record-demo-if-disabled into Saturn 2023-08-29 09:13:21 +02:00
+59 -13
View File
@@ -5699,6 +5699,9 @@ void G_GhostAddHit(INT32 playernum, mobj_t *victim)
void G_WriteAllGhostTics(void)
{
UINT8 *save_demo_p = demo_p;
#define CHECKSPACE(num) if (demo_p+(num) > demoend) { demo_p = save_demo_p; G_CheckDemoStatus(); return; }
INT32 i, counter = leveltime;
for (i = 0; i < MAXPLAYERS; i++)
{
@@ -5713,10 +5716,16 @@ void G_WriteAllGhostTics(void)
if (counter % cv_netdemosyncquality.value != 0) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size.
continue;
CHECKSPACE(1);
WRITEUINT8(demo_p, i);
G_WriteGhostTic(players[i].mo, i);
}
CHECKSPACE(1);
WRITEUINT8(demo_p, 0xFF);
#undef CHECKSPACE
}
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
@@ -5727,6 +5736,9 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
UINT8 sprite;
UINT8 frame;
UINT8 *save_demo_p = demo_p;
#define CHECKSPACE(num) if (demo_p+(num) > demoend) { demo_p = save_demo_p; G_CheckDemoStatus(); return; }
if (!demo_p)
return;
if (!(demoflags & DF_GHOST))
@@ -5753,6 +5765,8 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
oldghost[playernum].y = ghost->y;
oldghost[playernum].z = ghost->z;
ziptic |= GZT_XYZ;
CHECKSPACE(sizeof(fixed_t)*3);
WRITEFIXED(demo_p,oldghost[playernum].x);
WRITEFIXED(demo_p,oldghost[playernum].y);
WRITEFIXED(demo_p,oldghost[playernum].z);
@@ -5769,6 +5783,9 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
oldghost[playernum].momx = momx;
oldghost[playernum].momy = momy;
ziptic |= GZT_MOMXY;
CHECKSPACE(4);
WRITEINT16(demo_p,momx);
WRITEINT16(demo_p,momy);
}
@@ -5777,6 +5794,9 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
{
oldghost[playernum].momz = momx;
ziptic |= GZT_MOMZ;
CHECKSPACE(2);
WRITEINT16(demo_p,momx);
}
@@ -5797,6 +5817,9 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
{
oldghost[playernum].angle = ghost->angle>>24;
ziptic |= GZT_ANGLE;
CHECKSPACE(1);
WRITEUINT8(demo_p,oldghost[playernum].angle);
}
@@ -5806,6 +5829,9 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
{
oldghost[playernum].frame = frame;
ziptic |= GZT_SPRITE;
CHECKSPACE(1);
WRITEUINT8(demo_p,oldghost[playernum].frame);
}
@@ -5845,20 +5871,26 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
if (ghostext[playernum].flags & EZT_COLOR)
{
CHECKSPACE(1);
WRITEUINT8(demo_p,ghostext[playernum].color);
ghostext[playernum].lastcolor = ghostext[playernum].color;
}
if (ghostext[playernum].flags & EZT_SCALE)
{
CHECKSPACE(sizeof(fixed_t));
WRITEFIXED(demo_p,ghostext[playernum].scale);
ghostext[playernum].lastscale = ghostext[playernum].scale;
}
if (ghostext[playernum].flags & EZT_HIT)
{
CHECKSPACE(2);
WRITEUINT16(demo_p,ghostext[playernum].hits);
for (i = 0; i < ghostext[playernum].hits; i++)
{
mobj_t *mo = ghostext[playernum].hitlist[i];
CHECKSPACE(4+4+2+sizeof(fixed_t)*3+sizeof(angle_t));
WRITEUINT32(demo_p,UINT32_MAX); // reserved for some method of determining exactly which mobj this is. (mobjnum doesn't work here.)
WRITEUINT32(demo_p,mo->type);
WRITEUINT16(demo_p,(UINT16)mo->health);
@@ -5872,9 +5904,14 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
ghostext[playernum].hitlist = NULL;
}
if (ghostext[playernum].flags & EZT_SPRITE)
{
CHECKSPACE(1);
WRITEUINT8(demo_p,sprite);
}
if (ghostext[playernum].flags & EZT_KART)
{
CHECKSPACE(12);
WRITEINT32(demo_p, ghostext[playernum].kartitem);
WRITEINT32(demo_p, ghostext[playernum].kartamount);
WRITEINT32(demo_p, ghostext[playernum].kartbumpers);
@@ -5891,6 +5928,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
G_CheckDemoStatus(); // no more space
return;
}
#undef CHECKSPACE
}
void G_ConsAllGhostTics(void)
@@ -6743,22 +6781,30 @@ void G_RecordDemo(const char *name)
{
INT32 maxsize;
CONS_Printf("Recording demo %s.lmp\n", name);
strcpy(demoname, name);
strcat(demoname, ".lmp");
maxsize = cv_maxdemosize.value*1024*1024;
if (demobuffer)
free(demobuffer);
demo_p = NULL;
demo.recording = false;
demobuffer = malloc(maxsize);
demoend = demobuffer + maxsize;
if (demobuffer)
demo.recording = true;
else
CONS_Alert(CONS_ERROR, "Failed to allocate demo buffer\n");
free(demobuffer);
demobuffer = NULL;
demoend = NULL;
if (cv_recordmultiplayerdemos.value)
{
CONS_Printf("Recording demo %s.lmp\n", name);
strcpy(demoname, name);
strcat(demoname, ".lmp");
maxsize = cv_maxdemosize.value*1024*1024;
demobuffer = malloc(maxsize);
demoend = demobuffer + maxsize;
if (demobuffer)
demo.recording = true;
else
CONS_Alert(CONS_ERROR, "Failed to allocate demo buffer\n");
}
}
void G_RecordMetal(void)