diff options
| author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2025-01-07 14:18:48 +0100 |
|---|---|---|
| committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2025-01-21 21:16:42 +0100 |
| commit | 78a46bf16b7061bfd77b7b3bcf392c28ee788bfc (patch) | |
| tree | 6c81c474a5141d81a6e58a26d4afe12edbdbe017 /src/corelib/tools/qeasingcurve.cpp | |
| parent | afa34d5f3773dec4fb2a7d524100a6f7a307e3e6 (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.cpp | 30 |
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; |
