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;
