summaryrefslogtreecommitdiff
path: root/basegfx
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2018-07-04 10:13:16 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2018-07-05 19:58:52 +0200
commitf73eeabf6e584e4a1414ecb0878bb46143f90ff5 (patch)
treea63e9d3636ffa2e31eff1614ec498c0bbf84225e /basegfx
parent7e971b500f164cf07728cc128f63b50d9e56f909 (diff)
Only access css::drawing::PointSequence when not empty
Had to adapt EscherPropertyContainer::GetPolyPolygon due to it using conversions from UNO API drawing::PointSequence to old tools::polygon, containing unsafe memory accesses. It is not useful to fix that, use new tooling instead. Before correctly testing nCount for zero in b2dpolygontools.cxx when you look closely always a point was added - a random one due to accessing random memory. This is corrected, so in test case for "tdf104115.docx" a PolyPolygon with two polys is used, the first being empty (had one point due to the error mentioned above). When having no points, CreatePolygonProperties in escherex.cxx does badly calculate and alloc the pSegmentBuf array used to write to doc formats (in the test case - 20 bytes alloced, 22 written). This did not happen before due to having always a point due to the error before - argh! Corrected that and hopefully this will work now. To be on the safe side and to not need to redefine that whole CreatePolygonProperties I will turn back that little change and better sort-out empty polygons inside GetPolyPolygon alrteady. That should bring us back to the original state, at the same time avoiding that CreatePolygonProperties has to handle empty Polygons at all. That stuff urgently needs cleanup - I took a look and thought about using std::vector<sal_uInt8> so no wrong alloc or write too much could happen, but that nTotalBezPoints needs to be pre-calculated because it gets itself written to that buffers... Change-Id: Iefc885928f5bb29bceaf36c2a1555346bb21fd26 Reviewed-on: https://gerrit.libreoffice.org/56927 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Diffstat (limited to 'basegfx')
-rw-r--r--basegfx/source/polygon/b2dpolygontools.cxx136
1 files changed, 70 insertions, 66 deletions
diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx
index db3365eee313..94590d7483a8 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -3285,90 +3285,94 @@ namespace basegfx
// prepare new polygon
B2DPolygon aRetval;
- const css::awt::Point* pPointSequence = rPointSequenceSource.getConstArray();
- const css::drawing::PolygonFlags* pFlagSequence = rFlagSequenceSource.getConstArray();
- // get first point and flag
- B2DPoint aNewCoordinatePair(pPointSequence->X, pPointSequence->Y); pPointSequence++;
- css::drawing::PolygonFlags ePolygonFlag(*pFlagSequence); pFlagSequence++;
- B2DPoint aControlA;
- B2DPoint aControlB;
+ if(0 != nCount)
+ {
+ const css::awt::Point* pPointSequence = rPointSequenceSource.getConstArray();
+ const css::drawing::PolygonFlags* pFlagSequence = rFlagSequenceSource.getConstArray();
- // first point is not allowed to be a control point
- OSL_ENSURE(ePolygonFlag != css::drawing::PolygonFlags_CONTROL,
- "UnoPolygonBezierCoordsToB2DPolygon: Start point is a control point, illegal input polygon (!)");
+ // get first point and flag
+ B2DPoint aNewCoordinatePair(pPointSequence->X, pPointSequence->Y); pPointSequence++;
+ css::drawing::PolygonFlags ePolygonFlag(*pFlagSequence); pFlagSequence++;
+ B2DPoint aControlA;
+ B2DPoint aControlB;
- // add first point as start point
- aRetval.append(aNewCoordinatePair);
+ // first point is not allowed to be a control point
+ OSL_ENSURE(ePolygonFlag != css::drawing::PolygonFlags_CONTROL,
+ "UnoPolygonBezierCoordsToB2DPolygon: Start point is a control point, illegal input polygon (!)");
- for(sal_uInt32 b(1); b < nCount;)
- {
- // prepare loop
- bool bControlA(false);
- bool bControlB(false);
+ // add first point as start point
+ aRetval.append(aNewCoordinatePair);
- // get next point and flag
- aNewCoordinatePair = B2DPoint(pPointSequence->X, pPointSequence->Y);
- ePolygonFlag = *pFlagSequence;
- pPointSequence++; pFlagSequence++; b++;
-
- if(b < nCount && ePolygonFlag == css::drawing::PolygonFlags_CONTROL)
+ for(sal_uInt32 b(1); b < nCount;)
{
- aControlA = aNewCoordinatePair;
- bControlA = true;
+ // prepare loop
+ bool bControlA(false);
+ bool bControlB(false);
// get next point and flag
aNewCoordinatePair = B2DPoint(pPointSequence->X, pPointSequence->Y);
ePolygonFlag = *pFlagSequence;
pPointSequence++; pFlagSequence++; b++;
- }
- if(b < nCount && ePolygonFlag == css::drawing::PolygonFlags_CONTROL)
- {
- aControlB = aNewCoordinatePair;
- bControlB = true;
+ if(b < nCount && ePolygonFlag == css::drawing::PolygonFlags_CONTROL)
+ {
+ aControlA = aNewCoordinatePair;
+ bControlA = true;
- // get next point and flag
- aNewCoordinatePair = B2DPoint(pPointSequence->X, pPointSequence->Y);
- ePolygonFlag = *pFlagSequence;
- pPointSequence++; pFlagSequence++; b++;
- }
+ // get next point and flag
+ aNewCoordinatePair = B2DPoint(pPointSequence->X, pPointSequence->Y);
+ ePolygonFlag = *pFlagSequence;
+ pPointSequence++; pFlagSequence++; b++;
+ }
- // two or no control points are consumed, another one would be an error.
- // It's also an error if only one control point was read
- SAL_WARN_IF(ePolygonFlag == css::drawing::PolygonFlags_CONTROL || bControlA != bControlB,
- "basegfx", "UnoPolygonBezierCoordsToB2DPolygon: Illegal source polygon (!)");
+ if(b < nCount && ePolygonFlag == css::drawing::PolygonFlags_CONTROL)
+ {
+ aControlB = aNewCoordinatePair;
+ bControlB = true;
- // the previous writes used the B2DPolyPoygon -> utils::PolyPolygon converter
- // which did not create minimal PolyPolygons, but created all control points
- // as null vectors (identical points). Because of the former P(CA)(CB)-norm of
- // B2DPolygon and it's unused sign of being the zero-vector and CA and CB being
- // relative to P, an empty edge was exported as P == CA == CB. Luckily, the new
- // export format can be read without errors by the old OOo-versions, so we need only
- // to correct here at read and do not need to export a wrong but compatible version
- // for the future.
- if(bControlA
- && aControlA.equal(aControlB)
- && aControlA.equal(aRetval.getB2DPoint(aRetval.count() - 1)))
- {
- bControlA = false;
- }
+ // get next point and flag
+ aNewCoordinatePair = B2DPoint(pPointSequence->X, pPointSequence->Y);
+ ePolygonFlag = *pFlagSequence;
+ pPointSequence++; pFlagSequence++; b++;
+ }
- if(bControlA)
- {
- // add bezier edge
- aRetval.appendBezierSegment(aControlA, aControlB, aNewCoordinatePair);
- }
- else
- {
- // add edge
- aRetval.append(aNewCoordinatePair);
+ // two or no control points are consumed, another one would be an error.
+ // It's also an error if only one control point was read
+ SAL_WARN_IF(ePolygonFlag == css::drawing::PolygonFlags_CONTROL || bControlA != bControlB,
+ "basegfx", "UnoPolygonBezierCoordsToB2DPolygon: Illegal source polygon (!)");
+
+ // the previous writes used the B2DPolyPoygon -> utils::PolyPolygon converter
+ // which did not create minimal PolyPolygons, but created all control points
+ // as null vectors (identical points). Because of the former P(CA)(CB)-norm of
+ // B2DPolygon and it's unused sign of being the zero-vector and CA and CB being
+ // relative to P, an empty edge was exported as P == CA == CB. Luckily, the new
+ // export format can be read without errors by the old OOo-versions, so we need only
+ // to correct here at read and do not need to export a wrong but compatible version
+ // for the future.
+ if(bControlA
+ && aControlA.equal(aControlB)
+ && aControlA.equal(aRetval.getB2DPoint(aRetval.count() - 1)))
+ {
+ bControlA = false;
+ }
+
+ if(bControlA)
+ {
+ // add bezier edge
+ aRetval.appendBezierSegment(aControlA, aControlB, aNewCoordinatePair);
+ }
+ else
+ {
+ // add edge
+ aRetval.append(aNewCoordinatePair);
+ }
}
- }
- // #i72807# API import uses old line start/end-equal definition for closed,
- // so we need to correct this to closed state here
- checkClosed(aRetval);
+ // #i72807# API import uses old line start/end-equal definition for closed,
+ // so we need to correct this to closed state here
+ checkClosed(aRetval);
+ }
return aRetval;
}