QPainterPath: detach and reset before streaming in

Otherwise we end up appending and modifying the shared object.

Pick-to: 6.6 6.5 5.15
Task-number: QTBUG-122704
Change-Id: I01ec3c774d9943adb903fffd17b692c2e6d53e97
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 2925683268ca9d8dc6811f8f64c50ca488b27acc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2024-02-23 19:54:34 +01:00 committed by Qt Cherry-pick Bot
parent 20c44b7bac
commit 5fea2d374b
2 changed files with 21 additions and 8 deletions

View File

@ -2442,14 +2442,14 @@ QDataStream &operator>>(QDataStream &s, QPainterPath &p)
int size;
s >> size;
if (size == 0)
if (size == 0) {
p = {};
return s;
}
p.ensureData(); // in case if p.d_func() == 0
if (p.d_func()->elements.size() == 1) {
Q_ASSERT(p.d_func()->elements.at(0).type == QPainterPath::MoveToElement);
p.d_func()->elements.clear();
}
p.detach();
p.d_func()->elements.clear();
for (int i=0; i<size; ++i) {
int type;
double x, y;
@ -2472,9 +2472,7 @@ QDataStream &operator>>(QDataStream &s, QPainterPath &p)
s >> fillRule;
Q_ASSERT(fillRule == Qt::OddEvenFill || fillRule == Qt::WindingFill);
p.d_func()->fillRule = Qt::FillRule(fillRule);
p.d_func()->dirtyBounds = true;
p.d_func()->dirtyControlBounds = true;
if (errorDetected)
if (errorDetected || p.d_func()->elements.isEmpty())
p = QPainterPath(); // Better than to return path with possibly corrupt datastructure, which would likely cause crash
return s;
}

View File

@ -765,6 +765,21 @@ void tst_QPainterPath::testOperatorDatastream()
}
QCOMPARE(other, path);
// Check reset & detach
QPainterPath p3;
p3.lineTo(1, 1);
QCOMPARE(p3.elementCount(), 2);
QPainterPath p4 = p3;
QCOMPARE(p4.elementCount(), 2);
{
QFile data(tempDir.path() + "/data");
QVERIFY(data.open(QFile::ReadOnly));
QDataStream stream(&data);
stream >> p3;
}
QCOMPARE(p3.elementCount(), path.elementCount());
QCOMPARE(p4.elementCount(), 2);
}
void tst_QPainterPath::closing()