From ee7f36bd6883f8c6a75672ed9b9d648e27a7751b Mon Sep 17 00:00:00 2001 From: Aditya Sharat Date: Mon, 1 Jun 2026 16:45:26 -0700 Subject: [PATCH] Fix NPE in ReactProgressBarViewManager.measure() with nullable params (#57035) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Match `ViewManager.measure()`'s Java signature (which has always accepted nullable `localData`/`props`/`state`) and the sibling `ReactSwitchManager.kt` pattern. The Kotlin migration in D49551193 (2024-07) wrongly tightened the override on `ReactProgressBarViewManager` to non-null `ReadableMap`, which threw NPE on entry whenever the C++ side passed `nullptr` for `localData` or `state` — which `AndroidProgressBarMeasurementsManager::measure` has always done. The latent bug was masked by Yoga's measure cache plus the now-removed `AndroidProgressBarMeasurementsManager` measurement cache (removed in D60192289, 2025-06). D105720159's CSS Flexbox §4.5 auto-min-size probe reliably bypasses Yoga's cache by calling `node->measure(... AtMost 0 ...)` per flex item, exposing the NPE and crashing Airwave on Android (T273821098, P2359486686). Fix: change `localData`/`props`/`state` to nullable `ReadableMap?` and use safe call on `props?.getString(...)`. This unblocks D105720159 from being re-landed. Differential Revision: D107178838 --- .../views/progressbar/ReactProgressBarViewManager.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.kt index 93b28c4a43a..17c2c94ece9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.kt @@ -100,16 +100,16 @@ internal class ReactProgressBarViewManager : override fun measure( context: Context, - localData: ReadableMap, - props: ReadableMap, - state: ReadableMap, + localData: ReadableMap?, + props: ReadableMap?, + state: ReadableMap?, width: Float, widthMode: YogaMeasureMode, height: Float, heightMode: YogaMeasureMode, attachmentsPositions: FloatArray?, ): Long { - val style = getStyleFromString(props.getString(PROP_STYLE)) + val style = getStyleFromString(props?.getString(PROP_STYLE)) val value = measuredStyles.getOrPut(style) { val progressBar = createProgressBar(context, style)