560625
From f045768636399e028963a259dc074afcaa4bef2e Mon Sep 17 00:00:00 2001
560625
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
560625
Date: Wed, 10 Jan 2018 14:27:35 +0000
560625
Subject: [PATCH] limit WEBSERVICE to http[s] protocols
560625
MIME-Version: 1.0
560625
Content-Type: text/plain; charset=UTF-8
560625
Content-Transfer-Encoding: 8bit
560625
560625
and like excel...
560625
560625
'For protocols that aren’t supported, such as ftp:// or file://, WEBSERVICE
560625
returns the #VALUE! error value.'
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/47776
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
560625
560625
Better handle ScDde formulas with missing dde-link entries
560625
560625
typically each ScDde formula has a matching table:dde-link which
560625
results in a ScDdeLink getting inserted during the load. If that dde-link
560625
is missing then no ScDdeLink exists and ScDde() will create a new one without
560625
cached content. So detect that ScDde is used in the freshing loaded ods
560625
and defer fetching new content until the right time.
560625
560625
only call GetHasMacroFunc to set SetHasMacroFunc
560625
560625
and bHasMacroFunc is not accessed any other way, so this is an oxbow
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/47757
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
560625
Tested-by: Caolán McNamara <caolanm@redhat.com>
560625
(cherry picked from commit b0597ba5d745974fce752e1b677451a19350d351)
560625
Reviewed-on: https://gerrit.libreoffice.org/47818
560625
Reviewed-by: Eike Rathke <erack@redhat.com>
560625
560625
handle ocWebservice similarly to ocDde
560625
560625
might have too much in here seeing as we don't need to worry about
560625
ocWebservice calling into itself
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/47819
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Eike Rathke <erack@redhat.com>
560625
560625
CheckLinkFormulaNeedingCheck() for .xls and .xlsx formula cells
560625
560625
 This is a combination of 3 commits.
560625
560625
Move implementation to CheckLinkFormulaNeedingCheck() for further reuse
560625
560625
(cherry picked from commit 55e484c7bcd3ef218e08d3fd93f97bf98fd8cb7f)
560625
560625
CheckLinkFormulaNeedingCheck() for .xlsx cell formulas
560625
560625
(cherry picked from commit f96dbc3dd9c33202f75e29ef49d962386595995d)
560625
560625
CheckLinkFormulaNeedingCheck() for .xls cell formulas
560625
560625
(cherry picked from commit 6bc48275558c3f76c4da25eb8af3c48583ac5599)
560625
560625
a6dd195f7eb4d43483e87eeca59f651e7bf2dcb8
560625
2587fbc4fec39b6f2c8e733331815a2953dee308
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/48143
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
560625
Tested-by: Caolán McNamara <caolanm@redhat.com>
560625
560625
CheckLinkFormulaNeedingCheck() for conditional format expressions
560625
560625
 This is a combination of 4 commits.
560625
560625
Prepare CheckLinkFormulaNeedingCheck() to use either RPN or tokenized code
560625
560625
Conditional format formulas aren't finally compiled until needed
560625
so the check will have to operate on the tokenized expression
560625
instead of RPN code.
560625
560625
(cherry picked from commit faa0305ba3d0dc698fce4915d4f3a1fb52422380)
560625
560625
CheckLinkFormulaNeedingCheck() for .ods conditional format expressions
560625
560625
(cherry picked from commit 2930ba2ac5d9423f2848b968edcd8ddc71966186)
560625
560625
CheckLinkFormulaNeedingCheck() for .xlsx conditional format expressions
560625
560625
(cherry picked from commit fef24d9f999ee54d7936900485d97ff26656f517)
560625
560625
CheckLinkFormulaNeedingCheck() for .xls conditional format expressions
560625
560625
(cherry picked from commit af2a2a0c72db312902e466c36697b5c198041e82)
560625
560625
45eb1ab5efa0ec9da2663f20427d2474ce300826
560625
31ede1a23223a798141a0891deeabd8cf88fff58
560625
afa112cc591b411d80ead48bf726788d361f6eb3
560625
560625
Reviewed-on: https://gerrit.libreoffice.org/48719
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
560625
Tested-by: Caolán McNamara <caolanm@redhat.com>
560625
560625
CheckLinkFormulaNeedingCheck() for named expressions
560625
560625
 This is a combination of 3 commits.
560625
560625
CheckLinkFormulaNeedingCheck() for .ods named expressions
560625
560625
This is specifically necessary for named expressions that are used
560625
in conditional format formulas, for which RPN is generated at a
560625
later stage, not during import.
560625
560625
(cherry picked from commit eae9648e99be53ba441d9d8207aac6f3ce211ef2)
560625
560625
CheckLinkFormulaNeedingCheck() for .xls named expressions
560625
560625
(cherry picked from commit 8512f13c42ae3fbb287a555616fe10ff04295616)
560625
560625
CheckLinkFormulaNeedingCheck() for .xlsx named expressions
560625
560625
(cherry picked from commit a1f933ee2b9e23a505d937035821e9571cf4119c)
560625
560625
 Conflicts:
560625
	sc/source/filter/oox/defnamesbuffer.cxx
