sc/qa/unit/data/dataprovider/csv/test2.csv                  |    3 ++
 sc/qa/unit/data/dataprovider/tdf169541_two_data_mapping.ods |binary
 sc/qa/unit/dataproviders_test.cxx                           |   13 ++++++++++++
 sc/source/filter/xml/xmlmappingi.cxx                        |    3 +-
 sc/source/ui/dataprovider/dataprovider.cxx                  |    8 +++----
 5 files changed, 22 insertions(+), 5 deletions(-)

New commits:
commit 39948910b829d6ce93dd8fbc89095a3f772df0e9
Author:     Regina Henschel <[email protected]>
AuthorDate: Mon Nov 24 12:05:18 2025 +0100
Commit:     Xisco Fauli <[email protected]>
CommitDate: Thu Nov 27 12:42:55 2025 +0100

    tdf#169541 DataProvider avoid corrupt backreference
    
    If a document has defined more than one calcext:data-mapping element,
    the import builds a vector DataResources in the ExternalDataMapper.
    Error was, that not the current last item in the vector was refreshed
    but always the first one.
    
    If more than one DataResource exist, those before the last one have a
    corrupted backreference to the data provider. I have not found where
    this happens. Therefore, I now create in each refresh a new one. That
    is the same as done in the first refresh. If someone finds where it
    becomes corrupt it could be fixed differently. However, since the
    error causes a crash, we should use this solution in the meantime.
    
    Change-Id: If489c8e599bf44333c4936c608392c22d0f02d14
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194433
    Tested-by: Jenkins
    Code-Style: Regina Henschel <[email protected]>
    Reviewed-by: Regina Henschel <[email protected]>
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194691

diff --git a/sc/qa/unit/data/dataprovider/csv/test2.csv 
b/sc/qa/unit/data/dataprovider/csv/test2.csv
new file mode 100644
index 000000000000..cc977daf33f3
--- /dev/null
+++ b/sc/qa/unit/data/dataprovider/csv/test2.csv
@@ -0,0 +1,3 @@
+test4,test5,test6,test7
+"a row with text"
+4,5,6
diff --git a/sc/qa/unit/data/dataprovider/tdf169541_two_data_mapping.ods 
b/sc/qa/unit/data/dataprovider/tdf169541_two_data_mapping.ods
new file mode 100644
index 000000000000..913c14aece51
Binary files /dev/null and 
b/sc/qa/unit/data/dataprovider/tdf169541_two_data_mapping.ods differ
diff --git a/sc/qa/unit/dataproviders_test.cxx 
b/sc/qa/unit/dataproviders_test.cxx
index 680769afbbfc..f62f40ac13db 100644
--- a/sc/qa/unit/dataproviders_test.cxx
+++ b/sc/qa/unit/dataproviders_test.cxx
@@ -30,6 +30,7 @@ public:
     void testHTMLImport();
     void testXMLImport();
     void testBaseImport();
+    void testTdf169541_TwoDataMapping();
 
     CPPUNIT_TEST_SUITE(ScDataProvidersTest);
     CPPUNIT_TEST(testCSVImport);
@@ -37,6 +38,7 @@ public:
     CPPUNIT_TEST(testHTMLImport);
     CPPUNIT_TEST(testXMLImport);
     CPPUNIT_TEST(testBaseImport);
+    CPPUNIT_TEST(testTdf169541_TwoDataMapping);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -213,6 +215,17 @@ void ScDataProvidersTest::testBaseImport()
     CPPUNIT_ASSERT_EQUAL(OUString("AVV00"), pDoc->GetString(0, 1, 0));
 }
 
+void ScDataProvidersTest::testTdf169541_TwoDataMapping()
+{
+    // tdf#169541 Crash in: Data Provider: import 2x + save = crash on open 
file
+    // Without fix, loading had crashed after initial creating and saving
+    createScDoc("tdf169541_two_data_mapping.ods");
+    ScDocument* pDoc = getScDoc();
+    CPPUNIT_ASSERT(pDoc);
+    // Because this test is only about the crash, the pathes in the test 
document are
+    // not adapted to the test environment and thus no further tests about the 
content here.
+}
+
 ScDataProvidersTest::ScDataProvidersTest()
     : ScModelTestBase(u"sc/qa/unit/data/dataprovider"_ustr)
 {
diff --git a/sc/source/filter/xml/xmlmappingi.cxx 
b/sc/source/filter/xml/xmlmappingi.cxx
index 9e9b23e36a98..5ce0967762ff 100644
--- a/sc/source/filter/xml/xmlmappingi.cxx
+++ b/sc/source/filter/xml/xmlmappingi.cxx
@@ -117,7 +117,8 @@ ScXMLMappingContext::~ScXMLMappingContext()
     auto& rDataMapper = pDoc->GetExternalDataMapper();
     auto& rDataSources = rDataMapper.getDataSources();
     if(!rDataSources.empty())
-        rDataSources[0].refresh(pDoc, true);
+        rDataSources.back().refresh(pDoc, true);
+
 }
 
 uno::Reference<xml::sax::XFastContextHandler>
diff --git a/sc/source/ui/dataprovider/dataprovider.cxx 
b/sc/source/ui/dataprovider/dataprovider.cxx
index 296ca0ee2722..75a9a2342bd6 100644
--- a/sc/source/ui/dataprovider/dataprovider.cxx
+++ b/sc/source/ui/dataprovider/dataprovider.cxx
@@ -154,11 +154,11 @@ void ExternalDataSource::refresh(ScDocument* pDoc, bool 
bDeterministic)
     if (!mpDBDataManager)
         return;
 
-    // if no data provider exists, try to create one
-    if (!mpDataProvider)
-        mpDataProvider = DataProviderFactory::getDataProvider(pDoc, *this);
+    // tdf#169541 An existing mpDataProvider might have a corrupted 
backreference to `this`.
+    // Thus create a new one in any case.
+    mpDataProvider = DataProviderFactory::getDataProvider(pDoc, *this);
 
-    // if we still have not been able to create one, we can not refresh the 
data
+    // if we have not been able to create one, we can not refresh the data
     if (!mpDataProvider)
         return;
 

Reply via email to