From 291f79948e4b2e904a091972811fa00c0bbc60c2 Mon Sep 17 00:00:00 2001 From: Stas Veretennikov Date: Thu, 27 Apr 2023 17:13:05 -0700 Subject: [PATCH] Make createConstantsForViewManager work correctly with read-only maps (#37132) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37132 Changelog: [Internal] The root cause was that one of the custom view managers was returning a read-only map for getExportedCustomDirectEventTypeConstants. React Native merges these maps between view managers, so if the view managers were initialized in a particular order, it will try to merge events into the read-only map and silently crashes. Reviewed By: rshest Differential Revision: D45370622 fbshipit-source-id: 7b4b4de372844835d60f81b6700438f56a6b9302 --- .../react/uimanager/UIManagerModuleConstantsHelper.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java index a570c7acdf0..cd10e3a76d0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java @@ -15,6 +15,7 @@ import com.facebook.react.common.MapBuilder; import com.facebook.react.config.ReactFeatureFlags; import com.facebook.systrace.SystraceMessage; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -187,6 +188,11 @@ import java.util.Set; Object sourceValue = source.get(key); Object destValue = dest.get(key); if (destValue != null && (sourceValue instanceof Map) && (destValue instanceof Map)) { + // Since event maps are client based Map interface, it could be immutable + if (!(destValue instanceof HashMap)) { + destValue = new HashMap((Map) destValue); + dest.replace(key, (Map) destValue); + } recursiveMerge((Map) destValue, (Map) sourceValue); } else { dest.put(key, sourceValue);