aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/common
diff options
context:
space:
mode:
authorOlivier De Cannière <olivier.decanniere@qt.io>2023-07-28 16:30:45 +0200
committerOlivier De Cannière <olivier.decanniere@qt.io>2023-08-01 14:06:18 +0200
commit9df4293adf7d019b4d3ccaaa2f5d87ddfe0b041b (patch)
tree00a4263f24751568e62c816e8f1be75ce44621af /src/qml/common
parent115916f217b0dc299b8df298f5c9c30369f561f8 (diff)
UndefinedBehavior: fix some things found with -sanitize undefined
Here are the sorts of things that were found: - Uninitialized variables containing garbage. - Calling member function through nullptr (where this is not actually used inside the function because that would trigger a segfault). - static_cast'ing double to int where the double is either +/-infinity or is outside the range of min and max values for int. Additionally, the uses of QJSNumberCoercion::isInteger() in the code generator have been replaced by QJSNumberCoercion::isArrayIndex() and the former was deprecated as it is no longer being used. Pick-to: 6.5 6.6 Change-Id: I9318671ccbda37e5519f4fcb84a1537585c2103f Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/common')
-rw-r--r--src/qml/common/qjsnumbercoercion.cpp14
-rw-r--r--src/qml/common/qjsnumbercoercion.h36
-rw-r--r--src/qml/common/qv4staticvalue_p.h2
3 files changed, 46 insertions, 6 deletions
diff --git a/src/qml/common/qjsnumbercoercion.cpp b/src/qml/common/qjsnumbercoercion.cpp
index 986a3e97f2..ba76c12bb0 100644
--- a/src/qml/common/qjsnumbercoercion.cpp
+++ b/src/qml/common/qjsnumbercoercion.cpp
@@ -14,6 +14,20 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn bool QJSNumberCoercion::isInteger(double d)
+ \internal
+ \deprecated 6.7
+ */
+
+/*!
+ \fn bool QJSNumberCoercion::isArrayIndex(double d)
+ \internal
+
+ Checks whether \a d contains a value that can serve as an index into an array.
+ For that, \a d must be a non-negative value representable as an int.
+ */
+
+/*!
\fn int QJSNumberCoercion::toInteger(double d)
\internal
diff --git a/src/qml/common/qjsnumbercoercion.h b/src/qml/common/qjsnumbercoercion.h
index 03827f82f1..bc04794d2f 100644
--- a/src/qml/common/qjsnumbercoercion.h
+++ b/src/qml/common/qjsnumbercoercion.h
@@ -12,17 +12,43 @@ QT_BEGIN_NAMESPACE
class QJSNumberCoercion
{
public:
- static constexpr bool isInteger(double d) {
- return equals(d, d) && equals(static_cast<int>(d), d);
+
+#if QT_DEPRECATED_SINCE(6, 7)
+
+ QT_DEPRECATED_VERSION_6_7
+ static constexpr bool isInteger(double d)
+ {
+ // Comparing d with itself checks for NaN and comparing d with the min and max values
+ // for int also covers infinities.
+ if (!equals(d, d) || d < std::numeric_limits<int>::min()
+ || d > std::numeric_limits<int>::max()) {
+ return false;
+ }
+
+ return equals(static_cast<int>(d), d);
+ }
+
+#endif
+
+ static constexpr bool isArrayIndex(double d)
+ {
+ if (d < 0 || !equals(d, d) || d > std::numeric_limits<int>::max()) {
+ return false;
+ }
+
+ return equals(static_cast<int>(d), d);
}
static constexpr int toInteger(double d) {
+ // Check for NaN
if (!equals(d, d))
return 0;
- const int i = static_cast<int>(d);
- if (equals(i, d))
- return i;
+ if (d >= std::numeric_limits<int>::min() && d <= std::numeric_limits<int>::max()) {
+ const int i = static_cast<int>(d);
+ if (equals(i, d))
+ return i;
+ }
return QJSNumberCoercion(d).toInteger();
}
diff --git a/src/qml/common/qv4staticvalue_p.h b/src/qml/common/qv4staticvalue_p.h
index e9c3554104..9a88fccc04 100644
--- a/src/qml/common/qv4staticvalue_p.h
+++ b/src/qml/common/qv4staticvalue_p.h
@@ -393,7 +393,7 @@ struct StaticValue
}
QV4_NEARLY_ALWAYS_INLINE static bool isInt32(double d) {
- int i = int(d);
+ int i = QJSNumberCoercion::toInteger(d);
return (i == d && !(d == 0 && std::signbit(d)));
}