Changeset - r21562:3a3a489566c6
[Not reviewed]
master
0 6 0
alberth - 10 years ago 2014-07-12 17:04:14
alberth@openttd.org
(svn r26685) -Fix: Tighten parameter bound checks on GSCargoMonitor functions, and return -1 on out-of-bound parameters.
6 files changed with 56 insertions and 23 deletions:
0 comments (0 inline, 0 general)
src/cargomonitor.cpp
Show inline comments
 
@@ -69,7 +69,7 @@ void ClearCargoDeliveryMonitoring(Compan
 
 * @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 
 
		}
 
		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 
 
 * @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 
 
 * @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);
 
}
src/cargomonitor.h
Show inline comments
 
@@ -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(C
 

	
 
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 */
src/core/overflowsafe_type.hpp
Show inline comments
 
@@ -152,5 +152,6 @@ template <class T, int64 T_MAX, int64 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 */
src/script/api/game_changelog.hpp
Show inline comments
 
@@ -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:
src/script/api/script_cargomonitor.cpp
Show inline comments
 
@@ -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);
 
}
 

	
src/script/api/script_cargomonitor.hpp
Show inline comments
 
@@ -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();
0 comments (0 inline, 0 general)