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>
This commit is contained in:
parent
afa34d5f37
commit
78a46bf16b
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user