From 70c19e55662e8a42876bc6aebdc7cfe1ede14ee1 Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Tue, 2 Apr 2024 08:55:51 +0500 Subject: Fix UB after 8962141a12c966b2d891829925e6203bf8d51852 (tdf#160430: Fix glyph bounds calculation, and use basegfx::B2DRectangle, 2024-04-01). As reported by Stephan in https://gerrit.libreoffice.org/c/core/+/165553/6#message-fec1e45288c0e87d43c58f777ebe51b03c534d82: `CppunitTest_sw_rtfexport CPPUNIT_TEST_NAME=testMathEqarray::TestBody` now fails with vcl/source/gdi/sallayout.cxx:245:30: runtime error: inf is outside the range of representable values of type 'long' #0 in SalLayout::GetBoundRect(tools::Rectangle&) const at vcl/source/gdi/sallayout.cxx:245:30 #1 in OutputDevice::GetTextBoundRect(tools::Rectangle&, rtl::OUString const&, int, int, int, unsigned long, KernArraySpan, std::span, SalLayoutGlyphs const*) const at vcl/source/outdev/text.cxx:1932:28 #2 in (anonymous namespace)::SmGetGlyphBoundRect(OutputDevice const&, rtl::OUString const&, tools::Rectangle&) at starmath/source/rect.cxx:80:32 #3 in SmRect::SmRect(OutputDevice const&, SmFormat const*, rtl::OUString const&, unsigned short) at starmath/source/rect.cxx:224:21 #4 in SmMathSymbolNode::AdaptToY(OutputDevice&, unsigned long) at starmath/source/node.cxx:2122:18 #5 in SmBraceNode::Arrange(OutputDevice&, SmFormat const&) at starmath/source/node.cxx:1340:17 #6 in SmBinHorNode::Arrange(OutputDevice&, SmFormat const&) at starmath/source/node.cxx:816:13 #7 in SmLineNode::Arrange(OutputDevice&, SmFormat const&) at starmath/source/node.cxx:610:20 #8 in SmTableNode::Arrange(OutputDevice&, SmFormat const&) at starmath/source/node.cxx:534:20 #9 in SmDocShell::ArrangeFormula() at starmath/source/document.cxx:280:13 #10 in SmDocShell::GetSize() at starmath/source/document.cxx:405:9 #11 in SmDocShell::Repaint() at starmath/source/document.cxx:566:21 #12 in SmDocShell::OnDocumentPrinterChanged(Printer*) at starmath/source/document.cxx:552:5 #13 in SmDocShell::SetText(rtl::OUString const&) at starmath/source/document.cxx:188:9 #14 in SmDocShell::readFormulaOoxml(oox::formulaimport::XmlStream&) at starmath/source/document.cxx:848:5 #15 in SmModel::readFormulaOoxml(oox::formulaimport::XmlStream&) at starmath/source/unomodel.cxx:1105:22 #16 in writerfilter::rtftok::RTFDocumentImpl::beforePopState(writerfilter::rtftok::RTFParserState&) at writerfilter/source/rtftok/rtfdocumentimpl.cxx:3010:30 #17 in writerfilter::rtftok::RTFDocumentImpl::popState() at writerfilter/source/rtftok/rtfdocumentimpl.cxx:3666:23 #18 in writerfilter::rtftok::RTFTokenizer::resolveParse() at writerfilter/source/rtftok/rtftokenizer.cxx:114:37 #19 in writerfilter::rtftok::RTFDocumentImpl::resolve(writerfilter::Stream&) at writerfilter/source/rtftok/rtfdocumentimpl.cxx:856:27 #20 in (anonymous namespace)::RtfFilter::filter(com::sun::star::uno::Sequence const&) at writerfilter/source/filter/RtfFilter.cxx:163:20 #21 in SfxObjectShell::ImportFrom(SfxMedium&, com::sun::star::uno::Reference const&) at sfx2/source/doc/objstor.cxx:2392:34 #22 in SfxObjectShell::DoLoad(SfxMedium*) at sfx2/source/doc/objstor.cxx:760:23 #23 in SfxBaseModel::load(com::sun::star::uno::Sequence const&) at sfx2/source/doc/sfxbasemodel.cxx:1980:36 #24 in (anonymous namespace)::SfxFrameLoader_Impl::load(com::sun::star::uno::Sequence const&, com::sun::star::uno::Reference const&) at sfx2/source/view/frmload.cxx:720:28 #25 in framework::LoadEnv::impl_loadContent() at framework/source/loadenv/loadenv.cxx:1176:37 #26 in framework::LoadEnv::start() at framework/source/loadenv/loadenv.cxx:412:20 #27 in framework::LoadEnv::startLoading(rtl::OUString const&, com::sun::star::uno::Sequence const&, com::sun::star::uno::Reference const&, rtl::OUString const&, int, LoadEnvFeatures) at framework/source/loadenv/loadenv.cxx:308:5 #28 in framework::LoadEnv::loadComponentFromURL(com::sun::star::uno::Reference const&, com::sun::star::uno::Reference const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence const&) at framework/source/loadenv/loadenv.cxx:168:14 #29 in framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence const&) at framework/source/services/desktop.cxx:591:16 #30 in non-virtual thunk to framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence const&) at framework/source/services/desktop.cxx #31 in unotest::MacrosTest::loadFromDesktop(rtl::OUString const&, rtl::OUString const&, com::sun::star::uno::Sequence const&) at unotest/source/cpp/macros_test.cxx:71:62 #32 in UnoApiTest::loadWithParams(rtl::OUString const&, com::sun::star::uno::Sequence const&) at test/source/unoapi_test.cxx:126:19 #33 in UnoApiTest::load(rtl::OUString const&, char const*) at test/source/unoapi_test.cxx:108:5 #34 in SwModelTestBase::loadURL(rtl::OUString const&, char const*) at sw/qa/unit/swmodeltestbase.cxx:441:20 #35 in SwModelTestBase::loadAndReload(char const*) at sw/qa/unit/swmodeltestbase.cxx:466:5 #36 in (anonymous namespace)::testMathEqarray::TestBody() at sw/qa/extras/rtfexport/rtfexport.cxx:198:5 Change-Id: I857861f5bc51a1e43bfbf5e0c9dbce542d673ca7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165664 Tested-by: Jenkins Reviewed-by: Mike Kaganski (cherry picked from commit 51244ebe62bb25f7d87ab1332e863720d980db66) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165844 Reviewed-by: Xisco Fauli --- vcl/source/gdi/sallayout.cxx | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx index 756a427f1dda..28138c3f61fd 100644 --- a/vcl/source/gdi/sallayout.cxx +++ b/vcl/source/gdi/sallayout.cxx @@ -215,7 +215,10 @@ bool SalLayout::GetOutline(basegfx::B2DPolyPolygonVector& rVector) const } // No need to expand to the next pixel, when the character only covers its tiny fraction -static double trimInsignificant(double n) { return std::round(n * 1e5) / 1e5; } +static double trimInsignificant(double n) +{ + return std::abs(n) >= 0x1p53 ? n : std::round(n * 1e5) / 1e5; +} bool SalLayout::GetBoundRect(tools::Rectangle& rRect) const { @@ -242,10 +245,19 @@ bool SalLayout::GetBoundRect(tools::Rectangle& rRect) const bRet = true; } } - rRect = tools::Rectangle(rtl::math::approxFloor(trimInsignificant(aUnion.getMinX())), - rtl::math::approxFloor(trimInsignificant(aUnion.getMinY())), - rtl::math::approxCeil(trimInsignificant(aUnion.getMaxX())), - rtl::math::approxCeil(trimInsignificant(aUnion.getMaxY()))); + if (aUnion.isEmpty()) + { + rRect = {}; + } + else + { + double l = rtl::math::approxFloor(trimInsignificant(aUnion.getMinX())), + t = rtl::math::approxFloor(trimInsignificant(aUnion.getMinY())), + r = rtl::math::approxCeil(trimInsignificant(aUnion.getMaxX())), + b = rtl::math::approxCeil(trimInsignificant(aUnion.getMaxY())); + assert(std::isfinite(l) && std::isfinite(t) && std::isfinite(r) && std::isfinite(b)); + rRect = tools::Rectangle(l, t, r, b); + } return bRet; } -- cgit v1.2.3