https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5b3e84f2ef2c8e8806a984...
commit 5b3e84f2ef2c8e8806a984e315b4f272b6677a90 Author: Mark Jansen mark.jansen@reactos.org AuthorDate: Sun Jan 26 23:40:04 2020 +0100 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Tue Jan 28 19:25:11 2020 +0100
[BROWSEUI] Fix infinite recursion in autocomplete control import wine commits 9c2217 and 644358, slightly tweaked to fit our code --- dll/win32/browseui/CAutoComplete.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/dll/win32/browseui/CAutoComplete.cpp b/dll/win32/browseui/CAutoComplete.cpp index e1ed083dae3..8bf5b152e84 100644 --- a/dll/win32/browseui/CAutoComplete.cpp +++ b/dll/win32/browseui/CAutoComplete.cpp @@ -65,8 +65,11 @@ CAutoComplete::~CAutoComplete() TRACE(" destroying IAutoComplete(%p)\n", this); HeapFree(GetProcessHeap(), 0, quickComplete); HeapFree(GetProcessHeap(), 0, txtbackup); - RemovePropW(hwndEdit, autocomplete_propertyW); - SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR)wpOrigEditProc); + if (wpOrigEditProc) + { + SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR)wpOrigEditProc); + RemovePropW(hwndEdit, autocomplete_propertyW); + } if (hwndListBox) DestroyWindow(hwndListBox); } @@ -148,10 +151,27 @@ HRESULT WINAPI CAutoComplete::Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR p
this->hwndEdit = hwndEdit; this->initialized = TRUE; - this->wpOrigEditProc = (WNDPROC)SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR) ACEditSubclassProc); + /* Keep at least one reference to the object until the edit window is destroyed. */ this->AddRef(); - SetPropW( this->hwndEdit, autocomplete_propertyW, (HANDLE)this ); + + /* If another AutoComplete object was previously assigned to this edit control, + release it but keep the same callback on the control, to avoid an infinite + recursive loop in ACEditSubclassProc while the property is set to this object */ + CAutoComplete *prev = static_cast<CAutoComplete *>(GetPropW(hwndEdit, autocomplete_propertyW)); + + if (prev && prev->initialized) + { + this->wpOrigEditProc = prev->wpOrigEditProc; + SetPropW(hwndEdit, autocomplete_propertyW, this); + prev->wpOrigEditProc = NULL; + prev->Release(); + } + else + { + SetPropW( this->hwndEdit, autocomplete_propertyW, (HANDLE)this ); + this->wpOrigEditProc = (WNDPROC)SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR)ACEditSubclassProc); + }
if (options & ACO_AUTOSUGGEST) {