Commit f2a250a
fix(android): crash when setting a percentage borderRadius on Image (#57795)
Summary:
Fixes #53977
Setting a percentage border radius on `<Image>` (e.g. `borderRadius: '50%'`) crashes Android with `java.lang.String cannot be cast to java.lang.Double`. Percentage radii arrive from JS as strings, but `ReactImageManager`'s `borderRadius` `ReactPropGroup` setter was still typed as `Float`, so the reflection-based property updater (`ViewManagersPropertyCache`) failed on the cast. (The crash reproduces on any API level, not just API 35 as reported.)
This applies the same migration `ReactViewManager` received in 0.75: the setter now accepts a `Dynamic` and parses it with `LengthPercentage.setFromDynamic`, which handles both numbers and `'NN%'` strings (invalid values degrade to a warning + null instead of a crash). The old `Float` overload is kept as a deprecated pass-through so existing subclasses stay source/binary compatible, mirroring the `ReactViewManager` precedent, and the public API dump is updated accordingly.
No rendering changes are needed: the manager already delegates to `BackgroundStyleApplicator`, which resolves `PERCENT` length values against the view bounds.
Note: the same `Float`-typed setter still exists in `ReactTextViewManager`, `PreparedLayoutTextViewManager`, `ReactTextInputManager`, `ReactScrollViewManager`, and `ReactHorizontalScrollViewManager`, so `<Text>`, `<TextInput>`, and `<ScrollView>` crash the same way. I kept this PR scoped to the reported Image crash and I'm happy to follow up with the same fix for the others.
## Changelog:
[ANDROID] [FIXED] - Fix crash when setting a percentage borderRadius on Image
Pull Request resolved: #57795
Test Plan:
- Added `testBorderRadius` to `ReactImagePropertyTest`, driving the real crash path (`ViewManager.updateProperties` → reflection prop updater) with `'50%'`, a plain number, a per-corner percentage, and null, asserting the resolved `LengthPercentage` on the view. Without the fix it fails with the exact exception from the issue; with the fix the suite passes (9/9):
`./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests "com.facebook.react.views.image.ReactImagePropertyTest"`
- Added a `borderRadius: '50%'` image to rn-tester's Image → Border Radius example. Verified on a Pixel 9 Pro emulator (API 36) with rn-tester built from source: the screen that previously redboxed on mount now renders, with the percentage image drawn as a circle and the existing numeric-radius images unchanged (screenshot below).
- Re-recorded the `Image-border-radius-e2e` screenshot baselines. The new image goes inside the shared `border-radius-example` container, which is `flexDirection: 'row'` with `flexWrap: 'wrap'`, so it wraps onto a third row and the container grows taller. That is why the old baselines failed on a dimension mismatch rather than a pixel diff. Regenerated per variant with:
`jest-e2e /Image-border-radius-e2e.js -u -t '<variant>'`
for `rntester_android`, `rntester_android_rtl`, `rntester_android_nougat` and `rntester_ios`.
Each comparison was checked by hand before accepting, to confirm the new image renders as a green-bordered circle rather than a square, that the existing five images keep their positions and that under RTL the new image wraps to the right edge instead of the left. The dimensions back this up: 288 → 432 on `rntester_android` and `rntester_android_rtl`, 216 → 324 on `rntester_android_nougat`, which is exactly one extra row in each case with widths unchanged.
All deltas: https://www.internalfb.com/compare-screenshots-from-diff/D114576433
## Screenshot
<img width="372" height="786" alt="image" src="https://github.com/user-attachments/assets/fa240927-3850-4036-9f73-f9ad9f825b18" />
Reviewed By: javache
Differential Revision: D114576433
Pulled By: fabriziocucci
fbshipit-source-id: 1ed7fcd14df65d870d28b149c40d40872c5976051 parent 88feed5 commit f2a250a
4 files changed
Lines changed: 68 additions & 1 deletion
File tree
- packages
- react-native/ReactAndroid
- api
- src
- main/java/com/facebook/react/views/image
- test/java/com/facebook/react/views/image
- rn-tester/js/examples/Image
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5312 | 5312 | | |
5313 | 5313 | | |
5314 | 5314 | | |
| 5315 | + | |
5315 | 5316 | | |
5316 | 5317 | | |
5317 | 5318 | | |
| |||
Lines changed: 12 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
201 | 201 | | |
202 | 202 | | |
203 | 203 | | |
204 | | - | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
205 | 212 | | |
206 | 213 | | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
207 | 218 | | |
208 | 219 | | |
209 | 220 | | |
| |||
Lines changed: 46 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
26 | 27 | | |
| 28 | + | |
| 29 | + | |
27 | 30 | | |
28 | 31 | | |
| 32 | + | |
29 | 33 | | |
30 | 34 | | |
31 | 35 | | |
| |||
142 | 146 | | |
143 | 147 | | |
144 | 148 | | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
145 | 191 | | |
146 | 192 | | |
147 | 193 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1186 | 1186 | | |
1187 | 1187 | | |
1188 | 1188 | | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
1189 | 1194 | | |
1190 | 1195 | | |
1191 | 1196 | | |
| |||
1448 | 1453 | | |
1449 | 1454 | | |
1450 | 1455 | | |
| 1456 | + | |
| 1457 | + | |
| 1458 | + | |
| 1459 | + | |
1451 | 1460 | | |
1452 | 1461 | | |
1453 | 1462 | | |
| |||
0 commit comments