chore(rn-tester): add Playground reproducer for Android Fabric shared TextPaint typeface leak - #58783
pangziqiang wants to merge 1 commit into
Conversation
… TextPaint typeface leak
|
Hi @pangziqiang! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
|
信件已经收到。
|
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
Summary
Adds an RNTester Playground reproducer for #57950.
On Android with the new architecture, Fabric measures every
<Text>with one shared, thread-localTextPaint. For text without an explicit font family/weight/style,TextLayoutManager.updateTextPaint()restores the default with
paint.reset(); paint.setTypeface(null). On some OEM ROMs that does notrestore the typeface —
Paint.reset()keeps the resolved font and the followingPaint.setTypeface(null)is a no-op — so the paint keeps the last typeface that was set explicitly,and every following plain
<Text>is measured with it whileReactTextViewrenders with the realsystem font. Line boxes come out ~24% too short and descenders / trailing glyphs are clipped.
Changelog:
How the reproducer works
No bundled font asset is needed: any explicit font family poisons the shared paint. The screen uses
the framework alias
casual(Dancing Script, present since API 21) because its vertical metrics arefar from the default font's on every Android version, so the rows are trivially distinguishable:
<Text style={{fontSize: 48, fontFamily: 'casual'}}><Text style={{fontSize: 48}}>— different strings from R1R2/R3 must use different strings: RN caches text layouts per attributed string, and an identical
string silently reuses R1's layout (our first attempt had exactly this false negative).
Verdict: R2/R3 == R1 → leaked (reproduced); R2/R3 == default-font metrics → not affected.
Test Plan
Open the Playground example in RNTester and compare the metrics printed under the three rows.
onTextLayoutmetrics at fontSize 48, in px (ascender / descender / height):Fix: #58036.