summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2021-02-08 11:48:36 +0100
committerStephan Bergmann <sbergman@redhat.com>2021-02-08 13:56:06 +0100
commit89d770f9727b9e7eddf933c96771df98082b3efb (patch)
tree97ed642688505617cfb8867055ae57b273575d41 /sw
parent0a76b8ebbaf934faad27ddb3a4e951b9c743e536 (diff)
Revert "replace SwClient by SvtListener in SwGrammarContact"
This reverts commit dcae40491eea2534c30ba96f10bc45035d073a46, it causes heap-use-after-free during JunitTest_sw_unoapi_1 (see also <https://ci.libreoffice.org/job/lo_ubsan/1913/> and following), > ==1281072==ERROR: AddressSanitizer: heap-use-after-free on address 0x6150043ea120 at pc 0x7fd7ddcc4afe bp 0x7fd6603350b0 sp 0x7fd6603350a8 > READ of size 8 at 0x6150043ea120 thread T116 (cppu_threadpool) > #0 in SwTextNode::SetGrammarCheck(SwGrammarMarkUp*, bool) at sw/source/core/txtnode/txtedt.cxx:2194:10 > #1 in (anonymous namespace)::SwGrammarContact::updateCursorPosition(SwPosition const&) at sw/source/core/txtnode/SwGrammarContact.cxx:94:26 > #2 in SwCursorShell::UpdateCursorPos() at sw/source/core/crsr/crsrsh.cxx:1508:26 > #3 in SwCursorShell::UpdateCursor(unsigned short, bool) at sw/source/core/crsr/crsrsh.cxx:1815:5 > #4 in SwCursorShell::EndAction(bool, bool) at sw/source/core/crsr/crsrsh.cxx:283:5 > #5 in SwRootFrame::EndAllAction(bool) at sw/source/core/layout/pagechg.cxx:1913:27 > #6 in UnoActionContext::~UnoActionContext() at sw/source/core/unocore/unoobj2.cxx:202:25 > #7 in SwXTextCursor::DeleteAndInsert(rtl::OUString const&, bool) at sw/source/core/unocore/unoobj.cxx:759:1 > #8 in SwXTextCursor::setString(rtl::OUString const&) at sw/source/core/unocore/unoobj.cxx:1721:5 > #9 in SwXText::setString(rtl::OUString const&) at sw/source/core/unocore/unotext.cxx:968:11 > #10 in gcc3::callVirtualMethod(void*, unsigned int, void*, _typelib_TypeDescriptionReference*, bool, unsigned long*, unsigned int, unsigned long*, double*) at bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx:77:5 > #11 in cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy*, bridges::cpp_uno::shared::VtableSlot, _typelib_TypeDescriptionReference*, int, _typelib_MethodParameter*, void*, void**, _uno_Any**) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:233:13 > #12 in unoInterfaceProxyDispatch at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:413:13 > #13 in binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >*) const at binaryurp/source/incomingrequest.cxx:235:13 > #14 in binaryurp::IncomingRequest::execute() const at binaryurp/source/incomingrequest.cxx:78:26 > #15 in request at binaryurp/source/reader.cxx:85:9 > #16 in cppu_threadpool::JobQueue::enter(void const*, bool) at cppu/source/threadpool/jobqueue.cxx:100:17 > #17 in cppu_threadpool::ORequestThread::run() at cppu/source/threadpool/thread.cxx:165:31 > #18 in threadFunc at include/osl/thread.hxx:189:15 > #19 in osl_thread_start_Impl(void*) at sal/osl/unx/thread.cxx:264:9 > > 0x6150043ea120 is located 416 bytes inside of 464-byte region [0x6150043e9f80,0x6150043ea150) > freed by thread T116 (cppu_threadpool) here: > #0 in operator delete(void*, unsigned long) at ~/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:172:3 > #1 in SwTextNode::~SwTextNode() at sw/source/core/txtnode/ndtxt.cxx:231:1 > #2 in SwNodes::RemoveNode(unsigned long, unsigned long, bool) at sw/source/core/docnode/nodes.cxx:2274:13 > #3 in SwNodes::Delete(SwNodeIndex const&, unsigned long) at sw/source/core/docnode/nodes.cxx:1221:9 > #4 in SwTextNode::JoinNext() at sw/source/core/txtnode/ndtxt.cxx:1027:14 > #5 in sw_JoinText(SwPaM&, bool) at sw/source/core/doc/docedt.cxx:489:22 > #6 in sw::DocumentContentOperationsManager::DeleteAndJoinImpl(SwPaM&, bool) at sw/source/core/doc/DocumentContentOperationsManager.cxx:4043:9 > #7 in (anonymous namespace)::lcl_DoWithBreaks(sw::DocumentContentOperationsManager&, SwPaM&, bool (sw::DocumentContentOperationsManager::*)(SwPaM&, bool), bool) at sw/source/core/doc/DocumentContentOperationsManager.cxx:630:20 > #8 in sw::DocumentContentOperationsManager::DeleteAndJoin(SwPaM&, bool) at sw/source/core/doc/DocumentContentOperationsManager.cxx:2184:22 > #9 in SwXTextCursor::DeleteAndInsert(rtl::OUString const&, bool) at sw/source/core/unocore/unoobj.cxx:744:50 > #10 in SwXTextCursor::setString(rtl::OUString const&) at sw/source/core/unocore/unoobj.cxx:1721:5 > #11 in SwXText::setString(rtl::OUString const&) at sw/source/core/unocore/unotext.cxx:968:11 > #12 in gcc3::callVirtualMethod(void*, unsigned int, void*, _typelib_TypeDescriptionReference*, bool, unsigned long*, unsigned int, unsigned long*, double*) at bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx:77:5 > #13 in cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy*, bridges::cpp_uno::shared::VtableSlot, _typelib_TypeDescriptionReference*, int, _typelib_MethodParameter*, void*, void**, _uno_Any**) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:233:13 > #14 in unoInterfaceProxyDispatch at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:413:13 > #15 in binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >*) const at binaryurp/source/incomingrequest.cxx:235:13 > #16 in binaryurp::IncomingRequest::execute() const at binaryurp/source/incomingrequest.cxx:78:26 > #17 in request at binaryurp/source/reader.cxx:85:9 > #18 in cppu_threadpool::JobQueue::enter(void const*, bool) at cppu/source/threadpool/jobqueue.cxx:100:17 > #19 in cppu_threadpool::ORequestThread::run() at cppu/source/threadpool/thread.cxx:165:31 > > previously allocated by thread T116 (cppu_threadpool) here: > #0 in operator new(unsigned long) at ~/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:99:3 > #1 in SwDoc::SwDoc() at sw/source/core/doc/docnew.cxx:329:5 > #2 in SwDocFac::GetDoc() at sw/source/filter/basflt/docfact.cxx:36:21 > #3 in SwDocShell::AddLink() at sw/source/uibase/app/docshini.cxx:396:28 > #4 in SwDocShell::InitNew(com::sun::star::uno::Reference<com::sun::star::embed::XStorage> const&) at sw/source/uibase/app/docshini.cxx:96:9 > #5 in SfxObjectShell::DoInitNew(SfxMedium*) at sfx2/source/doc/objstor.cxx:466:10 > #6 in SfxBaseModel::initNew() at sfx2/source/doc/sfxbasemodel.cxx:1802:42 > #7 in (anonymous namespace)::SfxFrameLoader_Impl::load(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&) at sfx2/source/view/frmload.cxx:674:28 > #8 in framework::LoadEnv::impl_loadContent() at framework/source/loadenv/loadenv.cxx:1163:37 > #9 in framework::LoadEnv::start() at framework/source/loadenv/loadenv.cxx:394:20 > #10 in framework::LoadEnv::startLoading(rtl::OUString const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, rtl::OUString const&, int, LoadEnvFeatures) at framework/source/loadenv/loadenv.cxx:299:5 > #11 in framework::LoadEnv::loadComponentFromURL(com::sun::star::uno::Reference<com::sun::star::frame::XComponentLoader> const&, com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) at framework/source/loadenv/loadenv.cxx:168:14 > #12 in framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) at framework/source/services/desktop.cxx:593:12 > #13 in non-virtual thunk to framework::Desktop::loadComponentFromURL(rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) at framework/source/services/desktop.cxx > #14 in gcc3::callVirtualMethod(void*, unsigned int, void*, _typelib_TypeDescriptionReference*, bool, unsigned long*, unsigned int, unsigned long*, double*) at bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx:77:5 > #15 in cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy*, bridges::cpp_uno::shared::VtableSlot, _typelib_TypeDescriptionReference*, int, _typelib_MethodParameter*, void*, void**, _uno_Any**) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:233:13 > #16 in unoInterfaceProxyDispatch at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:413:13 > #17 in binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >*) const at binaryurp/source/incomingrequest.cxx:235:13 > #18 in binaryurp::IncomingRequest::execute() const at binaryurp/source/incomingrequest.cxx:78:26 > #19 in request at binaryurp/source/reader.cxx:85:9 Change-Id: Icbefd7e731bd6f6557ef0371d5f81e76c59cd090 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110557 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/txtnode/SwGrammarContact.cxx89
1 files changed, 43 insertions, 46 deletions
diff --git a/sw/source/core/txtnode/SwGrammarContact.cxx b/sw/source/core/txtnode/SwGrammarContact.cxx
index e296cc7375e6..7b061bdaf9ba 100644
--- a/sw/source/core/txtnode/SwGrammarContact.cxx
+++ b/sw/source/core/txtnode/SwGrammarContact.cxx
@@ -23,7 +23,6 @@
#include <ndtxt.hxx>
#include <SwGrammarMarkUp.hxx>
#include <txtfrm.hxx>
-#include <svl/listener.hxx>
namespace {
@@ -38,32 +37,34 @@ namespace {
* will replace the old list. If the grammar checker has completed the paragraph ('setChecked')
* then a timer is setup which replaces the old list as well.
*/
-class SwGrammarContact : public IGrammarContact, public SvtListener
+class SwGrammarContact : public IGrammarContact, public SwClient
{
- Timer m_aTimer;
- std::unique_ptr<SwGrammarMarkUp> m_pProxyList;
- bool m_isFinished;
- SwTextNode* m_pTextNode;
- DECL_LINK( TimerRepaint, Timer *, void );
+ Timer aTimer;
+ std::unique_ptr<SwGrammarMarkUp> mpProxyList;
+ bool mbFinished;
+ SwTextNode* getMyTextNode() { return static_cast<SwTextNode*>(GetRegisteredIn()); }
+ DECL_LINK( TimerRepaint, Timer *, void );
public:
SwGrammarContact();
- virtual ~SwGrammarContact() override { m_aTimer.Stop(); }
+ virtual ~SwGrammarContact() override { aTimer.Stop(); }
// (pure) virtual functions of IGrammarContact
virtual void updateCursorPosition( const SwPosition& rNewPos ) override;
virtual SwGrammarMarkUp* getGrammarCheck( SwTextNode& rTextNode, bool bCreate ) override;
virtual void finishGrammarCheck( SwTextNode& rTextNode ) override;
- virtual void Notify( const SfxHint& rHint) override;
+protected:
+ // virtual function of SwClient
+ virtual void SwClientNotify( const SwModify&, const SfxHint& rHint) override;
};
}
-SwGrammarContact::SwGrammarContact() : m_isFinished( false ), m_pTextNode(nullptr)
+SwGrammarContact::SwGrammarContact() : mbFinished( false )
{
- m_aTimer.SetTimeout( 2000 ); // Repaint of grammar check after 'setChecked'
- m_aTimer.SetInvokeHandler( LINK(this, SwGrammarContact, TimerRepaint) );
- m_aTimer.SetDebugName( "sw::SwGrammarContact TimerRepaint" );
+ aTimer.SetTimeout( 2000 ); // Repaint of grammar check after 'setChecked'
+ aTimer.SetInvokeHandler( LINK(this, SwGrammarContact, TimerRepaint) );
+ aTimer.SetDebugName( "sw::SwGrammarContact TimerRepaint" );
}
IMPL_LINK( SwGrammarContact, TimerRepaint, Timer *, pTimer, void )
@@ -71,10 +72,10 @@ IMPL_LINK( SwGrammarContact, TimerRepaint, Timer *, pTimer, void )
if( pTimer )
{
pTimer->Stop();
- if( m_pTextNode )
+ if( GetRegisteredIn() )
{ //Replace the old wrong list by the proxy list and repaint all frames
- m_pTextNode->SetGrammarCheck( m_pProxyList.release() );
- SwTextFrame::repaintTextFrames( *m_pTextNode );
+ getMyTextNode()->SetGrammarCheck( mpProxyList.release() );
+ SwTextFrame::repaintTextFrames( *getMyTextNode() );
}
}
}
@@ -83,51 +84,48 @@ IMPL_LINK( SwGrammarContact, TimerRepaint, Timer *, pTimer, void )
void SwGrammarContact::updateCursorPosition( const SwPosition& rNewPos )
{
SwTextNode* pTextNode = rNewPos.nNode.GetNode().GetTextNode();
- if( pTextNode == m_pTextNode ) // paragraph has been changed
+ if( pTextNode == GetRegisteredIn() ) // paragraph has been changed
return;
- m_aTimer.Stop();
- if( m_pTextNode ) // My last paragraph has been left
+ aTimer.Stop();
+ if( GetRegisteredIn() ) // My last paragraph has been left
{
- if( m_pProxyList )
+ if( mpProxyList )
{ // replace old list by the proxy list and repaint
- m_pTextNode->SetGrammarCheck( m_pProxyList.release() );
- SwTextFrame::repaintTextFrames( *m_pTextNode );
+ getMyTextNode()->SetGrammarCheck( mpProxyList.release() );
+ SwTextFrame::repaintTextFrames( *getMyTextNode() );
}
EndListeningAll();
}
if( pTextNode )
- {
- m_pTextNode = pTextNode;
- StartListening(pTextNode->GetNotifier()); // welcome new paragraph
- }
+ pTextNode->Add( this ); // welcome new paragraph
}
/* deliver a grammar check list for the given text node */
SwGrammarMarkUp* SwGrammarContact::getGrammarCheck( SwTextNode& rTextNode, bool bCreate )
{
SwGrammarMarkUp *pRet = nullptr;
- if( m_pTextNode == &rTextNode ) // hey, that's my current paragraph!
+ if( GetRegisteredIn() == &rTextNode ) // hey, that's my current paragraph!
{ // so you will get a proxy list...
if( bCreate )
{
- if( m_isFinished )
+ if( mbFinished )
{
- m_pProxyList.reset();
+ mpProxyList.reset();
}
- if( !m_pProxyList )
+ if( !mpProxyList )
{
if( rTextNode.GetGrammarCheck() )
- m_pProxyList.reset( static_cast<SwGrammarMarkUp*>(rTextNode.GetGrammarCheck()->Clone()) );
+ mpProxyList.reset( static_cast<SwGrammarMarkUp*>(rTextNode.GetGrammarCheck()->Clone()) );
else
{
- m_pProxyList.reset( new SwGrammarMarkUp() );
- m_pProxyList->SetInvalid( 0, COMPLETE_STRING );
+ mpProxyList.reset( new SwGrammarMarkUp() );
+ mpProxyList->SetInvalid( 0, COMPLETE_STRING );
}
}
- m_isFinished = false;
+ mbFinished = false;
}
- pRet = m_pProxyList.get();
+ pRet = mpProxyList.get();
}
else
{
@@ -143,32 +141,31 @@ SwGrammarMarkUp* SwGrammarContact::getGrammarCheck( SwTextNode& rTextNode, bool
return pRet;
}
-void SwGrammarContact::Notify(const SfxHint& rHint)
+void SwGrammarContact::SwClientNotify(const SwModify&, const SfxHint& rHint)
{
auto pLegacy = dynamic_cast<const sw::LegacyModifyHint*>(&rHint);
if(!pLegacy || pLegacy->GetWhich() != RES_OBJECTDYING)
return;
- m_aTimer.Stop();
+ aTimer.Stop();
EndListeningAll();
- m_pTextNode = nullptr;
- m_pProxyList.reset();
+ mpProxyList.reset();
}
void SwGrammarContact::finishGrammarCheck( SwTextNode& rTextNode )
{
- if( &rTextNode != m_pTextNode ) // not my paragraph
+ if( &rTextNode != GetRegisteredIn() ) // not my paragraph
SwTextFrame::repaintTextFrames( rTextNode ); // can be repainted directly
else
{
- if( m_pProxyList )
+ if( mpProxyList )
{
- m_isFinished = true;
- m_aTimer.Start(); // will replace old list and repaint with delay
+ mbFinished = true;
+ aTimer.Start(); // will replace old list and repaint with delay
}
- else if( m_pTextNode->GetGrammarCheck() )
+ else if( getMyTextNode()->GetGrammarCheck() )
{ // all grammar problems seems to be gone, no delay needed
- m_pTextNode->SetGrammarCheck( nullptr );
- SwTextFrame::repaintTextFrames( *m_pTextNode );
+ getMyTextNode()->SetGrammarCheck( nullptr );
+ SwTextFrame::repaintTextFrames( *getMyTextNode() );
}
}
}