sc/qa/unit/data/xls/tdf168589.xls      |binary
 sc/qa/unit/subsequent_filters-test.cxx |   12 ++++++++++++
 sc/source/core/tool/compiler.cxx       |   27 +++++++++++++++++++++------
 3 files changed, 33 insertions(+), 6 deletions(-)

New commits:
commit 20876b128a7391ac64c118cbd07201d4bc792148
Author:     Caolán McNamara <[email protected]>
AuthorDate: Sun Oct 5 17:52:56 2025 +0100
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Oct 14 23:40:36 2025 +0200

    Threaded import crash in ScDocument::ShrinkToDataArea
    
    since possibly(?) https://gerrit.libreoffice.org/c/core/+/180773
    
    one thread, importing sheet 0, uses ScDocument::ShrinkToDataArea
    for a range on sheet 1 while sheet 1 is importing on a different
    thread.
    
    cherry-pick from: 7a6ebc8be8f5df795d1c9e0cca1a740ee2b62b27
    
    Change-Id: Ia982e4c0af4859aacbca19420941f19ee85479eb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191920
    Reviewed-by: Caolán McNamara <[email protected]>
    Tested-by: Jenkins
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192155
    Tested-by: allotropia jenkins <[email protected]>
    Reviewed-by: Thorsten Behrens <[email protected]>

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index da534e5c3bbe..98cc295a5e60 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -6259,6 +6259,16 @@ void ScCompiler::CorrectSumRange(const ScComplexRefData& 
rBaseRange,
     pNewSumRangeTok->IncRef();
 }
 
