summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-03-14 13:35:22 (GMT)
committerSamuel Rødal <samuel.rodal@nokia.com>2011-03-14 15:18:10 (GMT)
commitc30714122c58a3dc6fd8401427da60c4afc4127b (patch)
treeb54f010500472e7998f93177a861565bb907687b
parent1b3514e4b2d9a41f73bf5b87caf73ce409eadf2a (diff)
downloadQt-c30714122c58a3dc6fd8401427da60c4afc4127b.zip
Qt-c30714122c58a3dc6fd8401427da60c4afc4127b.tar.gz
Qt-c30714122c58a3dc6fd8401427da60c4afc4127b.tar.bz2
Prevented infinite recursion in QPainterPath::contains().
Limit the amount of recursions in qt_painterpath_isect_curve to prevent a crash. Task-number: QTBUG-16422 Reviewed-by: Kim
-rw-r--r--src/gui/painting/qpainterpath.cpp8
-rw-r--r--tests/auto/qpainterpath/tst_qpainterpath.cpp5
2 files changed, 9 insertions, 4 deletions
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 7ecf10a..88eef99 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1690,7 +1690,7 @@ static void qt_painterpath_isect_line(const QPointF &p1,
}
static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
- int *winding)
+ int *winding, int depth = 0)
{
qreal y = pt.y();
qreal x = pt.x();
@@ -1705,7 +1705,7 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
// hit lower limit... This is a rough threshold, but its a
// tradeoff between speed and precision.
const qreal lower_bound = qreal(.001);
- if (bounds.width() < lower_bound && bounds.height() < lower_bound) {
+ if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound)) {
// We make the assumption here that the curve starts to
// approximate a line after while (i.e. that it doesn't
// change direction drastically during its slope)
@@ -1718,8 +1718,8 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
// split curve and try again...
QBezier first_half, second_half;
bezier.split(&first_half, &second_half);
- qt_painterpath_isect_curve(first_half, pt, winding);
- qt_painterpath_isect_curve(second_half, pt, winding);
+ qt_painterpath_isect_curve(first_half, pt, winding, depth + 1);
+ qt_painterpath_isect_curve(second_half, pt, winding, depth + 1);
}
}
diff --git a/tests/auto/qpainterpath/tst_qpainterpath.cpp b/tests/auto/qpainterpath/tst_qpainterpath.cpp
index 00f9b91..4ade9ad 100644
--- a/tests/auto/qpainterpath/tst_qpainterpath.cpp
+++ b/tests/auto/qpainterpath/tst_qpainterpath.cpp
@@ -290,6 +290,11 @@ void tst_QPainterPath::contains_QPointF_data()
QTest::newRow("horizontal cubic, out left") << path << QPointF(0, 100) << false;
QTest::newRow("horizontal cubic, out right") << path << QPointF(300, 100) <<false;
QTest::newRow("horizontal cubic, in mid") << path << QPointF(150, 100) << true;
+
+ path = QPainterPath();
+ path.addEllipse(QRectF(-5000.0, -5000.0, 1500000.0, 1500000.0));
+ QTest::newRow("huge ellipse, qreal=float crash") << path << QPointF(1100000.35, 1098000.2) << true;
+
}
void tst_QPainterPath::contains_QPointF()