1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-23 18:19:43 +01:00

Fix indexing out-of-bounds via an entity's drawframe

I tracked down all the functions that took in an entity's drawframe and
made sure that no matter what value an entity's drawframe was, the game
would never segfault.
This commit is contained in:
Misa 2020-06-13 18:35:12 -07:00 committed by Ethan Lee
parent 6900553f57
commit 5195299e65
3 changed files with 44 additions and 5 deletions

View file

@ -4603,8 +4603,11 @@ void entityclass::entitycollisioncheck()
colpoint1.y = entities[i].yp; colpoint1.y = entities[i].yp;
colpoint2.x = entities[j].xp; colpoint2.x = entities[j].xp;
colpoint2.y = entities[j].yp; colpoint2.y = entities[j].yp;
if (graphics.Hitest(spritesvec[entities[i].drawframe], int drawframe1 = entities[i].drawframe;
colpoint1, spritesvec[entities[j].drawframe], colpoint2)) int drawframe2 = entities[j].drawframe;
if (INBOUNDS(drawframe1, spritesvec) && INBOUNDS(drawframe2, spritesvec)
&& graphics.Hitest(spritesvec[drawframe1],
colpoint1, spritesvec[drawframe2], colpoint2))
{ {
//Do the collision stuff //Do the collision stuff
game.deathseq = 30; game.deathseq = 30;
@ -4703,8 +4706,11 @@ void entityclass::entitycollisioncheck()
colpoint1.y = entities[i].yp; colpoint1.y = entities[i].yp;
colpoint2.x = entities[j].xp; colpoint2.x = entities[j].xp;
colpoint2.y = entities[j].yp; colpoint2.y = entities[j].yp;
if (graphics.Hitest(spritesvec[entities[i].drawframe], int drawframe1 = entities[i].drawframe;
colpoint1, spritesvec[entities[j].drawframe], colpoint2)) int drawframe2 = entities[j].drawframe;
if (INBOUNDS(drawframe1, spritesvec) && INBOUNDS(drawframe2, spritesvec)
&& graphics.Hitest(spritesvec[drawframe1],
colpoint1, spritesvec[drawframe2], colpoint2))
{ {
//Do the collision stuff //Do the collision stuff
game.deathseq = 30; game.deathseq = 30;

View file

@ -143,6 +143,10 @@ Graphics::~Graphics()
void Graphics::drawspritesetcol(int x, int y, int t, int c) void Graphics::drawspritesetcol(int x, int y, int t, int c)
{ {
if (!INBOUNDS(t, sprites))
{
return;
}
SDL_Rect rect; SDL_Rect rect;
setRect(rect,x,y,sprites_rect.w,sprites_rect.h); setRect(rect,x,y,sprites_rect.w,sprites_rect.h);
setcol(c); setcol(c);
@ -1442,6 +1446,10 @@ void Graphics::drawentities()
{ {
case 0: case 0:
// Sprites // Sprites
if (!INBOUNDS(obj.entities[i].drawframe, (*spritesvec)))
{
continue;
}
tpoint.x = obj.entities[i].xp; tpoint.x = obj.entities[i].xp;
tpoint.y = obj.entities[i].yp - yoff; tpoint.y = obj.entities[i].yp - yoff;
setcol(obj.entities[i].colour); setcol(obj.entities[i].colour);
@ -1494,6 +1502,10 @@ void Graphics::drawentities()
break; break;
case 1: case 1:
// Tiles // Tiles
if (!INBOUNDS(obj.entities[i].drawframe, tiles))
{
continue;
}
tpoint.x = obj.entities[i].xp; tpoint.x = obj.entities[i].xp;
tpoint.y = obj.entities[i].yp - yoff; tpoint.y = obj.entities[i].yp - yoff;
drawRect = tiles_rect; drawRect = tiles_rect;
@ -1505,6 +1517,10 @@ void Graphics::drawentities()
case 8: case 8:
{ {
// Special: Moving platform, 4 tiles or 8 tiles // Special: Moving platform, 4 tiles or 8 tiles
if (!INBOUNDS(obj.entities[i].drawframe, (*tilesvec)))
{
continue;
}
tpoint.x = obj.entities[i].xp; tpoint.x = obj.entities[i].xp;
tpoint.y = obj.entities[i].yp - yoff; tpoint.y = obj.entities[i].yp - yoff;
int thiswidth = 4; int thiswidth = 4;
@ -1559,6 +1575,10 @@ void Graphics::drawentities()
// Note: This code is in the 4-tile code // Note: This code is in the 4-tile code
break; break;
case 9: // Really Big Sprite! (2x2) case 9: // Really Big Sprite! (2x2)
if (!INBOUNDS(obj.entities[i].drawframe, (*spritesvec)))
{
continue;
}
setcol(obj.entities[i].colour); setcol(obj.entities[i].colour);
tpoint.x = obj.entities[i].xp; tpoint.x = obj.entities[i].xp;
@ -1594,6 +1614,10 @@ void Graphics::drawentities()
BlitSurfaceColoured((*spritesvec)[obj.entities[i].drawframe + 13],NULL, backBuffer, &drawRect, ct); BlitSurfaceColoured((*spritesvec)[obj.entities[i].drawframe + 13],NULL, backBuffer, &drawRect, ct);
break; break;
case 10: // 2x1 Sprite case 10: // 2x1 Sprite
if (!INBOUNDS(obj.entities[i].drawframe, (*spritesvec)))
{
continue;
}
setcol(obj.entities[i].colour); setcol(obj.entities[i].colour);
tpoint.x = obj.entities[i].xp; tpoint.x = obj.entities[i].xp;
@ -1617,6 +1641,10 @@ void Graphics::drawentities()
drawimagecol(3, obj.entities[i].xp, obj.entities[i].yp - yoff); drawimagecol(3, obj.entities[i].xp, obj.entities[i].yp - yoff);
break; break;
case 12: // Regular sprites that don't wrap case 12: // Regular sprites that don't wrap
if (!INBOUNDS(obj.entities[i].drawframe, (*spritesvec)))
{
continue;
}
tpoint.x = obj.entities[i].xp; tpoint.x = obj.entities[i].xp;
tpoint.y = obj.entities[i].yp - yoff; tpoint.y = obj.entities[i].yp - yoff;
setcol(obj.entities[i].colour); setcol(obj.entities[i].colour);
@ -1674,6 +1702,10 @@ void Graphics::drawentities()
case 13: case 13:
{ {
//Special for epilogue: huge hero! //Special for epilogue: huge hero!
if (!INBOUNDS(obj.entities[i].drawframe, (*spritesvec)))
{
continue;
}
tpoint.x = obj.entities[i].xp; tpoint.y = obj.entities[i].yp - yoff; tpoint.x = obj.entities[i].xp; tpoint.y = obj.entities[i].yp - yoff;
setcol(obj.entities[i].colour); setcol(obj.entities[i].colour);

View file

@ -2816,7 +2816,8 @@ void editorrender()
SDL_FillRect(graphics.ghostbuffer, NULL, SDL_MapRGBA(graphics.ghostbuffer->format, 0, 0, 0, 0)); SDL_FillRect(graphics.ghostbuffer, NULL, SDL_MapRGBA(graphics.ghostbuffer->format, 0, 0, 0, 0));
for (int i = 0; i < (int)ed.ghosts.size(); i++) { for (int i = 0; i < (int)ed.ghosts.size(); i++) {
if (i <= ed.currentghosts) { // We don't want all of them to show up at once :) if (i <= ed.currentghosts) { // We don't want all of them to show up at once :)
if (ed.ghosts[i].rx != ed.levx || ed.ghosts[i].ry != ed.levy) if (ed.ghosts[i].rx != ed.levx || ed.ghosts[i].ry != ed.levy
|| !INBOUNDS(ed.ghosts[i].frame, graphics.sprites))
continue; continue;
point tpoint; point tpoint;
tpoint.x = ed.ghosts[i].x; tpoint.x = ed.ghosts[i].x;