summaryrefslogtreecommitdiff
path: root/basegfx
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2022-03-21 15:33:06 +0000
committerCaolán McNamara <caolanm@redhat.com>2022-03-21 17:35:37 +0100
commitf4474b2967f9c7b3b82239c6e9c66850964c6e8b (patch)
treee99d6724ebb93015ced117e7c134a2028c5b9b47 /basegfx
parent79b5ff92b17fde902c2f9db3e806f1c77a387dff (diff)
ofz#45878 add a way to set some limit on hugely complex clips
Change-Id: I6bbf7c6068560e3bb656560fb5c6cc2ed72cecd4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131907 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'basegfx')
-rw-r--r--basegfx/source/polygon/b2dpolygonclipper.cxx13
-rw-r--r--basegfx/source/polygon/b2dpolygoncutandtouch.cxx35
-rw-r--r--basegfx/source/polygon/b2dpolypolygoncutter.cxx8
3 files changed, 44 insertions, 12 deletions
diff --git a/basegfx/source/polygon/b2dpolygonclipper.cxx b/basegfx/source/polygon/b2dpolygonclipper.cxx
index 246d5a10ab84..69eba2c84fa7 100644
--- a/basegfx/source/polygon/b2dpolygonclipper.cxx
+++ b/basegfx/source/polygon/b2dpolygonclipper.cxx
@@ -25,6 +25,7 @@
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
#include <basegfx/utils/rectcliptools.hxx>
+#include <sal/log.hxx>
namespace basegfx::utils
{
@@ -330,7 +331,8 @@ namespace basegfx::utils
return aRetval;
}
- B2DPolyPolygon clipPolyPolygonOnPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPolyPolygon& rClip, bool bInside, bool bStroke)
+ B2DPolyPolygon clipPolyPolygonOnPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPolyPolygon& rClip,
+ bool bInside, bool bStroke, size_t* pPointLimit)
{
B2DPolyPolygon aRetval;
@@ -471,7 +473,14 @@ namespace basegfx::utils
// prepare 2nd source polygon in same way
- B2DPolyPolygon aMergePolyPolygonB = solveCrossovers(rCandidate);
+ B2DPolyPolygon aMergePolyPolygonB = solveCrossovers(rCandidate, pPointLimit);
+
+ if (pPointLimit && !*pPointLimit)
+ {
+ SAL_WARN("basegfx", "clipPolyPolygonOnPolyPolygon hit point limit");
+ return aRetval;
+ }
+
aMergePolyPolygonB = stripNeutralPolygons(aMergePolyPolygonB);
aMergePolyPolygonB = correctOrientations(aMergePolyPolygonB);
diff --git a/basegfx/source/polygon/b2dpolygoncutandtouch.cxx b/basegfx/source/polygon/b2dpolygoncutandtouch.cxx
index 99a73ca82bc3..d5ab5887da61 100644
--- a/basegfx/source/polygon/b2dpolygoncutandtouch.cxx
+++ b/basegfx/source/polygon/b2dpolygoncutandtouch.cxx
@@ -19,6 +19,7 @@
#include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
#include <osl/diagnose.h>
+#include <sal/log.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dvector.hxx>
@@ -203,7 +204,7 @@ namespace basegfx
// predefines for calls to this methods before method implementation
- void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints);
+ void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints, size_t* pPointLimit = nullptr);
void findTouches(const B2DPolygon& rEdgePolygon, const B2DPolygon& rPointPolygon, temporaryPointVector& rTempPoints);
void findCuts(const B2DPolygon& rCandidateA, const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB);
@@ -487,7 +488,7 @@ namespace basegfx
}
}
- void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints)
+ void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints, size_t* pPointLimit)
{
// find out if there are edges with intersections (self-cuts). If yes, add
// entries to rTempPoints accordingly
@@ -588,6 +589,9 @@ namespace basegfx
findEdgeCutsTwoEdges(aCurrA, aNextA, aCurrB, aNextB, a, b, rTempPoints, rTempPoints);
}
+ if (pPointLimit && rTempPoints.size() > *pPointLimit)
+ break;
+
// prepare next step
aCurrB = aNextB;
}
@@ -596,6 +600,14 @@ namespace basegfx
aCurrA = aNextA;
}
}
+
+ if (pPointLimit)
+ {
+ if (rTempPoints.size() > *pPointLimit)
+ *pPointLimit = 0;
+ else
+ *pPointLimit -= rTempPoints.size();
+ }
}
} // end of anonymous namespace
@@ -841,14 +853,19 @@ namespace basegfx
namespace basegfx::utils
{
- B2DPolygon addPointsAtCutsAndTouches(const B2DPolygon& rCandidate)
+ B2DPolygon addPointsAtCutsAndTouches(const B2DPolygon& rCandidate, size_t* pPointLimit)
{
if(rCandidate.count())
{
temporaryPointVector aTempPoints;
findTouches(rCandidate, rCandidate, aTempPoints);
- findCuts(rCandidate, aTempPoints);
+ findCuts(rCandidate, aTempPoints, pPointLimit);
+ if (pPointLimit && !*pPointLimit)
+ {
+ SAL_WARN("basegfx", "addPointsAtCutsAndTouches hit point limit");
+ return rCandidate;
+ }
return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
}
@@ -858,7 +875,7 @@ namespace basegfx::utils
}
}
- B2DPolyPolygon addPointsAtCutsAndTouches(const B2DPolyPolygon& rCandidate)
+ B2DPolyPolygon addPointsAtCutsAndTouches(const B2DPolyPolygon& rCandidate, size_t* pPointLimit)
{
const sal_uInt32 nCount(rCandidate.count());
@@ -880,7 +897,13 @@ namespace basegfx::utils
for(a = 0; a < nCount; a++)
{
// use polygons with solved self intersections
- pTempData[a].setPolygon(addPointsAtCutsAndTouches(rCandidate.getB2DPolygon(a)));
+ pTempData[a].setPolygon(addPointsAtCutsAndTouches(rCandidate.getB2DPolygon(a), pPointLimit));
+ }
+
+ if (pPointLimit && !*pPointLimit)
+ {
+ SAL_WARN("basegfx", "addPointsAtCutsAndTouches hit point limit");
+ return rCandidate;
}
// now cuts and touches between the polygons
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
index ac1e10660607..ddec57374649 100644
--- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx
+++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
@@ -513,7 +513,7 @@ namespace basegfx
impSolve();
}
- explicit solver(const B2DPolyPolygon& rOriginal)
+ explicit solver(const B2DPolyPolygon& rOriginal, size_t* pPointLimit = nullptr)
: maOriginal(rOriginal),
mbIsCurve(false),
mbChanged(false)
@@ -523,7 +523,7 @@ namespace basegfx
if(!nOriginalCount)
return;
- B2DPolyPolygon aGeometry(utils::addPointsAtCutsAndTouches(maOriginal));
+ B2DPolyPolygon aGeometry(utils::addPointsAtCutsAndTouches(maOriginal, pPointLimit));
aGeometry.removeDoublePoints();
aGeometry = utils::simplifyCurveSegments(aGeometry);
mbIsCurve = aGeometry.areControlPointsUsed();
@@ -684,11 +684,11 @@ namespace basegfx
namespace basegfx::utils
{
- B2DPolyPolygon solveCrossovers(const B2DPolyPolygon& rCandidate)
+ B2DPolyPolygon solveCrossovers(const B2DPolyPolygon& rCandidate, size_t* pPointLimit)
{
if(rCandidate.count() > 0)
{
- solver aSolver(rCandidate);
+ solver aSolver(rCandidate, pPointLimit);
return aSolver.getB2DPolyPolygon();
}
else