diff options
author | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-02-04 22:54:01 +0000 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-02-05 08:42:23 +0100 |
commit | ef1e14db395b7850957534246b2960356b1b2bb7 (patch) | |
tree | afe0625554b33a61a961ba051a1375fbed66e4a6 | |
parent | 5986ab58db89ee73dc1bc30a7f3800ccb598a3b6 (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.hxx | 2 | ||||
-rw-r--r-- | vcl/source/filter/svm/SvmReader.cxx | 9 | ||||
-rw-r--r-- | vcl/source/gdi/TypeSerializer.cxx | 26 |
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) |