QPainterPath: detach and reset before streaming in

Otherwise we end up appending and modifying the shared object.

Pick-to: 5.15 6.5 6.6 6.7
Task-number: QTBUG-122704
Change-Id: I01ec3c774d9943adb903fffd17b692c2e6d53e97
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Thiago Macieira 2024-02-23 19:54:34 +01:00 committed by Eirik Aavitsland
parent c1921abf65
commit 2925683268
2 changed files with 21 additions and 8 deletions

View File

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

View File

@ -765,6 +765,21 @@ void tst_QPainterPath::testOperatorDatastream()
} }
QCOMPARE(other, path); 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() void tst_QPainterPath::closing()