File 0002-Fix-crash-in-font-distancefield-computation.patch of Package libqt5-qtbase.40462

From 861b30001294e7ba2876664c7c61e530702feb6b Mon Sep 17 00:00:00 2001
From: Eirik Aavitsland <eirik.aavitsland@qt.io>
Date: Mon, 12 Aug 2024 10:55:25 +0200
Subject: [PATCH] Fix crash in font distancefield computation

If setting a larger-than-default distance field base font size
(renderTypeQuality in qml), an exceptionally large glyph could cause
integer overflows in the distance filed computation, causing asserts
or crashes.
Change the computation types to avoid the overflow.

This improves on b6f962c87f5084eaf962bfb033b1398f80475120.

Fixes: QTBUG-124310
Pick-to: 6.8 6.7 6.5 6.2 5.15
Change-Id: I48b7dc3c0a0f35859d45c40d03498ac057e9fa70
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit 30a753944300c13e96f9239a9891cbc8e2e378c1)
---
 src/gui/painting/qpathsimplifier.cpp | 34 ++++++++++++++++------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/gui/painting/qpathsimplifier.cpp b/src/gui/painting/qpathsimplifier.cpp
index a2900d8fe49..60018c18571 100644
--- a/src/gui/painting/qpathsimplifier.cpp
+++ b/src/gui/painting/qpathsimplifier.cpp
@@ -164,11 +164,15 @@ QPoint IntersectionPoint::round() const
 
 // Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the
 // line and zero if exactly on the line.
-// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1',
-// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order).
-inline int pointDistanceFromLine(const QPoint &p, const QPoint &v1, const QPoint &v2)
+// The returned value is the sign of the cross product between 'v2-v1' and 'p-v1'.
+inline int pointSideOfLine(const QPoint &p, const QPoint &v1, const QPoint &v2)
 {
-    return cross(v2 - v1, p - v1);
+    qint64 ux = qint64(v2.x()) - v1.x();
+    qint64 uy = qint64(v2.y()) - v1.y();
+    qint64 vx = qint64(p.x()) - v1.x();
+    qint64 vy = qint64(p.y()) - v1.y();
+    qint64 c = (ux * vy) - (uy * vx);
+    return (c > 0) ? 1 : (c < 0) ? -1 : 0;
 }
 
 IntersectionPoint intersectionPoint(const QPoint &u1, const QPoint &u2,
@@ -1428,19 +1432,19 @@ bool PathSimplifier::elementIsLeftOf(const Element *left, const Element *right)
         return true;
     if (leftU.x() > qMax(rightL.x(), rightU.x()))
         return false;
-    int d = pointDistanceFromLine(leftU, rightL, rightU);
+    int d = pointSideOfLine(leftU, rightL, rightU);
     // d < 0: left, d > 0: right, d == 0: on top
     if (d == 0) {
-        d = pointDistanceFromLine(leftL, rightL, rightU);
+        d = pointSideOfLine(leftL, rightL, rightU);
         if (d == 0) {
             if (right->degree > Element::Line) {
-                d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[1]));
+                d = pointSideOfLine(leftL, rightL, m_points->at(right->indices[1]));
                 if (d == 0)
-                    d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[2]));
+                    d = pointSideOfLine(leftL, rightL, m_points->at(right->indices[2]));
             } else if (left->degree > Element::Line) {
-                d = pointDistanceFromLine(m_points->at(left->indices[1]), rightL, rightU);
+                d = pointSideOfLine(m_points->at(left->indices[1]), rightL, rightU);
                 if (d == 0)
-                    d = pointDistanceFromLine(m_points->at(left->indices[2]), rightL, rightU);
+                    d = pointSideOfLine(m_points->at(left->indices[2]), rightL, rightU);
             }
         }
     }
@@ -1460,13 +1464,13 @@ QPair<PathSimplifier::RBNode *, PathSimplifier::RBNode *> PathSimplifier::outerB
         Q_ASSERT(point >= v2 && point <= v1);
         if (point == v1 || point == v2)
             break;
-        int d = pointDistanceFromLine(point, v1, v2);
+        int d = pointSideOfLine(point, v1, v2);
         if (d == 0) {
             if (element->degree == Element::Line)
                 break;
-            d = pointDistanceFromLine(point, v1, m_points->at(element->indices[1]));
+            d = pointSideOfLine(point, v1, m_points->at(element->indices[1]));
             if (d == 0)
-                d = pointDistanceFromLine(point, v1, m_points->at(element->indices[2]));
+                d = pointSideOfLine(point, v1, m_points->at(element->indices[2]));
             Q_ASSERT(d != 0);
         }
         if (d < 0) {
@@ -1492,7 +1496,7 @@ QPair<PathSimplifier::RBNode *, PathSimplifier::RBNode *> PathSimplifier::outerB
         Q_ASSERT(point >= v2 && point <= v1);
         bool equal = (point == v1 || point == v2);
         if (!equal) {
-            int d = pointDistanceFromLine(point, v1, v2);
+            int d = pointSideOfLine(point, v1, v2);
             Q_ASSERT(d >= 0);
             equal = (d == 0 && element->degree == Element::Line);
         }
@@ -1513,7 +1517,7 @@ QPair<PathSimplifier::RBNode *, PathSimplifier::RBNode *> PathSimplifier::outerB
         Q_ASSERT(point >= v2 && point <= v1);
         bool equal = (point == v1 || point == v2);
         if (!equal) {
-            int d = pointDistanceFromLine(point, v1, v2);
+            int d = pointSideOfLine(point, v1, v2);
             Q_ASSERT(d <= 0);
             equal = (d == 0 && element->degree == Element::Line);
         }
-- 
GitLab

openSUSE Build Service is sponsored by