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

Bounds check all entity getters that can return 0

The entity getters I'm referring to are entityclass::getscm(),
entityclass::getlineat(), entityclass::getcrewman(), and
entityclass::getcustomcrewman().

Even though the player should always exist, and the player should always
be indice 0, I wouldn't want to make that assumption. I've been wrong
before.

Also, these functions returning 0 lull you into a false sense of
security. If you assume that commands using these functions are fine,
you'll forget about the fact that `i` in those commands could be
potentially anything, given an invalid argument. In fact, it's possible
to index createactivityzone(), flipgravity(), and customposition()
out-of-bounds by setting `i` to anything! Well, WAS possible. I fixed it
so now they can't.

Furthermore, in the game.scmmoveme block in gamelogic(), obj.getplayer()
wasn't even checked, even though it's been checked in all other places.
I only caught it just now because I wanted to bounds-check all usages of
obj.getscm(), too, and that game.scmmove block also used obj.getscm()
without bounds-checking it as well.
This commit is contained in:
Misa 2020-09-09 22:31:09 -07:00 committed by Ethan Lee
parent 19a8352775
commit 76d6a3536b
5 changed files with 136 additions and 96 deletions

View file

@ -2813,110 +2813,125 @@ bool entityclass::updateentities( int i )
{ {
//11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue) //11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue)
int j=getcrewman(1); //purple int j=getcrewman(1); //purple
if (entities[j].xp > entities[i].xp + 5) if (INBOUNDS_VEC(j, entities))
{ {
entities[i].dir = 1; if (entities[j].xp > entities[i].xp + 5)
} {
else if (entities[j].xp < entities[i].xp - 5) entities[i].dir = 1;
{ }
entities[i].dir = 0; else if (entities[j].xp < entities[i].xp - 5)
} {
entities[i].dir = 0;
}
if (entities[j].xp > entities[i].xp + 45) if (entities[j].xp > entities[i].xp + 45)
{ {
entities[i].ax = 3; entities[i].ax = 3;
} }
else if (entities[j].xp < entities[i].xp - 45) else if (entities[j].xp < entities[i].xp - 45)
{ {
entities[i].ax = -3; entities[i].ax = -3;
}
} }
} }
else if (entities[i].state == 12) else if (entities[i].state == 12)
{ {
//11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue) //11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue)
int j=getcrewman(2); //yellow int j=getcrewman(2); //yellow
if (entities[j].xp > entities[i].xp + 5) if (INBOUNDS_VEC(j, entities))
{ {
entities[i].dir = 1; if (entities[j].xp > entities[i].xp + 5)
} {
else if (entities[j].xp < entities[i].xp - 5) entities[i].dir = 1;
{ }
entities[i].dir = 0; else if (entities[j].xp < entities[i].xp - 5)
} {
entities[i].dir = 0;
}
if (entities[j].xp > entities[i].xp + 45) if (entities[j].xp > entities[i].xp + 45)
{ {
entities[i].ax = 3; entities[i].ax = 3;
} }
else if (entities[j].xp < entities[i].xp - 45) else if (entities[j].xp < entities[i].xp - 45)
{ {
entities[i].ax = -3; entities[i].ax = -3;
}
} }
} }
else if (entities[i].state == 13) else if (entities[i].state == 13)
{ {
//11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue) //11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue)
int j=getcrewman(3); //red int j=getcrewman(3); //red
if (entities[j].xp > entities[i].xp + 5) if (INBOUNDS_VEC(j, entities))
{ {
entities[i].dir = 1; if (entities[j].xp > entities[i].xp + 5)
} {
else if (entities[j].xp < entities[i].xp - 5) entities[i].dir = 1;
{ }
entities[i].dir = 0; else if (entities[j].xp < entities[i].xp - 5)
} {
entities[i].dir = 0;
}
if (entities[j].xp > entities[i].xp + 45) if (entities[j].xp > entities[i].xp + 45)
{ {
entities[i].ax = 3; entities[i].ax = 3;
} }
else if (entities[j].xp < entities[i].xp - 45) else if (entities[j].xp < entities[i].xp - 45)
{ {
entities[i].ax = -3; entities[i].ax = -3;
}
} }
} }
else if (entities[i].state == 14) else if (entities[i].state == 14)
{ {
//11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue) //11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue)
int j=getcrewman(4); //green int j=getcrewman(4); //green
if (entities[j].xp > entities[i].xp + 5) if (INBOUNDS_VEC(j, entities))
{ {
entities[i].dir = 1; if (entities[j].xp > entities[i].xp + 5)
} {
else if (entities[j].xp < entities[i].xp - 5) entities[i].dir = 1;
{ }
entities[i].dir = 0; else if (entities[j].xp < entities[i].xp - 5)
} {
entities[i].dir = 0;
}
if (entities[j].xp > entities[i].xp + 45) if (entities[j].xp > entities[i].xp + 45)
{ {
entities[i].ax = 3; entities[i].ax = 3;
} }
else if (entities[j].xp < entities[i].xp - 45) else if (entities[j].xp < entities[i].xp - 45)
{ {
entities[i].ax = -3; entities[i].ax = -3;
}
} }
} }
else if (entities[i].state == 15) else if (entities[i].state == 15)
{ {
//11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue) //11-15 means to follow a specific character, in crew order (cyan, purple, yellow, red, green, blue)
int j=getcrewman(5); //blue int j=getcrewman(5); //blue
if (entities[j].xp > entities[i].xp + 5) if (INBOUNDS_VEC(j, entities))
{ {
entities[i].dir = 1; if (entities[j].xp > entities[i].xp + 5)
} {
else if (entities[j].xp < entities[i].xp - 5) entities[i].dir = 1;
{ }
entities[i].dir = 0; else if (entities[j].xp < entities[i].xp - 5)
} {
entities[i].dir = 0;
}
if (entities[j].xp > entities[i].xp + 45) if (entities[j].xp > entities[i].xp + 45)
{ {
entities[i].ax = 3; entities[i].ax = 3;
} }
else if (entities[j].xp < entities[i].xp - 45) else if (entities[j].xp < entities[i].xp - 45)
{ {
entities[i].ax = -3; entities[i].ax = -3;
}
} }
} }
else if (entities[i].state == 16) else if (entities[i].state == 16)

