https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5b3e84f2ef2c8e8806a98…
commit 5b3e84f2ef2c8e8806a984e315b4f272b6677a90
Author: Mark Jansen <mark.jansen(a)reactos.org>
AuthorDate: Sun Jan 26 23:40:04 2020 +0100
Commit: Mark Jansen <mark.jansen(a)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)
{