From 92291448c091db4c19bdd09bfe9b6521c6d87b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 25 Sep 2024 20:56:05 -0300 Subject: [PATCH] Fix invalid memory access when Event::OnDocumentChange is processed in LSPClientPlugin. Some refactor of Keyboards Shortcuts. --- include/eepp/ui/keyboardshortcut.hpp | 5 +++++ include/eepp/ui/uicodeeditor.hpp | 14 +++++++++++++- src/eepp/ui/keyboardshortcut.cpp | 18 ++++++++++++++---- src/eepp/ui/uicodeeditor.cpp | 7 ++++--- .../ecode/plugins/lsp/lspclientplugin.cpp | 7 +++---- 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/include/eepp/ui/keyboardshortcut.hpp b/include/eepp/ui/keyboardshortcut.hpp index 13c9defce..db3ade6a5 100644 --- a/include/eepp/ui/keyboardshortcut.hpp +++ b/include/eepp/ui/keyboardshortcut.hpp @@ -37,6 +37,11 @@ class EE_API KeyBindings { static std::string keybindFormat( std::string str ); + static Shortcut toShortcut( const Window::Input* input, const std::string& keys ); + + static std::string fromShortcut( const Window::Input* input, KeyBindings::Shortcut shortcut, + bool format = false ); + KeyBindings( const Window::Input* input ); void addKeybindsString( const std::map& binds ); diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index 740b4a081..ab93feba9 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -136,6 +136,18 @@ class EE_API DocEvent : public Event { TextDocument* doc; }; +class EE_API DocChangedEvent : public DocEvent { + public: + DocChangedEvent( Node* node, TextDocument* doc, const Uint32& eventType, URI oldDocURI ) : + DocEvent( node, doc, eventType ), mOldDocURI( oldDocURI ) {} + + const URI& getOldDocURI() const { return mOldDocURI; } + + protected: + TextDocument* doc; + URI mOldDocURI; +}; + class EE_API DocSyntaxDefEvent : public DocEvent { public: DocSyntaxDefEvent( Node* node, TextDocument* doc, const Uint32& eventType, @@ -990,7 +1002,7 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { virtual void onDocumentReset( TextDocument* ); - virtual void onDocumentChanged(); + virtual void onDocumentChanged( URI oldDocURI ); virtual void onFoldRegionsUpdated( size_t oldCount, size_t newCount ); diff --git a/src/eepp/ui/keyboardshortcut.cpp b/src/eepp/ui/keyboardshortcut.cpp index 4fc762f51..48e92853d 100644 --- a/src/eepp/ui/keyboardshortcut.cpp +++ b/src/eepp/ui/keyboardshortcut.cpp @@ -76,7 +76,8 @@ void KeyBindings::replaceKeybind( const KeyBindings::Shortcut& keys, const std:: mKeybindingsInvert[command] = sanitizeShortcut( keys ); } -KeyBindings::Shortcut KeyBindings::getShortcutFromString( const std::string& keys ) { +KeyBindings::Shortcut KeyBindings::toShortcut( const Window::Input* input, + const std::string& keys ) { Shortcut shortcut; Uint32 mod = 0; auto keysSplit = String::split( keys, '+' ); @@ -89,12 +90,16 @@ KeyBindings::Shortcut KeyBindings::getShortcutFromString( const std::string& key if ( ( mod = KeyMod::getKeyMod( part ) ) ) { shortcut.mod |= mod; } else { - shortcut.key = mInput->getKeyFromName( part ); + shortcut.key = input->getKeyFromName( part ); } } return shortcut; } +KeyBindings::Shortcut KeyBindings::getShortcutFromString( const std::string& keys ) { + return toShortcut( mInput, keys ); +} + void KeyBindings::removeKeybind( const KeyBindings::Shortcut& keys ) { auto it = mShortcuts.find( keys.toUint64() ); if ( it != mShortcuts.end() ) { @@ -163,9 +168,10 @@ const std::map KeyBindings::getKeybindings() const { return mKeybindingsInvert; } -std::string KeyBindings::getShortcutString( KeyBindings::Shortcut shortcut, bool format ) const { +std::string KeyBindings::fromShortcut( const Window::Input* input, KeyBindings::Shortcut shortcut, + bool format ) { std::vector mods; - std::string keyname( String::toLower( mInput->getKeyName( shortcut.key ) ) ); + std::string keyname( String::toLower( input->getKeyName( shortcut.key ) ) ); const auto& MOD_MAP = KeyMod::getModMap(); if ( shortcut.mod & MOD_MAP.at( "mod" ) ) mods.emplace_back( "mod" ); @@ -185,4 +191,8 @@ std::string KeyBindings::getShortcutString( KeyBindings::Shortcut shortcut, bool return format ? keybindFormat( ret ) : ret; } +std::string KeyBindings::getShortcutString( KeyBindings::Shortcut shortcut, bool format ) const { + return fromShortcut( mInput, shortcut, format ); +} + }} // namespace EE::UI diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index f18c88df7..406c03b10 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -654,10 +654,10 @@ void UICodeEditor::onDocumentReset( TextDocument* ) { findRegionsDelayed(); } -void UICodeEditor::onDocumentChanged() { +void UICodeEditor::onDocumentChanged( URI oldDocURI ) { if ( mFindReplace ) mFindReplace->setDoc( mDoc ); - DocEvent event( this, mDoc.get(), Event::OnDocumentChanged ); + DocChangedEvent event( this, mDoc.get(), Event::OnDocumentChanged, oldDocURI ); sendEvent( &event ); } @@ -942,6 +942,7 @@ TextDocument& UICodeEditor::getDocument() { void UICodeEditor::setDocument( std::shared_ptr doc ) { if ( mDoc.get() != doc.get() ) { + URI oldDocURI = mDoc->getURI(); mDoc->unregisterClient( this ); mDocView.setDocument( nullptr ); if ( mDoc.use_count() == 1 ) @@ -949,7 +950,7 @@ void UICodeEditor::setDocument( std::shared_ptr doc ) { mDoc = doc; mDoc->registerClient( this ); mDocView.setDocument( doc ); - onDocumentChanged(); + onDocumentChanged( oldDocURI ); if ( mDoc->isLoading() ) { mInvalidateOnLoaded = true; } else { diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp index cccf10260..d9ba53c84 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp @@ -1479,20 +1479,19 @@ void LSPClientPlugin::onRegister( UICodeEditor* editor ) { } ) ); listeners.push_back( - editor->addEventListener( Event::OnDocumentChanged, [this, editor]( const Event* ) { + editor->addEventListener( Event::OnDocumentChanged, [this, editor]( const Event* event ) { + const DocChangedEvent* docChangedEvent = static_cast( event ); TextDocument* oldDoc = mEditorDocs[editor]; TextDocument* newDoc = editor->getDocumentRef().get(); - URI docURI; { Lock l( mDocMutex ); - docURI = oldDoc->getURI(); mDocs.erase( oldDoc ); mEditorDocs[editor] = newDoc; } { Lock l( mDocCurrentSymbolsMutex ); - mDocCurrentSymbols.erase( docURI ); + mDocCurrentSymbols.erase( docChangedEvent->getOldDocURI() ); } updateCurrentSymbol( editor->getDocument() );