mirror of
https://github.com/react/react-native.git
synced 2026-09-28 13:23:09 +08:00
Fix TalkBack crash in ReactScrollViewAccessibilityDelegate when a list child has no accessibilityCollectionItem (#58660)
Summary:
With TalkBack on, a `ScrollView` that has `accessibilityCollection` set crashes the app as soon as any direct child of its content view lacks `accessibilityCollectionItem` — e.g. a FlatList `ListHeaderComponent` or `ListFooterComponent`. It reproduces on a common path: a screen reader user navigating away from a list screen. In release builds there is no red box; the process just dies.
```
java.lang.NullPointerException: null cannot be cast to non-null type com.facebook.react.bridge.ReadableMap
at ReactScrollViewAccessibilityDelegate.onInitializeAccessibilityEventInternal(ReactScrollViewAccessibilityDelegate.kt:74)
...
at android.view.View.clearAccessibilityFocus(View.java:15215)
at android.view.ViewGroup.removeViewInternal(ViewGroup.java:5611)
at com.facebook.react.fabric.mounting.SurfaceMountingManager.removeViewAt(SurfaceMountingManager.kt:493)
```
The cause is a non-null cast on a value the code expects to be null:
```kotlin
var accessibilityCollectionItem: ReadableMap? =
nextChild.getTag(R.id.accessibility_collection_item) as ReadableMap // throws on null
...
// If this child's accessibilityCollectionItem is null, we'll check one more nested child.
if (nextChild.childCount > 0 && accessibilityCollectionItem == null) {
```
The variable is declared nullable and the null branch right below it was written for exactly this case, but the `as` cast throws before that branch can run. This PR changes it to `as?`, matching the other tag reads in the same file. No behavior change for children that do carry the tag.
It has gone unnoticed because no React Native component sets `accessibilityCollection` itself (it was added in 105a2397b6 for https://github.com/react/react-native/issues/30977), so the early return at the top of the method skips this code for core lists. Any library that sets it to announce a windowed list's real length hits the crash immediately. Observed on 0.87.1 (API 36, new architecture, Hermes); details in https://github.com/iray-tno/hozo/issues/512.
## Changelog:
[ANDROID] [FIXED] - Fix crash in ScrollView accessibility delegate when `accessibilityCollection` is set and a child (e.g. a list header or footer) has no `accessibilityCollectionItem`
Pull Request resolved: https://github.com/react/react-native/pull/58660
Test Plan:
- One-token change (`as` → `as?`); the assigned variable is already `ReadableMap?` and all later uses are null-checked, so types are unchanged.
- Not built or tested locally: the environment had no Android SDK. Relying on CI for the Android build.
- Repro (before this change): Android + TalkBack, a `FlatList` with `ListHeaderComponent`, `accessibilityCollection` on the list and `accessibilityCollectionItem` on cells only; put accessibility focus inside the list and unmount the screen → crash above. Expected after: no crash.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed By: Abbondanzo
Differential Revision: D121556760
Pulled By: cortinico
fbshipit-source-id: ccbfe470dc53adec3deac3458b83ae2bc08a48cb
This commit is contained in:
committed by
meta-codesync[bot]
parent
9fae71c2dd
commit
2915fe02ca
+1
-1
@@ -71,7 +71,7 @@ internal class ReactScrollViewAccessibilityDelegate : AccessibilityDelegateCompa
|
||||
return
|
||||
}
|
||||
var accessibilityCollectionItem: ReadableMap? =
|
||||
nextChild.getTag(R.id.accessibility_collection_item) as ReadableMap
|
||||
nextChild.getTag(R.id.accessibility_collection_item) as? ReadableMap
|
||||
|
||||
if (nextChild !is ViewGroup) {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user