560625
560625
e03cb5767c34f8157a492a6d6c3b0700d065052d
560625
217c89822ab477a6c383d170ae739e44efd10fa3
560625
560625
Change-Id: I0e9c6fd3426fad56a199eafac48de9b0f23914b3
560625
016b53288076d83dd49e92e245346a5f7f560522
560625
0145f38cc1c1f9ff514a496f7101d81cde9e7c67
560625
541d2b6e12a88371c064b901b00e71206ee0c18e
560625
68837e9bd33f125ab47b10b1a6fa18175abd1627
560625
54ab8dc14f81d6b18b0d17f448187d19d8e396fc
560625
Reviewed-on: https://gerrit.libreoffice.org/48858
560625
Tested-by: Jenkins <ci@libreoffice.org>
560625
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
560625
Tested-by: Caolán McNamara <caolanm@redhat.com>
560625
---
560625
 sc/Library_sc.mk                          |   1 +
560625
 sc/inc/document.hxx                       |   8 ++-
560625
 sc/inc/documentlinkmgr.hxx                |   6 +-
560625
 sc/source/core/data/conditio.cxx          |   6 ++
560625
 sc/source/core/data/documen2.cxx          |   2 +-
560625
 sc/source/core/data/documen8.cxx          |  23 +++++++
560625
 sc/source/core/data/formulacell.cxx       |   7 +-
560625
 sc/source/core/inc/webservicelink.hxx     |  49 ++++++++++++++
560625
 sc/source/core/tool/interpr2.cxx          |   8 ++-
560625
 sc/source/core/tool/interpr7.cxx          | 106 ++++++++++++++++++++++--------
560625
 sc/source/core/tool/rangenam.cxx          |   8 ++-
560625
 sc/source/core/tool/webservicelink.cxx    | 106 ++++++++++++++++++++++++++++++
560625
 sc/source/filter/excel/excform.cxx        |   1 +
560625
 sc/source/filter/excel/excform8.cxx       |   1 +
560625
 sc/source/filter/excel/impop.cxx          |   1 +
560625
 sc/source/filter/excel/xicontent.cxx      |   6 ++
560625
 sc/source/filter/excel/xiname.cxx         |   3 +
560625
 sc/source/filter/oox/condformatbuffer.cxx |   2 +
560625
 sc/source/filter/oox/defnamesbuffer.cxx   |   2 +
560625
 sc/source/filter/oox/formulabuffer.cxx    |   4 ++
560625
 sc/source/ui/docshell/docsh4.cxx          |   4 +-
560625
 sc/source/ui/docshell/documentlinkmgr.cxx |  20 ++++--
560625
 sc/source/ui/view/tabvwsh4.cxx            |   2 +-
560625
 23 files changed, 327 insertions(+), 49 deletions(-)
560625
 create mode 100644 sc/source/core/inc/webservicelink.hxx
560625
 create mode 100644 sc/source/core/tool/webservicelink.cxx
560625
560625
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
560625
index d2fd5cd..02d3b7d 100644
560625
--- a/sc/Library_sc.mk
560625
+++ b/sc/Library_sc.mk
560625
@@ -282,6 +282,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
560625
     sc/source/core/tool/unitconv \
560625
     sc/source/core/tool/userlist \
560625
     sc/source/core/tool/viewopti \
560625
+    sc/source/core/tool/webservicelink \
560625
     sc/source/core/tool/zforauto \
560625
     sc/source/filter/xml/datastreamimport \
560625
     sc/source/filter/xml/XMLCalculationSettingsContext \
560625
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
560625
index 69e6f5b..77ff388 100644
560625
--- a/sc/inc/document.hxx
560625
+++ b/sc/inc/document.hxx
560625
@@ -429,7 +429,7 @@ private:
560625
     bool                bDetectiveDirty;
560625
 
560625
     sal_uInt8               nMacroCallMode;     // Macros per warning dialog disabled?
560625
-    bool                bHasMacroFunc;      // valid only after loading
560625
+    bool                bLinkFormulaNeedingCheck; // valid only after loading, for ocDde and ocWebservice
560625
 
560625
     sal_uInt8               nVisSpellState;
560625
 
560625
@@ -1793,8 +1793,10 @@ public:
560625
     sal_uInt8           GetMacroCallMode() const     { return nMacroCallMode; }
560625
     void            SetMacroCallMode(sal_uInt8 nNew)     { nMacroCallMode = nNew; }
560625
 
560625
-    bool            GetHasMacroFunc() const      { return bHasMacroFunc; }
560625
-    void            SetHasMacroFunc(bool bSet)   { bHasMacroFunc = bSet; }
560625
+    bool            HasLinkFormulaNeedingCheck() const      { return bLinkFormulaNeedingCheck; }
560625
+    void            SetLinkFormulaNeedingCheck(bool bSet)   { bLinkFormulaNeedingCheck = bSet; }
560625
+    /** Check token array and set link check if ocDde/ocWebservice is contained. */
560625
+    SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode );
560625
 
560625
     static bool     CheckMacroWarn();
560625
 
