diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index cd75a7a0172..db411b6285d 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -1,7 +1,13 @@ // Remove these once we have Byond implementation. -#define ISNAN(a) (a!=a) -#define ISINF(a) (!ISNAN(a) && ISNAN(a-a)) -#define IS_INF_OR_NAN(a) (ISNAN(a-a)) +// ------------------------------------ +#define IS_NAN(a) (a!=a) + +#define IS_INF__UNSAFE(a) (a==a && a-a!=a-a) +#define IS_INF(a) (isnum(a) && IS_INF__UNSAFE(a)) + +#define IS_FINITE__UNSAFE(a) (a-a==a-a) +#define IS_FINITE(a) (isnum(a) && IS_FINITE__UNSAFE(a)) +// ------------------------------------ // Aight dont remove the rest // Credits to Nickr5 for the useful procs I've taken from his library resource. @@ -104,7 +110,7 @@ . = list() var/d = b*b - 4 * a * c var/bottom = 2 * a - if(d < 0 || IS_INF_OR_NAN(d) || IS_INF_OR_NAN(bottom)) + if(d < 0 || !IS_FINITE__UNSAFE(d) || !IS_FINITE__UNSAFE(bottom)) return var/root = sqrt(d) . += (-b + root) / bottom diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 609b39ecc34..77b72c5c4ce 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -174,8 +174,8 @@ return var/multiplier = text2num(params["multiplier"]) - if(!multiplier) - to_chat(usr, span_alert("[src] only accepts a numerical multiplier!")) + if(!multiplier || !IS_FINITE(multiplier)) + stack_trace("Invalid multiplier value in stack creation [multiplier], [usr] is likely attempting an exploit") return var/is_stack = ispath(being_built.build_path, /obj/item/stack) multiplier = clamp(round(multiplier),1,50) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 982272eeb97..e6977643697 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -357,7 +357,8 @@ return if(!is_valid_recipe(recipe, recipes)) //href exploit protection return - if(!multiplier || multiplier < 1) //href exploit protection + if(!multiplier || multiplier < 1 || !IS_FINITE(multiplier)) //href exploit protection + stack_trace("Invalid multiplier value in stack creation [multiplier], [usr] is likely attempting an exploit") return if(!building_checks(builder, recipe, multiplier)) return diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 20f25223287..acb8b58f0db 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -659,7 +659,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) /// Do mind that the numbers can get very big and might hit BYOND's single point float limit. /datum/gas_mixture/proc/gas_pressure_quadratic(a, b, c, lower_limit, upper_limit) var/solution - if(!IS_INF_OR_NAN(a) && !IS_INF_OR_NAN(b) && !IS_INF_OR_NAN(c)) + if(IS_FINITE(a) && IS_FINITE(b) && IS_FINITE(c)) solution = max(SolveQuadratic(a, b, c)) if(solution > lower_limit && solution < upper_limit) //SolveQuadratic can return empty lists so be careful here return solution @@ -670,7 +670,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) /// We use the slope of an approximate value to get closer to the root of a given equation. /datum/gas_mixture/proc/gas_pressure_approximate(a, b, c, lower_limit, upper_limit) var/solution - if(!IS_INF_OR_NAN(a) && !IS_INF_OR_NAN(b) && !IS_INF_OR_NAN(c)) + if(IS_FINITE(a) && IS_FINITE(b) && IS_FINITE(c)) // We start at the extrema of the equation, added by a number. // This way we will hopefully always converge on the positive root, while starting at a reasonable number. solution = (-b / (2 * a)) + 200 diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 96c8e81d41b..8372a8a5642 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -163,10 +163,12 @@ * * ignore splitting - Don't call the process that handles reagent spliting in a mob (impure/inverse) - generally leave this false unless you care about REAGENTS_DONOTSPLIT flags (see reagent defines) */ /datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = DEFAULT_REAGENT_TEMPERATURE, added_purity = null, added_ph, no_react = FALSE, override_base_ph = FALSE, ignore_splitting = FALSE) - if(!isnum(amount) || !amount) + // Prevents small amount problems, as well as zero and below zero amounts. + if(amount <= CHEMICAL_QUANTISATION_LEVEL) return FALSE - if(amount <= CHEMICAL_QUANTISATION_LEVEL)//To prevent small amount problems. + if(!IS_FINITE(amount)) + stack_trace("non finite amount passed to add reagent [amount] [reagent]") return FALSE if(SEND_SIGNAL(src, COMSIG_REAGENTS_PRE_ADD_REAGENT, reagent, amount, reagtemp, data, no_react) & COMPONENT_CANCEL_REAGENT_ADD) @@ -277,13 +279,11 @@ /// Remove a specific reagent /datum/reagents/proc/remove_reagent(reagent, amount, safety = TRUE, no_react = FALSE)//Added a safety check for the trans_id_to if(isnull(amount)) - amount = 0 - CRASH("null amount passed to reagent code") - - if(!isnum(amount)) + stack_trace("null amount passed to reagent code") return FALSE - if(amount < 0) + if(amount < 0 || !IS_FINITE(amount)) + stack_trace("invalid number passed to remove_reagent [amount]") return FALSE var/list/cached_reagents = reagent_list