tdf#103859 emfio: Update variable types to match EMF specification

This patch corrects several variable types across the EMF reader
to strictly align with the official Enhanced Metafile specification,
improving memory safety and fixing minor logging bugs.

Change-Id: I1cc1351248bcdb40220c33441e363aaa226f1ea1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202625
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
This commit is contained in:
Bartosz Kosiorek
2026-03-24 19:52:59 +01:00
parent 23e3413f39
commit 3407985249
2 changed files with 50 additions and 57 deletions
+1 -1
View File
@@ -469,7 +469,7 @@ namespace emfio
, bTransparent(bTrans)
{}
WinMtfLineStyle(const Color& rColor, const sal_uInt32 nStyle, const sal_Int32 nPenWidth)
WinMtfLineStyle(const Color& rColor, const sal_uInt32 nStyle, const sal_uInt32 nPenWidth)
: aLineColor(rColor)
{
// According to documentation: nStyle = PS_COSMETIC = 0x0 - line with a width of one logical unit and a style that is a solid color
+49 -56
View File
@@ -432,14 +432,7 @@ namespace emfio
case EMR_COMMENT_BEGINGROUP:
{
SAL_INFO("emfio", "\t\t\tEMR_COMMENT_BEGINGROUP");
sal_uInt32 left, top, right, bottom;
mpInputStream->ReadUInt32(left).ReadUInt32(top).ReadUInt32(right).ReadUInt32(bottom);
SAL_INFO("emfio", "\t\t\t\tBounding rect");
SAL_INFO("emfio", "\t\t\t\t\tLeft: " << left);
SAL_INFO("emfio", "\t\t\t\t\tTop: " << top);
SAL_INFO("emfio", "\t\t\t\t\tRight: " << right);
SAL_INFO("emfio", "\t\t\t\t\tBottom: " << bottom);
mpInputStream->SeekRel(0x10); // RectL bounds
sal_uInt32 nDescChars(0);
mpInputStream->ReadUInt32(nDescChars);
@@ -732,8 +725,8 @@ namespace emfio
// taking the amount of points of each polygon, retrieving the total number of points
if ( !(mpInputStream->good() &&
( nNumberOfPolylines < SAL_MAX_UINT32 / sizeof( sal_uInt16 ) ) &&
( nNumberOfPolylines * sizeof( sal_uInt16 ) ) <= ( nEndPos - mpInputStream->Tell() ))
( nNumberOfPolylines < SAL_MAX_UINT32 / sizeof( sal_uInt32 ) ) &&
( nNumberOfPolylines * sizeof( sal_uInt32 ) ) <= ( nEndPos - mpInputStream->Tell() ))
)
return;
@@ -778,55 +771,55 @@ namespace emfio
//check against numeric overflowing
if (nGesPoints >= SAL_MAX_UINT32 / sizeof(Point))
return;
if (nPoly >= SAL_MAX_UINT32 / sizeof(sal_uInt16))
if (nPoly >= SAL_MAX_UINT32 / sizeof(sal_uInt32))
return;
if (nPoly * sizeof(sal_uInt16) > nEndPos - mpInputStream->Tell())
if (nPoly * sizeof(sal_uInt32) > nEndPos - mpInputStream->Tell())
return;
// Get number of points in each polygon
std::vector<sal_uInt16> aPoints(nPoly);
std::vector<sal_uInt32> aPoints(nPoly);
for (sal_uInt32 i = 0; i < nPoly && mpInputStream->good(); ++i)
{
sal_uInt32 nPoints(0);
mpInputStream->ReadUInt32( nPoints );
mpInputStream->ReadUInt32(nPoints);
SAL_INFO("emfio", "\t\t\t\tPolygon " << i << " points: " << nPoints);
aPoints[i] = static_cast<sal_uInt16>(nPoints);
aPoints[i] = nPoints;
}
if ( mpInputStream->good() && ( nGesPoints * (sizeof(T)+sizeof(T)) ) <= ( nEndPos - mpInputStream->Tell() ) )
if (!mpInputStream->good() || (nGesPoints * (sizeof(T) * 2)) > (nEndPos - mpInputStream->Tell()))
return;
// Get polygon points
tools::PolyPolygon aPolyPoly(nPoly);
for (sal_uInt32 i = 0; i < nPoly && mpInputStream->good(); ++i)
{
// Get polygon points
tools::PolyPolygon aPolyPoly(nPoly);
for (sal_uInt32 i = 0; i < nPoly && mpInputStream->good(); ++i)
const sal_uInt32 nPointCount(aPoints[i]);
std::vector<Point> aPtAry(nPointCount);
for (sal_uInt32 j = 0; j < nPointCount && mpInputStream->good(); ++j)
{
const sal_uInt16 nPointCount(aPoints[i]);
std::vector<Point> aPtAry(nPointCount);
for (sal_uInt16 j = 0; j < nPointCount && mpInputStream->good(); ++j)
{
T nX(0), nY(0);
*mpInputStream >> nX >> nY;
aPtAry[j] = Point( nX, nY );
++nReadPoints;
}
aPolyPoly.Insert(tools::Polygon(aPtAry.size(), aPtAry.data()));
T nX(0), nY(0);
*mpInputStream >> nX >> nY;
aPtAry[j] = Point(nX, nY);
++nReadPoints;
}
DrawPolyPolygon(aPolyPoly, mbRecordPath);
aPolyPoly.Insert(tools::Polygon(aPtAry.size(), aPtAry.data()));
}
DrawPolyPolygon(aPolyPoly, mbRecordPath);
OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)");
}
bool EmfReader::ReadEnhWMF()
{
sal_uInt32 nStretchBltMode = 0;
sal_uInt32 nNextPos(0),
nW(0), nH(0), nColor(0), nIndex(0),
nDat32(0), nNom1(0), nDen1(0), nNom2(0), nDen2(0);
sal_Int32 nX32(0), nY32(0), nx32(0), ny32(0);
sal_uInt32 nStretchBltMode = 0;
sal_uInt32 nNextPos(0),
nW(0), nH(0), nColor(0), nIndex(0),
nDat32(0);
sal_Int32 nX32(0), nY32(0), nx32(0), ny32(0),
nNom1(0), nDen1(0), nNom2(0), nDen2(0);
bool bStatus = ReadHeader();
bool bHaveDC = false;
@@ -1063,14 +1056,14 @@ namespace emfio
}
break;
case EMR_SCALEWINDOWEXTEX :
case EMR_SCALEWINDOWEXTEX:
{
mpInputStream->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 );
mpInputStream->ReadInt32(nNom1).ReadInt32(nDen1).ReadInt32(nNom2).ReadInt32(nDen2);
SAL_INFO("emfio", "\t\tHorizontal scale: " << nNom1 << " / " << nDen1);
SAL_INFO("emfio", "\t\tVertical scale: " << nNom2 << " / " << nDen2);
if (nDen1 != 0 && nDen2 != 0)
ScaleWinExt( static_cast<double>(nNom1) / nDen1, static_cast<double>(nNom2) / nDen2 );
ScaleWinExt(static_cast<double>(nNom1) / nDen1, static_cast<double>(nNom2) / nDen2);
else
SAL_WARN("vcl.emf", "ignoring bogus divide by zero");
}
@@ -1084,14 +1077,14 @@ namespace emfio
}
break;
case EMR_SCALEVIEWPORTEXTEX :
case EMR_SCALEVIEWPORTEXTEX:
{
mpInputStream->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 );
mpInputStream->ReadInt32(nNom1).ReadInt32(nDen1).ReadInt32(nNom2).ReadInt32(nDen2);
SAL_INFO("emfio", "\t\tHorizontal scale: " << nNom1 << " / " << nDen1);
SAL_INFO("emfio", "\t\tVertical scale: " << nNom2 << " / " << nDen2);
if (nDen1 != 0 && nDen2 != 0)
ScaleDevExt( static_cast<double>(nNom1) / nDen1, static_cast<double>(nNom2) / nDen2 );
ScaleDevExt(static_cast<double>(nNom1) / nDen1, static_cast<double>(nNom2) / nDen2);
else
SAL_WARN("vcl.emf", "ignoring bogus divide by zero");
}
@@ -1148,10 +1141,10 @@ namespace emfio
}
break;
case EMR_SETSTRETCHBLTMODE :
case EMR_SETSTRETCHBLTMODE:
{
mpInputStream->ReadUInt32( nStretchBltMode );
SAL_INFO("emfio", "\t\tStretchBltMode: 0x" << std::hex << nDat32 << std::dec);
mpInputStream->ReadUInt32(nStretchBltMode);
SAL_INFO("emfio", "\t\tStretchBltMode: 0x" << std::hex << nStretchBltMode << std::dec);
}
break;
@@ -1467,8 +1460,8 @@ namespace emfio
case EMR_SELECTCLIPPATH :
{
sal_Int32 nClippingMode(0);
mpInputStream->ReadInt32(nClippingMode);
sal_uInt32 nClippingMode(0);
mpInputStream->ReadUInt32(nClippingMode);
SetClipPath(GetPathObj(), static_cast<RegionMode>(nClippingMode), true);
}
break;
@@ -1480,9 +1473,9 @@ namespace emfio
bStatus = false;
else
{
sal_Int32 nClippingMode(0), cbRgnData(0);
mpInputStream->ReadInt32(cbRgnData);
mpInputStream->ReadInt32(nClippingMode);
sal_uInt32 nClippingMode(0), cbRgnDataSize(0);
mpInputStream->ReadUInt32(cbRgnDataSize);
mpInputStream->ReadUInt32(nClippingMode);
nRemainingRecSize -= 8;
// This record's region data should be ignored if mode
@@ -1494,7 +1487,7 @@ namespace emfio
else
{
basegfx::B2DPolyPolygon aPolyPoly;
if (cbRgnData)
if (cbRgnDataSize)
ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize, GetWinOrg());
const tools::PolyPolygon aPolyPolygon(aPolyPoly);
SetClipPath(aPolyPolygon, static_cast<RegionMode>(nClippingMode), false);
@@ -2257,11 +2250,11 @@ namespace emfio
else
{
// index of the logical color space object in the EMF object table
sal_Int32 ihCS(0);
mpInputStream->ReadInt32(ihCS);
sal_Int32 nDescChars = nRemainingRecSize - 4;
sal_uInt32 ihCS(0);
mpInputStream->ReadUInt32(ihCS); // TODO
sal_uInt32 nDescChars = nRemainingRecSize - 4;
OUStringBuffer aDesc;
for (sal_Int32 i=0; i < nDescChars; i++)
for (sal_uInt32 i = 0; i < nDescChars; i++)
{
unsigned char cChar(0);
mpInputStream->ReadUChar(cChar);