Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Addresses Issue #4984. This is a port of a servicing fix in .NET 4.7-4.8.
Description
The Text Services Framework (Cicero) uses a locking protocol for communication between an IME and WPF. When an IME wants to change the text:
• Cicero asks for a write lock (ITextStoreACP.RequestLock)
• WPF (specifically TextStore) grants the lock and calls back into Cicero (ITextStoreACPSink.OnLockGranted)
• Cicero calls other ITextStoreACP methods to make the desired changes. No one else is allowed to change the text during this time, until OnLockGranted returns.
• WPF notifies other parties about the changes, as follows (HandleCompositionEvents):
+ Undo the IME changes
+ Replay the IME changes one-by-one, this time raising public events (except to Cicero itself)
+ If the event listeners changed the text, inform the IME
The bug arises when Cicero starts the next round of changes before the previous one finishes -- more precisely, when Cicero requests a lock while WPF is still replaying IME changes from a previous lock. These normally can't happen as WPF is careful not to call Cicero during the replay, but they can happen if raising a public event causes messages to be pumped and Cicero's message hook sees a WM_KEY* message and tries to act on it. (For example, a 3rd-party TextBox listens to the TextChanged event and calls an unrelated COM component, causing COM to pump messages.)
Granting such a request has several possible outcomes, most of them bad:
Of course, we can't know in advance if a Write request is going to change the text - we can't distinguish (2) and (3).
To avoid these problems, defer the request. If the request was synchronous we'll simply ignore it; this may lead to other problems (unknown at this time), but it's better than FailFast.
Customer Impact
Crash while using Chinese IME.
Regression
Testing
Ad-hoc around customer scenario.
Standard regression test.
Risk
Low. Port of .NETFx servicing fix released earlier this year.