-
-
Notifications
You must be signed in to change notification settings - Fork 1.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
Fix convertWCStringToQString assert #11310
Conversation
… longer, than the specified length
dabdeb2
to
98f2e01
Compare
I spend a bunch of time trying to understand the purpose of the function in the first place. I think we should remove it entirely. The explanation states that "We cannot use Qts wchar_t functions, since they may work or not depending on the '/Zc:wchar_t-' build flag in the Qt configs on Windows build." However, Microsoft docs state: "We do not recommend /Zc:wchar_t- because the C++ standard requires that wchar_t be a built-in type.". So if Qt is really building with that, it is a Qt bug IMO. We should be able to rely on Qt's I gather from this comment that we can remove Maybe @daschuer knows more since he introduced that change. |
This PR fixes an typo that has been introduced here: 3c58f6b#diff-71badc1cc71ba46244f7841a088251bb294265f4fe9e662c0ad6b15be540eee4R43 I can confirm that this is fixed here. |
In the Qt 5 code I can find this: We use win32-msvc.conf including msvc-desktop.conf Conclusion: We can assume -Zc:wchar_t is set. |
Even without explicit setting the flag the option is on by default:
And in addition QString::fromWCharArray() is defined in a qstring.h build with the Mixxx compiler flags. |
Conclusion: We may use QString::fromWCharArray() but it is is not null-safe and it uses the not optimized while loop that has been dismissed here: #11083 (comment) See: |
@Swiftb0y Can we merge this now? |
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.
If we want to merge this, I think this needs more discussion. Currently the primary issue is that the purpose of maxLen
is unclear. Is it supposed to be the string length like in QString::fromWCharArray()
or is it supposed to be a bound like in wcsnlen_s
? We can see that discussion even in the current code as both examples linked in @JoergAtGithub's initial post use it differently.
The while loop is in |
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.
Oh yes right, my bad. The original code is just right.
The issue is at the usage.
We need to fix this:
mixxx/src/controllers/hid/hidiothread.cpp
Lines 106 to 108 in 7307fc9
<< mixxx::convertWCStringToQString( | |
hid_error(m_pHidDevice), | |
kMaxHidErrorMessageSize); |
And this:
mixxx/src/controllers/hid/hidiooutputreport.cpp
Lines 127 to 129 in 7307fc9
<< mixxx::convertWCStringToQString( | |
hid_error(pHidDevice), | |
kMaxHidErrorMessageSize); |
By replacing the constant with
mixxx::wcsnlen_s() instead of the constant.
return QString(); | ||
} | ||
DEBUG_ASSERT(wcsnlen_s(wcs, len) == len); | ||
|
||
std::size_t len = wcsnlen_s(wcs, maxLen + 1); |
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.
maxLen + 1 may lead to an out of bounds access. What is the purpose?
I argue the opposite. IMO |
I don't mind which way we turn it. One will fix the recently introduced wrong usage of the existing function and the other will change the behaviour of the existing function towards the expectations in the new code. |
convertWCStringToQString is only used at a few places in HID code currently:
Either a constant is used with the maximum string length:
mixxx/src/controllers/hid/hidiothread.cpp
Lines 104 to 108 in 1b99e57
Or it's calculated it's the caller using wcsnlen_s:
mixxx/src/controllers/hid/hiddevice.cpp
Lines 40 to 43 in 1b99e57
In th case of a constant, we always get an assert, in the second case we compare two values calculated by the same wcsnlen_s function. Therefore the actual length check assert is usesless.
This PR changes the code, that we detect strings longer than the specified length. But I wonder, if this assert is useful at all, since nothing breaks if these strings are longer.
Furthermore the function wcsnlen_s which made problems on OpenBCD #11083 is only existing in the Mixxx code, to generate this one DEBUG_ASSERT.