summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolan.mcnamara@collabora.com>2024-02-04 22:54:01 +0000
committerCaolán McNamara <caolan.mcnamara@collabora.com>2024-02-05 08:42:23 +0100
commitef1e14db395b7850957534246b2960356b1b2bb7 (patch)
treeafe0625554b33a61a961ba051a1375fbed66e4a6
parent5986ab58db89ee73dc1bc30a7f3800ccb598a3b6 (diff)
ofz#66471 Direct-leak
when a cairo surface gets into an error state typically none of the functions do anything any more, so this leak is because of an invalid uninvertable matrix which comes from a 0 x denom in the svm MapMode, so detect the problem there at the outer boundary. Change-Id: Idedc29b48f2be3853064b4369727bc91082c5a87 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162980 Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com> Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
-rw-r--r--include/vcl/TypeSerializer.hxx2
-rw-r--r--vcl/source/filter/svm/SvmReader.cxx9
-rw-r--r--vcl/source/gdi/TypeSerializer.cxx26
3 files changed, 25 insertions, 12 deletions
diff --git a/include/vcl/TypeSerializer.hxx b/include/vcl/TypeSerializer.hxx
index e85b25b1cfe3..433dbc058eb1 100644
--- a/include/vcl/TypeSerializer.hxx
+++ b/include/vcl/TypeSerializer.hxx
@@ -51,7 +51,7 @@ public:
void readGraphic(Graphic& rGraphic);
void writeGraphic(const Graphic& rGraphic);
- void readMapMode(MapMode& rMapMode);
+ bool readMapMode(MapMode& rMapMode);
void writeMapMode(MapMode const& rMapMode);
};
diff --git a/vcl/source/filter/svm/SvmReader.cxx b/vcl/source/filter/svm/SvmReader.cxx
index 429dfadacf04..c04ebbec2222 100644
--- a/vcl/source/filter/svm/SvmReader.cxx
+++ b/vcl/source/filter/svm/SvmReader.cxx
@@ -1233,15 +1233,16 @@ rtl::Reference<MetaAction> SvmReader::TextAlignHandler()
rtl::Reference<MetaAction> SvmReader::MapModeHandler()
{
- rtl::Reference<MetaMapModeAction> pAction(new MetaMapModeAction);
-
VersionCompatRead aCompat(mrStream);
TypeSerializer aSerializer(mrStream);
+
MapMode aMapMode;
- aSerializer.readMapMode(aMapMode);
+ const bool bSuccess = aSerializer.readMapMode(aMapMode);
+ if (!bSuccess)
+ return nullptr;
+ rtl::Reference<MetaMapModeAction> pAction(new MetaMapModeAction);
pAction->SetMapMode(aMapMode);
-
return pAction;
}
diff --git a/vcl/source/gdi/TypeSerializer.cxx b/vcl/source/gdi/TypeSerializer.cxx
index 49890fc38ea0..d8522bad3615 100644
--- a/vcl/source/gdi/TypeSerializer.cxx
+++ b/vcl/source/gdi/TypeSerializer.cxx
@@ -444,29 +444,41 @@ static bool UselessScaleForMapMode(const Fraction& rScale)
return false;
}
-void TypeSerializer::readMapMode(MapMode& rMapMode)
+bool TypeSerializer::readMapMode(MapMode& rMapMode)
{
VersionCompatRead aCompat(mrStream);
- sal_uInt16 nTmp16(0);
+ sal_uInt16 nUnit(0);
Point aOrigin;
Fraction aScaleX;
Fraction aScaleY;
bool bSimple(true);
- mrStream.ReadUInt16(nTmp16);
- MapUnit eUnit = static_cast<MapUnit>(nTmp16);
+ mrStream.ReadUInt16(nUnit);
readPoint(aOrigin);
readFraction(aScaleX);
readFraction(aScaleY);
mrStream.ReadCharAsBool(bSimple);
- const bool bBogus = UselessScaleForMapMode(aScaleX) || UselessScaleForMapMode(aScaleY);
- SAL_WARN_IF(bBogus, "vcl", "invalid scale");
+ if (nUnit < sal_Int16(MapUnit::Map100thMM) || nUnit > sal_Int16(MapUnit::LAST))
+ {
+ SAL_WARN("vcl.gdi", "Parsing error: invalid mapmode");
+ return false;
+ }
+ MapUnit eUnit = static_cast<MapUnit>(nUnit);
- if (bSimple || bBogus)
+ if (bSimple)
rMapMode = MapMode(eUnit);
else
+ {
+ const bool bBogus = UselessScaleForMapMode(aScaleX) || UselessScaleForMapMode(aScaleY);
+ if (bBogus)
+ {
+ SAL_WARN("vcl", "invalid scale");
+ return false;
+ }
rMapMode = MapMode(eUnit, aOrigin, aScaleX, aScaleY);
+ }
+ return true;
}
void TypeSerializer::writeMapMode(MapMode const& rMapMode)