Version in base suite: 25.2.3-2+deb13u4 Base version: libreoffice_25.2.3-2+deb13u4 Target version: libreoffice_25.2.3-2+deb13u5 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libr/libreoffice/libreoffice_25.2.3-2+deb13u4.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libr/libreoffice/libreoffice_25.2.3-2+deb13u5.dsc changelog | 15 ++ patches/CVE-2026-6039.diff | 59 ++++++++++ patches/CVE-2026-6040.diff | 75 +++++++++++++ patches/CVE-2026-6045.diff | 258 +++++++++++++++++++++++++++++++++++++++++++++ patches/CVE-2026-8356.diff | 152 ++++++++++++++++++++++++++ patches/CVE-2026-8357.diff | 42 +++++++ patches/CVE-2026-8358.diff | 110 +++++++++++++++++++ patches/series | 6 + 8 files changed, 717 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp1je7kjzy/libreoffice_25.2.3-2+deb13u4.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp1je7kjzy/libreoffice_25.2.3-2+deb13u5.dsc: no acceptable signature found diff -Nru libreoffice-25.2.3/debian/changelog libreoffice-25.2.3/debian/changelog --- libreoffice-25.2.3/debian/changelog 2026-03-19 20:20:19.000000000 +0000 +++ libreoffice-25.2.3/debian/changelog 2026-05-25 11:04:39.000000000 +0000 @@ -1,3 +1,18 @@ +libreoffice (4:25.2.3-2+deb13u5) trixie-security; urgency=medium + + * debian/patches/CVE-2026-*.diff: fix + - CVE-2026-6039 DXF heap-buffer-overflow in DrawLWPolyLineEntity + - CVE-2026-6040 ODT use-after-free in lcl_InsertBlankWidthChars + - CVE-2026-6045 EMF+ Heap-buffer-overflow in EMFPBrush::Read + - CVE-2026-8356 ANT-2026-01882: Stack Buffer Overflow in + `SdrEscherImport::RecolorGraphic()` + - CVE-2026-8357 ANT-2026-03093: Off-by-one heap-buffer-overflow in + LibreOffice Calc formula compiler + - CVE-2026-8358 ANT-2026-03238: Heap-buffer-overflow in LibreOffice + Calc FODS tracked-changes importer via duplicate action ID + + -- Rene Engelhard Mon, 25 May 2026 13:04:39 +0200 + libreoffice (4:25.2.3-2+deb13u4) trixie-security; urgency=medium * debian/patches/Conform-AlignEngine-parsing-to-spec.diff: as name says; diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-6039.diff libreoffice-25.2.3/debian/patches/CVE-2026-6039.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-6039.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-6039.diff 2026-05-23 13:54:55.000000000 +0000 @@ -0,0 +1,59 @@ +CVE-2026-6039: DXF heap-buffer-overflow in DrawLWPolyLineEntity +It looks like our oss-fuzz efforts didn't find this because we capped +the dxffuzzer.options size at 64KB which is too small to capture this +issue. + +From cf825c7608ded2cb1b7c846bde15d0ebcf6a5c44 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 9 Apr 2026 17:23:39 +0100 +Subject: [PATCH] stay within max Polygon points + +Change-Id: I02e34bb413e6332d8c5683504a63a591a33d7730 +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203575 +Reviewed-by: Xisco Fauli +Tested-by: Jenkins +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203626 +Signed-off-by: Xisco Fauli +--- + vcl/source/filter/idxf/dxf2mtf.cxx | 12 ++++++++---- + vcl/workben/dxffuzzer.options | 2 +- + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/vcl/source/filter/idxf/dxf2mtf.cxx b/vcl/source/filter/idxf/dxf2mtf.cxx +index 022da932fc79..41cdb8c440ee 100644 +--- a/vcl/source/filter/idxf/dxf2mtf.cxx ++++ b/vcl/source/filter/idxf/dxf2mtf.cxx +@@ -554,13 +554,17 @@ void DXF2GDIMetaFile::DrawPolyLineEntity(const DXFPolyLineEntity & rE, const DXF + void DXF2GDIMetaFile::DrawLWPolyLineEntity(const DXFLWPolyLineEntity & rE, const DXFTransform & rTransform ) + { + sal_Int32 nPolySize = rE.aP.size(); +- if (!nPolySize) ++ if (nPolySize <= 0 || nPolySize > SAL_MAX_UINT16) ++ { ++ SAL_WARN("vcl.filter", "DXF2GDIMetaFile::DrawLWPolyLineEntity: invalid num of points: " << nPolySize); + return; ++ } + +- tools::Polygon aPoly( static_cast(nPolySize)); +- for (sal_Int32 i = 0; i < nPolySize; ++i) ++ sal_uInt16 nSize = static_cast(nPolySize); ++ tools::Polygon aPoly(nSize); ++ for (sal_uInt16 i = 0; i < nSize; ++i) + { +- rTransform.Transform( rE.aP[ static_cast(i) ], aPoly[ static_cast(i) ] ); ++ rTransform.Transform( rE.aP[i], aPoly[i] ); + } + if ( SetLineAttribute( rE ) ) + { +diff --git a/vcl/workben/dxffuzzer.options b/vcl/workben/dxffuzzer.options +index 678d526b1ea9..965216112046 100644 +--- a/vcl/workben/dxffuzzer.options ++++ b/vcl/workben/dxffuzzer.options +@@ -1,2 +1,2 @@ + [libfuzzer] +-max_len = 65536 ++max_len = 524288 +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-6040.diff libreoffice-25.2.3/debian/patches/CVE-2026-6040.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-6040.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-6040.diff 2026-05-23 13:54:55.000000000 +0000 @@ -0,0 +1,75 @@ +CVE-2026-6040: ODT use-after-free in lcl_InsertBlankWidthChars +oss-fuzz efforts might not have found this because the fuzzer +dictionary was based on OpenDocument-v1.3-schema.rng and the +loext:blank-width-char isn't in that schema, adding in the extra +extension schema might help for the future. + +From 997ef5c01cedc4a4f8b966310d4a79906009735e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 9 Apr 2026 17:47:09 +0100 +Subject: [PATCH] process loext:blank-width-char better + +Change-Id: Iea005facd85443091c5144a0a0f8f15fa995dbf3 +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203576 +Reviewed-by: Xisco Fauli +Tested-by: Jenkins +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203627 +Signed-off-by: Xisco Fauli +--- + bin/oss-fuzz-setup.sh | 7 ++++--- + xmloff/source/style/xmlnumfi.cxx | 9 ++++----- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/bin/oss-fuzz-setup.sh b/bin/oss-fuzz-setup.sh +index caddb5ef9a8a..4984a8821caf 100755 +--- a/bin/oss-fuzz-setup.sh ++++ b/bin/oss-fuzz-setup.sh +@@ -97,12 +97,13 @@ curl --no-progress-meter -S \ + -C - -O https://raw.githubusercontent.com/google/fuzzing/master/dictionaries/mathml.dict + # build our own fuzz dict for odf, following the pattern of svg.dict + echo "# Keywords taken from libreoffice/schema/odf1.3/OpenDocument-v1.3-schema.rng" > odf.dict ++echo "# and libreoffice/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng" >> odf.dict + echo "# tags" >> odf.dict +-grep "rng:element name=" libreoffice/schema/odf1.3/OpenDocument-v1.3-schema.rng | sed 's#]*$##' >> odf.dict ++grep -h "rng:element name=" libreoffice/schema/odf1.3/OpenDocument-v1.3-schema.rng libreoffice/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng | sed 's#]*$##' >> odf.dict + echo "# attributes " >> odf.dict +-grep "rng:attribute name=" libreoffice/schema/odf1.3/OpenDocument-v1.3-schema.rng | sed 's#]*$##' >> odf.dict ++grep -h "rng:attribute name=" libreoffice/schema/odf1.3/OpenDocument-v1.3-schema.rng libreoffice/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng | sed 's#]*$##' >> odf.dict + echo "# attributes' values" >> odf.dict +-grep "rng:value" libreoffice/schema/odf1.3/OpenDocument-v1.3-schema.rng | sed 's##"#;s##"#;s#^[[:blank:]]*##;s#[[:blank:]>]*$##' | sort | uniq >> odf.dict ++grep -h "rng:value" libreoffice/schema/odf1.3/OpenDocument-v1.3-schema.rng libreoffice/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng | sed 's##"#;s##"#;s#^[[:blank:]]*##;s#[[:blank:]>]*$##' | sort | uniq >> odf.dict + + #fuzzing corpuses + #afl jpeg, gif, bmp, png, webp +diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx +index 2ed570fb330e..778547724d17 100644 +--- a/xmloff/source/style/xmlnumfi.cxx ++++ b/xmloff/source/style/xmlnumfi.cxx +@@ -895,7 +895,7 @@ void lcl_InsertBlankWidthChars( std::u16string_view rBlankWidthString, OUStringB + nPositionContent = o3tl::toInt32( rBlankWidthString.substr( i ) ); + } + nPositionContent += nShiftPosition; +- if ( nPositionContent >= 0 ) ++ if ( nPositionContent >= 0 && nPositionContent <= rContent.getLength() ) + { + rContent.remove( nPositionContent, aBlanks.getLength() ); + if ( nPositionContent >= 1 && rContent[ nPositionContent-1 ] == '\"' ) +@@ -916,11 +916,10 @@ void lcl_InsertBlankWidthChars( std::u16string_view rBlankWidthString, OUStringB + } + } + // remove empty string at the end of rContent +- if ( std::u16string_view( rContent ).substr( rContent.getLength() - 2 ) == u"\"\"" ) ++ sal_Int32 nLen = rContent.getLength(); ++ if ( nLen >= 3 && std::u16string_view( rContent ).substr( nLen - 2 ) == u"\"\"" && rContent[ nLen-3 ] != '\\' ) + { +- sal_Int32 nLen = rContent.getLength(); +- if ( nLen >= 3 && rContent[ nLen-3 ] != '\\' ) +- rContent.truncate( nLen - 2 ); ++ rContent.truncate( nLen - 2 ); + } + } + } +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-6045.diff libreoffice-25.2.3/debian/patches/CVE-2026-6045.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-6045.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-6045.diff 2026-05-25 11:04:32.000000000 +0000 @@ -0,0 +1,258 @@ +CVE-2026-6045 EMF+ Heap-buffer-overflow in EMFPBrush::Read +A nested format problem tucked away in the rendering path, probably +need to add something dedicated to the simpler fuzzer to force that +render path to be exercised. + +From 279c7ea61829efe5cabc5832d06e1833ad28379f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 9 Apr 2026 20:00:38 +0100 +Subject: [PATCH] check that the file can provide the claimed data + +and make sure we initialize these locals + +Change-Id: Ifa899e36f678216574364e5206037ab57b2d19d9 +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203577 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203628 +Signed-off-by: Xisco Fauli +--- + drawinglayer/source/tools/emfpbrush.cxx | 56 ++++++++++++++++++++----- + 1 file changed, 45 insertions(+), 11 deletions(-) + +diff --git a/drawinglayer/source/tools/emfpbrush.cxx b/drawinglayer/source/tools/emfpbrush.cxx +index 51fce424b70a..fe910e4e56e0 100644 +--- a/drawinglayer/source/tools/emfpbrush.cxx ++++ b/drawinglayer/source/tools/emfpbrush.cxx +@@ -63,7 +63,7 @@ namespace emfplushelper + + void EMFPBrush::Read(SvStream& s, EmfPlusHelperData const & rR) + { +- sal_uInt32 header; ++ sal_uInt32 header(0); + + s.ReadUInt32(header).ReadUInt32(type); + +@@ -73,7 +73,7 @@ namespace emfplushelper + { + case BrushTypeSolidColor: + { +- sal_uInt32 color; ++ sal_uInt32 color(0); + s.ReadUInt32(color); + + solidColor = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); +@@ -82,9 +82,9 @@ namespace emfplushelper + } + case BrushTypeHatchFill: + { +- sal_uInt32 style; +- sal_uInt32 foregroundColor; +- sal_uInt32 backgroundColor; ++ sal_uInt32 style(0); ++ sal_uInt32 foregroundColor(0); ++ sal_uInt32 backgroundColor(0); + s.ReadUInt32(style); + s.ReadUInt32(foregroundColor); + s.ReadUInt32(backgroundColor); +@@ -120,7 +120,7 @@ namespace emfplushelper + { + s.ReadUInt32(additionalFlags).ReadInt32(wrapMode); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tAdditional flags: 0x" << std::hex << additionalFlags << std::dec); +- sal_uInt32 color; ++ sal_uInt32 color(0); + s.ReadUInt32(color); + solidColor = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tCenter color: 0x" << std::hex << color << std::dec); +@@ -129,6 +129,12 @@ namespace emfplushelper + s.ReadUInt32(surroundColorsNumber); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\t number of surround colors: " << surroundColorsNumber); + ++ if (surroundColorsNumber > s.remainingSize() / sizeof(sal_uInt32)) ++ { ++ SAL_WARN("drawinglayer.emf", "EMF+\t\t\t\tTruncated surround colors"); ++ return; ++ } ++ + surroundColors.reset( new ::Color[surroundColorsNumber] ); + + for (sal_uInt32 i = 0; i < surroundColorsNumber; i++) +@@ -142,15 +148,15 @@ namespace emfplushelper + + if (additionalFlags & 0x01) // BrushDataPath + { +- sal_Int32 pathLength; ++ sal_Int32 pathLength(0); + + s.ReadInt32(pathLength); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tPath length: " << pathLength); + + sal_uInt64 const pos = s.Tell(); + +- sal_uInt32 pathHeader; +- sal_Int32 pathPoints, pathFlags; ++ sal_uInt32 pathHeader(0); ++ sal_Int32 pathPoints(0), pathFlags(0); + s.ReadUInt32(pathHeader).ReadInt32(pathPoints).ReadInt32(pathFlags); + + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tPath (brush path gradient)"); +@@ -171,7 +177,7 @@ namespace emfplushelper + } + else + { +- sal_Int32 boundaryPointCount; ++ sal_Int32 boundaryPointCount(0); + s.ReadInt32(boundaryPointCount); + + sal_uInt64 const pos = s.Tell(); +@@ -205,6 +211,13 @@ namespace emfplushelper + { + s.ReadUInt32(blendPoints); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tuse blend, points: " << blendPoints); ++ ++ if (blendPoints > s.remainingSize() / (2 * sizeof(float))) ++ { ++ SAL_WARN("drawinglayer.emf", "EMF+\t\t\t\tTruncated blend points"); ++ return; ++ } ++ + blendPositions.reset( new float[2 * blendPoints] ); + blendFactors = blendPositions.get() + blendPoints; + +@@ -225,6 +238,13 @@ namespace emfplushelper + { + s.ReadUInt32(colorblendPoints); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tUse color blend, points: " << colorblendPoints); ++ ++ if (colorblendPoints > s.remainingSize() / (sizeof(float) + sizeof(sal_uInt32))) ++ { ++ SAL_WARN("drawinglayer.emf", "EMF+\t\t\t\tTruncated color blend points"); ++ return; ++ } ++ + colorblendPositions.reset( new float[colorblendPoints] ); + colorblendColors.reset( new ::Color[colorblendPoints] ); + +@@ -251,7 +271,7 @@ namespace emfplushelper + s.ReadFloat(firstPointX).ReadFloat(firstPointY).ReadFloat(aWidth).ReadFloat(aHeight); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tFirst gradient point: " << firstPointX << ":" << firstPointY + << ", size " << aWidth << "x" << aHeight); +- sal_uInt32 color; ++ sal_uInt32 color(0); + s.ReadUInt32(color); + solidColor = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tfirst color: 0x" << std::hex << color << std::dec); +@@ -280,6 +300,13 @@ namespace emfplushelper + { + s.ReadUInt32(blendPoints); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tUse blend, points: " << blendPoints); ++ ++ if (blendPoints > s.remainingSize() / (2 * sizeof(float))) ++ { ++ SAL_WARN("drawinglayer.emf", "EMF+\t\t\t\tTruncated blend points"); ++ return; ++ } ++ + blendPositions.reset( new float[2 * blendPoints] ); + blendFactors = blendPositions.get() + blendPoints; + +@@ -300,6 +327,13 @@ namespace emfplushelper + { + s.ReadUInt32(colorblendPoints); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tUse color blend, points: " << colorblendPoints); ++ ++ if (colorblendPoints > s.remainingSize() / (sizeof(float) + sizeof(sal_uInt32))) ++ { ++ SAL_WARN("drawinglayer.emf", "EMF+\t\t\t\tTruncated color blend points"); ++ return; ++ } ++ + colorblendPositions.reset( new float[colorblendPoints] ); + colorblendColors.reset( new ::Color[colorblendPoints] ); + +-- +2.47.3 + +From 4e969bc73a3cfa15952648ac8a68aa4a36bfe168 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 9 Apr 2026 21:50:22 +0100 +Subject: [PATCH] check that the file can provide the claimed data + +and make sure we initialize these locals + +Change-Id: I94317301368780761c0c6550add3e3e5ab63cf5f +Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/723 +Reviewed-by: Michael Stahl +Tested-by: Jenkins CPCI +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203582 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203633 +Signed-off-by: Xisco Fauli +--- + drawinglayer/source/tools/emfppen.cxx | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drawinglayer/source/tools/emfppen.cxx b/drawinglayer/source/tools/emfppen.cxx +index 789239d62e8b..9ec5a58e0c5f 100644 +--- a/drawinglayer/source/tools/emfppen.cxx ++++ b/drawinglayer/source/tools/emfppen.cxx +@@ -183,7 +183,7 @@ namespace emfplushelper + void EMFPPen::Read(SvStream& s, EmfPlusHelperData const & rR) + { + sal_Int32 lineJoin = EmfPlusLineJoinTypeMiter; +- sal_uInt32 graphicsVersion, penType; ++ sal_uInt32 graphicsVersion(0), penType(0); + s.ReadUInt32(graphicsVersion).ReadUInt32(penType).ReadUInt32(penDataFlags).ReadUInt32(penUnit).ReadFloat(penWidth); + SAL_INFO("drawinglayer.emf", "EMF+\t\tGraphics version: 0x" << std::hex << graphicsVersion); + SAL_INFO("drawinglayer.emf", "EMF+\t\tType: " << penType); +@@ -246,7 +246,7 @@ namespace emfplushelper + + if (penDataFlags & EmfPlusPenDataMiterLimit) + { +- float miterLimit; ++ float miterLimit(0); + s.ReadFloat(miterLimit); + + // EMF+ JoinTypeMiterClipped is working as our B2DLineJoin::Miter +@@ -300,11 +300,17 @@ namespace emfplushelper + if (penDataFlags & EmfPlusPenDataDashedLine) + { + dashStyle = EmfPlusLineStyleCustom; +- sal_uInt32 dashPatternLen; ++ sal_uInt32 dashPatternLen(0); + + s.ReadUInt32(dashPatternLen); + SAL_INFO("drawinglayer.emf", "EMF+\t\t\tdashPatternLen: " << dashPatternLen); + ++ if (dashPatternLen > s.remainingSize() / sizeof(float)) ++ { ++ SAL_WARN("drawinglayer.emf", "EMF+\t\t\tTruncated dash pattern"); ++ return; ++ } ++ + dashPattern.resize( dashPatternLen ); + + for (sal_uInt32 i = 0; i < dashPatternLen; i++) +@@ -327,9 +333,15 @@ namespace emfplushelper + if (penDataFlags & EmfPlusPenDataCompoundLine) + { + SAL_WARN("drawinglayer.emf", "EMF+\t\t\tTODO PenDataCompoundLine"); +- sal_uInt32 compoundArrayLen; ++ sal_uInt32 compoundArrayLen(0); + s.ReadUInt32(compoundArrayLen); + ++ if (compoundArrayLen > s.remainingSize() / sizeof(float)) ++ { ++ SAL_WARN("drawinglayer.emf", "EMF+\t\t\tTruncated compound array"); ++ return; ++ } ++ + compoundArray.resize(compoundArrayLen); + + for (sal_uInt32 i = 0; i < compoundArrayLen; i++) +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-8356.diff libreoffice-25.2.3/debian/patches/CVE-2026-8356.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-8356.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-8356.diff 2026-05-23 14:34:00.000000000 +0000 @@ -0,0 +1,152 @@ +From 54c0ec8700f53ede20af1d0fa2e5fe3d587f2ce3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 26 Apr 2026 15:49:32 +0000 +Subject: [PATCH] SdrEscherImport::RecolorGraphic reads but doesn't use + FillColors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +it never did, but at: + +commit 025bfa7e510bdab3ef93ad45a731fc25085ba3cc +Date: Thu Apr 23 10:03:58 2015 +0100 + + cppcheck: unreadVariable + +the wrong choice was made wrt the dead store, the dead loop should have +been fixed rather than let the unused fill colors accumulate in the +globalcolors buffer. + +This function doesn't need to consume the unused data, all callers don't +expect the entire record to be read so just drop the loop. + +Signed-off-by: Caolán McNamara +Change-Id: I02bce4dd78dc566f18edc3d45603534c3f724cc3 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1689 +(cherry picked from commit 07faeadace3d8d93225f9dd72c4f911e331070e2) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205089 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit 9ba100c0d2131862c9356a86906921abc80d8f98) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205097 +--- + filter/source/msfilter/svdfppt.cxx | 97 +++++++++++++----------------- + 1 file changed, 43 insertions(+), 54 deletions(-) + +diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx +index 1a5e67d03b41..e0c37fe2cc3c 100644 +--- a/filter/source/msfilter/svdfppt.cxx ++++ b/filter/source/msfilter/svdfppt.cxx +@@ -619,65 +619,54 @@ void SdrEscherImport::RecolorGraphic( SvStream& rSt, sal_uInt32 nRecLen, Graphic + sal_uInt32 OriginalGlobalColors[ 64 ]; + sal_uInt32 NewGlobalColors[ 64 ]; + +- sal_uInt32 i, j, nGlobalColorsChanged, nFillColorsChanged; +- nGlobalColorsChanged = nFillColorsChanged = 0; +- +- sal_uInt32* pCurrentOriginal = OriginalGlobalColors; +- sal_uInt32* pCurrentNew = NewGlobalColors; +- sal_uInt32* pCount = &nGlobalColorsChanged; +- i = nGlobalColorsCount; +- +- for ( j = 0; j < 2; j++ ) +- { +- for ( ; i > 0; i-- ) +- { +- sal_uInt64 nPos = rSt.Tell(); +- sal_uInt16 nChanged; +- rSt.ReadUInt16( nChanged ); +- if ( nChanged & 1 ) +- { +- sal_uInt8 nDummy, nRed, nGreen, nBlue; +- sal_uInt32 nColor = 0; +- sal_uInt32 nIndex; +- rSt.ReadUChar( nDummy ) +- .ReadUChar( nRed ) +- .ReadUChar( nDummy ) +- .ReadUChar( nGreen ) +- .ReadUChar( nDummy ) +- .ReadUChar( nBlue ) +- .ReadUInt32( nIndex ); +- +- if ( nIndex < 8 ) +- { +- Color aColor = MSO_CLR_ToColor( nIndex << 24 ); +- nRed = aColor.GetRed(); +- nGreen = aColor.GetGreen(); +- nBlue = aColor.GetBlue(); +- } +- nColor = nRed | ( nGreen << 8 ) | ( nBlue << 16 ); +- *pCurrentNew++ = nColor; +- rSt.ReadUChar( nDummy ) +- .ReadUChar( nRed ) +- .ReadUChar( nDummy ) +- .ReadUChar( nGreen ) +- .ReadUChar( nDummy ) +- .ReadUChar( nBlue ); +- nColor = nRed | ( nGreen << 8 ) | ( nBlue << 16 ); +- *pCurrentOriginal++ = nColor; +- (*pCount)++; +- } +- rSt.Seek( nPos + 44 ); +- } +- pCount = &nFillColorsChanged; +- i = nFillColorsCount; +- } +- if ( !(nGlobalColorsChanged || nFillColorsChanged) ) ++ sal_uInt32 nGlobalColorsChanged = 0; ++ ++ for ( sal_uInt32 i = 0; i < nGlobalColorsCount; i++ ) ++ { ++ sal_uInt64 nPos = rSt.Tell(); ++ sal_uInt16 nChanged(0); ++ rSt.ReadUInt16( nChanged ); ++ if ( nChanged & 1 ) ++ { ++ sal_uInt8 nDummy, nRed, nGreen, nBlue; ++ sal_uInt32 nColor(0); ++ sal_uInt32 nIndex(0); ++ rSt.ReadUChar( nDummy ) ++ .ReadUChar( nRed ) ++ .ReadUChar( nDummy ) ++ .ReadUChar( nGreen ) ++ .ReadUChar( nDummy ) ++ .ReadUChar( nBlue ) ++ .ReadUInt32( nIndex ); ++ ++ if ( nIndex < 8 ) ++ { ++ Color aColor = MSO_CLR_ToColor( nIndex << 24 ); ++ nRed = aColor.GetRed(); ++ nGreen = aColor.GetGreen(); ++ nBlue = aColor.GetBlue(); ++ } ++ nColor = nRed | ( nGreen << 8 ) | ( nBlue << 16 ); ++ NewGlobalColors[ nGlobalColorsChanged ] = nColor; ++ rSt.ReadUChar( nDummy ) ++ .ReadUChar( nRed ) ++ .ReadUChar( nDummy ) ++ .ReadUChar( nGreen ) ++ .ReadUChar( nDummy ) ++ .ReadUChar( nBlue ); ++ nColor = nRed | ( nGreen << 8 ) | ( nBlue << 16 ); ++ OriginalGlobalColors[ nGlobalColorsChanged ] = nColor; ++ nGlobalColorsChanged++; ++ } ++ rSt.Seek( nPos + 44 ); ++ } ++ if ( !nGlobalColorsChanged ) + return; + + std::unique_ptr pSearchColors(new Color[ nGlobalColorsChanged ]); + std::unique_ptr pReplaceColors(new Color[ nGlobalColorsChanged ]); + +- for ( j = 0; j < nGlobalColorsChanged; j++ ) ++ for ( sal_uInt32 j = 0; j < nGlobalColorsChanged; j++ ) + { + sal_uInt32 nSearch = OriginalGlobalColors[ j ]; + sal_uInt32 nReplace = NewGlobalColors[ j ]; +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-8357.diff libreoffice-25.2.3/debian/patches/CVE-2026-8357.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-8357.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-8357.diff 2026-05-23 14:34:00.000000000 +0000 @@ -0,0 +1,42 @@ +From 1cf0663f5dbad8d883df70ba77b91738101cc1a7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 26 Apr 2026 17:12:34 +0100 +Subject: [PATCH] A formula of length L, composed entirely of open tokens, + needs L+1 slots +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Caolán McNamara +Change-Id: I7cf1fd4fdaca780a8f0cf0d0b9d10def9b3af1ef +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1690 +Tested-by: Jenkins CPCI +(cherry picked from commit 0b7a9149d7c7b5e044bb4f02668297bdf41b64d6) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205090 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit a28cead4b7796642d946173b479281a6272117f2) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205102 +--- + sc/source/core/tool/compiler.cxx | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx +index aaf78acd7754..89cc6e6395b4 100644 +--- a/sc/source/core/tool/compiler.cxx ++++ b/sc/source/core/tool/compiler.cxx +@@ -4925,8 +4925,9 @@ std::unique_ptr ScCompiler::CompileString( const OUString& rFormul + bool bUseFunctionStack = (bPODF || bOOXML); + const size_t nAlloc = 512; + FunctionStack aFuncs[ nAlloc ]; +- FunctionStack* pFunctionStack = (bUseFunctionStack && o3tl::make_unsigned(rFormula.getLength()) > nAlloc ? +- new FunctionStack[rFormula.getLength()] : &aFuncs[0]); ++ // A formula of length L composed entirely of open tokens needs L+1 slots, ++ FunctionStack* pFunctionStack = (bUseFunctionStack && o3tl::make_unsigned(rFormula.getLength()) >= nAlloc ? ++ new FunctionStack[rFormula.getLength() + 1] : &aFuncs[0]); + pFunctionStack[0].eOp = ocNone; + pFunctionStack[0].nSep = 0; + size_t nFunction = 0; +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-8358.diff libreoffice-25.2.3/debian/patches/CVE-2026-8358.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-8358.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-8358.diff 2026-05-23 14:34:00.000000000 +0000 @@ -0,0 +1,110 @@ +From bf5665d6e39abbd2755ee1521a3b0cb6ea405fda Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 26 Apr 2026 17:48:52 +0000 +Subject: [PATCH] drop malformed duplicate-id calc change track actions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Caolán McNamara +Change-Id: I0d532eb84d122e39ce71e94b4760b94cd636eeea +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1691 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit b5b56a2239369e45d7fac2ea965558a1f337b602) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205091 +Reviewed-by: Xisco Fauli +Tested-by: Jenkins +(cherry picked from commit a20ae7b5f80a45e49a47ce22f5e92749cd9816a0) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205101 +--- + sc/inc/chgtrack.hxx | 3 ++- + sc/source/core/tool/chgtrack.cxx | 7 +++++-- + .../filter/xml/XMLChangeTrackingImportHelper.cxx | 15 ++++++++++----- + 3 files changed, 17 insertions(+), 8 deletions(-) + +diff --git a/sc/inc/chgtrack.hxx b/sc/inc/chgtrack.hxx +index 259d79b786e1..ae51f67e7ef6 100644 +--- a/sc/inc/chgtrack.hxx ++++ b/sc/inc/chgtrack.hxx +@@ -1115,7 +1115,8 @@ public: + + sal_uLong AddLoadedGenerated( const ScCellValue& rNewCell, + const ScBigRange& aBigRange, const OUString& sNewValue ); // only to use in the XML import +- void AppendLoaded( std::unique_ptr pAppend ); // this is only for the XML import public, it should be protected ++ // returns false if the action number is already in use, in which case the new duplicate is dropped ++ bool AppendLoaded( std::unique_ptr pAppend ); // this is only for the XML import public, it should be protected + void SetActionMax(sal_uLong nTempActionMax) + { nActionMax = nTempActionMax; } // only to use in the XML import + +diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx +index ab18add226a2..7c4dcde3d031 100644 +--- a/sc/source/core/tool/chgtrack.cxx ++++ b/sc/source/core/tool/chgtrack.cxx +@@ -2315,10 +2315,12 @@ void ScChangeTrack::MasterLinks( ScChangeAction* pAppend ) + } + } + +-void ScChangeTrack::AppendLoaded( std::unique_ptr pActionParam ) ++bool ScChangeTrack::AppendLoaded( std::unique_ptr pActionParam ) + { ++ auto [it, inserted] = aMap.insert(std::make_pair(pActionParam->GetActionNumber(), pActionParam.get())); ++ if (!inserted) ++ return false; + ScChangeAction* pAppend = pActionParam.release(); +- aMap.insert( ::std::make_pair( pAppend->GetActionNumber(), pAppend ) ); + if ( !pLast ) + pFirst = pLast = pAppend; + else +@@ -2328,6 +2330,7 @@ void ScChangeTrack::AppendLoaded( std::unique_ptr pActionParam ) + pLast = pAppend; + } + MasterLinks( pAppend ); ++ return true; + } + + void ScChangeTrack::Append( ScChangeAction* pAppend, sal_uLong nAction ) +diff --git a/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx +index 177332225cd3..84363af364cc 100644 +--- a/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx ++++ b/sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx +@@ -719,8 +719,10 @@ void ScXMLChangeTrackingImportHelper::CreateChangeTrack(ScDocument* pDoc) + // old files didn't store nanoseconds, disable until encountered + pTrack->SetTimeNanoSeconds( false ); + +- for (const auto & rAction : aActions) ++ auto aItr = aActions.begin(); ++ while (aItr != aActions.end()) + { ++ const auto& rAction = *aItr; + std::unique_ptr pAction; + + switch (rAction->nActionType) +@@ -764,17 +766,20 @@ void ScXMLChangeTrackingImportHelper::CreateChangeTrack(ScDocument* pDoc) + } + } + +- if (pAction) +- pTrack->AppendLoaded(std::move(pAction)); ++ // Malformed documents can repeat the same XML id across actions. If ++ // this happens drop entries whose action number is already in the track. ++ if (pAction && pTrack->AppendLoaded(std::move(pAction))) ++ ++aItr; + else + { +- OSL_FAIL("no action"); ++ SAL_WARN("sc.filter", "Dropping malformed change track entry"); ++ aItr = aActions.erase(aItr); + } + } + if (pTrack->GetLast()) + pTrack->SetActionMax(pTrack->GetLast()->GetActionNumber()); + +- auto aItr = aActions.begin(); ++ aItr = aActions.begin(); + while (aItr != aActions.end()) + { + SetDependencies(aItr->get(), *pDoc); +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/series libreoffice-25.2.3/debian/patches/series --- libreoffice-25.2.3/debian/patches/series 2026-03-19 20:20:19.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/series 2026-05-25 08:48:22.000000000 +0000 @@ -56,3 +56,9 @@ qt-Consolidate-to-one-toOUString-helper.diff default-to-Euro-for-Bulgaria.diff Conform-AlignEngine-parsing-to-spec.diff +CVE-2026-6039.diff +CVE-2026-6040.diff +CVE-2026-6045.diff +CVE-2026-8356.diff +CVE-2026-8357.diff +CVE-2026-8358.diff