From 5873a228f41bca763c35c470375a9f3cb36f80ab Mon Sep 17 00:00:00 2001 From: Andy Street Date: Wed, 15 Mar 2017 07:49:53 -0700 Subject: [PATCH] Fix crash if native code tries to update the size of a modal view after JS has removed it Summary: See https://github.com/facebook/react-native/issues/10845 onSizeChanged is enqueueing a runnable from the ui thread that references a shadow view by id on the native modules thread. Since the shadow thread 'runs ahead' of the UI thread (e.g. it has a newer state of the world than the UI thread), this isn't safe. By the time that code block runs, it's possible that an update from JS has already removed that view from the shadow hierarchy (a change which would then propagate to the native hierarchy on the UI thread). Reviewed By: AaaChiuuu Differential Revision: D4706521 fbshipit-source-id: 0915f081068709b895f70b2edce12163b39e5456 --- .../java/com/facebook/react/uimanager/UIImplementation.java | 6 ++++++ .../com/facebook/react/views/modal/ReactModalHostView.java | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java index e6499c43def..ab6e6f2aa99 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java @@ -153,6 +153,12 @@ public class UIImplementation { int newWidth, int newHeight) { ReactShadowNode cssNode = mShadowNodeRegistry.getNode(nodeViewTag); + if (cssNode == null) { + FLog.w( + ReactConstants.TAG, + "Tried to update size of non-existent tag: " + nodeViewTag); + return; + } cssNode.setStyleWidth(newWidth); cssNode.setStyleHeight(newHeight); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java index 50a00923b21..674c6ef8067 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java @@ -304,13 +304,14 @@ public class ReactModalHostView extends ViewGroup implements LifecycleEventListe protected void onSizeChanged(final int w, final int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (getChildCount() > 0) { + final int viewTag = getChildAt(0).getId(); ReactContext reactContext = (ReactContext) getContext(); reactContext.runOnNativeModulesQueueThread( new GuardedRunnable(reactContext) { @Override public void runGuarded() { ((ReactContext) getContext()).getNativeModule(UIManagerModule.class) - .updateNodeSize(getChildAt(0).getId(), w, h); + .updateNodeSize(viewTag, w, h); } }); }