summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command.cpp18
-rw-r--r--src/economy.cpp4
-rw-r--r--src/macros.h6
-rw-r--r--src/misc_cmd.cpp9
-rw-r--r--src/oldloader.cpp2
-rw-r--r--src/stdafx.h1
6 files changed, 31 insertions, 9 deletions
diff --git a/src/command.cpp b/src/command.cpp
index 31c0d417e..8b814d034 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -594,7 +594,7 @@ callb_err:
CommandCost CommandCost::AddCost(CommandCost ret)
{
- this->cost += ret.cost;
+ this->AddCost(ret.cost);
if (this->success && !ret.success) {
this->message = ret.message;
this->success = false;
@@ -604,13 +604,25 @@ CommandCost CommandCost::AddCost(CommandCost ret)
CommandCost CommandCost::AddCost(Money cost)
{
- this->cost += cost;
+ /* Overflow protection */
+ if (cost < 0 && (this->cost + cost) > this->cost) {
+ this->cost = INT64_MIN;
+ } else if (cost > 0 && (this->cost + cost) < this->cost) {
+ this->cost = INT64_MAX;
+ } else {
+ this->cost += cost;
+ }
return *this;
}
CommandCost CommandCost::MultiplyCost(int factor)
{
- this->cost *= factor;
+ /* Overflow protection */
+ if (factor != 0 && (INT64_MAX / myabs(factor)) < myabs(this->cost)) {
+ this->cost = (this->cost < 0 == factor < 0) ? INT64_MAX : INT64_MIN;
+ } else {
+ this->cost *= factor;
+ }
return *this;
}
diff --git a/src/economy.cpp b/src/economy.cpp
index dd51e0911..fde538feb 100644
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -660,8 +660,8 @@ static void PlayersGenStatistics()
static void AddSingleInflation(Money *value, uint16 *frac, int32 amt)
{
/* Is it safe to add inflation ? */
- if ((MAX_UVALUE(Money) / 2 / amt) > (*value + *frac + 1)) {
- *value = MAX_UVALUE(Money);
+ if ((INT64_MAX / amt) < (*value + 1)) {
+ *value = INT64_MAX / amt;
*frac = 0;
} else {
int64 tmp = (int64)*value * amt + *frac;
diff --git a/src/macros.h b/src/macros.h
index 7b8b8dba6..c10ef4d49 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -26,6 +26,12 @@ static inline T max(T a, T b)
return a >= b ? a : b;
}
+template <typename T>
+static inline T min(T a, T b)
+{
+ return a < b ? a : b;
+}
+
static inline int min(int a, int b) { if (a <= b) return a; return b; }
static inline uint minu(uint a, uint b) { if (a <= b) return a; return b; }
diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp
index ecbf5d8bf..69ecbf29d 100644
--- a/src/misc_cmd.cpp
+++ b/src/misc_cmd.cpp
@@ -144,6 +144,9 @@ CommandCost CmdIncreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
break;
}
+ /* Overflow protection */
+ if (p->player_money + p->current_loan + loan < p->player_money) return CMD_ERROR;
+
if (flags & DC_EXEC) {
p->player_money += loan;
p->current_loan += loan;
@@ -166,14 +169,14 @@ CommandCost CmdDecreaseLoan(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (p->current_loan == 0) return_cmd_error(STR_702D_LOAN_ALREADY_REPAYED);
- int32 loan;
+ Money loan;
switch (p2) {
default: return CMD_ERROR; // Invalid method
case 0: // Pay back one step
loan = min(p->current_loan, (IsHumanPlayer(_current_player) || _patches.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI);
break;
case 1: // Pay back as much as possible
- loan = max(min(p->current_loan, p->player_money), (int32)LOAN_INTERVAL);
+ loan = max(min(p->current_loan, p->player_money), (Money)LOAN_INTERVAL);
loan -= loan % LOAN_INTERVAL;
break;
}
@@ -304,7 +307,7 @@ CommandCost CmdMoneyCheat(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
const Player *p = GetPlayer(_current_player);
- CommandCost amount((Money)min(p1, 20000000LL));
+ CommandCost amount(min((Money)p1, 20000000LL));
SET_EXPENSES_TYPE(EXPENSES_OTHER);
diff --git a/src/oldloader.cpp b/src/oldloader.cpp
index d0a4030bd..28496cc7c 100644
--- a/src/oldloader.cpp
+++ b/src/oldloader.cpp
@@ -541,7 +541,7 @@ static bool LoadOldPrice(LoadgameState *ls, int num)
/* We use a struct to store the prices, but they are ints in a row..
so just access the struct as an array of int32's */
- ((int32*)&_price)[num] = _old_price;
+ ((Money*)&_price)[num] = _old_price;
_price_frac[num] = _old_price_frac;
return true;
diff --git a/src/stdafx.h b/src/stdafx.h
index 8dd3fcd85..7d19e5896 100644
--- a/src/stdafx.h
+++ b/src/stdafx.h
@@ -20,6 +20,7 @@
# endif
#else
# define INT64_MAX 9223372036854775807LL
+# define INT64_MIN -9223372036854775808LL
#endif
#include <cstdio>