560625
diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx
560625
index cc42410..d7972b1 100644
560625
--- a/sc/inc/documentlinkmgr.hxx
560625
+++ b/sc/inc/documentlinkmgr.hxx
560625
@@ -53,9 +53,9 @@ public:
560625
     bool idleCheckLinks();
560625
 
560625
     bool hasDdeLinks() const;
560625
-    bool hasDdeOrOleLinks() const;
560625
+    bool hasDdeOrOleOrWebServiceLinks() const;
560625
 
560625
-    bool updateDdeOrOleLinks(vcl::Window* pWin);
560625
+    bool updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin);
560625
 
560625
     bool updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem );
560625
 
560625
@@ -63,7 +63,7 @@ public:
560625
 
560625
     void disconnectDdeLinks();
560625
 private:
560625
-    bool hasDdeOrOleLinks(bool bDde, bool bOle) const;
560625
+    bool hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const;
560625
 };
560625
 
560625
 }
560625
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
560625
index f087af6..8627367 100644
560625
--- a/sc/source/core/data/conditio.cxx
560625
+++ b/sc/source/core/data/conditio.cxx
560625
@@ -471,6 +471,12 @@ void ScConditionEntry::CompileXML()
560625
     Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1),
560625
              GetExpression(aSrcPos, 1, 0, eTempGrammar2),
560625
              aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, true );
560625
+
560625
+    // Importing ocDde/ocWebservice?
560625
+    if (pFormula1)
560625
+        mpDoc->CheckLinkFormulaNeedingCheck(*pFormula1);
560625
+    if (pFormula2)
560625
+        mpDoc->CheckLinkFormulaNeedingCheck(*pFormula2);
560625
 }
560625
 
560625
 void ScConditionEntry::SetSrcString( const OUString& rNew )
560625
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
560625
index 8d3e4e3..0d494c4 100644
560625
--- a/sc/source/core/data/documen2.cxx
560625
+++ b/sc/source/core/data/documen2.cxx
560625
@@ -202,7 +202,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
560625
         bExpandRefs( false ),
560625
         bDetectiveDirty( false ),
560625
         nMacroCallMode( SC_MACROCALL_ALLOWED ),
560625
-        bHasMacroFunc( false ),
560625
+        bLinkFormulaNeedingCheck( false ),
560625
         nVisSpellState( 0 ),
560625
         nAsianCompression(SC_ASIANCOMPRESSION_INVALID),
560625
         nAsianKerning(SC_ASIANKERNING_INVALID),
560625
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
560625
index 2bdfa30..7391e1c 100644
560625
--- a/sc/source/core/data/documen8.cxx
560625
+++ b/sc/source/core/data/documen8.cxx
560625
@@ -88,6 +88,7 @@
560625
 #include "stringutil.hxx"
560625
 #include <documentlinkmgr.hxx>
560625
 #include <scopetools.hxx>
560625
+#include <tokenarray.hxx>
560625
 
560625
 #include <boost/scoped_ptr.hpp>
560625
 
560625
@@ -1158,6 +1159,28 @@ void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
560625
     }
560625
 }
560625
 
560625
+void ScDocument::CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode )
560625
+{
560625
+    if (HasLinkFormulaNeedingCheck())
560625
+        return;
560625
+
560625
+    // Prefer RPN over tokenized formula if available.
560625
+    if (rCode.GetCodeLen())
560625
+    {
560625
+        if (rCode.HasOpCodeRPN(ocDde) || rCode.HasOpCodeRPN(ocWebservice))
560625
+            SetLinkFormulaNeedingCheck(true);
560625
+    }
560625
+    else if (rCode.GetLen())
560625
+    {
560625
+        if (rCode.HasOpCode(ocDde) || rCode.HasOpCode(ocWebservice))
560625
+            SetLinkFormulaNeedingCheck(true);
560625
+    }
560625
+    else
560625
+    {
560625
+        assert(!"called with empty ScTokenArray");
560625
+    }
560625
+}
560625
+
560625
 // TimerDelays etc.
560625
 void ScDocument::KeyInput( const KeyEvent& )
560625
 {
560625
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
560625
index ceb7f68..49d3133 100644
560625
--- a/sc/source/core/data/formulacell.cxx
560625
+++ b/sc/source/core/data/formulacell.cxx
560625
@@ -1351,10 +1351,9 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr
560625
             bChanged = true;
560625
     }
560625
 
560625
-    //  Same as in Load: after loading, it must be known if ocMacro is in any formula
560625
-    //  (for macro warning, CompileXML is called at the end of loading XML file)
560625
-    if ( !pDocument->GetHasMacroFunc() && pCode->HasOpCodeRPN( ocMacro ) )
560625
-        pDocument->SetHasMacroFunc( true );
560625
+    //  After loading, it must be known if ocDde/ocWebservice is in any formula
560625
+    //  (for external links warning, CompileXML is called at the end of loading XML file)
560625
+    pDocument->CheckLinkFormulaNeedingCheck(*pCode);
560625
 
560625
     //volatile cells must be added here for import
560625
     if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() ||
