Skip to content
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(client): Crash when opening connect dialog #6307

Merged
merged 1 commit into from
Jan 21, 2024

Conversation

Krzmbrzl
Copy link
Member

@Krzmbrzl Krzmbrzl commented Jan 13, 2024

When selecting new public servers, we randomize their order. The random number used for that is an unsigned integer from which we compute the modulus with the list size in order to get a random index into the list.

This involved an implicit conversion from an unsigned integer (the random number) to a signed integer (the list index - as Qt uses signed integers for that). Thus, b5a67c0 added an explicit cast to a signed integer. However, it did this to the random number before the modulus operation, meaning that if a large enough random number is drawn, the cast would actually create a negative integer, yielding a negative list index after the modulus. This caused a crash of the application.

The fix consists in switching to using the bounded() function that has an overload for signed integers and which can directly generate numbers in the desired range, making all of the above superfluous.

Fixes #6306

Checks

@Krzmbrzl Krzmbrzl added client bug A bug (error) in the software labels Jan 13, 2024
@radioactiveman
Copy link
Contributor

radioactiveman commented Jan 13, 2024

@Krzmbrzl: My proposed fix would be this. It's cleaner and does not require a cast at all. What do you think? If you like it, I can create a proper patch with my author information.

diff --git a/src/mumble/ConnectDialog.cpp b/src/mumble/ConnectDialog.cpp
index 8da030018..c07f3fce3 100644
--- a/src/mumble/ConnectDialog.cpp
+++ b/src/mumble/ConnectDialog.cpp
@@ -1468,7 +1468,7 @@ void ConnectDialog::fillList() {
 	while (!ql.isEmpty()) {
 #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
 		ServerItem *si = static_cast< ServerItem * >(
-			ql.takeAt(static_cast< int >(QRandomGenerator::global()->generate()) % ql.count()));
+			ql.takeAt(QRandomGenerator::global()->bounded(ql.count())));
 #else
 		// Qt 5.10 introduces the QRandomGenerator class and in Qt 5.15 qrand got deprecated in its favor
 		ServerItem *si = static_cast< ServerItem * >(ql.takeAt(qrand() % ql.count()));

@Krzmbrzl
Copy link
Member Author

Krzmbrzl commented Jan 13, 2024

It will still require casts (as Qt uses signed sizes but the random API uses unsigned integers) but it saves the modulo operation (or at least hides it in Qt internals).
And it's cleaner to use bounded for semantic reasons as well 👍

@radioactiveman
Copy link
Contributor

radioactiveman commented Jan 13, 2024

No, it does not require casts. bounded() returns an int like expected by takeAt().
See https://doc.qt.io/qt-5/qrandomgenerator.html#bounded-3
Using bounded(0, ql.count()) behaves the same but is semantically even more clear.

Feel free to adapt your patch with my suggestion if you give credits in the commit message with
Co-authored-by: Thomas Lange <[email protected]>. I guess that's easier for both of us, thanks.

@Krzmbrzl
Copy link
Member Author

Ah indeed - there is an overload for signed integers. Thanks for pointing that out 👍

@radioactiveman
Copy link
Contributor

Regarding FreeBSD:
You may try the same sed "fix" for CMakeLists.txt like Arch Linux does for Mumble, mentioned in my issue #6165.
For some reason -DCMAKE_CXX_STANDARD=17 does not help here.

@radioactiveman
Copy link
Contributor

No, it does not require casts. bounded() returns an int like expected by takeAt(). See https://doc.qt.io/qt-5/qrandomgenerator.html#bounded-3 Using bounded(0, ql.count()) behaves the same but is semantically even more clear.

Feel free to adapt your patch with my suggestion if you give credits in the commit message with Co-authored-by: Thomas Lange <[email protected]>. I guess that's easier for both of us, thanks.

Do you want me to submit a separate pull request instead? Can you not merge your PR when the FreeBSD build has failed? The crash makes Mumble unusable right now, a fast fix would be appreciated.

When selecting new public servers, we randomize their order. The random
number used for that is an unsigned integer from which we compute the
modulus with the list size in order to get a random index into the list.

This involved an implicit conversion from an unsigned integer (the
random number) to a signed integer (the list index - as Qt uses signed
integers for that). Thus, b5a67c0 added
an explicit cast to a signed integer. However, it did this to the random
number before the modulus operation, meaning that if a large enough
random number is drawn, the cast would actually create a negative
integer, yielding a negative list index after the modulus. This caused a
crash of the application.

The fix consists in switching to using the bounded() function that has
an overload for signed integers and which can directly generate numbers
in the desired range, making all of the above superfluous.

Fixes mumble-voip#6306

Co-authored-by: Thomas Lange <[email protected]>
@Krzmbrzl Krzmbrzl force-pushed the fix-connectdialog-crash branch from 31cb390 to 41fac28 Compare January 21, 2024 09:50
@Krzmbrzl
Copy link
Member Author

Can you not merge your PR when the FreeBSD build has failed?

No - if we start to merge failing CIs, we might as well stop having CI in the first place. Imo CI is the same as (unit) tests: if you start accepting that some (sometimes) fail, they become mostly useless.

The crash makes Mumble unusable right now, a fast fix would be appreciated.

Agreed. I only was quite busy this week. Didn't get to work on this earlier. I expect to merge this now as soon as the CI has finished :)

@Krzmbrzl Krzmbrzl merged commit 910c2aa into mumble-voip:master Jan 21, 2024
15 checks passed
@radioactiveman
Copy link
Contributor

Thanks for the fix and sorry for my impatience. 😃

Since you removed the Qt version check now, I would recommend to require 5.10.0 with CMake.
In the code there are more checks for even 5.6.0 which can then be removed as well.

@Krzmbrzl
Copy link
Member Author

Yeah, at this point we should require 5.15 as a preparation for a migration to Qt6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug (error) in the software client
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Regression] Mumble crashes immediately when showing the connect dialog
2 participants