View file

@ -769,12 +769,16 @@ void gamelogic()
} }
else if (game.swngame == 3) //extend line else if (game.swngame == 3) //extend line
{ {
obj.entities[obj.getlineat(84 - 32)].w += 24; int line = obj.getlineat(84 - 32);
if (obj.entities[obj.getlineat(84 - 32)].w > 332) if (INBOUNDS_VEC(line, obj.entities))
{ {
obj.entities[obj.getlineat(84 - 32)].w = 332; obj.entities[line].w += 24;
game.swngame = 2; if (obj.entities[line].w > 332)
graphics.kludgeswnlinewidth = true; {
obj.entities[line].w = 332;
game.swngame = 2;
graphics.kludgeswnlinewidth = true;
}
} }
} }
else if (game.swngame == 4) //create top line else if (game.swngame == 4) //create top line
@ -786,12 +790,16 @@ void gamelogic()
} }
else if (game.swngame == 5) //remove line else if (game.swngame == 5) //remove line
{ {
obj.entities[obj.getlineat(148 + 32)].xp += 24; int line = obj.getlineat(148 + 32);
if (obj.entities[obj.getlineat(148 + 32)].xp > 320) if (INBOUNDS_VEC(line, obj.entities))
{ {
obj.removeentity(obj.getlineat(148 + 32)); obj.entities[line].xp += 24;
game.swnmode = false; if (obj.entities[line].xp > 320)
game.swngame = 6; {
obj.removeentity(line);
game.swnmode = false;
game.swngame = 6;
}
} }
} }
else if (game.swngame == 6) //Init the super gravitron else if (game.swngame == 6) //Init the super gravitron
@ -1587,7 +1595,12 @@ void gamelogic()
if (game.scmmoveme) if (game.scmmoveme)
{ {
obj.entities[obj.getscm()].xp = obj.entities[obj.getplayer()].xp; int scm = obj.getscm();
int player = obj.getplayer();
if (INBOUNDS_VEC(scm, obj.entities) && INBOUNDS_VEC(player, obj.entities))
{
obj.entities[scm].xp = obj.entities[player].xp;
}
game.scmmoveme = false; game.scmmoveme = false;
} }
break; break;

View file

@ -2077,8 +2077,11 @@ void mapclass::loadlevel(int rx, int ry)
//A slight varation - she's upside down //A slight varation - she's upside down
obj.createentity(249, 62, 18, 16, 0, 18); obj.createentity(249, 62, 18, 16, 0, 18);
int j = obj.getcrewman(5); int j = obj.getcrewman(5);
obj.entities[j].rule = 7; if (INBOUNDS_VEC(j, obj.entities))
obj.entities[j].tile +=6; {
obj.entities[j].rule = 7;
obj.entities[j].tile +=6;
}
//What script do we use? //What script do we use?
obj.createblock(5, 249-32, 0, 32+32+32, 240, 5); obj.createblock(5, 249-32, 0, 32+32+32, 240, 5);
} }

