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);

Reply via email to