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
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
static bool isConfigFunction(QEasingCurve::Type type)
|
static constexpr bool isConfigFunction(QEasingCurve::Type type)
|
||||||
{
|
{
|
||||||
return (type >= QEasingCurve::InElastic
|
return (type >= QEasingCurve::InElastic
|
||||||
&& type <= QEasingCurve::OutInBounce) ||
|
&& 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
|
Writes the given \a easing curve to the given \a stream and returns a
|
||||||
reference to the stream.
|
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}
|
\sa {Serializing Qt Data Types}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QDataStream &operator<<(QDataStream &stream, const QEasingCurve &easing)
|
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 << 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;
|
bool hasConfig = easing.d_ptr->config;
|
||||||
stream << hasConfig;
|
stream << hasConfig;
|
||||||
@ -1525,11 +1542,16 @@ QDataStream &operator>>(QDataStream &stream, QEasingCurve &easing)
|
|||||||
quint8 int_type;
|
quint8 int_type;
|
||||||
stream >> int_type;
|
stream >> int_type;
|
||||||
type = static_cast<QEasingCurve::Type>(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);
|
easing.setType(type);
|
||||||
|
|
||||||
quint64 ptr_func;
|
// Unused; for backwards compatibility
|
||||||
|
[[maybe_unused]] quint64 ptr_func;
|
||||||
stream >> ptr_func;
|
stream >> ptr_func;
|
||||||
easing.d_ptr->func = QEasingCurve::EasingFunction(quintptr(ptr_func));
|
|
||||||
|
|
||||||
bool hasConfig;
|
bool hasConfig;
|
||||||
stream >> hasConfig;
|
stream >> hasConfig;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user