sc/qa/unit/data/xlsx/tdf147014.xlsx      |binary
 sc/qa/unit/subsequent_filters_test2.cxx  |   18 ++++++++++++++++++
 sc/source/filter/oox/worksheethelper.cxx |   24 +++++++++++++++++++-----
 3 files changed, 37 insertions(+), 5 deletions(-)

New commits:
commit c5160e2151cf9d5f1fac9975caeac10f9c40158d
Author:     Aron Budea <aron.bu...@collabora.com>
AuthorDate: Sun Feb 13 06:57:16 2022 +0100
Commit:     Aron Budea <aron.bu...@collabora.com>
CommitDate: Mon Mar 28 11:26:22 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>

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 df6bb82fa518..d54267d99e56 100644
--- a/sc/qa/unit/subsequent_filters_test2.cxx
+++ b/sc/qa/unit/subsequent_filters_test2.cxx
@@ -179,6 +179,7 @@ public:
     void testTdf139612();
     void testTdf144740();
     void testTdf146722();
+    void testTdf147014();
     void testTdf139763ShapeAnchor();
     void testAutofilterNamedRangesXLSX();
     void testInvalidBareBiff5();
@@ -291,6 +292,7 @@ public:
     CPPUNIT_TEST(testTdf139612);
     CPPUNIT_TEST(testTdf144740);
     CPPUNIT_TEST(testTdf146722);
+    CPPUNIT_TEST(testTdf147014);
     CPPUNIT_TEST(testTdf139763ShapeAnchor);
     CPPUNIT_TEST(testAutofilterNamedRangesXLSX);
     CPPUNIT_TEST(testInvalidBareBiff5);
@@ -2907,6 +2909,22 @@ void ScFiltersTest2::testTdf146722()
     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 3de0547393ca..0d0aa8ce795a 100644
--- a/sc/source/filter/oox/worksheethelper.cxx
+++ b/sc/source/filter/oox/worksheethelper.cxx
@@ -75,6 +75,7 @@
 #include <editeng/eeitem.hxx>
 #include <editeng/editobj.hxx>
 #include <editeng/flditem.hxx>
+#include <tools/gen.hxx>
 
 namespace oox::xls {
 
@@ -95,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() :
@@ -537,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;
 }
 
@@ -1356,8 +1369,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() )

Reply via email to