From c0d0949448c5a75d50ca189974d4d9f48133aea8 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Mon, 3 Aug 2020 22:42:23 +0200 Subject: [PATCH] QLineF: Don't try calculating a unit vector when length is null It's undefined and causes a division by zero. Fixes: oss-fuzz-24561 Pick-to: 5.12 5.15 Change-Id: Idebaba4b286e3ab0ecb74825d203244958ce6aec Reviewed-by: hjk Reviewed-by: Thiago Macieira --- src/corelib/tools/qline.cpp | 1 - src/corelib/tools/qline.h | 11 ++++++++--- tests/auto/corelib/tools/qline/tst_qline.cpp | 11 +++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index da66ada3731..e652f84772d 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -40,7 +40,6 @@ #include "qline.h" #include "qdebug.h" #include "qdatastream.h" -#include "qmath.h" #include QT_BEGIN_NAMESPACE diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h index 066bcecc1b2..8889c4afb9b 100644 --- a/src/corelib/tools/qline.h +++ b/src/corelib/tools/qline.h @@ -40,6 +40,8 @@ #ifndef QLINE_H #define QLINE_H +#include "qmath.h" + #include QT_BEGIN_NAMESPACE @@ -369,12 +371,15 @@ constexpr inline QPointF QLineF::center() const return QPointF(0.5 * pt1.x() + 0.5 * pt2.x(), 0.5 * pt1.y() + 0.5 * pt2.y()); } +QT_WARNING_DISABLE_FLOAT_COMPARE + inline void QLineF::setLength(qreal len) { - if (isNull()) + const qreal oldlength = qSqrt(dx() * dx() + dy() * dy()); + if (!oldlength) return; - QLineF v = unitVector(); - pt2 = QPointF(pt1.x() + v.dx() * len, pt1.y() + v.dy() * len); + const qreal factor = len / oldlength; + pt2 = QPointF(pt1.x() + dx() * factor, pt1.y() + dy() * factor); } constexpr inline QPointF QLineF::pointAt(qreal t) const diff --git a/tests/auto/corelib/tools/qline/tst_qline.cpp b/tests/auto/corelib/tools/qline/tst_qline.cpp index 4f3be0f3d99..7e07e9d1e21 100644 --- a/tests/auto/corelib/tools/qline/tst_qline.cpp +++ b/tests/auto/corelib/tools/qline/tst_qline.cpp @@ -40,6 +40,8 @@ private slots: void testLength(); void testLength_data(); + void testSetLength(); + void testCenter(); void testCenter_data(); @@ -258,6 +260,15 @@ void tst_QLine::testLength() QCOMPARE(l.dy(), qreal(vy)); } +void tst_QLine::testSetLength() +{ + QLineF l(0, 0, 4e-323, 5e-324); + const qreal newLength = 1892; + const qreal oldLength = l.length(); + l.setLength(newLength); + QCOMPARE(l.length(), oldLength ? newLength : 0); +} + void tst_QLine::testCenter() { QFETCH(int, x1);