Fix NullReferenceException in TextLeadingPrefixCharacterEllipsis when collapsing an unbreakable cluster#21371
Fix NullReferenceException in TextLeadingPrefixCharacterEllipsis when collapsing an unbreakable cluster#21371Symbai wants to merge 1 commit into
Conversation
|
You can test this PR using the following package version. |
Gillibald
left a comment
There was a problem hiding this comment.
There is no matching unit test that covers the failing scenario. Please add a unit test.
|
@Gillibald reproducing this branch end-to-end requires a font that produces multi-character clusters (e.g. Thai combining marks). The only such font in the test assets is the monospace Cascadia Code, and with a monospace font the widths required to reach this branch are mutually exclusive, it would need a proportional cluster-capable font, which the test project does not ship. |
Feel free to add any font needed to the test project (as long as the license allows it). |
What does the pull request do?
Fixes a latent
NullReferenceExceptioninTextLeadingPrefixCharacterEllipsis.Collapse(thePrefixCharacterEllipsistext-trimming mode). When the suffix portion of a collapsed line ends in an unbreakable cluster, a ligature, or a base character with combining marks, shaped as a single glyph cluster, the code dereferences anullsplit result and crashes.What is the current behavior?
While building the trailing suffix of an ellipsized line,
CollapsecallsendShapedRun.Split(run.Length - suffixCount)and unconditionally usessplitSuffix.Second!:Since #21351,
ShapedTextRun.Splitreturns(first, null)- rather than throwing - when the requested split position falls inside an unbreakable cluster that reaches the end of the run. In that casesplitSuffix.Secondisnull, andsplitSuffix.Second!throws aNullReferenceException, crashing layout/rendering.What is the updated/expected behavior with this PR?
When the suffix run cannot be split because it is a single unbreakable cluster, the whole run is kept as the suffix instead of crashing, which is the correct outcome, since an indivisible cluster is an all-or-nothing unit:
To test: apply
TextTrimming.PrefixCharacterEllipsisto text whose trailing portion is a single unbreakable cluster, in a width that forces collapsing. Before this PR it crashes; after it, the line collapses normally with the cluster preserved as the suffix.How was the solution implemented (if it's not obvious)?
The fix is a single defensive null-coalesce.
ShapedTextRun.Splitalways returns a non-nullFirst(the whole run when no further split is possible), so falling back tosplitSuffix.Firstis safe and complete. This mirrors the pattern already used byTextFormatterImpl.SplitTextRuns, which null-checkssplit.Secondbefore consuming it.No unit test is included: reproducing this branch end-to-end requires a font that produces multi-character clusters (e.g. Thai combining marks). The only such font in the test assets is the monospace Cascadia Code, and with a monospace font the widths required to reach this branch are mutually exclusive, it would need a proportional cluster-capable font, which the test project does not ship.
Checklist
Breaking changes
None.
Obsoletions / Deprecations
None.