From bdede2a61107106bdfd5babbedc7619ccd43a8b5 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Feb 09 2018 13:40:18 +0000 Subject: CVE-2018-1055 WEBSERVICE formula issue --- diff --git a/0001-limit-WEBSERVICE-to-http-s-protocols.patch b/0001-limit-WEBSERVICE-to-http-s-protocols.patch new file mode 100644 index 0000000..26beccc --- /dev/null +++ b/0001-limit-WEBSERVICE-to-http-s-protocols.patch @@ -0,0 +1,937 @@ +From a3f5d838d091df6c1582b0fb6d539292edf536a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 10 Jan 2018 14:27:35 +0000 +Subject: [PATCH] limit WEBSERVICE to http[s] protocols +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +and like excel... + +'For protocols that aren’t supported, such as ftp:// or file://, WEBSERVICE +returns the #VALUE! error value.' + +Reviewed-on: https://gerrit.libreoffice.org/47776 +Tested-by: Jenkins +Reviewed-by: Markus Mohrhard + +Better handle ScDde formulas with missing dde-link entries + +typically each ScDde formula has a matching table:dde-link which +results in a ScDdeLink getting inserted during the load. If that dde-link +is missing then no ScDdeLink exists and ScDde() will create a new one without +cached content. So detect that ScDde is used in the freshing loaded ods +and defer fetching new content until the right time. + +only call GetHasMacroFunc to set SetHasMacroFunc + +and bHasMacroFunc is not accessed any other way, so this is an oxbow + +Reviewed-on: https://gerrit.libreoffice.org/47757 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit b0597ba5d745974fce752e1b677451a19350d351) +Reviewed-on: https://gerrit.libreoffice.org/47818 +Reviewed-by: Eike Rathke + +handle ocWebservice similarly to ocDde + +might have too much in here seeing as we don't need to worry about +ocWebservice calling into itself + +Reviewed-on: https://gerrit.libreoffice.org/47819 +Tested-by: Jenkins +Reviewed-by: Eike Rathke + +CheckLinkFormulaNeedingCheck() for .xls and .xlsx formula cells + + This is a combination of 3 commits. + +Move implementation to CheckLinkFormulaNeedingCheck() for further reuse + +(cherry picked from commit 55e484c7bcd3ef218e08d3fd93f97bf98fd8cb7f) + +CheckLinkFormulaNeedingCheck() for .xlsx cell formulas + +(cherry picked from commit f96dbc3dd9c33202f75e29ef49d962386595995d) + +CheckLinkFormulaNeedingCheck() for .xls cell formulas + +(cherry picked from commit 6bc48275558c3f76c4da25eb8af3c48583ac5599) + +a6dd195f7eb4d43483e87eeca59f651e7bf2dcb8 +2587fbc4fec39b6f2c8e733331815a2953dee308 + +Reviewed-on: https://gerrit.libreoffice.org/48143 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara + +CheckLinkFormulaNeedingCheck() for conditional format expressions + + This is a combination of 4 commits. + +Prepare CheckLinkFormulaNeedingCheck() to use either RPN or tokenized code + +Conditional format formulas aren't finally compiled until needed +so the check will have to operate on the tokenized expression +instead of RPN code. + +(cherry picked from commit faa0305ba3d0dc698fce4915d4f3a1fb52422380) + +CheckLinkFormulaNeedingCheck() for .ods conditional format expressions + +(cherry picked from commit 2930ba2ac5d9423f2848b968edcd8ddc71966186) + +CheckLinkFormulaNeedingCheck() for .xlsx conditional format expressions + +(cherry picked from commit fef24d9f999ee54d7936900485d97ff26656f517) + +CheckLinkFormulaNeedingCheck() for .xls conditional format expressions + +(cherry picked from commit af2a2a0c72db312902e466c36697b5c198041e82) + +45eb1ab5efa0ec9da2663f20427d2474ce300826 +31ede1a23223a798141a0891deeabd8cf88fff58 +afa112cc591b411d80ead48bf726788d361f6eb3 + +Reviewed-on: https://gerrit.libreoffice.org/48719 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara + +CheckLinkFormulaNeedingCheck() for named expressions + + This is a combination of 3 commits. + +CheckLinkFormulaNeedingCheck() for .ods named expressions + +This is specifically necessary for named expressions that are used +in conditional format formulas, for which RPN is generated at a +later stage, not during import. + +(cherry picked from commit eae9648e99be53ba441d9d8207aac6f3ce211ef2) + +CheckLinkFormulaNeedingCheck() for .xls named expressions + +(cherry picked from commit 8512f13c42ae3fbb287a555616fe10ff04295616) + +CheckLinkFormulaNeedingCheck() for .xlsx named expressions + +(cherry picked from commit a1f933ee2b9e23a505d937035821e9571cf4119c) + + Conflicts: + sc/source/filter/oox/defnamesbuffer.cxx + +e03cb5767c34f8157a492a6d6c3b0700d065052d +217c89822ab477a6c383d170ae739e44efd10fa3 + +Change-Id: I0e9c6fd3426fad56a199eafac48de9b0f23914b3 +016b53288076d83dd49e92e245346a5f7f560522 +0145f38cc1c1f9ff514a496f7101d81cde9e7c67 +541d2b6e12a88371c064b901b00e71206ee0c18e +68837e9bd33f125ab47b10b1a6fa18175abd1627 +54ab8dc14f81d6b18b0d17f448187d19d8e396fc +Reviewed-on: https://gerrit.libreoffice.org/48858 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +--- + sc/Library_sc.mk | 1 + + sc/inc/document.hxx | 8 ++- + sc/inc/documentlinkmgr.hxx | 6 +- + sc/qa/unit/ucalc.cxx | 2 +- + sc/source/core/data/conditio.cxx | 6 ++ + sc/source/core/data/documen2.cxx | 2 +- + sc/source/core/data/documen8.cxx | 23 +++++++ + sc/source/core/data/formulacell.cxx | 7 +- + sc/source/core/inc/webservicelink.hxx | 49 ++++++++++++++ + sc/source/core/tool/interpr2.cxx | 8 ++- + sc/source/core/tool/interpr7.cxx | 106 ++++++++++++++++++++++-------- + sc/source/core/tool/rangenam.cxx | 8 ++- + sc/source/core/tool/webservicelink.cxx | 106 ++++++++++++++++++++++++++++++ + sc/source/filter/excel/excform.cxx | 1 + + sc/source/filter/excel/excform8.cxx | 1 + + sc/source/filter/excel/impop.cxx | 1 + + sc/source/filter/excel/xicontent.cxx | 6 ++ + sc/source/filter/excel/xiname.cxx | 3 + + sc/source/filter/oox/condformatbuffer.cxx | 2 + + sc/source/filter/oox/defnamesbuffer.cxx | 2 + + sc/source/filter/oox/formulabuffer.cxx | 4 ++ + sc/source/ui/docshell/docsh4.cxx | 4 +- + sc/source/ui/docshell/documentlinkmgr.cxx | 20 ++++-- + sc/source/ui/view/tabvwsh4.cxx | 2 +- + 24 files changed, 329 insertions(+), 49 deletions(-) + create mode 100644 sc/source/core/inc/webservicelink.hxx + create mode 100644 sc/source/core/tool/webservicelink.cxx + +diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk +index 3714c966a62e..05a3ee49a32c 100644 +--- a/sc/Library_sc.mk ++++ b/sc/Library_sc.mk +@@ -285,6 +285,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ + sc/source/core/tool/unitconv \ + sc/source/core/tool/userlist \ + sc/source/core/tool/viewopti \ ++ sc/source/core/tool/webservicelink \ + sc/source/core/tool/zforauto \ + sc/source/filter/xml/datastreamimport \ + sc/source/filter/xml/XMLCalculationSettingsContext \ +diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx +index f5f9f0387174..d25ca0b913a8 100644 +--- a/sc/inc/document.hxx ++++ b/sc/inc/document.hxx +@@ -448,7 +448,7 @@ private: + // for detective update, is set for each change of a formula + bool bDetectiveDirty; + +- bool bHasMacroFunc; // valid only after loading ++ bool bLinkFormulaNeedingCheck; // valid only after loading, for ocDde and ocWebservice + + sal_uInt8 nAsianCompression; + sal_uInt8 nAsianKerning; +@@ -1928,8 +1928,10 @@ public: + bool IsDetectiveDirty() const { return bDetectiveDirty; } + void SetDetectiveDirty(bool bSet) { bDetectiveDirty = bSet; } + +- bool GetHasMacroFunc() const { return bHasMacroFunc; } +- void SetHasMacroFunc(bool bSet) { bHasMacroFunc = bSet; } ++ bool HasLinkFormulaNeedingCheck() const { return bLinkFormulaNeedingCheck; } ++ void SetLinkFormulaNeedingCheck(bool bSet) { bLinkFormulaNeedingCheck = bSet; } ++ /** Check token array and set link check if ocDde/ocWebservice is contained. */ ++ SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode ); + + void SetRangeOverflowType(sal_uInt32 nType) { nRangeOverflowType = nType; } + bool HasRangeOverflow() const { return nRangeOverflowType != 0; } +diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx +index d5d801a4aeb2..86dba66f2d3d 100644 +--- a/sc/inc/documentlinkmgr.hxx ++++ b/sc/inc/documentlinkmgr.hxx +@@ -55,9 +55,9 @@ public: + bool idleCheckLinks(); + + bool hasDdeLinks() const; +- bool hasDdeOrOleLinks() const; ++ bool hasDdeOrOleOrWebServiceLinks() const; + +- bool updateDdeOrOleLinks(vcl::Window* pWin); ++ bool updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin); + + void updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem ); + +@@ -65,7 +65,7 @@ public: + + void disconnectDdeLinks(); + private: +- bool hasDdeOrOleLinks(bool bDde, bool bOle) const; ++ bool hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const; + }; + + } +diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx +index ea44ff7d4f3d..90ca51f47073 100644 +--- a/sc/qa/unit/ucalc.cxx ++++ b/sc/qa/unit/ucalc.cxx +@@ -6215,7 +6215,7 @@ void Test::testEmptyCalcDocDefaults() + CPPUNIT_ASSERT_EQUAL( false, m_pDoc->IdleCalcTextWidth() ); + CPPUNIT_ASSERT_EQUAL( true, m_pDoc->IsIdleEnabled() ); + CPPUNIT_ASSERT_EQUAL( false, m_pDoc->IsDetectiveDirty() ); +- CPPUNIT_ASSERT_EQUAL( false, m_pDoc->GetHasMacroFunc() ); ++ CPPUNIT_ASSERT_EQUAL( false, m_pDoc->HasLinkFormulaNeedingCheck() ); + CPPUNIT_ASSERT_EQUAL( false, m_pDoc->IsChartListenerCollectionNeedsUpdate() ); + + CPPUNIT_ASSERT_EQUAL( false, m_pDoc->HasRangeOverflow() ); +diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx +index c970520f3377..1fc8ee34b60b 100644 +--- a/sc/source/core/data/conditio.cxx ++++ b/sc/source/core/data/conditio.cxx +@@ -522,6 +522,12 @@ void ScConditionEntry::CompileXML() + Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1), + GetExpression(aSrcPos, 1, 0, eTempGrammar2), + aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, true ); ++ ++ // Importing ocDde/ocWebservice? ++ if (pFormula1) ++ mpDoc->CheckLinkFormulaNeedingCheck(*pFormula1); ++ if (pFormula2) ++ mpDoc->CheckLinkFormulaNeedingCheck(*pFormula2); + } + + void ScConditionEntry::SetSrcString( const OUString& rNew ) +diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx +index 7a41f14c01c2..017f8629c910 100644 +--- a/sc/source/core/data/documen2.cxx ++++ b/sc/source/core/data/documen2.cxx +@@ -200,7 +200,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) : + bInDtorClear( false ), + bExpandRefs( false ), + bDetectiveDirty( false ), +- bHasMacroFunc( false ), ++ bLinkFormulaNeedingCheck( false ), + nAsianCompression(SC_ASIANCOMPRESSION_INVALID), + nAsianKerning(SC_ASIANKERNING_INVALID), + bPastingDrawFromOtherDoc( false ), +diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx +index 572d594b3697..49985b4cd93d 100644 +--- a/sc/source/core/data/documen8.cxx ++++ b/sc/source/core/data/documen8.cxx +@@ -88,6 +88,7 @@ + #include "stringutil.hxx" + #include + #include ++#include + + #include + +@@ -1153,6 +1154,28 @@ void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode, + } + } + ++void ScDocument::CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode ) ++{ ++ if (HasLinkFormulaNeedingCheck()) ++ return; ++ ++ // Prefer RPN over tokenized formula if available. ++ if (rCode.GetCodeLen()) ++ { ++ if (rCode.HasOpCodeRPN(ocDde) || rCode.HasOpCodeRPN(ocWebservice)) ++ SetLinkFormulaNeedingCheck(true); ++ } ++ else if (rCode.GetLen()) ++ { ++ if (rCode.HasOpCode(ocDde) || rCode.HasOpCode(ocWebservice)) ++ SetLinkFormulaNeedingCheck(true); ++ } ++ else ++ { ++ assert(!"called with empty ScTokenArray"); ++ } ++} ++ + // TimerDelays etc. + void ScDocument::KeyInput( const KeyEvent& ) + { +diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx +index 381fb173d4b7..8eb4f9f23400 100644 +--- a/sc/source/core/data/formulacell.cxx ++++ b/sc/source/core/data/formulacell.cxx +@@ -1379,10 +1379,9 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr + bChanged = true; + } + +- // Same as in Load: after loading, it must be known if ocMacro is in any formula +- // (for macro warning, CompileXML is called at the end of loading XML file) +- if ( !pDocument->GetHasMacroFunc() && pCode->HasOpCodeRPN( ocMacro ) ) +- pDocument->SetHasMacroFunc( true ); ++ // After loading, it must be known if ocDde/ocWebservice is in any formula ++ // (for external links warning, CompileXML is called at the end of loading XML file) ++ pDocument->CheckLinkFormulaNeedingCheck(*pCode); + + //volatile cells must be added here for import + if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() || +diff --git a/sc/source/core/inc/webservicelink.hxx b/sc/source/core/inc/webservicelink.hxx +new file mode 100644 +index 000000000000..e61ebfdb4347 +--- /dev/null ++++ b/sc/source/core/inc/webservicelink.hxx +@@ -0,0 +1,49 @@ ++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ ++/* ++ * This file is part of the LibreOffice project. ++ * ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ */ ++ ++#ifndef INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX ++#define INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX ++ ++#include ++#include ++#include ++#include ++ ++class ScDocument; ++ ++class ScWebServiceLink : public ::sfx2::SvBaseLink, public SvtBroadcaster ++{ ++private: ++ ScDocument* pDoc; ++ OUString aURL; // connection/ link data ++ bool bHasResult; // is set aResult is useful ++ OUString aResult; ++ ++public: ++ ScWebServiceLink(ScDocument* pD, const OUString& rURL); ++ virtual ~ScWebServiceLink() override; ++ ++ // SvBaseLink override: ++ virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(const OUString& rMimeType, ++ const css::uno::Any& rValue) override; ++ ++ // SvtBroadcaster override: ++ virtual void ListenersGone() override; ++ ++ // for interpreter: ++ ++ const OUString& GetResult() const { return aResult; } ++ bool HasResult() const { return bHasResult; } ++ ++ const OUString& GetURL() const { return aURL; } ++}; ++ ++#endif ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ +diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx +index c40623320b3d..7f215495538b 100644 +--- a/sc/source/core/tool/interpr2.cxx ++++ b/sc/source/core/tool/interpr2.cxx +@@ -2742,8 +2742,14 @@ void ScInterpreter::ScDde() + pBindings->Invalidate( SID_LINKS ); // Link-Manager enablen + } + ++ //if the document was just loaded, but the ScDdeLink entry was missing, then ++ //don't update this link until the links are updated in response to the users ++ //decision ++ if (!pDok->HasLinkFormulaNeedingCheck()) ++ { + //TODO: evaluate asynchron ??? +- pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times ++ pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times ++ } + + if (pMyFormulaCell) + { +diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx +index 48a34b3ece36..e2f562848a31 100644 +--- a/sc/source/core/tool/interpr7.cxx ++++ b/sc/source/core/tool/interpr7.cxx +@@ -13,7 +13,9 @@ + #include "scmatrix.hxx" + #include + #include ++#include + #include ++#include + + #include + #include +@@ -23,6 +25,10 @@ + #include + #include + #include ++#include ++#include ++ ++#include + + #include + #include +@@ -234,6 +240,22 @@ void ScInterpreter::ScFilterXML() + } + } + ++static ScWebServiceLink* lcl_GetWebServiceLink(const sfx2::LinkManager* pLinkMgr, const OUString& rURL) ++{ ++ size_t nCount = pLinkMgr->GetLinks().size(); ++ for (size_t i=0; iGetLinks()[i].get(); ++ if (ScWebServiceLink* pLink = dynamic_cast(pBase)) ++ { ++ if (pLink->GetURL() == rURL) ++ return pLink; ++ } ++ } ++ ++ return nullptr; ++} ++ + void ScInterpreter::ScWebservice() + { + sal_uInt8 nParamCount = GetByte(); +@@ -241,54 +263,82 @@ void ScInterpreter::ScWebservice() + { + OUString aURI = GetString().getString(); + +- if(aURI.isEmpty()) ++ if (aURI.isEmpty()) + { + PushError( FormulaError::NoValue ); + return; + } + +- uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY ); +- if(!xFileAccess.is()) ++ INetURLObject aObj(aURI, INetProtocol::File); ++ INetProtocol eProtocol = aObj.GetProtocol(); ++ if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https) + { +- PushError( FormulaError::NoValue ); ++ PushError(FormulaError::NoValue); + return; + } + +- uno::Reference< io::XInputStream > xStream; +- try { +- xStream = xFileAccess->openFileRead( aURI ); +- } +- catch (...) ++ if (!mpLinkManager) + { +- // don't let any exceptions pass +- PushError( FormulaError::NoValue ); +- return; +- } +- if ( !xStream.is() ) +- { +- PushError( FormulaError::NoValue ); ++ PushError(FormulaError::NoValue); + return; + } + +- const sal_Int32 BUF_LEN = 8000; +- uno::Sequence< sal_Int8 > buffer( BUF_LEN ); +- OStringBuffer aBuffer( 64000 ); ++ // Need to reinterpret after loading (build links) ++ if (rArr.IsRecalcModeNormal()) ++ rArr.SetExclusiveRecalcModeOnLoad(); ++ ++ // while the link is not evaluated, idle must be disabled (to avoid circular references) ++ bool bOldEnabled = pDok->IsIdleEnabled(); ++ pDok->EnableIdle(false); ++ ++ // Get/ Create link object ++ ScWebServiceLink* pLink = lcl_GetWebServiceLink(mpLinkManager, aURI); ++ ++ bool bWasError = (pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE); + +- sal_Int32 nRead = 0; +- while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN ) ++ if (!pLink) + { +- aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead ); +- } ++ pLink = new ScWebServiceLink(pDok, aURI); ++ mpLinkManager->InsertFileLink(*pLink, OBJECT_CLIENT_FILE, aURI); ++ if ( mpLinkManager->GetLinks().size() == 1 ) // the first one? ++ { ++ SfxBindings* pBindings = pDok->GetViewBindings(); ++ if (pBindings) ++ pBindings->Invalidate( SID_LINKS ); // Link-Manager enabled ++ } + +- if ( nRead > 0 ) ++ //if the document was just loaded, but the ScDdeLink entry was missing, then ++ //don't update this link until the links are updated in response to the users ++ //decision ++ if (!pDok->HasLinkFormulaNeedingCheck()) ++ { ++ pLink->Update(); ++ } ++ ++ if (pMyFormulaCell) ++ { ++ // StartListening after the Update to avoid circular references ++ pMyFormulaCell->StartListening(*pLink); ++ } ++ } ++ else + { +- aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead ); ++ if (pMyFormulaCell) ++ pMyFormulaCell->StartListening(*pLink); + } + +- xStream->closeInput(); ++ // If an new Error from Reschedule appears when the link is executed then reset the errorflag ++ if (pMyFormulaCell && pMyFormulaCell->GetRawError() != FormulaError::NONE && !bWasError) ++ pMyFormulaCell->SetErrCode(FormulaError::NONE); ++ ++ // check the value ++ if (pLink->HasResult()) ++ PushString(pLink->GetResult()); ++ else ++ PushError(FormulaError::NoValue); + +- OUString aContent = OStringToOUString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); +- PushString( aContent ); ++ pDok->EnableIdle(bOldEnabled); ++ mpLinkManager->CloseCachedComps(); + } + } + +diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx +index eae117c08434..18cbabb1cd93 100644 +--- a/sc/source/core/tool/rangenam.cxx ++++ b/sc/source/core/tool/rangenam.cxx +@@ -64,9 +64,14 @@ ScRangeData::ScRangeData( ScDocument* pDok, + mnMaxCol (-1) + { + if (!rSymbol.isEmpty()) +- CompileRangeData( rSymbol, pDoc->IsImportingXML()); ++ { + // Let the compiler set an error on unknown names for a subsequent + // CompileUnresolvedXML(). ++ const bool bImporting = pDoc->IsImportingXML(); ++ CompileRangeData( rSymbol, bImporting); ++ if (bImporting) ++ pDoc->CheckLinkFormulaNeedingCheck( *pCode); ++ } + else + { + // #i63513#/#i65690# don't leave pCode as NULL. +@@ -199,6 +204,7 @@ void ScRangeData::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ) + // Don't let the compiler set an error for unknown names on final + // compile, errors are handled by the interpreter thereafter. + CompileRangeData( aSymbol, false); ++ rCxt.getDoc()->CheckLinkFormulaNeedingCheck( *pCode); + } + } + +diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx +new file mode 100644 +index 000000000000..82310f2b1351 +--- /dev/null ++++ b/sc/source/core/tool/webservicelink.cxx +@@ -0,0 +1,106 @@ ++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ ++/* ++ * This file is part of the LibreOffice project. ++ * ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ScWebServiceLink::ScWebServiceLink(ScDocument* pD, const OUString& rURL) ++ : ::sfx2::SvBaseLink(SfxLinkUpdateMode::ALWAYS, SotClipboardFormatId::STRING) ++ , pDoc(pD) ++ , aURL(rURL) ++ , bHasResult(false) ++{ ++} ++ ++ScWebServiceLink::~ScWebServiceLink() {} ++ ++sfx2::SvBaseLink::UpdateResult ScWebServiceLink::DataChanged(const OUString&, const css::uno::Any&) ++{ ++ aResult.clear(); ++ bHasResult = false; ++ ++ css::uno::Reference xFileAccess( ++ css::ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext()), ++ css::uno::UNO_QUERY); ++ if (!xFileAccess.is()) ++ return ERROR_GENERAL; ++ ++ css::uno::Reference xStream; ++ try ++ { ++ xStream = xFileAccess->openFileRead(aURL); ++ } ++ catch (...) ++ { ++ // don't let any exceptions pass ++ return ERROR_GENERAL; ++ } ++ if (!xStream.is()) ++ return ERROR_GENERAL; ++ ++ const sal_Int32 BUF_LEN = 8000; ++ css::uno::Sequence buffer(BUF_LEN); ++ OStringBuffer aBuffer(64000); ++ ++ sal_Int32 nRead = 0; ++ while ((nRead = xStream->readBytes(buffer, BUF_LEN)) == BUF_LEN) ++ aBuffer.append(reinterpret_cast(buffer.getConstArray()), nRead); ++ ++ if (nRead > 0) ++ aBuffer.append(reinterpret_cast(buffer.getConstArray()), nRead); ++ ++ xStream->closeInput(); ++ ++ aResult = OStringToOUString(aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8); ++ bHasResult = true; ++ ++ // Something happened... ++ if (HasListeners()) ++ { ++ Broadcast(ScHint(SC_HINT_DATACHANGED, ScAddress())); ++ pDoc->TrackFormulas(); // must happen immediately ++ pDoc->StartTrackTimer(); ++ } ++ ++ return SUCCESS; ++} ++ ++void ScWebServiceLink::ListenersGone() ++{ ++ ScDocument* pStackDoc = pDoc; // member pDoc can't be used after removing the link ++ ++ sfx2::LinkManager* pLinkMgr = pDoc->GetLinkManager(); ++ pLinkMgr->Remove(this); // deletes this ++ ++ if (pLinkMgr->GetLinks().empty()) // deleted the last one ? ++ { ++ SfxBindings* pBindings = pStackDoc->GetViewBindings(); // don't use member pDoc! ++ if (pBindings) ++ pBindings->Invalidate(SID_LINKS); ++ } ++} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ +diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx +index 67e7657f3428..889225c364bc 100644 +--- a/sc/source/filter/excel/excform.cxx ++++ b/sc/source/filter/excel/excform.cxx +@@ -156,6 +156,7 @@ void ImportExcel::Formula( + { + pCell = new ScFormulaCell(&rDoc.getDoc(), aScPos, *pResult); + pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8); ++ rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode()); + rDoc.getDoc().EnsureTable(aScPos.Tab()); + rDoc.setFormulaCell(aScPos, pCell); + SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell); +diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx +index ef3d09ae1c8b..ff3387bf916b 100644 +--- a/sc/source/filter/excel/excform8.cxx ++++ b/sc/source/filter/excel/excform8.cxx +@@ -730,6 +730,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, + << nMerk0 << ocClose; + aPool >> aStack; + pExtName->CreateDdeData( GetDoc(), aApplic, aTopic ); ++ GetDoc().SetLinkFormulaNeedingCheck(true); + } + } + break; +diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx +index 01b5b736951e..a76a81db3ff8 100644 +--- a/sc/source/filter/excel/impop.cxx ++++ b/sc/source/filter/excel/impop.cxx +@@ -866,6 +866,7 @@ void ImportExcel::Shrfmla() + + ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, *pErgebnis); + pCell->GetCode()->WrapReference(aPos, EXC_MAXCOL8, EXC_MAXROW8); ++ rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode()); + rDoc.getDoc().EnsureTable(aPos.Tab()); + rDoc.setFormulaCell(aPos, pCell); + pCell->SetNeedNumberFormat(false); +diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx +index bb80a929b35f..d2418806da53 100644 +--- a/sc/source/filter/excel/xicontent.cxx ++++ b/sc/source/filter/excel/xicontent.cxx +@@ -662,7 +662,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm ) + rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_CondFormat ); + // formula converter owns pTokArr -> create a copy of the token array + if( pTokArr ) ++ { + xTokArr1.reset( pTokArr->Clone() ); ++ GetDocRef().CheckLinkFormulaNeedingCheck( *xTokArr1); ++ } + } + + ::std::unique_ptr< ScTokenArray > pTokArr2; +@@ -673,7 +676,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm ) + rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_CondFormat ); + // formula converter owns pTokArr -> create a copy of the token array + if( pTokArr ) ++ { + pTokArr2.reset( pTokArr->Clone() ); ++ GetDocRef().CheckLinkFormulaNeedingCheck( *pTokArr2); ++ } + } + + // *** create the Calc conditional formatting *** +diff --git a/sc/source/filter/excel/xiname.cxx b/sc/source/filter/excel/xiname.cxx +index 7189c2a0a2f2..efc181921091 100644 +--- a/sc/source/filter/excel/xiname.cxx ++++ b/sc/source/filter/excel/xiname.cxx +@@ -265,7 +265,10 @@ void XclImpName::InsertName(const ScTokenArray* pArray) + } + } + if (pData) ++ { ++ GetDoc().CheckLinkFormulaNeedingCheck( *pData->GetCode()); + mpScData = pData; // cache for later use ++ } + } + + XclImpNameManager::XclImpNameManager( const XclImpRoot& rRoot ) : +diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx +index 1d0dd13fd773..aa8fbbaa4d96 100644 +--- a/sc/source/filter/oox/condformatbuffer.cxx ++++ b/sc/source/filter/oox/condformatbuffer.cxx +@@ -874,11 +874,13 @@ void CondFormatRule::finalizeImport() + { + pTokenArray2.reset(new ScTokenArray()); + ScTokenConversion::ConvertToTokenArray( rDoc, *pTokenArray2.get(), maModel.maFormulas[ 1 ] ); ++ rDoc.CheckLinkFormulaNeedingCheck( *pTokenArray2.get()); + } + + ScTokenArray aTokenArray; + OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId ); + ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, maModel.maFormulas[ 0 ] ); ++ rDoc.CheckLinkFormulaNeedingCheck( aTokenArray); + ScCondFormatEntry* pNewEntry = new ScCondFormatEntry(eOperator, + &aTokenArray, pTokenArray2.get(), &rDoc, aPos, aStyleName); + mpFormat->AddEntry(pNewEntry); +diff --git a/sc/source/filter/oox/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx +index 79457ab57e5f..a1d10906c687 100644 +--- a/sc/source/filter/oox/defnamesbuffer.cxx ++++ b/sc/source/filter/oox/defnamesbuffer.cxx +@@ -38,6 +38,7 @@ + #include "tokenarray.hxx" + #include "tokenuno.hxx" + #include "compiler.hxx" ++#include "document.hxx" + + namespace oox { + namespace xls { +@@ -334,6 +335,7 @@ std::unique_ptr DefinedName::getScTokens( + // after, a resulting error must be reset. + FormulaError nErr = pArray->GetCodeError(); + aCompiler.CompileTokenArray(); ++ getScDocument().CheckLinkFormulaNeedingCheck( *pArray); + pArray->DelRPN(); + pArray->SetCodeError(nErr); + +diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx +index 003d0b96769b..bfa229292775 100644 +--- a/sc/source/filter/oox/formulabuffer.cxx ++++ b/sc/source/filter/oox/formulabuffer.cxx +@@ -223,6 +223,10 @@ void applyCellFormulas( + continue; + + aCompiler.CompileTokenArray(); // Generate RPN tokens. ++ ++ // Check if ocDde/ocWebservice is in any formula for external links warning. ++ rDoc.getDoc().CheckLinkFormulaNeedingCheck(*pCode); ++ + ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pCode); + rDoc.setFormulaCell(aPos, pCell); + rCache.store(aPos, pCell); +diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx +index 81dbf194d0c7..a2b1b11ee646 100644 +--- a/sc/source/ui/docshell/docsh4.cxx ++++ b/sc/source/ui/docshell/docsh4.cxx +@@ -450,7 +450,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) + ReloadTabLinks(); + aDocument.UpdateExternalRefLinks(GetActiveDialogParent()); + +- bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent()); ++ bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(GetActiveDialogParent()); + + if (bAnyDde) + { +@@ -472,6 +472,8 @@ void ScDocShell::Execute( SfxRequest& rReq ) + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); + rReq.Ignore(); + } ++ ++ rDoc.SetLinkFormulaNeedingCheck(false); + } + break; + +diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx +index 520b8542afc0..b8a9df65cb6b 100644 +--- a/sc/source/ui/docshell/documentlinkmgr.cxx ++++ b/sc/source/ui/docshell/documentlinkmgr.cxx +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -115,15 +116,15 @@ bool DocumentLinkManager::idleCheckLinks() + + bool DocumentLinkManager::hasDdeLinks() const + { +- return hasDdeOrOleLinks(true, false); ++ return hasDdeOrOleOrWebServiceLinks(true, false, false); + } + +-bool DocumentLinkManager::hasDdeOrOleLinks() const ++bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks() const + { +- return hasDdeOrOleLinks(true, true); ++ return hasDdeOrOleOrWebServiceLinks(true, true, true); + } + +-bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const ++bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const + { + if (!mpImpl->mpLinkManager) + return false; +@@ -136,12 +137,14 @@ bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const + return true; + if (bOle && dynamic_cast(pBase)) + return true; ++ if (bWebService && dynamic_cast(pBase)) ++ return true; + } + + return false; + } + +-bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin ) ++bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin) + { + if (!mpImpl->mpLinkManager) + return false; +@@ -163,6 +166,13 @@ bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin ) + continue; + } + ++ ScWebServiceLink* pWebserviceLink = dynamic_cast(pBase); ++ if (pWebserviceLink) ++ { ++ pWebserviceLink->Update(); ++ continue; ++ } ++ + ScDdeLink* pDdeLink = dynamic_cast(pBase); + if (!pDdeLink) + continue; +diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx +index e8f4491ae26e..17fb575a162f 100644 +--- a/sc/source/ui/view/tabvwsh4.cxx ++++ b/sc/source/ui/view/tabvwsh4.cxx +@@ -1575,7 +1575,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode ) + if (!bLink) + { + const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); +- if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks()) ++ if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasDdeOrOleOrWebServiceLinks()) + bLink = true; + } + if (bLink) +-- +2.14.3 + diff --git a/libreoffice.spec b/libreoffice.spec index 2767300..bf36e86 100644 --- a/libreoffice.spec +++ b/libreoffice.spec @@ -60,7 +60,7 @@ Summary: Free Software Productivity Suite Name: libreoffice Epoch: 1 Version: %{libo_version}.2 -Release: 7%{?libo_prerelease}%{?dist} +Release: 8%{?libo_prerelease}%{?dist} License: (MPLv1.1 or LGPLv3+) and LGPLv3 and LGPLv2+ and BSD and (MPLv1.1 or GPLv2 or LGPLv2 or Netscape) and Public Domain and ASL 2.0 and Artistic and MPLv2.0 and CC0 URL: http://www.libreoffice.org/ @@ -282,6 +282,7 @@ Patch39: 0001-Compensate-for-loss-of-Type-1-Standard-Symbols-L-sub.patch Patch40: 0001-Related-tdf-105998-except-cut-and-paste-as-bitmap-in.patch Patch41: 0001-Resolves-tdf-114406-treat-as-the-operator-that-it-is.patch Patch42: 0001-rhbz-1541486-Fix-localized-ness-of-ooSetupFactoryUIN.patch +Patch43: 0001-limit-WEBSERVICE-to-http-s-protocols.patch %if 0%{?rhel} # not upstreamed @@ -2376,7 +2377,10 @@ done %{_includedir}/LibreOfficeKit %changelog -* Tue Feb 06 2018 Stephan Bergmann - 1:5.3.7.2-7-UNBUILT +* Fri Feb 09 2018 Caolán McNamara - 1:5.3.7.2-8 +- CVE-2018-1055 WEBSERVICE formula woes + +* Tue Feb 06 2018 Stephan Bergmann - 1:5.3.7.2-7 - Resolves: rhbz#1541486 Base table dialog title shown in wrong language * Tue Dec 12 2017 Eike Rathke - 1:5.3.7.2-6