560625
diff --git a/sc/source/core/inc/webservicelink.hxx b/sc/source/core/inc/webservicelink.hxx
560625
new file mode 100644
560625
index 0000000..e61ebfd
560625
--- /dev/null
560625
+++ b/sc/source/core/inc/webservicelink.hxx
560625
@@ -0,0 +1,49 @@
560625
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
560625
+/*
560625
+ * This file is part of the LibreOffice project.
560625
+ *
560625
+ * This Source Code Form is subject to the terms of the Mozilla Public
560625
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
560625
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
560625
+ */
560625
+
560625
+#ifndef INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX
560625
+#define INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX
560625
+
560625
+#include <address.hxx>
560625
+#include <sfx2/lnkbase.hxx>
560625
+#include <svl/broadcast.hxx>
560625
+#include <types.hxx>
560625
+
560625
+class ScDocument;
560625
+
560625
+class ScWebServiceLink : public ::sfx2::SvBaseLink, public SvtBroadcaster
560625
+{
560625
+private:
560625
+    ScDocument* pDoc;
560625
+    OUString aURL; // connection/ link data
560625
+    bool bHasResult; // is set aResult is useful
560625
+    OUString aResult;
560625
+
560625
+public:
560625
+    ScWebServiceLink(ScDocument* pD, const OUString& rURL);
560625
+    virtual ~ScWebServiceLink() override;
560625
+
560625
+    // SvBaseLink override:
560625
+    virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(const OUString& rMimeType,
560625
+                                                         const css::uno::Any& rValue) override;
560625
+
560625
+    // SvtBroadcaster override:
560625
+    virtual void ListenersGone() override;
560625
+
560625
+    // for interpreter:
560625
+
560625
+    const OUString& GetResult() const { return aResult; }
560625
+    bool HasResult() const { return bHasResult; }
560625
+
560625
+    const OUString& GetURL() const { return aURL; }
560625
+};
560625
+
560625
+#endif
560625
+
560625
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
560625
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
560625
index d82bc29..5f6b5af 100644
560625
--- a/sc/source/core/tool/interpr2.cxx
560625
+++ b/sc/source/core/tool/interpr2.cxx
560625
@@ -2421,8 +2421,14 @@ void ScInterpreter::ScDde()
560625
                     pBindings->Invalidate( SID_LINKS );             // Link-Manager enablen
560625
             }
560625
 
560625
+            //if the document was just loaded, but the ScDdeLink entry was missing, then
560625
+            //don't update this link until the links are updated in response to the users
560625
+            //decision
560625
+            if (!pDok->HasLinkFormulaNeedingCheck())
560625
+            {
560625
                                     //TODO: evaluate asynchron ???
560625
-            pLink->TryUpdate();     //  TryUpdate doesn't call Update multiple times
560625
+                pLink->TryUpdate(); //  TryUpdate doesn't call Update multiple times
560625
+            }
560625
 
560625
             if (pMyFormulaCell)
560625
             {
560625
diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx
560625
index ce69848..53524a1 100644
560625
--- a/sc/source/core/tool/interpr7.cxx
560625
+++ b/sc/source/core/tool/interpr7.cxx
560625
@@ -10,7 +10,10 @@
560625
 #include "interpre.hxx"
560625
 #include <rtl/strbuf.hxx>
560625
 #include <formula/errorcodes.hxx>
560625
+#include <sfx2/bindings.hxx>
560625
+#include <sfx2/linkmgr.hxx>
560625
 #include <svtools/miscopt.hxx>
560625
+#include <tools/urlobj.hxx>
560625
 
560625
 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
560625
 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
560625
@@ -20,6 +23,11 @@
560625
 #include <datastreamgettime.hxx>
560625
 #include <dpobject.hxx>
560625
 #include <document.hxx>
560625
+#include "formulacell.hxx"
560625
+#include <tokenarray.hxx>
560625
+#include <webservicelink.hxx>
560625
+
560625
+#include <sc.hrc>
560625
 
560625
 #include <boost/shared_ptr.hpp>
560625
 #include <cstring>
560625
@@ -145,6 +153,22 @@ void ScInterpreter::ScFilterXML()
560625
     }
560625
 }
560625
 
