mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-11-04 18:29:41 +01:00
Prevent same-frame infinite loops in scripts
It's trivially easy to send the scripting system into an infinite loop on the same frame (i.e. without any script delay in between, i.e. within the same execution of script.run()). Just take a look at these two scripts: a: iftrinkets(0,b) # b: iftrinkets(0,a) # The hashes are to prevent the scripting system from parsing iftrinkets() using the internal version instead of the simplified version, because after doing a simplified iftrinkets(), the parser will (to oversimplify) execute the last line of the script as internal. Anyway, sending the game into an infinite loop like this will cause the Not Responding dialog on Windows. So to prevent this from happening, I've added an execution counter to scriptclass::run(). If it gets too high, we're in an infinite loop and so we stop running the script.
This commit is contained in:
parent
662a658cf6
commit
a6a8173e20
1 changed files with 15 additions and 0 deletions
|
@ -9,6 +9,8 @@
|
||||||
#include "Music.h"
|
#include "Music.h"
|
||||||
#include "UtilityClass.h"
|
#include "UtilityClass.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
scriptclass::scriptclass()
|
scriptclass::scriptclass()
|
||||||
{
|
{
|
||||||
//Start SDL
|
//Start SDL
|
||||||
|
@ -76,6 +78,8 @@ void scriptclass::tokenize( const std::string& t )
|
||||||
|
|
||||||
void scriptclass::run()
|
void scriptclass::run()
|
||||||
{
|
{
|
||||||
|
// This counter here will stop the function when it gets too high
|
||||||
|
short execution_counter = 0;
|
||||||
while(running && scriptdelay<=0 && !game.pausescript)
|
while(running && scriptdelay<=0 && !game.pausescript)
|
||||||
{
|
{
|
||||||
if (position < (int) commands.size())
|
if (position < (int) commands.size())
|
||||||
|
@ -2603,6 +2607,17 @@ void scriptclass::run()
|
||||||
{
|
{
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
// Don't increment if we're at the max, signed int overflow is UB
|
||||||
|
if (execution_counter == SHRT_MAX)
|
||||||
|
{
|
||||||
|
// We must be in an infinite loop
|
||||||
|
printf("Warning: execution counter got to %i, stopping script\n", SHRT_MAX);
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
execution_counter++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scriptdelay>0)
|
if(scriptdelay>0)
|
||||||
|
|
Loading…
Reference in a new issue