View file

@ -3,6 +3,7 @@
#include "Game.h" #include "Game.h"
#include "Entity.h" #include "Entity.h"
#include "MakeAndPlay.h" #include "MakeAndPlay.h"
#include "UtilityClass.h"
const short* otherlevelclass::loadlevel(int rx, int ry) const short* otherlevelclass::loadlevel(int rx, int ry)
{ {
@ -8892,8 +8893,12 @@ const short* otherlevelclass::loadlevel(int rx, int ry)
//violet //violet
obj.createentity(83, 126, 18, 20, 0, 18); obj.createentity(83, 126, 18, 20, 0, 18);
obj.entities[obj.getcrewman(1)].rule = 7; int crewman = obj.getcrewman(1);
obj.entities[obj.getcrewman(1)].tile +=6; if (INBOUNDS_VEC(crewman, obj.entities))
{
obj.entities[crewman].rule = 7;
obj.entities[crewman].tile +=6;
}
obj.createblock(5, 83 - 32, 0, 32 + 32 + 32, 240, 1); obj.createblock(5, 83 - 32, 0, 32 + 32 + 32, 240, 1);
} }
result = contents; result = contents;

View file

@ -582,7 +582,7 @@ void scriptclass::run()
} }
//next is whether to position above or below //next is whether to position above or below
if (words[2] == "above") if (INBOUNDS_VEC(i, obj.entities) && words[2] == "above")
{ {
if (j == 1) //left if (j == 1) //left
{ {
@ -595,7 +595,7 @@ void scriptclass::run()
texty = obj.entities[i].yp - 18 - (txt.size() * 8); texty = obj.entities[i].yp - 18 - (txt.size() * 8);
} }
} }
else else if (INBOUNDS_VEC(i, obj.entities))
{ {
if (j == 1) //left if (j == 1) //left
{ {
@ -922,11 +922,11 @@ void scriptclass::run()
obj.customcrewmoods[1]=ss_toi(words[2]); obj.customcrewmoods[1]=ss_toi(words[2]);
} }
if (ss_toi(words[2]) == 0) if (INBOUNDS_VEC(i, obj.entities) && ss_toi(words[2]) == 0)
{ {
obj.entities[i].tile = 0; obj.entities[i].tile = 0;
} }
else else if (INBOUNDS_VEC(i, obj.entities))
{ {
obj.entities[i].tile = 144; obj.entities[i].tile = 144;
} }
@ -1001,12 +1001,12 @@ void scriptclass::run()
i=obj.getcrewman(1); i=obj.getcrewman(1);
} }
if (obj.entities[i].rule == 7) if (INBOUNDS_VEC(i, obj.entities) && obj.entities[i].rule == 7)
{ {
obj.entities[i].rule = 6; obj.entities[i].rule = 6;
obj.entities[i].tile = 0; obj.entities[i].tile = 0;
} }
else if (obj.getplayer() != i) // Don't destroy player entity else if (INBOUNDS_VEC(i, obj.entities) && obj.getplayer() != i) // Don't destroy player entity
{ {
obj.entities[i].rule = 7; obj.entities[i].rule = 7;
obj.entities[i].tile = 6; obj.entities[i].tile = 6;
@ -1863,13 +1863,14 @@ void scriptclass::run()
i=1; i=1;
} }
if (i == 4) int crewman = obj.getcrewman(i);
if (INBOUNDS_VEC(crewman, obj.entities) && i == 4)
{ {
obj.createblock(5, obj.entities[obj.getcrewman(i)].xp - 32, obj.entities[obj.getcrewman(i)].yp-20, 96, 60, i); obj.createblock(5, obj.entities[crewman].xp - 32, obj.entities[crewman].yp-20, 96, 60, i);
} }
else else if (INBOUNDS_VEC(crewman, obj.entities))
{ {
obj.createblock(5, obj.entities[obj.getcrewman(i)].xp - 32, 0, 96, 240, i); obj.createblock(5, obj.entities[crewman].xp - 32, 0, 96, 240, i);
} }
} }
else if (words[0] == "createrescuedcrew") else if (words[0] == "createrescuedcrew")
@ -2097,7 +2098,10 @@ void scriptclass::run()
obj.createentity(200, 153, 18, r, 0, 19, 30); obj.createentity(200, 153, 18, r, 0, 19, 30);
i = obj.getcrewman(game.lastsaved); i = obj.getcrewman(game.lastsaved);
obj.entities[i].dir = 1; if (INBOUNDS_VEC(i, obj.entities))
{
obj.entities[i].dir = 1;
}
} }
else if (words[0] == "specialline") else if (words[0] == "specialline")
{ {