560625
+static ScWebServiceLink* lcl_GetWebServiceLink(const sfx2::LinkManager* pLinkMgr, const OUString& rURL)
560625
+{
560625
+    size_t nCount = pLinkMgr->GetLinks().size();
560625
+    for (size_t i=0; i
560625
+    {
560625
+        ::sfx2::SvBaseLink* pBase = *pLinkMgr->GetLinks()[i];
560625
+        if (ScWebServiceLink* pLink = dynamic_cast<ScWebServiceLink*>(pBase))
560625
+        {
560625
+            if (pLink->GetURL() == rURL)
560625
+                return pLink;
560625
+        }
560625
+    }
560625
+
560625
+    return nullptr;
560625
+}
560625
+
560625
 void ScInterpreter::ScWebservice()
560625
 {
560625
     sal_uInt8 nParamCount = GetByte();
560625
@@ -152,54 +176,78 @@ void ScInterpreter::ScWebservice()
560625
     {
560625
         OUString aURI = GetString().getString();
560625
 
560625
-        if(aURI.isEmpty())
560625
+        if (aURI.isEmpty())
560625
         {
560625
             PushError( errNoValue );
560625
             return;
560625
         }
560625
 
560625
-        uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY );
560625
-        if(!xFileAccess.is())
560625
+        INetURLObject aObj(aURI, INetProtocol::File);
560625
+        INetProtocol eProtocol = aObj.GetProtocol();
560625
+        if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https)
560625
         {
560625
-            PushError( errNoValue );
560625
+            PushError(errNoValue);
560625
             return;
560625
         }
560625
 
560625
-        uno::Reference< io::XInputStream > xStream;
560625
-        try {
560625
-            xStream = xFileAccess->openFileRead( aURI );
560625
-        }
560625
-        catch (...)
560625
+        sfx2::LinkManager* pLinkMgr = pDok->GetLinkManager();
560625
+        if (!pLinkMgr)
560625
         {
560625
-            // don't let any exceptions pass
560625
-            PushError( errNoValue );
560625
-            return;
560625
-        }
560625
-        if ( !xStream.is() )
560625
-        {
560625
-            PushError( errNoValue );
560625
+            PushError(errNoValue);
560625
             return;
560625
         }
560625
 
560625
-        const sal_Int32 BUF_LEN = 8000;
560625
-        uno::Sequence< sal_Int8 > buffer( BUF_LEN );
560625
-        OStringBuffer aBuffer( 64000 );
560625
+        // Need to reinterpret after loading (build links)
560625
+        if (rArr.IsRecalcModeNormal())
560625
+            rArr.SetExclusiveRecalcModeOnLoad();
560625
 
560625
-        sal_Int32 nRead = 0;
560625
-        while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN )
560625
-        {
560625
-            aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
560625
-        }
560625
+        //  while the link is not evaluated, idle must be disabled (to avoid circular references)
560625
+        bool bOldEnabled = pDok->IsIdleEnabled();
560625
+        pDok->EnableIdle(false);
560625
+
560625
+        // Get/ Create link object
560625
+        ScWebServiceLink* pLink = lcl_GetWebServiceLink(pLinkMgr, aURI);
560625
 
560625
-        if ( nRead > 0 )
560625
+        bool bWasError = (pMyFormulaCell && pMyFormulaCell->GetRawError() != 0);
560625
+
560625
+        if (!pLink)
560625
         {
560625
-            aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
560625
+            pLink = new ScWebServiceLink(pDok, aURI);
560625
+            pLinkMgr->InsertFileLink(*pLink, OBJECT_CLIENT_FILE, aURI);
560625
+            if ( pLinkMgr->GetLinks().size() == 1 )                    // the first one?
560625
+            {
560625
+                SfxBindings* pBindings = pDok->GetViewBindings();
560625
+                if (pBindings)
560625
+                    pBindings->Invalidate( SID_LINKS );             // Link-Manager enabled
560625
+            }
560625
+
560625
+            //if the document was just loaded, but the ScDdeLink entry was missing, then
560625
+            //don't update this link until the links are updated in response to the users
560625
+            //decision
560625
+            if (!pDok->HasLinkFormulaNeedingCheck())
560625
+            {
560625
+                pLink->Update();
560625
+            }
560625
+
560625
+            if (pMyFormulaCell)
560625
+            {
560625
+                // StartListening after the Update to avoid circular references
560625
+                pMyFormulaCell->StartListening(*pLink);
560625
+            }
560625
         }
560625
 
560625
-        xStream->closeInput();
560625
+        //  If an new Error from Reschedule appears when the link is executed then reset the errorflag
560625
+        if (pMyFormulaCell && pMyFormulaCell->GetRawError() != 0 && !bWasError)
560625
+            pMyFormulaCell->SetErrCode(0);
560625
+
560625
+        //  check the value
560625
+        if (pLink->HasResult())
560625
+            PushString(pLink->GetResult());
560625
+        else
560625
+            PushError(errNoValue);
560625
 
560625
-        OUString aContent = OStringToOUString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
560625
-        PushString( aContent );
560625
+        pDok->EnableIdle(bOldEnabled);
560625
+        pLinkMgr->CloseCachedComps();
560625
     }
560625
 }
560625
 
560625
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
560625
index 4235ef7..f1f8b9d 100644
560625
--- a/sc/source/core/tool/rangenam.cxx
560625
+++ b/sc/source/core/tool/rangenam.cxx
560625
@@ -63,9 +63,14 @@ ScRangeData::ScRangeData( ScDocument* pDok,
560625
                 mnMaxCol    (-1)
560625
 {
560625
     if (!rSymbol.isEmpty())
560625
-        CompileRangeData( rSymbol, pDoc->IsImportingXML());
560625
+    {
560625
         // Let the compiler set an error on unknown names for a subsequent
560625
         // CompileUnresolvedXML().
560625
+        const bool bImporting = pDoc->IsImportingXML();
560625
+        CompileRangeData( rSymbol, bImporting);
560625
+        if (bImporting)
560625
+            pDoc->CheckLinkFormulaNeedingCheck( *pCode);
560625
+    }
560625
     else
560625
     {
560625
         // #i63513#/#i65690# don't leave pCode as NULL.
560625
@@ -198,6 +203,7 @@ void ScRangeData::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt )
560625
         // Don't let the compiler set an error for unknown names on final
560625
         // compile, errors are handled by the interpreter thereafter.
560625
         CompileRangeData( aSymbol, false);
560625
+        rCxt.getDoc()->CheckLinkFormulaNeedingCheck( *pCode);
560625
     }
560625
 }
