From 8064ef288b3bacda9abbd2f044d4b586c085349c Mon Sep 17 00:00:00 2001 From: Silent Date: Mon, 31 Jan 2022 23:06:54 +0100 Subject: [PATCH] Fix money overflow in scenario_entrance_fee_too_high_check and more --- src/openrct2/management/Award.cpp | 2 +- src/openrct2/scenario/Scenario.cpp | 3 +-- src/openrct2/util/Util.cpp | 10 +++++++++- src/openrct2/util/Util.h | 3 ++- src/openrct2/world/Park.cpp | 4 ++-- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/openrct2/management/Award.cpp b/src/openrct2/management/Award.cpp index 56f412ca17..b8d19438f5 100644 --- a/src/openrct2/management/Award.cpp +++ b/src/openrct2/management/Award.cpp @@ -231,7 +231,7 @@ static bool award_is_deserved_worst_value(int32_t activeAwardTypes) if (gParkFlags & PARK_FLAGS_NO_MONEY) return false; - money32 parkEntranceFee = park_get_entrance_fee(); + const auto parkEntranceFee = park_get_entrance_fee(); if (parkEntranceFee == MONEY(0, 00)) return false; if (parkEntranceFee <= gTotalRideValueForMoney) diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 498740074e..ceba5554f7 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -237,8 +237,7 @@ void scenario_success_submit_name(const char* name) */ static void scenario_entrance_fee_too_high_check() { - money16 totalRideValueForMoney = gTotalRideValueForMoney; - money16 max_fee = totalRideValueForMoney + (totalRideValueForMoney / 2); + const auto max_fee = add_clamp_money16(gTotalRideValueForMoney, gTotalRideValueForMoney / 2); if ((gParkFlags & PARK_FLAGS_PARK_OPEN) && park_get_entrance_fee() > max_fee) { diff --git a/src/openrct2/util/Util.cpp b/src/openrct2/util/Util.cpp index 2aa0575271..63d81e80f6 100644 --- a/src/openrct2/util/Util.cpp +++ b/src/openrct2/util/Util.cpp @@ -723,6 +723,14 @@ int64_t add_clamp_int64_t(int64_t value, int64_t value_to_add) return value; } +money16 add_clamp_money16(money16 value, money16 value_to_add) +{ + // This function is intended only for clarity, as money16 + // is technically the same as int16_t + assert_struct_size(money16, sizeof(int16_t)); + return add_clamp_int16_t(value, value_to_add); +} + money32 add_clamp_money32(money32 value, money32 value_to_add) { // This function is intended only for clarity, as money32 @@ -731,7 +739,7 @@ money32 add_clamp_money32(money32 value, money32 value_to_add) return add_clamp_int32_t(value, value_to_add); } -money32 add_clamp_money64(money64 value, money64 value_to_add) +money64 add_clamp_money64(money64 value, money64 value_to_add) { // This function is intended only for clarity, as money64 // is technically the same as int64_t diff --git a/src/openrct2/util/Util.h b/src/openrct2/util/Util.h index 7944e94fce..3e70ac10d8 100644 --- a/src/openrct2/util/Util.h +++ b/src/openrct2/util/Util.h @@ -61,8 +61,9 @@ int8_t add_clamp_int8_t(int8_t value, int8_t value_to_add); int16_t add_clamp_int16_t(int16_t value, int16_t value_to_add); int32_t add_clamp_int32_t(int32_t value, int32_t value_to_add); int64_t add_clamp_int64_t(int64_t value, int64_t value_to_add); +money16 add_clamp_money16(money16 value, money16 value_to_add); money32 add_clamp_money32(money32 value, money32 value_to_add); -money32 add_clamp_money64(money64 value, money64 value_to_add); +money64 add_clamp_money64(money64 value, money64 value_to_add); uint8_t lerp(uint8_t a, uint8_t b, float t); float flerp(float a, float b, float t); diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index e713740a50..24cfcd627e 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -489,7 +489,7 @@ money64 Park::CalculateParkValue() const } // +7.00 per guest - result += gNumGuestsInPark * MONEY(7, 00); + result += static_cast(gNumGuestsInPark) * MONEY(7, 00); return result; } @@ -500,7 +500,7 @@ money64 Park::CalculateRideValue(const Ride* ride) const if (ride != nullptr && ride->value != RIDE_VALUE_UNDEFINED) { const auto& rtd = ride->GetRideTypeDescriptor(); - result = (ride->value * 10LL) * (static_cast(ride_customers_in_last_5_minutes(ride)) + rtd.BonusValue * 4); + result = (ride->value * 10LL) * (static_cast(ride_customers_in_last_5_minutes(ride)) + rtd.BonusValue * 4LL); } return result; }