summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2022-05-12 16:59:50 +0200
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2022-05-18 02:21:31 +0200
commit07d80deeab64db9e10364a162f7d2b7bf9f8bb93 (patch)
treeff0f30e401cf0f45598d39cba7764ba054b1eea7 /src/widgets
parentcf3843a2684c434a4800a7c11071e77f45817b70 (diff)
QtWidgets: restore Qt 5 compatibility for save/restore state
Several classes in QWidget use QDataStream internally in order to save and restore state. These QDataStream usages were not versioned, meaning that if Qt changes the serialization for some datatype, then the data saved between different Qt versions becomes incompatible. Note that the save/restore API in question just produce opaque blobs as QByteArrays -- the user has no control over the QDataStream objects and thus versions. Fix by version the usages. In QHeaderView this has caused a regression because QBitArray *did* change version between Qt 5 and 6. In general, using QDataStream without explicit versioning is a mistake, so deploy the same fix elsewhere as well. Fixes: QTBUG-99487 Pick-to: 5.15 6.2 6.3 Change-Id: I82bb5c266f4e5dedc0887cbef855dccab1015e29 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: <doctor.whom@gmail.com>
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp2
-rw-r--r--src/widgets/itemviews/qheaderview.cpp2
-rw-r--r--src/widgets/widgets/qmainwindow.cpp2
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp2
-rw-r--r--src/widgets/widgets/qsplitter.cpp2
5 files changed, 10 insertions, 0 deletions
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index ae8d0c137a..966d86b089 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -418,6 +418,7 @@ QByteArray QFileDialog::saveState() const
int version = 4;
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
stream << qint32(QFileDialogMagic);
stream << qint32(version);
@@ -452,6 +453,7 @@ bool QFileDialog::restoreState(const QByteArray &state)
Q_D(QFileDialog);
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
if (stream.atEnd())
return false;
QStringList history;
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index a081a7d0f9..413857bf6c 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -1742,6 +1742,7 @@ QByteArray QHeaderView::saveState() const
Q_D(const QHeaderView);
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
stream << QHeaderViewPrivate::VersionMarker;
stream << 0; // current version is 0
d->write(stream);
@@ -1763,6 +1764,7 @@ bool QHeaderView::restoreState(const QByteArray &state)
return false;
QByteArray data = state;
QDataStream stream(&data, QIODevice::ReadOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
int marker;
int ver;
stream >> marker;
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 88f710870b..73ca584c7f 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1217,6 +1217,7 @@ QByteArray QMainWindow::saveState(int version) const
{
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
stream << QMainWindowLayout::VersionMarker;
stream << version;
d_func()->layout->saveState(stream);
@@ -1245,6 +1246,7 @@ bool QMainWindow::restoreState(const QByteArray &state, int version)
return false;
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
int marker, v;
stream >> marker;
stream >> v;
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index d1ea0b57da..4a199e0b18 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -1164,10 +1164,12 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream,
}
QDataStream ds(copy);
+ ds.setVersion(_stream.version());
if (!checkFormat(ds))
return false;
QDataStream stream(copy);
+ stream.setVersion(_stream.version());
while (!stream.atEnd()) {
uchar marker;
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 8507ebf356..7dfc2a04fa 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -1650,6 +1650,7 @@ QByteArray QSplitter::saveState() const
int version = 1;
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
stream << qint32(SplitterMagic);
stream << qint32(version);
@@ -1691,6 +1692,7 @@ bool QSplitter::restoreState(const QByteArray &state)
int version = 1;
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
QList<int> list;
bool b;
qint32 i;