560625
 
560625
diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx
560625
new file mode 100644
560625
index 0000000..82310f2
560625
--- /dev/null
560625
+++ b/sc/source/core/tool/webservicelink.cxx
560625
@@ -0,0 +1,106 @@
560625
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
560625
+/*
560625
+ * This file is part of the LibreOffice project.
560625
+ *
560625
+ * This Source Code Form is subject to the terms of the Mozilla Public
560625
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
560625
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
560625
+ */
560625
+
560625
+#include <comphelper/fileformat.h>
560625
+#include <comphelper/string.hxx>
560625
+#include <osl/thread.h>
560625
+#include <sfx2/linkmgr.hxx>
560625
+#include <sfx2/bindings.hxx>
560625
+
560625
+#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
560625
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
560625
+#include <com/sun/star/io/XInputStream.hpp>
560625
+
560625
+#include <webservicelink.hxx>
560625
+#include <brdcst.hxx>
560625
+#include <document.hxx>
560625
+#include <scmatrix.hxx>
560625
+#include <patattr.hxx>
560625
+#include <rechead.hxx>
560625
+#include <rangeseq.hxx>
560625
+#include <sc.hrc>
560625
+#include <hints.hxx>
560625
+
560625
+ScWebServiceLink::ScWebServiceLink(ScDocument* pD, const OUString& rURL)
560625
+    : ::sfx2::SvBaseLink(SfxLinkUpdateMode::ALWAYS, SotClipboardFormatId::STRING)
560625
+    , pDoc(pD)
560625
+    , aURL(rURL)
560625
+    , bHasResult(false)
560625
+{
560625
+}
560625
+
560625
+ScWebServiceLink::~ScWebServiceLink() {}
560625
+
560625
+sfx2::SvBaseLink::UpdateResult ScWebServiceLink::DataChanged(const OUString&, const css::uno::Any&)
560625
+{
560625
+    aResult.clear();
560625
+    bHasResult = false;
560625
+
560625
+    css::uno::Reference<css::ucb::XSimpleFileAccess3> xFileAccess(
560625
+        css::ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext()),
560625
+        css::uno::UNO_QUERY);
560625
+    if (!xFileAccess.is())
560625
+        return ERROR_GENERAL;
560625
+
560625
+    css::uno::Reference<css::io::XInputStream> xStream;
560625
+    try
560625
+    {
560625
+        xStream = xFileAccess->openFileRead(aURL);
560625
+    }
560625
+    catch (...)
560625
+    {
560625
+        // don't let any exceptions pass
560625
+        return ERROR_GENERAL;
560625
+    }
560625
+    if (!xStream.is())
560625
+        return ERROR_GENERAL;
560625
+
560625
+    const sal_Int32 BUF_LEN = 8000;
560625
+    css::uno::Sequence<sal_Int8> buffer(BUF_LEN);
560625
+    OStringBuffer aBuffer(64000);
560625
+
560625
+    sal_Int32 nRead = 0;
560625
+    while ((nRead = xStream->readBytes(buffer, BUF_LEN)) == BUF_LEN)
560625
+        aBuffer.append(reinterpret_cast<const char*>(buffer.getConstArray()), nRead);
560625
+
560625
+    if (nRead > 0)
560625
+        aBuffer.append(reinterpret_cast<const char*>(buffer.getConstArray()), nRead);
560625
+
560625
+    xStream->closeInput();
560625
+
560625
+    aResult = OStringToOUString(aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8);
560625
+    bHasResult = true;
560625
+
560625
+    //  Something happened...
560625
+    if (HasListeners())
560625
+    {
560625
+        Broadcast(ScHint(SC_HINT_DATACHANGED, ScAddress()));
560625
+        pDoc->TrackFormulas(); // must happen immediately
560625
+        pDoc->StartTrackTimer();
560625
+    }
560625
+
560625
+    return SUCCESS;
560625
+}
560625
+
560625
+void ScWebServiceLink::ListenersGone()
560625
+{
560625
+    ScDocument* pStackDoc = pDoc; // member pDoc can't be used after removing the link
560625
+
560625
+    sfx2::LinkManager* pLinkMgr = pDoc->GetLinkManager();
560625
+    pLinkMgr->Remove(this); // deletes this
560625
+
560625
+    if (pLinkMgr->GetLinks().empty()) // deleted the last one ?
560625
+    {
560625
+        SfxBindings* pBindings = pStackDoc->GetViewBindings(); // don't use member pDoc!
560625
+        if (pBindings)
560625
+            pBindings->Invalidate(SID_LINKS);
560625
+    }
560625
+}
560625
+
560625
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
560625
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
560625
index 0839955..14be167 100644
560625
--- a/sc/source/filter/excel/excform.cxx
560625
+++ b/sc/source/filter/excel/excform.cxx
560625
@@ -157,6 +157,7 @@ void ImportExcel::Formula(
560625
     {
560625
         pCell = new ScFormulaCell(&rDoc.getDoc(), aScPos, *pResult);
560625
         pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8);
560625
+        rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode());
560625
         rDoc.getDoc().EnsureTable(aScPos.Tab());
