Details
-
Suggestion
-
Resolution: Unresolved
-
P2: Important
-
None
-
None
-
None
-
13
-
Foundation Sprint 121, Foundation Sprint 122, Foundation Sprint 123, Foundation Sprint 124
Description
Several users of these functions have been observed to pass the template argument explicitly to the function, like this: qAddOverflow<qsizetype>(x, y, &r). This can lead to False Negatives with value corruption, e.g. in the following example, when qsizetype is 32-bit:
qint64 x64 = std::numeric_limits<qint32>::max() + qint64(1);
qsizetype x32 = 1;
if (qsizetype r; qAddOverflow<qsizetype>(x64, x32, &r))
Here, x64 is truncated to qsizetype for passing as the first argument, which makes the value small enough to not cause overflow, returning false even though qsizetype(x64 + x32) != x64 + x32.
To make these functions more secure, we should take all three arguments as different template arguments (with the return value first, to avoid implicit conversions for existing users of explicit template arguments):
template <typename R, typename T1, typename T2>
// requirements
bool qAddOverflow(T1 lhs, T2 rhs, R *r);
and then either static_assert that T1, T2 and R are all the same type, or, better, cast lhs and rhs to std::common_type_t<T1, T2>, do the operation there, and then check that R(result) == result.
Attachments
Issue Links
- relates to
-
QTBUG-105461 Impact of C++20 integer comparison functions on our code
-
- Closed
-
Gerrit Reviews
For Gerrit Dashboard: QTBUG-100881 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
613295,2 | WIP: Introduce qAddOverflowed() with different template arguments | dev | qt/qtbase | Status: NEW | -2 | 0 |
613296,1 | Deprecate qAddOverflow() functions and schedule it for removal in Qt 7 | dev | qt/qtbase | Status: NEW | -1 | 0 |