diff options
author | alberth <alberth@openttd.org> | 2014-07-12 17:04:14 +0000 |
---|---|---|
committer | alberth <alberth@openttd.org> | 2014-07-12 17:04:14 +0000 |
commit | 8fe8765aaa93e0c992305a7a9c4b21dd9c1842c7 (patch) | |
tree | dd7dcc52320f1a73f9fcb2af909e51fa6c1b36fb | |
parent | 98194e7b6a2ad0615b8c68fa368e246f470ea09d (diff) | |
download | openttd-8fe8765aaa93e0c992305a7a9c4b21dd9c1842c7.tar.xz |
(svn r26685) -Fix: Tighten parameter bound checks on GSCargoMonitor functions, and return -1 on out-of-bound parameters.
-rw-r--r-- | src/cargomonitor.cpp | 8 | ||||
-rw-r--r-- | src/cargomonitor.h | 7 | ||||
-rw-r--r-- | src/core/overflowsafe_type.hpp | 1 | ||||
-rw-r--r-- | src/script/api/game_changelog.hpp | 4 | ||||
-rw-r--r-- | src/script/api/script_cargomonitor.cpp | 39 | ||||
-rw-r--r-- | src/script/api/script_cargomonitor.hpp | 20 |
6 files changed, 56 insertions, 23 deletions
diff --git a/src/cargomonitor.cpp b/src/cargomonitor.cpp index 7e0ba9761..b1d52d6b1 100644 --- a/src/cargomonitor.cpp +++ b/src/cargomonitor.cpp @@ -69,7 +69,7 @@ void ClearCargoDeliveryMonitoring(CompanyID company) * @param keep_monitoring After returning from this call, continue monitoring. * @return Amount collected since last query/activation for the monitored combination. */ -static uint32 GetAmount(CargoMonitorMap &monitor_map, CargoMonitorID monitor, bool keep_monitoring) +static int32 GetAmount(CargoMonitorMap &monitor_map, CargoMonitorID monitor, bool keep_monitoring) { CargoMonitorMap::iterator iter = monitor_map.find(monitor); if (iter == monitor_map.end()) { @@ -79,7 +79,7 @@ static uint32 GetAmount(CargoMonitorMap &monitor_map, CargoMonitorID monitor, bo } return 0; } else { - uint32 result = iter->second; + int32 result = iter->second; iter->second = 0; if (!keep_monitoring) monitor_map.erase(iter); return result; @@ -92,7 +92,7 @@ static uint32 GetAmount(CargoMonitorMap &monitor_map, CargoMonitorID monitor, bo * @param keep_monitoring After returning from this call, continue monitoring. * @return Amount of delivered cargo for the monitored combination. */ -uint32 GetDeliveryAmount(CargoMonitorID monitor, bool keep_monitoring) +int32 GetDeliveryAmount(CargoMonitorID monitor, bool keep_monitoring) { return GetAmount(_cargo_deliveries, monitor, keep_monitoring); } @@ -104,7 +104,7 @@ uint32 GetDeliveryAmount(CargoMonitorID monitor, bool keep_monitoring) * @return Amount of picked up cargo for the monitored combination. * @note Cargo pick up is counted on final delivery, to prevent users getting credit for picking up cargo without delivering it. */ -uint32 GetPickupAmount(CargoMonitorID monitor, bool keep_monitoring) +int32 GetPickupAmount(CargoMonitorID monitor, bool keep_monitoring) { return GetAmount(_cargo_pickups, monitor, keep_monitoring); } diff --git a/src/cargomonitor.h b/src/cargomonitor.h index ce9a8e5d6..061a1821a 100644 --- a/src/cargomonitor.h +++ b/src/cargomonitor.h @@ -16,6 +16,7 @@ #include "company_func.h" #include "industry.h" #include "town.h" +#include "core/overflowsafe_type.hpp" #include <map> struct Station; @@ -31,7 +32,7 @@ struct Station; typedef uint32 CargoMonitorID; ///< Type of the cargo monitor number. /** Map type for storing and updating active cargo monitor numbers and their amounts. */ -typedef std::map<CargoMonitorID, uint32> CargoMonitorMap; +typedef std::map<CargoMonitorID, OverflowSafeInt32> CargoMonitorMap; extern CargoMonitorMap _cargo_pickups; extern CargoMonitorMap _cargo_deliveries; @@ -141,8 +142,8 @@ static inline TownID DecodeMonitorTown(CargoMonitorID num) void ClearCargoPickupMonitoring(CompanyID company = INVALID_OWNER); void ClearCargoDeliveryMonitoring(CompanyID company = INVALID_OWNER); -uint32 GetDeliveryAmount(CargoMonitorID monitor, bool keep_monitoring); -uint32 GetPickupAmount(CargoMonitorID monitor, bool keep_monitoring); +int32 GetDeliveryAmount(CargoMonitorID monitor, bool keep_monitoring); +int32 GetPickupAmount(CargoMonitorID monitor, bool keep_monitoring); void AddCargoDelivery(CargoID cargo_type, CompanyID company, uint32 amount, SourceType src_type, SourceID src, const Station *st); #endif /* CARGOMONITOR_H */ diff --git a/src/core/overflowsafe_type.hpp b/src/core/overflowsafe_type.hpp index 42ec98bd0..edc25d275 100644 --- a/src/core/overflowsafe_type.hpp +++ b/src/core/overflowsafe_type.hpp @@ -152,5 +152,6 @@ template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_ template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; } typedef OverflowSafeInt<int64, INT64_MAX, INT64_MIN> OverflowSafeInt64; +typedef OverflowSafeInt<int32, INT32_MAX, INT32_MIN> OverflowSafeInt32; #endif /* OVERFLOWSAFE_TYPE_HPP */ diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index a6a80f9b3..6f1a93b52 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -22,6 +22,10 @@ * API additions: * \li GSStation::GetCargoWaitingFromVia * + * Other changes: + * \li GSCargoMonitor delivery and pickup monitor functions have improved boundary checking for + * their parameters, and return \c -1 if they are found out of bounds. + * * \b 1.4.0 * * API additions: diff --git a/src/script/api/script_cargomonitor.cpp b/src/script/api/script_cargomonitor.cpp index 4b5b85ed6..3cb9b4a8e 100644 --- a/src/script/api/script_cargomonitor.cpp +++ b/src/script/api/script_cargomonitor.cpp @@ -10,31 +10,54 @@ /** @file script_cargomonitor.cpp Code to monitor cargo pickup and deliveries by companies. */ #include "../../stdafx.h" +#include "script_cargo.hpp" #include "script_cargomonitor.hpp" +#include "../../town.h" +#include "../../industry.h" #include "../../safeguards.h" -/* static */ uint32 ScriptCargoMonitor::GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) +/* static */ int32 ScriptCargoMonitor::GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) { - CargoMonitorID monitor = EncodeCargoTownMonitor(static_cast<CompanyID>(company), cargo, town_id); + CompanyID cid = static_cast<CompanyID>(company); + if (cid < OWNER_BEGIN || cid >= MAX_COMPANIES) return -1; + if (!ScriptCargo::IsValidCargo(cargo)) return -1; + if (!::Town::IsValidID(town_id)) return -1; + + CargoMonitorID monitor = EncodeCargoTownMonitor(cid, cargo, town_id); return GetDeliveryAmount(monitor, keep_monitoring); } -/* static */ uint32 ScriptCargoMonitor::GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) +/* static */ int32 ScriptCargoMonitor::GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) { - CargoMonitorID monitor = EncodeCargoIndustryMonitor(static_cast<CompanyID>(company), cargo, industry_id); + CompanyID cid = static_cast<CompanyID>(company); + if (cid < OWNER_BEGIN || cid >= MAX_COMPANIES) return -1; + if (!ScriptCargo::IsValidCargo(cargo)) return -1; + if (!::Industry::IsValidID(industry_id)) return -1; + + CargoMonitorID monitor = EncodeCargoIndustryMonitor(cid, cargo, industry_id); return GetDeliveryAmount(monitor, keep_monitoring); } -/* static */ uint32 ScriptCargoMonitor::GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) +/* static */ int32 ScriptCargoMonitor::GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) { - CargoMonitorID monitor = EncodeCargoTownMonitor(static_cast<CompanyID>(company), cargo, town_id); + CompanyID cid = static_cast<CompanyID>(company); + if (cid < OWNER_BEGIN || cid >= MAX_COMPANIES) return -1; + if (!ScriptCargo::IsValidCargo(cargo)) return -1; + if (!::Town::IsValidID(town_id)) return -1; + + CargoMonitorID monitor = EncodeCargoTownMonitor(cid, cargo, town_id); return GetPickupAmount(monitor, keep_monitoring); } -/* static */ uint32 ScriptCargoMonitor::GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) +/* static */ int32 ScriptCargoMonitor::GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) { - CargoMonitorID monitor = EncodeCargoIndustryMonitor(static_cast<CompanyID>(company), cargo, industry_id); + CompanyID cid = static_cast<CompanyID>(company); + if (cid < OWNER_BEGIN || cid >= MAX_COMPANIES) return -1; + if (!ScriptCargo::IsValidCargo(cargo)) return -1; + if (!::Industry::IsValidID(industry_id)) return -1; + + CargoMonitorID monitor = EncodeCargoIndustryMonitor(cid, cargo, industry_id); return GetPickupAmount(monitor, keep_monitoring); } diff --git a/src/script/api/script_cargomonitor.hpp b/src/script/api/script_cargomonitor.hpp index f0fa56be9..175936db2 100644 --- a/src/script/api/script_cargomonitor.hpp +++ b/src/script/api/script_cargomonitor.hpp @@ -50,9 +50,10 @@ public: * @param cargo Cargo type to query. * @param town_id %Town to query. * @param keep_monitoring If \c true, the given combination continues to be monitored for the next call. If \c false, monitoring ends. - * @return Amount of delivered cargo of the given cargo type to the given town by the given company since the last call. + * @return Amount of delivered cargo of the given cargo type to the given town by the given company since the last call, or + * \c -1 if a parameter is out-of-bound. */ - static uint32 GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring); + static int32 GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring); /** * Get the amount of cargo delivered to an industry by a company since the last query, and update the monitoring state. @@ -60,9 +61,10 @@ public: * @param cargo Cargo type to query. * @param industry_id %Industry to query. * @param keep_monitoring If \c true, the given combination continues to be monitored for the next call. If \c false, monitoring ends. - * @return Amount of delivered cargo of the given cargo type to the given industry by the given company since the last call. + * @return Amount of delivered cargo of the given cargo type to the given industry by the given company since the last call, or + * \c -1 if a parameter is out-of-bound. */ - static uint32 GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring); + static int32 GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring); /** * Get the amount of cargo picked up (and delivered) from a town by a company since the last query, and update the monitoring state. @@ -70,10 +72,11 @@ public: * @param cargo Cargo type to query. * @param town_id %Town to query. * @param keep_monitoring If \c true, the given combination continues to be monitored for the next call. If \c false, monitoring ends. - * @return Amount of picked up cargo of the given cargo type to the given town by the given company since the last call. + * @return Amount of picked up cargo of the given cargo type to the given town by the given company since the last call, or + * \c -1 if a parameter is out-of-bound. * @note Amounts of picked-up cargo are added during final delivery of it, to prevent users from getting credit for picking up without delivering it. */ - static uint32 GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring); + static int32 GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring); /** * Get the amount of cargo picked up (and delivered) from an industry by a company since the last query, and update the monitoring state. @@ -81,10 +84,11 @@ public: * @param cargo Cargo type to query. * @param industry_id %Industry to query. * @param keep_monitoring If \c true, the given combination continues to be monitored for the next call. If \c false, monitoring ends. - * @return Amount of picked up cargo of the given cargo type to the given industry by the given company since the last call. + * @return Amount of picked up cargo of the given cargo type to the given industry by the given company since the last call, or + * \c -1 if a parameter is out-of-bound. * @note Amounts of picked-up cargo are added during final delivery of it, to prevent users from getting credit for picking up without delivering it. */ - static uint32 GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring); + static int32 GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring); /** Stop monitoring everything. */ static void StopAllMonitoring(); |