Changeset - r7426:52df5c286c1e
[Not reviewed]
master
0 1 0
rubidium - 17 years ago 2007-08-08 14:18:05
rubidium@openttd.org
(svn r10827) -Fix [FS#1112]: out of bounds access in corner case of list allocations of vehicles.
1 file changed with 25 insertions and 11 deletions:
0 comments (0 inline, 0 general)
src/oldpool.h
Show inline comments
 
@@ -225,60 +225,74 @@ struct PoolItem {
 
	{
 
	}
 

	
 
	/**
 
	 * Is this a valid object or not?
 
	 * @return true if and only if it is valid
 
	 */
 
	virtual bool IsValid() const
 
	{
 
		return false;
 
	}
 

	
 
protected:
 
	/**
 
	 * Allocate a pool item; possibly allocate a new block in the pool.
 
	 * @return the allocated pool item (or NULL when the pool is full).
 
	 */
 
	static inline T *AllocateRaw()
 
	{
 
		return AllocateRaw(Tpool->first_free_index);
 
	}
 

	
 
private:
 
	/**
 
	 * Allocate a pool item; possibly allocate a new block in the pool.
 
	 * @param first the first pool item to start searching
 
	 * @pre first <= Tpool->GetSize()
 
	 * @return the allocated pool item (or NULL when the pool is full).
 
	 */
 
	static inline T *AllocateRaw(uint &first)
 
	static inline T *AllocateSafeRaw(uint &first)
 
	{
 
		uint last_minus_one = Tpool->GetSize() - 1;
 

	
 
		for (T *t = Tpool->Get(first); t != NULL; t = (t->index < last_minus_one) ? Tpool->Get(t->index + 1U) : NULL) {
 
			if (!t->IsValid()) {
 
				first = t->index;
 
				Tid index = t->index;
 

	
 
				memset(t, 0, Tpool->item_size);
 
				t->index = index;
 
				return t;
 
			}
 
		}
 

	
 
		/* Check if we can add a block to the pool */
 
		if (Tpool->AddBlockToPool()) return AllocateRaw(first);
 

	
 
		return NULL;
 
	}
 

	
 
protected:
 
	/**
 
	 * Allocate a pool item; possibly allocate a new block in the pool.
 
	 * @return the allocated pool item (or NULL when the pool is full).
 
	 */
 
	static inline T *AllocateRaw()
 
	{
 
		return AllocateSafeRaw(Tpool->first_free_index);
 
	}
 

	
 
	/**
 
	 * Allocate a pool item; possibly allocate a new block in the pool.
 
	 * @param first the first pool item to start searching
 
	 * @return the allocated pool item (or NULL when the pool is full).
 
	 */
 
	static inline T *AllocateRaw(uint &first)
 
	{
 
		if (first >= Tpool->GetSize() && !Tpool->AddBlockToPool()) return NULL;
 

	
 
		return AllocateSafeRaw(first);
 
	}
 

	
 
	/**
 
	 * Are we cleaning this pool?
 
	 * @return true if we are
 
	 */
 
	static inline bool CleaningPool()
 
	{
 
		return Tpool->CleaningPool();
 
	}
 
};
 

	
 

	
 
#define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
0 comments (0 inline, 0 general)