-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
[BUGFIX] Prevented infinite recursion on freeplay when a song doesn't have the normal
difficulty
#3036
[BUGFIX] Prevented infinite recursion on freeplay when a song doesn't have the normal
difficulty
#3036
Conversation
… have the `normal` difficulty Any attempt to create a song without the `normal` difficulty will result in a silent crash when opening freeplay. After some debugging, I discovered that the issue is caused by infinite recursion, which gets triggered at the start of `FreeplaySongData`'s `updateValues`.
It seems #2712 does fix part of the same issue. The only thing it doesn't address is What I can do is remove the second condition I added ( |
Any attempt to create a song without the
normal
difficulty will result in a silent crash when opening freeplay. After some debugging, I discovered that the crash was caused by an infinite recursion, which gets triggered at the start ofFreeplaySongData
'supdateValues
method.Code context
In
Constants
:In
FreeplaySongData
:Infinite recursion explanation
When
updateValues
gets called for the first time on aFreeplaySongData
object, if its song doesn't have the difficulty specified in itscurrentDifficulty
property (normal
), thecurrentDifficulty
property will be set toConstants.DEFAULT_DIFFICULTY
(normal
), which will trigger its setter-method, which will triggerupdateValues
again in the same conditions as before, meaning the same thing will keep happening until the program decides to exit.Usually, the compiler ensures that this kind of field access does not go through the accessor method when made from within the accessor method itself, thus avoiding infinite recursion. However, because the field access happens in a separate method, the compiler can't know if we're nested inside the scope of the accessor method or not, which means he won't be able to prevent infinite recursion in this case.
Solution
So to actually prevent the infinite recursion, I added another condition, which prevents the
currentDifficulty
property from being set toConstants.DEFAULT_DIFFICULTY
(normal
) if it's already set toConstants.DEFAULT_DIFFICULTY
(normal
). Additionally, I added areturn
expression after we set thecurrentDifficulty
property because, as I already described, this field access triggers the setter-method, which calls theupdateValues
again with the new value of thecurrentDifficulty
property, which means we don't need to continue the function, because we already went over the rest of the function in a nested call.