sc/qa/unit/data/xlsx/tdf147014.xlsx |binary sc/qa/unit/subsequent_filters_test2.cxx | 18 ++++++++++++++++++ sc/source/filter/oox/worksheethelper.cxx | 25 +++++++++++++++++++------ 3 files changed, 37 insertions(+), 6 deletions(-)
New commits: commit 4a614ad8c32ad09f4085980e49dce251358a0a46 Author: Aron Budea <aron.bu...@collabora.com> AuthorDate: Sun Feb 13 06:57:16 2022 +0100 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Mon Mar 28 14:04:11 2022 +0200 tdf#147014 Image missing due to integer overflow 32-bit awt::Point/Size/Rectangle cannot fit size of 1M rows with larger (eg. 5x the usual) height, and could overflow. This causes problems in 64-bit Linux builds and, since the following commit, in 64-bit Windows builds: 3d90997fb6f232d8008df4d166d7b97b869c200f For now, clamp possibly overflowing values to 32-bit. Change-Id: Ifda7265703388abdfb47f523da4f0c5822358404 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129876 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> Reviewed-by: Aron Budea <aron.bu...@collabora.com> Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132168 diff --git a/sc/qa/unit/data/xlsx/tdf147014.xlsx b/sc/qa/unit/data/xlsx/tdf147014.xlsx new file mode 100644 index 000000000000..df4428795d9d Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf147014.xlsx differ diff --git a/sc/qa/unit/subsequent_filters_test2.cxx b/sc/qa/unit/subsequent_filters_test2.cxx index c40f26dfc78d..ac0b8d8d82e9 100644 --- a/sc/qa/unit/subsequent_filters_test2.cxx +++ b/sc/qa/unit/subsequent_filters_test2.cxx @@ -204,6 +204,7 @@ public: void testTdf129940(); void testTdf139612(); void testTdf144740(); + void testTdf147014(); void testTdf139763ShapeAnchor(); void testAutofilterNamedRangesXLSX(); void testInvalidBareBiff5(); @@ -312,6 +313,7 @@ public: CPPUNIT_TEST(testTdf129940); CPPUNIT_TEST(testTdf139612); CPPUNIT_TEST(testTdf144740); + CPPUNIT_TEST(testTdf147014); CPPUNIT_TEST(testTdf139763ShapeAnchor); CPPUNIT_TEST(testAutofilterNamedRangesXLSX); CPPUNIT_TEST(testInvalidBareBiff5); @@ -2873,6 +2875,22 @@ void ScFiltersTest2::testTdf144740() xDocSh->DoClose(); } +void ScFiltersTest2::testTdf147014() +{ + ScDocShellRef xDocSh = loadDoc(u"tdf147014.", FORMAT_XLSX); + CPPUNIT_ASSERT_MESSAGE("Failed to load tdf147014.xlsx", xDocSh.is()); + uno::Reference<frame::XModel> xModel = xDocSh->GetModel(); + uno::Reference<sheet::XSpreadsheetDocument> xDoc(xModel, uno::UNO_QUERY_THROW); + uno::Reference<container::XIndexAccess> xIA(xDoc->getSheets(), uno::UNO_QUERY_THROW); + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIA->getByIndex(0), + uno::UNO_QUERY_THROW); + xIA.set(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW); + // The sheet has a single shape, without the fix it was not imported, except in 32-bit builds + CPPUNIT_ASSERT_EQUAL_MESSAGE("Shape not imported", static_cast<sal_Int32>(1), xIA->getCount()); + + xDocSh->DoClose(); +} + void ScFiltersTest2::testTdf139763ShapeAnchor() { ScDocShellRef xDocSh = loadDoc(u"tdf139763ShapeAnchor.", FORMAT_XLSX); diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx index 40a99cdb444b..95625751d4a0 100644 --- a/sc/source/filter/oox/worksheethelper.cxx +++ b/sc/source/filter/oox/worksheethelper.cxx @@ -75,7 +75,7 @@ #include <editeng/eeitem.hxx> #include <editeng/editobj.hxx> #include <editeng/flditem.hxx> -#include <tools/UnitConversion.hxx> +#include <tools/gen.hxx> namespace oox::xls { @@ -96,6 +96,18 @@ void lclUpdateProgressBar( const ISegmentProgressBarRef& rxProgressBar, double f rxProgressBar->setPosition( fPosition ); } +// TODO Needed because input might be >32-bit (in 64-bit builds), +// or a negative, already overflown value (in 32-bit builds) +sal_Int32 lclClampToNonNegativeInt32( tools::Long aVal ) +{ + if ( aVal > SAL_MAX_INT32 || aVal < 0 ) + { + SAL_WARN( "sc.filter", "Overflow detected, " << aVal << " does not fit into sal_Int32, or is negative." ); + return SAL_MAX_INT32; + } + return static_cast<sal_Int32>( aVal ); +} + } // namespace ColumnModel::ColumnModel() : @@ -538,9 +550,9 @@ const awt::Size& WorksheetGlobals::getDrawPageSize() const awt::Point WorksheetGlobals::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const { - awt::Point aPoint; - PropertySet aCellProp( getCell( ScAddress( nCol, nRow, getSheetIndex() ) ) ); - aCellProp.getProperty( aPoint, PROP_Position ); + const tools::Rectangle aMMRect( getScDocument().GetMMRect( nCol, nRow, nCol, nRow, getSheetIndex() ) ); + awt::Point aPoint( lclClampToNonNegativeInt32( aMMRect.Left() ), + lclClampToNonNegativeInt32( aMMRect.Top() ) ); return aPoint; } @@ -1360,8 +1372,9 @@ void WorksheetGlobals::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLa void WorksheetGlobals::finalizeDrawings() { // calculate the current drawing page size (after rows/columns are imported) - PropertySet aRangeProp( getCellRange( ScRange( 0, 0, getSheetIndex(), mrMaxApiPos.Col(), mrMaxApiPos.Row(), getSheetIndex() ) ) ); - aRangeProp.getProperty( maDrawPageSize, PROP_Size ); + const Size aPageSize( getScDocument().GetMMRect( 0, 0, mrMaxApiPos.Col(), mrMaxApiPos.Row(), getSheetIndex() ).GetSize() ); + maDrawPageSize.Width = lclClampToNonNegativeInt32( aPageSize.Width() ); + maDrawPageSize.Height = lclClampToNonNegativeInt32( aPageSize.Height() ); // import DML and VML if( !maDrawingPath.isEmpty() )