diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx index fe0b22311c96..5e8fad152502 100644 --- a/sfx2/source/doc/objmisc.cxx +++ b/sfx2/source/doc/objmisc.cxx @@ -1300,6 +1300,10 @@ void SfxObjectShell::TemplateDisconnectionAfterLoad() } } + // tdf#165348: release the lock on the original file before clearing the URL, otherwise + // UnlockFile (called later from Close) won't know which lock file to remove. + pTmpMedium->UnlockFile(false); + // set medium to noname pTmpMedium->SetName( OUString(), true ); pTmpMedium->Init_Impl(); diff --git a/sw/CppunitTest_sw_ooxmlimport2.mk b/sw/CppunitTest_sw_ooxmlimport2.mk index 39be13e05bee..0bde88310366 100644 --- a/sw/CppunitTest_sw_ooxmlimport2.mk +++ b/sw/CppunitTest_sw_ooxmlimport2.mk @@ -15,6 +15,10 @@ ifneq ($(OS),MACOSX) $(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_ooxmlimport2)) endif +$(eval $(call gb_CppunitTest_use_custom_headers,sw_ooxmlimport2,\ + officecfg/registry \ +)) + $(eval $(call gb_CppunitTest_add_exception_objects,sw_ooxmlimport2, \ sw/qa/extras/ooxmlimport/ooxmlimport2 \ )) diff --git a/sw/qa/extras/ooxmlimport/data/tdf165348_broken_package.docx b/sw/qa/extras/ooxmlimport/data/tdf165348_broken_package.docx new file mode 100644 index 000000000000..60d05ad2e9f1 Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf165348_broken_package.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx index 2b004ad44c6f..5968057d33aa 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx @@ -20,14 +20,24 @@ #include #include +#include +#include +#include +#include #include #include #include #include #include #include +#include #include +#include +#include +#include +#include +#include #include #include #include @@ -1436,6 +1446,53 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf169173) CPPUNIT_ASSERT(xServiceInfo->supportsService(u"com.sun.star.text.textfield.DropDown"_ustr)); } +CPPUNIT_TEST_FIXTURE(Test, testTdf165348_lockFileOnRepair) +{ + // Enable locking - disabled by default in the test environment + auto setConfig = [](bool b) { + auto xChanges = comphelper::ConfigurationChanges::create(); + officecfg::Office::Common::Misc::UseLocking::set(b, xChanges); + officecfg::Office::Common::Misc::UseDocumentOOoLockFile::set(b, xChanges); + xChanges->commit(); + }; + setConfig(true); + comphelper::ScopeGuard restoreConfig([&] { setConfig(false); }); + + // Copy the broken DOCX to a temp location so the lock file is in a writable temp directory + createTempCopy(u"tdf165348_broken_package.docx"); + OUString aTempURL = maTempFile.GetURL(); + + // Interaction handler that auto-approves BrokenPackageRequest (repair dialog) + class ApproveRepairHandler : public cppu::WeakImplHelper + { + public: + void SAL_CALL handle(const uno::Reference& xRequest) override + { + for (auto& xCont : xRequest->getContinuations()) + { + if (auto xApprove = xCont.query()) + { + xApprove->select(); + return; + } + } + } + }; + + // Load with an interaction handler that auto-approves the repair dialog + loadFromURL(aTempURL, { comphelper::makePropertyValue(u"InteractionHandler"_ustr, + uno::Reference( + new ApproveRepairHandler)) }); + + // The document should be in repair/template mode, with empty URL + CPPUNIT_ASSERT(mxComponent.queryThrow()->getURL().isEmpty()); + + // The lock file must not remain. Before the fix, the lock was never released; in that scenario, + // DocumentLockFile::GetLockData succeeded. + CPPUNIT_ASSERT_THROW(svt::DocumentLockFile(aTempURL).GetLockData(), + ucb::InteractiveAugmentedIOException); +} + // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT } // end of anonymous namespace