Fixes a regression introduced by d541087079a8770bb02bae830c56a6d3c0b6424e due to an alternate code path being executed for Firefox and Pale Moon browsers that made use of the Thread Manager, causing a crash.
AssociateFocus does not grab ownership of the Document Manager, but it does return it in the "prev" output parameter with an increased refcount. So, if the docmgr gets destroyed and AssociateFocus is called again, its "prev" parameter will refer to freed memory. Windows sets it to NULL in such case.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/msctf/tests/inputprocessor.c | 15 +++++++++++++-- dlls/msctf/threadmgr.c | 14 ++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c index 38c591e..f8ec492 100644 --- a/dlls/msctf/tests/inputprocessor.c +++ b/dlls/msctf/tests/inputprocessor.c @@ -2287,6 +2287,7 @@ static void test_AssociateFocus(void) ITfDocumentMgr *dm1, *dm2, *olddm, *dmcheck, *dmorig; HWND wnd1, wnd2, wnd3; HRESULT hr; + ULONG ref;
ITfThreadMgr_GetFocus(g_tm, &dmorig); test_CurrentFocus = NULL; @@ -2428,10 +2429,20 @@ static void test_AssociateFocus(void) processPendingMessages(); SetFocus(wnd1); processPendingMessages(); - test_OnSetFocus = SINK_UNEXPECTED; + + hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,dm2,&olddm); + ok(SUCCEEDED(hr),"AssociateFocus failed\n"); + + /* Vista doesn't return NULL */ + if (olddm) ITfDocumentMgr_Release(olddm); + ref = ITfDocumentMgr_Release(dm2); + ok(ref == 0, "incorrect DocumentMgr ref %d\n", ref); + + hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,NULL,&olddm); + ok(SUCCEEDED(hr),"AssociateFocus failed\n"); + ok(olddm == NULL, "incorrect old DocumentMgr returned\n");
ITfDocumentMgr_Release(dm1); - ITfDocumentMgr_Release(dm2);
test_CurrentFocus = dmorig; test_PrevFocus = FOCUS_IGNORE; diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c index 2c208fb..77cf47c 100644 --- a/dlls/msctf/threadmgr.c +++ b/dlls/msctf/threadmgr.c @@ -1530,6 +1530,8 @@ void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *iface, ITfDocumentMgr *mgr { ThreadMgr *This = impl_from_ITfThreadMgrEx((ITfThreadMgrEx *)iface); struct list *cursor; + BOOL found = FALSE; + LIST_FOR_EACH(cursor, &This->CreatedDocumentMgrs) { DocumentMgrEntry *mgrentry = LIST_ENTRY(cursor,DocumentMgrEntry,entry); @@ -1537,8 +1539,16 @@ void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *iface, ITfDocumentMgr *mgr { list_remove(cursor); HeapFree(GetProcessHeap(),0,mgrentry); - return; + found = TRUE; + break; } } - FIXME("ITfDocumentMgr %p not found in this thread\n",mgr); + if (!found) FIXME("ITfDocumentMgr %p not found in this thread\n",mgr); + + LIST_FOR_EACH(cursor, &This->AssociatedFocusWindows) + { + AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry); + if (wnd->docmgr == mgr) + wnd->docmgr = NULL; + } }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62910
Your paranoid android.
=== w1064v1809_he (task log) ===
Task errors: The previous 1 run(s) terminated abnormally
=== w1064v1809_ja (32 bit report) ===
msctf: inputprocessor.c:594: Test failed: Unexpected ThreadMgrEventSink_OnPopContext sink
This seems like random errors / pre-existing or unrelated to the patch. It doesn't do anything to push or pop the context.
On 06/01/2020 15:50, Marvin wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62910
Your paranoid android.
=== w1064v1809_he (task log) ===
Task errors: The previous 1 run(s) terminated abnormally
=== w1064v1809_ja (32 bit report) ===
msctf: inputprocessor.c:594: Test failed: Unexpected ThreadMgrEventSink_OnPopContext sink