1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 19:22:54 +08:00

Accept full range of int in SettingsNumberBox

This fixes stack overflow exceptions that would arise when a
`Current.Value` of 1 billion or more was set on a `SettingsNumberBox`.
The stack overflow was caused by the "maximum 9 digits" spec. If a value
technically within `int` bounds, but larger than 1 billion (in the range
[1,000,000,000; 2,147,483,647], to be more precise), a feedback loop
between the setting control's `Current` and its inner text box's
`Current` would occur, wherein the last digit would be trimmed and then
re-appended again forevermore.

To resolve, remove the offending spec and rely on `int.TryParse`
entirely to be able to discern overflow range. Additionally, UX of the
text box is slightly changed to notify when the `int` range is exceeded
with a red flash.

This behaviour would not have been possible to implement without recent
framework-side fixes to text box (removal of text set scheduling).
This commit is contained in:
Bartłomiej Dach 2021-11-22 20:41:27 +01:00
parent dced6a2e68
commit 4a9f080f3c
No known key found for this signature in database
GPG Key ID: BCECCD4FA41F6497

View File

@ -35,7 +35,6 @@ namespace osu.Game.Overlays.Settings
{
numberBox = new OutlinedNumberBox
{
LengthLimit = 9, // limited to less than a value that could overflow int32 backing.
Margin = new MarginPadding { Top = 5 },
RelativeSizeAxes = Axes.X,
CommitOnFocusLost = true
@ -44,12 +43,19 @@ namespace osu.Game.Overlays.Settings
numberBox.Current.BindValueChanged(e =>
{
int? value = null;
if (string.IsNullOrEmpty(e.NewValue))
{
Current.Value = null;
return;
}
if (int.TryParse(e.NewValue, out int intVal))
value = intVal;
Current.Value = intVal;
else
numberBox.NotifyInputError();
current.Value = value;
// trigger Current again to either restore the previous text box value, or to reformat the new value via .ToString().
Current.TriggerChange();
});
Current.BindValueChanged(e =>
@ -62,6 +68,8 @@ namespace osu.Game.Overlays.Settings
private class OutlinedNumberBox : OutlinedTextBox
{
protected override bool CanAddCharacter(char character) => char.IsNumber(character);
public new void NotifyInputError() => base.NotifyInputError();
}
}
}