+// If we are loading, we might be loading each sheet in a separate thread at 
the same time
+// It is unsafe to use ShrinkToDataArea on a range that refers to a different 
sheet whose
+// columns and rows are still being added to. Even if it is the same sheet, it 
probably
+// doesn't make sense to ShrinkToDataArea during document load.
+static bool IsSafeToShrinkToDataArea(const ScDocument* pDoc)
+{
+    const bool bIsLoading = !pDoc->GetDocumentShell() || 
pDoc->GetDocumentShell()->IsLoading();
+    return !bIsLoading;
+}
+
 void ScCompiler::AnnotateTrimOnDoubleRefs()
 {
     if (!pCode || !(*(pCode - 1)))
@@ -6459,8 +6469,8 @@ void ScCompiler::AnnotateTrimOnDoubleRefs()
                 SCROW nTempStartRow = rRange.aStart.Row();
                 SCCOL nTempEndCol = rRange.aEnd.Col();
                 SCROW nTempEndRow = rRange.aEnd.Row();
-                pDoc->ShrinkToDataArea(rRange.aStart.Tab(), nTempStartCol, 
nTempStartRow,
-                    nTempEndCol, nTempEndRow);
+                if (IsSafeToShrinkToDataArea(pDoc))
+                    pDoc->ShrinkToDataArea(rRange.aStart.Tab(), nTempStartCol, 
nTempStartRow, nTempEndCol, nTempEndRow);
                 // check if range is still valid
                 if (nTempStartRow <= nTempEndRow && nTempStartCol <= 
nTempEndCol)
                 {
commit 76ee30c4db0147f893ac38c693af0ae11a074ade
Author:     Balazs Varga <[email protected]>
AuthorDate: Tue Sep 30 19:05:23 2025 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Oct 14 23:40:26 2025 +0200

    tdf#168589 - sc fix xls import with subtotal function
    
    Check if the trimmed data range of Subtotal double references
    is valid otherwise do not trim.
    
    regression after: b89047a0f0100fb30121084cf42815aa792c1f88
    (tdf#164843 - sc optimize "SubTotal" function's reference ranges)
    
    cherry-pick from: fdf6777e02f4897bdb798457d3e6b8fbd343f8ab
    
    Change-Id: I5f1fa4f67a685deb4a391e19e3acd9849b03c1b4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191691
    Tested-by: Jenkins
    Reviewed-by: Balazs Varga <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191757
    Reviewed-by: Thorsten Behrens <[email protected]>
    Tested-by: allotropia jenkins <[email protected]>

diff --git a/sc/qa/unit/data/xls/tdf168589.xls 
b/sc/qa/unit/data/xls/tdf168589.xls
new file mode 100644
index 000000000000..103b35f64f6c
Binary files /dev/null and b/sc/qa/unit/data/xls/tdf168589.xls differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx 
b/sc/qa/unit/subsequent_filters-test.cxx
index e005b258d979..565279cec1f8 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -251,6 +251,7 @@ public:
     void testAutoheight2Rows();
     void testXLSDefColWidth();
     void testPreviewMissingObjLink();
+    void testTdf168589();
 
     CPPUNIT_TEST_SUITE(ScFiltersTest);
     CPPUNIT_TEST(testBooleanFormatXLSX);
@@ -393,6 +394,7 @@ public:
     CPPUNIT_TEST(testAutoheight2Rows);
     CPPUNIT_TEST(testXLSDefColWidth);
     CPPUNIT_TEST(testPreviewMissingObjLink);
+    CPPUNIT_TEST(testTdf168589);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -4344,6 +4346,16 @@ void ScFiltersTest::testPreviewMissingObjLink()
     xDocSh->DoClose();
 }
 
+void ScFiltersTest::testTdf168589()
+{
+    // Open xls document with Subtotal function
+    ScDocShellRef xDocSh = loadDoc("tdf168589.", FORMAT_XLS);
+    ScDocument& rDoc = xDocSh->GetDocument();
+    ASSERT_DOUBLES_EQUAL(6.0, rDoc.GetValue(4, 5, 0));
+
+    xDocSh->DoClose();
+}
+
 ScFiltersTest::ScFiltersTest()
       : ScBootstrapFixture( "sc/qa/unit/data" )
 {
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 0f7db65dc8b4..da534e5c3bbe 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -6453,17 +6453,22 @@ void ScCompiler::AnnotateTrimOnDoubleRefs()
             if (pTok->GetType() == svDoubleRef)
             {
                 ScComplexRefData* pRefData = pTok->GetDoubleRef();
-                // no need to set pRefData->SetTrimToData(true); because we 
already trim here
+                // do no set pRefData->SetTrimToData(true); because we need to 
trim here if possible
                 ScRange rRange = pRefData->toAbs(aPos);
                 SCCOL nTempStartCol = rRange.aStart.Col();
                 SCROW nTempStartRow = rRange.aStart.Row();
                 SCCOL nTempEndCol = rRange.aEnd.Col();
                 SCROW nTempEndRow = rRange.aEnd.Row();
-                pDoc->ShrinkToDataArea(rRange.aStart.Tab(), nTempStartCol, 
nTempStartRow, nTempEndCol, nTempEndRow);
-                rRange.aStart.Set(nTempStartCol, nTempStartRow, 
rRange.aStart.Tab());
-                rRange.aEnd.Set(nTempEndCol, nTempEndRow, rRange.aEnd.Tab());
-                rRange.PutInOrder();
-                pRefData->SetRange(rRange, aPos);
+                pDoc->ShrinkToDataArea(rRange.aStart.Tab(), nTempStartCol, 
nTempStartRow,
+                    nTempEndCol, nTempEndRow);
+                // check if range is still valid
+                if (nTempStartRow <= nTempEndRow && nTempStartCol <= 
nTempEndCol)
+                {
+                    rRange.aStart.Set(nTempStartCol, nTempStartRow, 
rRange.aStart.Tab());
+                    rRange.aEnd.Set(nTempEndCol, nTempEndRow, 
rRange.aEnd.Tab());
+                    if (rRange.IsValid())
+                        pRefData->SetRange(rRange, aPos);
+                }
             }
             --ppTok;
         }

Reply via email to