After reverting 2b4cd99d, editing an OLE link whose source is already
open in this LO instance produces a sharing-violation on save (the
intra-process scenario tdf#126742 was working around).
Detect the conflict at doVerb, gated to verbs targeting a visible
state so internal RUNNING transitions aren't intercepted. If the
source is loaded as another visible frame in this LO, switch to that
window (matches MSO behaviour). Otherwise probe for any .~lock or
MSO ~$ file - foreign user, hidden own frame, or stale own lock from
a crash - and show an async warning with the lock owner. In all
cases the OLE working copy is never created. Skipped in headless
mode.
Change-Id: Ic87bb6f073b0b04ec47597cc15f2c5a83cc2bffc
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2004
Reviewed-by: Michael Stahl <michael.stahl@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204940
Reviewed-by: Balazs Varga <balazs.varga@collabora.com>
Tested-by: Jenkins
This is an attempt to reduce areas that execute with mutex unlocked
because the called code may deadlock. Also, this copies objects on
stack before unlocking, using lambdas' own variables.
I hope that it somewhat improves reliability. OTOH, this runs more
code with lock active, has a potential of new deadlocks, so risky.
Change-Id: I558b7f5f18f63622fed3a9c3978327d0d76fe90d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172237
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
The request thread was calling OleComponent::CloseObject, which executed
on main thread; OleEmbeddedObject::m_aMutex as locked by request thread:
emboleobj.dll!OleComponent::CloseObject() Line 1004
emboleobj.dll!OleComponent::Dispose() Line 451
emboleobj.dll!OleComponent::close(unsigned char bDeliverOwnership) Line 1513
emboleobj.dll!OleEmbeddedObject::GetRidOfComponent() Line 235
emboleobj.dll!OleEmbeddedObject::Dispose() Line 269
emboleobj.dll!OleEmbeddedObject::close(unsigned char bDeliverOwnership) Line 498
comphelper.dll!comphelper::EmbeddedObjectContainer::CloseEmbeddedObjects() Line 208
sfxlo.dll!SfxObjectShell::~SfxObjectShell() Line 322
swlo.dll!SwDocShell::~SwDocShell() Line 380
swlo.dll!SwDocShell::`vector deleting destructor'(unsigned int)
cppuhelper3MSC.dll!cppu::OWeakObject::release() Line 229
sfxlo.dll!rtl::Reference<SfxObjectShell>::~Reference<SfxObjectShell>() Line 126
sfxlo.dll!IMPL_SfxBaseModel_DataContainer::~IMPL_SfxBaseModel_DataContainer() Line 265
sfxlo.dll!IMPL_SfxBaseModel_DataContainer::`scalar deleting destructor'(unsigned int)
sfxlo.dll!std::_Destroy_in_place<IMPL_SfxBaseModel_DataContainer>(IMPL_SfxBaseModel_DataContainer & _Obj) Line 293
sfxlo.dll!std::_Ref_count_obj2<IMPL_SfxBaseModel_DataContainer>::_Destroy() Line 2113
sfxlo.dll!std::_Ref_count_base::_Decref() Line 1164
sfxlo.dll!std::_Ptr_base<IMPL_SfxBaseModel_DataContainer>::_Decref() Line 1380
sfxlo.dll!std::shared_ptr<IMPL_SfxBaseModel_DataContainer>::~shared_ptr<IMPL_SfxBaseModel_DataContainer>() Line 1685
sfxlo.dll!std::shared_ptr<IMPL_SfxBaseModel_DataContainer>::reset() Line 1732
sfxlo.dll!SfxBaseModel::dispose() Line 794
swlo.dll!SwXTextDocument::dispose() Line 561
sfxlo.dll!SfxBaseModel::close(unsigned char bDeliverOwnership) Line 1523
swlo.dll!SwXTextDocument::close(unsigned char bDeliverOwnership) Line 574
sfxlo.dll!SfxBaseModel::dispose() Line 745
swlo.dll!SwXTextDocument::dispose() Line 561
mscx_uno.dll!`anonymous namespace'::cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, bridges::cpp_uno::shared::VtableSlot aVtableSlot, _typelib_TypeDescriptionReference * pReturnTypeRef, long nParams, _typelib_MethodParameter * pParams, void * pUnoReturn, void * * pUnoArgs, _uno_Any * * ppUnoExc) Line 214
mscx_uno.dll!unoInterfaceProxyDispatch(_uno_Interface * pUnoI, const _typelib_TypeDescription * pMemberTD, void * pReturn, void * * pArgs, _uno_Any * * ppException) Line 430
binaryurplo.dll!binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny * returnValue, std::vector<binaryurp::BinaryAny,std::allocator<binaryurp::BinaryAny>> * outArguments) Line 239
binaryurplo.dll!binaryurp::IncomingRequest::execute() Line 79
binaryurplo.dll!request(void * pThreadSpecificData) Line 84
cppu3.dll!cppu_threadpool::JobQueue::enter(const void * nDisposeId, bool bReturnWhenNoJob) Line 101
cppu3.dll!cppu_threadpool::ORequestThread::run() Line 165
cppu3.dll!threadFunc(void * param) Line 190
sal3.dll!oslWorkerWrapperFunction(void * pData) Line 67
Main thread was acquiring OleEmbeddedObject::m_aMutex, which deadlocked:
sal3.dll!osl_acquireMutex(_oslMutexImpl * Mutex) Line 65
emboleobj.dll!osl::Mutex::acquire() Line 63
emboleobj.dll!osl::ResettableGuard<osl::Mutex>::reset() Line 250
emboleobj.dll!OleEmbeddedObject::setVisualAreaSize(__int64 nAspect, const com::sun::star::awt::Size & aSize) Line 148
swlo.dll!SwWrtShell::CalcAndSetScale(svt::EmbeddedObjectRef & xObj, const SwRect * pFlyPrtRect, const SwRect * pFlyFrameRect, const bool bNoTextFramePrtAreaChanged) Line 777
swlo.dll!SwContentNotify::ImplDestroy() Line 926
swlo.dll!SwContentNotify::~SwContentNotify() Line 1037
swlo.dll!SwNoTextFrame::MakeAll(OutputDevice * pRenderContext) Line 584
swlo.dll!SwFrame::OptPrepareMake() Line 412
swlo.dll!SwFrame::OptCalc() Line 1110
swlo.dll!SwLayAction::FormatContent_(const SwContentFrame * pContent, const SwPageFrame * pPage) Line 1960
swlo.dll!SwLayAction::FormatFlyContent(const SwFlyFrame * pFly) Line 1985
swlo.dll!SwObjectFormatter::FormatObj_(SwAnchoredObject & _rAnchoredObj) Line 312
swlo.dll!SwObjectFormatterTextFrame::DoFormatObj(SwAnchoredObject & _rAnchoredObj, const bool _bCheckForMovedFwd) Line 133
swlo.dll!SwObjectFormatter::FormatObjsAtFrame_(SwTextFrame * _pMasterTextFrame) Line 414
swlo.dll!SwObjectFormatterTextFrame::DoFormatObjs() Line 348
swlo.dll!SwObjectFormatter::FormatObjsAtFrame(SwFrame & _rAnchorFrame, const SwPageFrame & _rPageFrame, SwLayAction * _pLayAction) Line 160
swlo.dll!SwLayAction::FormatContent(SwPageFrame * pPage) Line 1793
swlo.dll!SwLayAction::InternalAction(OutputDevice * pRenderContext) Line 605
swlo.dll!SwLayAction::Action(OutputDevice * pRenderContext) Line 389
swlo.dll!SwLayIdle::SwLayIdle(SwRootFrame * pRt, SwViewShellImp * pI) Line 2363
swlo.dll!SwViewShell::LayoutIdle() Line 827
swlo.dll!sw::DocumentTimerManager::DoIdleJobs(Timer * __formal) Line 176
swlo.dll!sw::DocumentTimerManager::LinkStubDoIdleJobs(void * instance, Timer * data) Line 156
vcllo.dll!Link<Timer *,void>::Call(Timer * data) Line 111
vcllo.dll!Timer::Invoke() Line 75
vcllo.dll!Scheduler::CallbackTaskScheduling() Line 509
vcllo.dll!SalTimer::CallCallback() Line 53
vclplug_winlo.dll!WinSalTimer::ImplHandleElapsedTimer() Line 169
vclplug_winlo.dll!ImplSalYield(bool bWait, bool bHandleAllCurrentEvents) Line 525
vclplug_winlo.dll!WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) Line 581
vcllo.dll!ImplYield(bool i_bWait, bool i_bAllEvents) Line 385
vcllo.dll!Application::Yield() Line 473
vcllo.dll!Application::Execute() Line 361
sofficeapp.dll!desktop::Desktop::Main() Line 1652
vcllo.dll!ImplSVMain() Line 229
vcllo.dll!SVMain() Line 262
sofficeapp.dll!soffice_main() Line 110
soffice.bin!sal_main() Line 51
soffice.bin!main(int argc, char * * argv) Line 49
soffice.bin!invoke_main() Line 79
soffice.bin!__scrt_common_main_seh() Line 288
soffice.bin!__scrt_common_main() Line 331
soffice.bin!mainCRTStartup(void * __formal) Line 17
Change-Id: Iaf5133c488d4f26f43530ea19584e99cce12d81e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171855
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
In a following scenario, there could be a crash:
1. Platform: a Windows system with MS Word installed.
2. LibreOffice is run in a listener mode;
3. A Java program opens a Writer document in a visible mode, with an
embedded Word OLE object;
4. It adds some text; then resizes the OLE object; then removes the
OLE object.
Word OLE objects have OLEMISC_RECOMPOSEONRESIZE flag [1]; this means,
that every re-layout of the document with this object must ask the
OLE server to re-layout the object content. So, the request thread
changes the document text, which triggers idle re-layout or redraw;
the idles start executing immediately in the idle main thread, with
solar mutex locked; then the request thread starts the OLE object
removal operation. The ongoing relayout in main thread would at some
stage need to execute a call to the OLE object, which temporarily
releases the solar mutex (this makes impossible using solar mutex to
synchronize the order of operations in this scenario). Other mutexes
guarding OLE object (in OleEmbeddedObject, and in OleComponent) are
also released for the duration of the call. Thus, the removal that
happens in the request thread proceeds, and the node containing the
OLE object is destroyed, while the main thread (processing exactly
this node) is waiting for the OLE server response, then for mutexes,
to proceed. After that, the main thread would attempt to access the
destroyed node object.
This change introduces a scheduler guard (a RAII object), that sets
a flag to not process idle events during the lifetime of the guard.
In its constructor, it also makes sure, that current pending idle
events are finished. This would make sure that guarded code started
from other threads would not race with idles potentially accessing
the model that is currently in transient state.
[1] https://learn.microsoft.com/en-us/windows/win32/api/oleidl/ne-oleidl-olemisc
Change-Id: I2ef0601ccd8b5872588a88493d1f43e39022dbed
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164753
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
... to make sure that object methods are called in correct apartment
The user-visible problem was, that running a Java code that connects
to LibreOffice, and opening a document with an embedded OLE object
(it was Word object in a specific case, which needs activation at
opening stage, because these objects have OLEMISC_RECOMPOSEONRESIZE
flag), using loadComponentFromURL with "OnMainThread" set to true,
then closing the document, resulted in a hang after several hundreds
iterations. This was caused by Word process, that was started in
background to serve the COM calls, wasn't closed properly, and kept
all the objects in memory, until OOM.
The reason why it wasn't closed was failed call to IOleObject::Close
in OleComponent::CloseObject, which returned RPC_E_WRONG_THREAD,
because the activation of the OLE object happened in the main thread
(because of "OnMainThread"), which is STA, but closing happened in
the handler thread (belonging to MTA).
Similar problems previously were addressed in commits
2dc3a6c273 (framework: allow loading a
component on the main thread, 2018-12-20),
6002014ce0 (framework: allow loading a
component on the main thread, using XDesktop, 2021-04-28),
d5cd62164d (embeddedobj: handle getting
the visible area on a thread, 2021-05-07).
These changes tried different workarounds for the same problem, when
a COM object instantiated in one apartment is later manipulated from
another, which fails. First two handled the case when the document
is loaded from a non-UI thread, and then manipulated with the UI; to
handle that, they introduced flags that delegated opening the file
to the main (UI) thread. The last change tried to handle the reverse
problem of the OLE object instantiated in the main thread was saved
in a handler thread, which again failed; the workaround was, again,
to try to delegate the second attempt to the main thread.
But basically all methods can fail in such circumstations, as shown
in this problem's case. The "OnMainThread" flag must be passed to
fileopen functions explicitly. Also, the workarounds only work by
passing everything to STA, and don't target a case when the calls
must be passed from STA to MTA.
Since Windows 2000, there is IGlobalInterfaceTable, which goal is
to solve this problem. It allows to use an intermediate object,
which can transparently delegate all calls to the correct thread.
This change re-implements how OLE objects are referenced from
OleComponentNative_Impl, using the said IGlobalInterfaceTable.
This should hopefully obsolete the previous workarounds, which
nevertheless are kept for now.
Change-Id: Ia1c590e547ed24a2c7389283aed6cc3d8ea024b0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164457
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
...by moving the char8_t -> char reinterpret_cast out of any potential constexpr
paths into a new TranslateId::getId. And demonstrate constexpr'ability by
making the aCategories var in OApplicationIconControl::Fill
(dbaccess/source/ui/app/AppIconControl.cxx) constexpr. (And there might be more
such cases that could now be made constexpr.)
Change-Id: I0b4e3292faf8f6b901f9b9e934e1aa6bf0f583ff
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157862
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
calc does a lot of "CaptureMouse" which then leads to a lot of
"ReleaseMouse", I'm somewhat unconvinced that there should be any
CaptureMouse calls in there.
Change-Id: I7c44d2c36c89a5c32c525d65939723da9be77a72
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149973
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
(See the upcoming commit introducing that loplugin:unocast on why such
dynamic_casts from UNO types are dangerous.)
Change-Id: Ia0f628be9adf749ffdd9ad36ca9b1e8c98e29936
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144755
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Regression from b099da78a6f0b3e120f706714003b05d84d11e70
we didn't update linked OLE document after document reload
Change-Id: I8e52f6430f454b276cb43449c6f7a3b0e07e909f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130692
Reviewed-by: Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de>
Tested-by: Jenkins
Commit 4f9f1ac333 (sw: allow viewing OLE
objects in protected sections, 2021-11-25) allowed launching OLE objects
in protected sections, and then made sure that changes done in "real"
OLE editors (on Windows) are discarded: both the native data and
preview.
Extend this mechanism to also handle common embedded objects (i.e. when
we load the data into an own document model, like Calc-in-Writer on
Linux): there we can simply load the data read-only, so there will be no
need to discard anything.
This requires some way to pass down the read-only flag from sw/ to
embeddedobj, implement XInitialization on OCommonEmbeddedObject to do
that.
Change-Id: I7b32d7514a6b0a40b4f58bed57879d292daa4ed7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125858
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
This gives UNO clients a reliable way to detect e.g.
OSpecialEmbeddedObject, where it's expected that double-clicking on the
object doesn't do anything.
Change-Id: I595453490b157b64214cd7359da1e3a3c959191d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120274
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
based on OInterfaceContainerHelper2 which is considerably
faster than the original OInterfaceContainerHelper
Change-Id: I9c8b6d0e5382018824bf7188a26343703abf2d51
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120161
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Before deactivating a linked OLE saved it and overwrote the
original, even when not saving the hosting document at all.
This is not intuitive from user perspective and may lead
to unexpected data loss (of the OLE content).
Reported case was especially about closing the hosted document
without saving in the understandable believe that that way the
changed OLE will not be changed on external medium.
Added mechanism for linked OLE to hold data in a hidden local
temp file, synching/writing back on hosting file save. Most
complicated was adapting the 'break link' case and ensuring
other cases to work, but looks good now from my POV
Change-Id: I7f63d667820b2d9725abc598a9dd7360be1f8d5a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113793
Tested-by: Armin Le Grand <Armin.Le.Grand@me.com>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Except for test/ which seems to be unused anyway
Found with bin/find-unneeded-includes
Only removal proposals are dealt with here.
Change-Id: I9d0b75dbb260f05390b513be75a4bdd24647c91b
Reviewed-on: https://gerrit.libreoffice.org/80077
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
It is expected that if you load an OLE2 storage (from reqif-xhtml) and
you save it as ODT, the OLE2 data is not modified. This was almost the
case, but we insisted on removing the OLE2 preview from the storage.
Add a new flag to OleEmbeddedObject, so import filters can opt in for
not modifying the OLE2 data.
[ The nice situation is that we already had a test file which had a
preview stream in the OLE2 storage, so we can easily assert there that
the size doesn't change. ]
Change-Id: I9b8b29f015dd4f2513e51a1066767218580cb5d8
Reviewed-on: https://gerrit.libreoffice.org/63381
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Embedded native data (what we don't parse just carry on) and real OLE2
embedding already worked, this adds the case where the actual content is
ODF, just inside OLE2.
The DOC import/export had support for handleing ODF content inside OLE2,
so reuse that code: add new functions to SvxMSDffManager for import
purposes and reuse SvxMSExportOLEObjects for export purposes.
Change-Id: I0acf65d4bf29af896b8f1dd625e8672050aae350
Reviewed-on: https://gerrit.libreoffice.org/55088
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>