Changeset - r11405:7360554fa9a2
[Not reviewed]
master
0 1 0
rubidium - 16 years ago 2009-03-19 17:58:25
rubidium@openttd.org
(svn r15767) -Fix: infinite loop when skipping sprites when a GRF is invalid (or truncated).
1 file changed with 5 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/spritecache.cpp
Show inline comments
 
@@ -77,31 +77,34 @@ static int _compact_cache_counter;
 
static void CompactSpriteCache();
 

	
 
/**
 
 * Skip the given amount of sprite graphics data.
 
 * @param type the type of sprite (compressed etc)
 
 * @param num the amount of sprites to skip
 
 * @return true if the data could be correctly skipped.
 
 */
 
void SkipSpriteData(byte type, uint16 num)
 
bool SkipSpriteData(byte type, uint16 num)
 
{
 
	if (type & 2) {
 
		FioSkipBytes(num);
 
	} else {
 
		while (num > 0) {
 
			int8 i = FioReadByte();
 
			if (i >= 0) {
 
				int size = (i == 0) ? 0x80 : i;
 
				if (size > num) return false;
 
				num -= size;
 
				FioSkipBytes(size);
 
			} else {
 
				i = -(i >> 3);
 
				num -= i;
 
				FioReadByte();
 
			}
 
		}
 
	}
 
	return true;
 
}
 

	
 
/**
 
 * Read the sprite header data and then skip the real payload.
 
 * @return type of sprite; ST_INVALID if the sprite is a pseudo- or unusable sprite
 
 */
 
@@ -117,15 +120,13 @@ static SpriteType ReadSpriteHeaderSkipDa
 
		/* Some NewGRF files have "empty" pseudo-sprites which are 1
 
		 * byte long. Catch these so the sprites won't be displayed. */
 
		return (num == 1) ? ST_INVALID : ST_RECOLOUR;
 
	}
 

	
 
	FioSkipBytes(7);
 
	SkipSpriteData(type, num - 8);
 

	
 
	return ST_NORMAL;
 
	return SkipSpriteData(type, num - 8) ? ST_NORMAL : ST_INVALID;
 
}
 

	
 
/* Check if the given Sprite ID exists */
 
bool SpriteExists(SpriteID id)
 
{
 
	/* Special case for Sprite ID zero -- its position is also 0... */
0 comments (0 inline, 0 general)