From e966e132e680ad2593aaddac191ec74120918ea5 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Mon, 16 Sep 2024 04:35:15 -0700 Subject: [PATCH] fix race condition in IntentModule.mInitialURLListener (#46499) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46499 changelog: [internal] IntentModule.mInitialURLListener is accessed and mutated on three different threads and is missing synchronisation. 1. In [waitForActivityAndGetInitialURL](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java#L83) it is accessed and mutated from thread mqt_v_native. 2. In [LifecycleEventListener](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java#L97) it is mutated from the main thread. 3. In [invalidate](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java#L44) it is read and mutated on a another thread. Reviewed By: javache Differential Revision: D62698183 --- .../react/modules/intent/IntentModule.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java index f3efa6cd0fc3..1e285b2c6f17 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java @@ -39,9 +39,11 @@ public IntentModule(ReactApplicationContext reactContext) { @Override public void invalidate() { - if (mInitialURLListener != null) { - getReactApplicationContext().removeLifecycleEventListener(mInitialURLListener); - mInitialURLListener = null; + synchronized (this) { + if (mInitialURLListener != null) { + getReactApplicationContext().removeLifecycleEventListener(mInitialURLListener); + mInitialURLListener = null; + } } super.invalidate(); } @@ -79,7 +81,7 @@ public void getInitialURL(Promise promise) { } } - private void waitForActivityAndGetInitialURL(final Promise promise) { + private synchronized void waitForActivityAndGetInitialURL(final Promise promise) { if (mInitialURLListener != null) { promise.reject( new IllegalStateException( @@ -94,7 +96,9 @@ public void onHostResume() { getInitialURL(promise); getReactApplicationContext().removeLifecycleEventListener(this); - mInitialURLListener = null; + synchronized (IntentModule.this) { + mInitialURLListener = null; + } } @Override