mirror of https://github.com/OpenTTD/OpenTTD
(svn r17417) [0.7] -Backport from trunk:
- Fix: Incomplete check on validity of industry type when building industries (r17413) - Fix: [Squirrel] Guard against Squirrel stack overflows (r17403) - Fix: [NoAI] During every save a few slots on the Squirrel stack were leaked (r17402) - Fix: [NoAI] Several AITile::* functions did not check whether their parameters were valid (r17378)release/0.7
parent
0a4299bdfd
commit
a442343076
|
@ -88,7 +88,7 @@ public:
|
||||||
}
|
}
|
||||||
SQUnsignedInteger capacity() { return _allocated; }
|
SQUnsignedInteger capacity() { return _allocated; }
|
||||||
inline T &back() const { return _vals[_size - 1]; }
|
inline T &back() const { return _vals[_size - 1]; }
|
||||||
inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
|
inline T& operator[](SQUnsignedInteger pos) const{ assert(pos < _allocated); return _vals[pos]; }
|
||||||
T* _vals;
|
T* _vals;
|
||||||
private:
|
private:
|
||||||
void _realloc(SQUnsignedInteger newsize)
|
void _realloc(SQUnsignedInteger newsize)
|
||||||
|
|
|
@ -1503,7 +1503,19 @@ void SQVM::Pop(SQInteger n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; }
|
void SQVM::Push(const SQObjectPtr &o) {
|
||||||
|
/* Normally the stack shouldn't get this full, sometimes it might. As of now
|
||||||
|
* all cases have been bugs in "our" (OpenTTD) code. Trigger an assert for
|
||||||
|
* all debug builds and for the release builds just increase the stack size.
|
||||||
|
* This way getting a false positive isn't that bad (releases work fine) and
|
||||||
|
* if there is something fishy it can be caught in RCs/nightlies. */
|
||||||
|
#ifdef NDEBUG
|
||||||
|
if (_top >= (int)_stack.capacity()) _stack.resize(2 * _stack.capacity());
|
||||||
|
#else
|
||||||
|
assert(_top < (int)_stack.capacity());
|
||||||
|
#endif
|
||||||
|
_stack[_top++] = o;
|
||||||
|
}
|
||||||
SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
|
SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
|
||||||
SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
|
SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
|
||||||
SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }
|
SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }
|
||||||
|
|
|
@ -87,31 +87,43 @@
|
||||||
|
|
||||||
/* static */ bool AITile::HasTreeOnTile(TileIndex tile)
|
/* static */ bool AITile::HasTreeOnTile(TileIndex tile)
|
||||||
{
|
{
|
||||||
|
if (!::IsValidTile(tile)) return false;
|
||||||
|
|
||||||
return ::IsTileType(tile, MP_TREES);
|
return ::IsTileType(tile, MP_TREES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool AITile::IsFarmTile(TileIndex tile)
|
/* static */ bool AITile::IsFarmTile(TileIndex tile)
|
||||||
{
|
{
|
||||||
|
if (!::IsValidTile(tile)) return false;
|
||||||
|
|
||||||
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_FIELDS));
|
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_FIELDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool AITile::IsRockTile(TileIndex tile)
|
/* static */ bool AITile::IsRockTile(TileIndex tile)
|
||||||
{
|
{
|
||||||
|
if (!::IsValidTile(tile)) return false;
|
||||||
|
|
||||||
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_ROCKS));
|
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_ROCKS));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool AITile::IsRoughTile(TileIndex tile)
|
/* static */ bool AITile::IsRoughTile(TileIndex tile)
|
||||||
{
|
{
|
||||||
|
if (!::IsValidTile(tile)) return false;
|
||||||
|
|
||||||
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_ROUGH));
|
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_ROUGH));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool AITile::IsSnowTile(TileIndex tile)
|
/* static */ bool AITile::IsSnowTile(TileIndex tile)
|
||||||
{
|
{
|
||||||
|
if (!::IsValidTile(tile)) return false;
|
||||||
|
|
||||||
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_SNOW));
|
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_SNOW));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool AITile::IsDesertTile(TileIndex tile)
|
/* static */ bool AITile::IsDesertTile(TileIndex tile)
|
||||||
{
|
{
|
||||||
|
if (!::IsValidTile(tile)) return false;
|
||||||
|
|
||||||
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_DESERT));
|
return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_DESERT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1642,7 +1642,10 @@ static Industry *CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCo
|
||||||
*/
|
*/
|
||||||
CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
{
|
{
|
||||||
const IndustrySpec *indspec = GetIndustrySpec(GB(p1, 0, 16));
|
IndustryType it = GB(p1, 0, 16);
|
||||||
|
if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR;
|
||||||
|
|
||||||
|
const IndustrySpec *indspec = GetIndustrySpec(it);
|
||||||
const Industry *ind = NULL;
|
const Industry *ind = NULL;
|
||||||
|
|
||||||
/* Check if the to-be built/founded industry is available for this climate. */
|
/* Check if the to-be built/founded industry is available for this climate. */
|
||||||
|
@ -1681,7 +1684,8 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||||
} else {
|
} else {
|
||||||
int count = indspec->num_table;
|
int count = indspec->num_table;
|
||||||
const IndustryTileTable * const *itt = indspec->table;
|
const IndustryTileTable * const *itt = indspec->table;
|
||||||
int num = Clamp(GB(p1, 16, 16), 0, count - 1);
|
int num = GB(p1, 16, 16);
|
||||||
|
if (num >= count) return CMD_ERROR;
|
||||||
|
|
||||||
_error_message = STR_0239_SITE_UNSUITABLE;
|
_error_message = STR_0239_SITE_UNSUITABLE;
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -222,7 +222,7 @@ bool Squirrel::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT
|
||||||
if (ret != NULL) sq_getstackobj(vm, -1, ret);
|
if (ret != NULL) sq_getstackobj(vm, -1, ret);
|
||||||
/* Reset the top, but don't do so for the AI main function, as we need
|
/* Reset the top, but don't do so for the AI main function, as we need
|
||||||
* a correct stack when resuming. */
|
* a correct stack when resuming. */
|
||||||
if (!this->IsSuspended()) sq_settop(this->vm, top);
|
if (suspend == -1) sq_settop(this->vm, top);
|
||||||
/* Restore the return-value location. */
|
/* Restore the return-value location. */
|
||||||
this->vm->_suspended_target = last_target;
|
this->vm->_suspended_target = last_target;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue