-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix possible crash when scaling objects in editor #32158
Conversation
The specific fail case here is when `s.{X,Y}` is 0, and `s{Lower,Upper}Bound` is `Infinity`. Because IEEE math is IEEE math, `0 * Infinity` is `NaN`. `MathHelper.Clamp()` is written the following way: https://github.com/ppy/osuTK/blob/af742f1afd01828efc7bc9fe77536b54aab8b419/src/osuTK/Math/MathHelper.cs#L284-L306 `Math.{Min,Max}` are both documented as reporting `NaN` when any of their operands are `NaN`: https://learn.microsoft.com/en-us/dotnet/api/system.math.min?view=net-8.0#system-math-min(system-single-system-single) https://learn.microsoft.com/en-us/dotnet/api/system.math.max?view=net-8.0#system-math-max(system-single-system-single) which means that if a `NaN` happens to sneak into the bounds, it will start spreading outwards in an uncontrolled manner, and likely crash things. In contrast, the standard library provided `Math.Clamp()` is written like so: https://github.com/dotnet/runtime/blob/577c36cee56480dec4d4610b35605b5d5836888b/src/libraries/System.Private.CoreLib/src/System/Math.cs#L711-L729 With this implementation, if either bound is `NaN`, it will essentially not be checked (because any and all comparisons involving `NaN` return false). This prevents the spread of `NaN`s, all the way to positions of hitobjects, and thus fixes the crash.
See previous commit for partial rationale. There's an argument to be made about the `NaN`-spreading semantics being desirable because at least something will loudly fail in that case, but I'm not so sure about that these days. It feels like either way if `NaN`s are produced, then things are outside of any control, and chances are the game can probably continue without crashing. And, this move reduces our dependence on osuTK, which has already been living on borrowed time for years now and is only awaiting someone brave to go excise it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds reasonable.
Interesting test failures in https://github.com/ppy/osu/runs/37991745826#r1s0; blocking pending investigation. (The fact that these failures are there now is another argument for ditching the osutk helper, as it would just silently do whatever if given invalid bounds.) |
Tests should be fixed with 47747ae. |
Fix possible crash when scaling objects in editor
Closes #32150.
The specific fail case here is when
s.{X,Y}
is 0, ands{Lower,Upper}Bound
isInfinity
. Because IEEE math is IEEE math,0 * Infinity
isNaN
.MathHelper.Clamp()
is written the following way, usingMath.{Min,Max}
.Math.{Min,Max}
are both documented as reportingNaN
when any of their operands areNaN
, which means that if aNaN
happens to sneak into the bounds, it will start spreading outwards in an uncontrolled manner, and likely crash things.In contrast, the standard library provided
Math.Clamp()
is written like so. With this implementation, if either bound isNaN
, it will essentially not be checked (because any and all comparisons involvingNaN
return false). This prevents the spread ofNaN
s, all the way to positions of hitobjects, and thus fixes the crash.Mark
MathHelper.Clamp()
as banned APISee above for partial rationale.
There's an argument to be made about the
NaN
-spreading semantics being desirable because at least something will loudly fail in that case, but I'm not so sure about that these days. It feels like either way ifNaN
s are produced, then things are outside of any control, and chances are the game can probably continue without crashing if theNaN
s are not produced. And, this move reduces our dependence on osuTK, which has already been living on borrowed time for years now and is only awaiting someone brave to go excise it.