560625
         rDoc.setFormulaCell(aScPos, pCell);
560625
         SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell);
560625
diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx
560625
index ebe3b64..c7e56af 100644
560625
--- a/sc/source/filter/excel/excform8.cxx
560625
+++ b/sc/source/filter/excel/excform8.cxx
560625
@@ -729,6 +729,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn,
560625
                                         << nMerk0 << ocClose;
560625
                                 aPool >> aStack;
560625
                                 pExtName->CreateDdeData( GetDoc(), aApplic, aTopic );
560625
+                                GetDoc().SetLinkFormulaNeedingCheck(true);
560625
                             }
560625
                         }
560625
                         break;
560625
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
560625
index 904209d..69e536e 100644
560625
--- a/sc/source/filter/excel/impop.cxx
560625
+++ b/sc/source/filter/excel/impop.cxx
560625
@@ -866,6 +866,7 @@ void ImportExcel::Shrfmla()
560625
 
560625
     ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, *pErgebnis);
560625
     pCell->GetCode()->WrapReference(aPos, EXC_MAXCOL8, EXC_MAXROW8);
560625
+    rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode());
560625
     rDoc.getDoc().EnsureTable(aPos.Tab());
560625
     rDoc.setFormulaCell(aPos, pCell);
560625
     pCell->SetNeedNumberFormat(false);
560625
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
560625
index 9613019..589ce4b 100644
560625
--- a/sc/source/filter/excel/xicontent.cxx
560625
+++ b/sc/source/filter/excel/xicontent.cxx
560625
@@ -641,7 +641,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
560625
         rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_CondFormat );
560625
         // formula converter owns pTokArr -> create a copy of the token array
560625
         if( pTokArr )
560625
+        {
560625
             xTokArr1.reset( pTokArr->Clone() );
560625
+            GetDocPtr()->CheckLinkFormulaNeedingCheck( *xTokArr1);
560625
+        }
560625
     }
560625
 
560625
     ::std::unique_ptr< ScTokenArray > pTokArr2;
560625
@@ -652,7 +655,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm )
560625
         rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_CondFormat );
560625
         // formula converter owns pTokArr -> create a copy of the token array
560625
         if( pTokArr )
560625
+        {
560625
             pTokArr2.reset( pTokArr->Clone() );
560625
+            GetDocPtr()->CheckLinkFormulaNeedingCheck( *pTokArr2);
560625
+        }
560625
     }
560625
 
560625
     // *** create the Calc conditional formatting ***
560625
diff --git a/sc/source/filter/excel/xiname.cxx b/sc/source/filter/excel/xiname.cxx
560625
index c1bee5a..344ecb6 100644
560625
--- a/sc/source/filter/excel/xiname.cxx
560625
+++ b/sc/source/filter/excel/xiname.cxx
560625
@@ -264,7 +264,10 @@ void XclImpName::InsertName(const ScTokenArray* pArray)
560625
         }
560625
     }
560625
     if (pData)
560625
+    {
560625
+        GetDoc().CheckLinkFormulaNeedingCheck( *pData->GetCode());
560625
         mpScData = pData;               // cache for later use
560625
+    }
560625
 }
560625
 
560625
 XclImpNameManager::XclImpNameManager( const XclImpRoot& rRoot ) :
560625
diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx
560625
index 955b304..9ffcf51 100644
560625
--- a/sc/source/filter/oox/condformatbuffer.cxx
560625
+++ b/sc/source/filter/oox/condformatbuffer.cxx
560625
@@ -882,11 +882,13 @@ void CondFormatRule::finalizeImport()
560625
         {
560625
             pTokenArray2.reset(new ScTokenArray());
560625
             ScTokenConversion::ConvertToTokenArray( rDoc, *pTokenArray2.get(), maModel.maFormulas[ 1 ] );
560625
+            rDoc.CheckLinkFormulaNeedingCheck( *pTokenArray2.get());
560625
         }
560625
 
560625
         ScTokenArray aTokenArray;
560625
         OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
560625
         ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, maModel.maFormulas[ 0 ] );
560625
+        rDoc.CheckLinkFormulaNeedingCheck( aTokenArray);
560625
         ScCondFormatEntry* pNewEntry = new ScCondFormatEntry(eOperator,
560625
                                             &aTokenArray, pTokenArray2.get(), &rDoc, aPos, aStyleName);
560625
         mpFormat->AddEntry(pNewEntry);
560625
diff --git a/sc/source/filter/oox/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx
560625
index fa2a0cf..c4cb011 100644
560625
--- a/sc/source/filter/oox/defnamesbuffer.cxx
560625
+++ b/sc/source/filter/oox/defnamesbuffer.cxx
560625
@@ -38,6 +38,7 @@
560625
 #include "tokenarray.hxx"
560625
 #include "tokenuno.hxx"
560625
 #include "compiler.hxx"
560625
+#include "document.hxx"
560625
 
