Fix FatalExecutionEngineError on insert at start of soft-wrapped line in TextBox (#11481)#11641
Open
wnvko-msft wants to merge 2 commits into
Open
Fix FatalExecutionEngineError on insert at start of soft-wrapped line in TextBox (#11481)#11641wnvko-msft wants to merge 2 commits into
wnvko-msft wants to merge 2 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses a hard process crash (FatalExecutionEngineError) in TextBoxView when inserting text at the start of a soft-wrapped continuation line in a wrapping TextBox. The fix updates incremental line measurement to re-format the entire affected wrapped paragraph (by walking back through soft-wrap predecessors), keeping _lineMetrics consistent and preventing stale offsets from corrupting subsequent layout.
Changes:
- Extend
IncrementalMeasureLinesAfterInsertto walk back over soft-wrap predecessor lines and re-format the wrapped paragraph as a unit. - Extract per-line reformatting and
_lineMetricsupdate logic into a newFormatIncrementalLinehelper and reuse it in the delete path.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Author
|
@dotnet-policy-service agree company="Microsoft" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fixes #11481
Description
A
TextBoxwithTextWrapping="Wrap"whose content includes a single long token that soft-wraps across multiple visual lines could crash the host process with aFatalExecutionEngineErrorwhen the user typed a character at the start of a soft-wrap continuation line.TextBoxView.IncrementalMeasureLinesAfterInsertonly remeasured starting at the directly inserted line, which left the preceding soft-wrapLineRecordentries pointing at stale character offsets. A subsequent measure pass read those stale records and corrupted internal state, producing the engine error.The fix walks back over preceding soft-wrap predecessors (lines whose
Length == ContentLength, i.e. lines that wrapped because text ran out of width rather than because of a hard break) before remeasuring, so the entire wrapped paragraph is re-formatted as a unit. The per-line work is extracted into a newFormatIncrementalLinehelper that updates the line record and invalidates the cached visual when the line's offset or length changed.Customer Impact
Without this fix, any WPF application that hosts a wrapping
TextBoxcontaining long unbreakable tokens (URLs, identifiers, generated strings, certain non-Latin scripts, etc.) is exposed to a hard process crash during normal text entry.FatalExecutionEngineErrorcannot be caught by user code, so the application terminates immediately with no opportunity for the user to save work.Regression
No. The defective logic in
IncrementalMeasureLinesAfterInserthas been present inTextBoxViewsince the original incremental-measure implementation; this is not introduced by a recent release.Testing
TextBoxwithTextWrapping="Wrap",Width="60",FontFamily="Segoe UI",FontSize="12", andText=" oooooooooooooooooooooooo"— place the caret at the start of the second visual line and press space.Debug|x64passes; existingPresentationFramework.Testssuite passes.PresentationFramework.Tests, xunit.stafact /[WpfFact]) provides an STA thread but does not pump aDispatcher, and the bug requires a fully realizedTextBoxView(template applied, hosted in a window, layout driven by the dispatcher) to reproduce. Attempts to drive the scenario in that host either degenerated into no-op smoke tests or hung the test runner.Risk
Low.
IncrementalMeasureLinesAfterInsert) plus a small, extracted helper (FormatIncrementalLine) inTextBoxView. No public API changes, no behavior changes for the non-soft-wrap path._lineMetricslist and terminates as soon as a non-soft-wrap predecessor is found (or the first line is reached). It cannot run beyond the current paragraph.Microsoft Reviewers: Open in CodeFlow