From c796eb372f40b6c6de3281f5dd839769aa8ae523 Mon Sep 17 00:00:00 2001 From: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Date: Fri, 2 Jan 2026 04:22:56 -0800 Subject: [PATCH] Guard against div/0 for HeatContainerHelpers (#42213) Guard against div/0 for HeatContainers --- .../HeatContainerHelpers.Exchange.cs | 15 +++++++++++++-- .../HeatContainer/HeatContainerHelpers.Merge.cs | 10 ++++++++-- .../HeatContainer/HeatContainerHelpers.cs | 4 ++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Exchange.cs b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Exchange.cs index a906cfa35e..75611d449a 100644 --- a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Exchange.cs +++ b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Exchange.cs @@ -16,9 +16,13 @@ public static partial class HeatContainerHelpers /// The amount of heat in joules that is needed /// to bring the containers to thermal equilibrium. /// A positive value indicates heat transfer from a hot cA to a cold cB. + /// Thrown when the combined heat capacity of both containers is zero or negative. [PublicAPI] public static float EquilibriumHeatQuery(this ref HeatContainer cA, ref HeatContainer cB) { + var cTotal = cA.HeatCapacity + cB.HeatCapacity; + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(cTotal); + /* The solution is derived from the following facts: 1. Let Q be the amount of heat energy transferred from cA to cB. @@ -32,7 +36,7 @@ public static partial class HeatContainerHelpers 7. Solve for Q. */ return (cA.Temperature - cB.Temperature) * - (cA.HeatCapacity * cB.HeatCapacity / (cA.HeatCapacity + cB.HeatCapacity)); + (cA.HeatCapacity * cB.HeatCapacity / cTotal); } /// @@ -42,11 +46,14 @@ public static partial class HeatContainerHelpers /// The first to exchange heat. /// The second to exchange heat with. /// The resulting equilibrium temperature both containers will be at. + /// Thrown when the combined heat capacity of both containers is zero or negative. [PublicAPI] public static float EquilibriumTemperatureQuery(this ref HeatContainer cA, ref HeatContainer cB) { + var cTotal = cA.HeatCapacity + cB.HeatCapacity; + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(cTotal); // Insert the above solution for Q into T_A_final = T_A_initial - Q / C_A and rearrange the result. - return (cA.HeatCapacity * cA.Temperature - cB.HeatCapacity * cB.Temperature) / (cA.HeatCapacity + cB.HeatCapacity); + return (cA.HeatCapacity * cA.Temperature - cB.HeatCapacity * cB.Temperature) / cTotal; } /// @@ -75,6 +82,7 @@ public static partial class HeatContainerHelpers var tFinal = EquilibriumTemperatureQuery(ref cA, ref cB); cA.Temperature = tFinal; cB.Temperature = tFinal; + // Guarded against div/0 in EquilibriumTemperatureQuery: totalHeatCapacity > 0. dQ = (tInitialA - tFinal) / cA.HeatCapacity; } @@ -120,6 +128,7 @@ public static partial class HeatContainerHelpers /// /// The array of s to bring into thermal equilibrium. /// The temperature of all s involved after reaching thermal equilibrium. + /// Thrown when the combined heat capacity of all containers is zero or negative. [PublicAPI] public static float EquilibriumTemperatureQuery(this HeatContainer[] cN) { @@ -161,6 +170,8 @@ public static partial class HeatContainerHelpers denominator += c.HeatCapacity; } + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(denominator); + return numerator / denominator; } diff --git a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Merge.cs b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Merge.cs index d9f2cdd3e7..5aa3dcbbde 100644 --- a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Merge.cs +++ b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.Merge.cs @@ -9,13 +9,16 @@ public static partial class HeatContainerHelpers /// /// The first to merge. This will be modified to contain the merged result. /// The second to merge. + /// Thrown when the combined heat capacity of both containers is zero or negative. [PublicAPI] public static void Merge(this ref HeatContainer cA, HeatContainer cB) { + var combinedHeatCapacity = cA.HeatCapacity + cB.HeatCapacity; + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(combinedHeatCapacity); var merged = new HeatContainer { - HeatCapacity = cA.HeatCapacity + cB.HeatCapacity, - Temperature = (cA.InternalEnergy + cB.InternalEnergy) / (cA.HeatCapacity + cB.HeatCapacity) + HeatCapacity = combinedHeatCapacity, + Temperature = (cA.InternalEnergy + cB.InternalEnergy) / combinedHeatCapacity, }; cA = merged; @@ -43,6 +46,7 @@ public static partial class HeatContainerHelpers /// /// The array of s to merge. /// A new representing the merged result. + /// Thrown when the combined heat capacity of all containers is zero or negative. [PublicAPI] public static HeatContainer Merge(this HeatContainer[] cN) { @@ -55,6 +59,8 @@ public static partial class HeatContainerHelpers totalEnergy += c.InternalEnergy; } + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(totalHeatCapacity); + var result = new HeatContainer { HeatCapacity = totalHeatCapacity, diff --git a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.cs b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.cs index 6ce01c752e..ed1eadc74a 100644 --- a/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.cs +++ b/Content.Shared/Temperature/HeatContainer/HeatContainerHelpers.cs @@ -29,9 +29,11 @@ public static partial class HeatContainerHelpers /// The to query. /// The energy in joules to add or remove. /// The resulting temperature in kelvin after the heat change. + /// Thrown when the heat capacity of the container is zero or negative. [PublicAPI] public static float AddHeatQuery(this ref HeatContainer c, float dQ) { + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(c.HeatCapacity); // Don't allow the temperature to go below the absolute minimum. return Math.Max(0f, c.Temperature + dQ / c.HeatCapacity); } @@ -42,9 +44,11 @@ public static partial class HeatContainerHelpers /// /// The to modify. /// The new heat capacity to set. + /// Thrown when the new heat capacity is zero or negative. [PublicAPI] public static void SetHeatCapacity(this ref HeatContainer c, float newHeatCapacity) { + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(c.HeatCapacity); var currentEnergy = c.InternalEnergy; c.HeatCapacity = newHeatCapacity; c.Temperature = currentEnergy / c.HeatCapacity; -- 2.52.0