sw/source/uibase/uiview/view2.cxx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
New commits: commit c6109a1b4bdec8e4ed3c69b889863c4d4dfc7b13 Author: Miklos Vajna <[email protected]> AuthorDate: Mon Jan 12 08:45:38 2026 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Mon Jan 12 10:59:54 2026 +0100 cool#13988 sw doc compare: fix handling of ephemeral URLs Try to dispatch .uno:CompareDocuments with URL=https://example.com/old.docx, notice that the document gets downloaded multiple times. This is a problem if the URL is set up in a way that the content can be downloaded only once. It seems the problem is in SwView::InsertDoc(), where we access the stream data at least twice: once during file detection and once during actual file import. Fix the problem by reading the remote stream data only once, somewhat similar to what GraphicFilter::LoadGraphic() does for non-file URLs. In practice this fixes doc compare when the URL is generated by the Nextcloud file picker, where doc compare didn't work, but image insertion did work. No testcase, that would require setting up some HTTP server which does more than serving static files. Change-Id: I2cae56db9d6c10f411770f23f1d0b66b24e63440 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197061 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx index 32b86da7be40..3f1aeaca400c 100644 --- a/sw/source/uibase/uiview/view2.cxx +++ b/sw/source/uibase/uiview/view2.cxx @@ -162,6 +162,7 @@ #include <o3tl/string_view.hxx> #include <svx/dialog/gotodlg.hxx> +#include <unotools/tempfile.hxx> const char sStatusDelim[] = " : "; @@ -2800,6 +2801,7 @@ void SwView::ExecuteInsertDoc( SfxRequest& rRequest, const SfxPoolItem* pItem ) tools::Long SwView::InsertDoc( sal_uInt16 nSlotId, const OUString& rFileName, const OUString& rFilterName, sal_Int16 nVersion ) { + std::unique_ptr<utl::TempFileNamed> pTempFile; std::unique_ptr<SfxMedium> pMed; SwDocShell* pDocSh = GetDocShell(); @@ -2809,7 +2811,20 @@ tools::Long SwView::InsertDoc( sal_uInt16 nSlotId, const OUString& rFileName, co std::shared_ptr<const SfxFilter> pFilter = rFact.GetFilterContainer()->GetFilter4FilterName( rFilterName ); if ( !pFilter ) { - pMed.reset(new SfxMedium(rFileName, StreamMode::READ, nullptr, nullptr )); + INetURLObject aURL(rFileName); + OUString aFileName = rFileName; + if (aURL.GetProtocol() != INetProtocol::File) + { + // Fetch the remote data only once, since it's possible it gets deleted after the + // first access. + std::unique_ptr<SvStream> pStream + = utl::UcbStreamHelper::CreateStream(rFileName, StreamMode::READ); + pTempFile.reset(new utl::TempFileNamed()); + pTempFile->GetStream(StreamMode::READWRITE)->WriteStream(*pStream); + aFileName = pTempFile->GetURL(); + } + pMed.reset(new SfxMedium(aFileName, StreamMode::READ, nullptr, nullptr)); + SfxFilterMatcher aMatcher( rFact.GetFilterContainer()->GetName() ); pMed->UseInteractionHandler( true ); ErrCode nErr = aMatcher.GuessFilter(*pMed, pFilter, SfxFilterFlags::NONE);
