summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qeasingcurve.cpp
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2025-01-07 14:18:48 +0100
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2025-01-21 21:16:42 +0100
commit78a46bf16b7061bfd77b7b3bcf392c28ee788bfc (patch)
tree6c81c474a5141d81a6e58a26d4afe12edbdbe017 /src/corelib/tools/qeasingcurve.cpp
parentafa34d5f3773dec4fb2a7d524100a6f7a307e3e6 (diff)
QEasingCurve: fix (de)serialization in QDataStream
The serialization code did stream out a function pointer as an integer, and then tried to set it back -- effectively, it has *never* worked since the beginning of public history, unless serialization/deserialization were done within the same process. While we cannot support streaming custom easing functions, we can recover the non-custom functions from the type, which was also streamed out; setType will take care of that, and we'll just ignore the subsequent field in the stream. If one tries to stream out a QEasingCurve with a custom curve, what do we do? I've decided to just print a warning and stream _something_ out, so I can keep some degree of behavioral compatibility and aggressively cherrypick this patch. AFAIK, there's no support for such a scenario in QDataStream: all out-stream operators have a wide contract, and there's no Status flag that meaningfully represents this case (and I doubt anyone checks QDS' status while writing into it). Change-Id: Ifa80cf3a9003cab074ddf112022c09b364497007 Fixes: QTBUG-132575 Pick-to: 6.9 6.8 6.5 6.2 5.15 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Diffstat (limited to 'src/corelib/tools/qeasingcurve.cpp')
-rw-r--r--src/corelib/tools/qeasingcurve.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index db44df9f29c..a1e47b033eb 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -276,7 +276,7 @@
QT_BEGIN_NAMESPACE
-static bool isConfigFunction(QEasingCurve::Type type)
+static constexpr bool isConfigFunction(QEasingCurve::Type type)
{
return (type >= QEasingCurve::InElastic
&& type <= QEasingCurve::OutInBounce) ||
@@ -1493,13 +1493,30 @@ QDebug operator<<(QDebug debug, const QEasingCurve &item)
Writes the given \a easing curve to the given \a stream and returns a
reference to the stream.
+ \warning Writing easing curves of QEasingCurve::Custom type
+ (that is, curves with a custom easing function) is not supported.
+
\sa {Serializing Qt Data Types}
*/
QDataStream &operator<<(QDataStream &stream, const QEasingCurve &easing)
{
+ if (easing.d_ptr->type == QEasingCurve::Custom) {
+ qWarning("QEasingCurve: Cannot serialize an easing curve with a custom easing function");
+
+ // Backwards compatibility: stream _something_ out.
+ // Deliberately choose a curve that uses a config and not a
+ // easing function. If this curve is deserialized from old
+ // code, it will ignore the function pointer (cf.
+ // QTBUG-132575).
+ static_assert(isConfigFunction(QEasingCurve::InElastic));
+ stream << QEasingCurve(QEasingCurve::InElastic);
+ return stream;
+ }
+
stream << quint8(easing.d_ptr->type);
- stream << quint64(quintptr(easing.d_ptr->func));
+ // Unused; for backwards compatibility
+ stream << quint64(0);
bool hasConfig = easing.d_ptr->config;
stream << hasConfig;
@@ -1525,11 +1542,16 @@ QDataStream &operator>>(QDataStream &stream, QEasingCurve &easing)
quint8 int_type;
stream >> int_type;
type = static_cast<QEasingCurve::Type>(int_type);
+ if (type == QEasingCurve::Custom) {
+ qWarning("QEasingCurve: Cannot deserialize an easing curve with a custom easing function");
+ stream.setStatus(QDataStream::ReadCorruptData);
+ type = QEasingCurve::Linear;
+ }
easing.setType(type);
- quint64 ptr_func;
+ // Unused; for backwards compatibility
+ [[maybe_unused]] quint64 ptr_func;
stream >> ptr_func;
- easing.d_ptr->func = QEasingCurve::EasingFunction(quintptr(ptr_func));
bool hasConfig;
stream >> hasConfig;