560625
 namespace oox {
560625
 namespace xls {
560625
@@ -392,6 +393,7 @@ std::unique_ptr<ScTokenArray> DefinedName::getScTokens()
560625
     // after, a resulting error must be reset.
560625
     sal_uInt16 nErr = pArray->GetCodeError();
560625
     aCompiler.CompileTokenArray();
560625
+    getScDocument().CheckLinkFormulaNeedingCheck( *pArray);
560625
     pArray->DelRPN();
560625
     pArray->SetCodeError(nErr);
560625
 
560625
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
560625
index 189017d..2d20e9d 100644
560625
--- a/sc/source/filter/oox/formulabuffer.cxx
560625
+++ b/sc/source/filter/oox/formulabuffer.cxx
560625
@@ -229,6 +229,10 @@ void applyCellFormulas(
560625
             continue;
560625
 
560625
         aCompiler.CompileTokenArray(); // Generate RPN tokens.
560625
+
560625
+        // Check if ocDde/ocWebservice is in any formula for external links warning.
560625
+        rDoc.getDoc().CheckLinkFormulaNeedingCheck(*pCode);
560625
+
560625
         ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pCode);
560625
         rDoc.setFormulaCell(aPos, pCell);
560625
         rCache.store(aPos, pCell);
560625
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
560625
index 9fcf549..2645c7f 100644
560625
--- a/sc/source/ui/docshell/docsh4.cxx
560625
+++ b/sc/source/ui/docshell/docsh4.cxx
560625
@@ -455,7 +455,7 @@ void ScDocShell::Execute( SfxRequest& rReq )
560625
                     ReloadTabLinks();
560625
                     aDocument.UpdateExternalRefLinks(GetActiveDialogParent());
560625
 
560625
-                    bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent());
560625
+                    bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(GetActiveDialogParent());
560625
 
560625
                     if (bAnyDde)
560625
                     {
560625
@@ -477,6 +477,8 @@ void ScDocShell::Execute( SfxRequest& rReq )
560625
                     rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false);
560625
                     rReq.Ignore();
560625
                 }
560625
+
560625
+                rDoc.SetLinkFormulaNeedingCheck(false);
560625
             }
560625
             break;
560625
 
560625
diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx
560625
index 8e5a5c3..ae8984b 100644
560625
--- a/sc/source/ui/docshell/documentlinkmgr.cxx
560625
+++ b/sc/source/ui/docshell/documentlinkmgr.cxx
560625
@@ -20,6 +20,7 @@
560625
 #include <documentlinkmgr.hxx>
560625
 #include <datastream.hxx>
560625
 #include <ddelink.hxx>
560625
+#include <webservicelink.hxx>
560625
 #include <sc.hrc>
560625
 #include <scresid.hxx>
560625
 
560625
@@ -115,15 +116,15 @@ bool DocumentLinkManager::idleCheckLinks()
560625
 
560625
 bool DocumentLinkManager::hasDdeLinks() const
560625
 {
560625
-    return hasDdeOrOleLinks(true, false);
560625
+    return hasDdeOrOleOrWebServiceLinks(true, false, false);
560625
 }
560625
 
560625
-bool DocumentLinkManager::hasDdeOrOleLinks() const
560625
+bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks() const
560625
 {
560625
-    return hasDdeOrOleLinks(true, true);
560625
+    return hasDdeOrOleOrWebServiceLinks(true, true, true);
560625
 }
560625
 
560625
-bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const
560625
+bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const
560625
 {
560625
     if (!mpImpl->mpLinkManager)
560625
         return false;
560625
@@ -136,12 +137,14 @@ bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const
560625
             return true;
560625
         if (bOle && dynamic_cast<SdrEmbedObjectLink*>(pBase))
560625
             return true;
560625
+        if (bWebService && dynamic_cast<ScWebServiceLink*>(pBase))
560625
+            return true;
560625
     }
560625
 
560625
     return false;
560625
 }
560625
 
560625
-bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin )
560625
+bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin)
560625
 {
560625
     if (!mpImpl->mpLinkManager)
560625
         return false;
560625
@@ -163,6 +166,13 @@ bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin )
560625
             continue;
560625
         }
560625
 
560625
+        ScWebServiceLink* pWebserviceLink = dynamic_cast<ScWebServiceLink*>(pBase);
560625
+        if (pWebserviceLink)
560625
+        {
560625
+            pWebserviceLink->Update();
560625
+            continue;
560625
+        }
560625
+
560625
         ScDdeLink* pDdeLink = dynamic_cast<ScDdeLink*>(pBase);
560625
         if (!pDdeLink)
560625
             continue;
560625
diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx
560625
index ff3a5a1..c7209c1 100644
560625
--- a/sc/source/ui/view/tabvwsh4.cxx
560625
+++ b/sc/source/ui/view/tabvwsh4.cxx
560625
@@ -1584,7 +1584,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode )
560625
             if (!bLink)
560625
             {
560625
                 const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager();
560625
-                if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks())
560625
+                if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasDdeOrOleOrWebServiceLinks())
560625
                     bLink = true;
560625
             }
560625
             if (bLink)
560625
-- 
560625
2.14.3
560625