From 9d74728dfe5ffbe86d71aec5fb883621fb5c1265 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Wed, 10 Nov 2021 04:33:12 -0800 Subject: [PATCH] Harden reflection Summary: Changelog: Fix theme reflection logging lot of errors if the APIs aren't accessible, see #1736 Harden theme reflection based on the comments in https://github.com/facebook/flipper/issues/1736 Reviewed By: jknoxville Differential Revision: D32202434 fbshipit-source-id: 99178df56c91715f9eff1e4764ebc55b29ecb6f3 --- .../utils/ContextDescriptorUtils.java | 66 ++++++++++++++----- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/utils/ContextDescriptorUtils.java b/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/utils/ContextDescriptorUtils.java index 7d6a32063..c4e990aa1 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/utils/ContextDescriptorUtils.java +++ b/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/utils/ContextDescriptorUtils.java @@ -21,6 +21,7 @@ import java.util.Map; public final class ContextDescriptorUtils { private static String TAG = "ContextDescriptor"; + private static boolean doneFieldDiscovery = false; private static Field sThemeImplField; private static Field sThemeImplThemeKeyField; private static Field sThemeImplAssetManagerField; @@ -47,30 +48,61 @@ public final class ContextDescriptorUtils { final Object themeKey; // Nasty reflection to get a list of theme attributes that apply to this context. - if (sThemeImplField == null - || sThemeImplThemeKeyField == null - || sThemeKeyResIdField == null - || sThemeImplAssetManagerField == null) { - sThemeImplField = theme.getClass().getDeclaredField("mThemeImpl"); - sThemeImplField.setAccessible(true); + if (!doneFieldDiscovery) { + doneFieldDiscovery = true; // even if it fails, we don't want to retry + try { + sThemeImplField = theme.getClass().getDeclaredField("mThemeImpl"); + sThemeImplField.setAccessible(true); + } catch (NoSuchFieldException e) { + // hardening against #1736 + return builderMap; + } themeImpl = sThemeImplField.get(theme); - sThemeImplThemeKeyField = themeImpl.getClass().getDeclaredField("mKey"); - sThemeImplThemeKeyField.setAccessible(true); + try { + sThemeImplThemeKeyField = themeImpl.getClass().getDeclaredField("mKey"); + sThemeImplThemeKeyField.setAccessible(true); + } catch (NoSuchFieldException e) { + // hardening against #1736 + return builderMap; + } - sThemeImplAssetManagerField = themeImpl.getClass().getDeclaredField("mAssets"); - sThemeImplAssetManagerField.setAccessible(true); + try { + sThemeImplAssetManagerField = themeImpl.getClass().getDeclaredField("mAssets"); + sThemeImplAssetManagerField.setAccessible(true); + } catch (NoSuchFieldException e) { + // hardening against #1736 + return builderMap; + } - sAssetManagerGetStyleAttributesMethod = - assetManager.getClass().getDeclaredMethod("getStyleAttributes", int.class); - sAssetManagerGetStyleAttributesMethod.setAccessible(true); + try { + sAssetManagerGetStyleAttributesMethod = + assetManager.getClass().getDeclaredMethod("getStyleAttributes", int.class); + sAssetManagerGetStyleAttributesMethod.setAccessible(true); + } catch (NoSuchMethodException e) { + // hardening against #1736 + return builderMap; + } themeKey = sThemeImplThemeKeyField.get(themeImpl); - sThemeKeyResIdField = themeKey.getClass().getDeclaredField("mResId"); - sThemeKeyResIdField.setAccessible(true); + try { + sThemeKeyResIdField = themeKey.getClass().getDeclaredField("mResId"); + sThemeKeyResIdField.setAccessible(true); + } catch (NoSuchFieldException e) { + // hardening against #1736 + return builderMap; + } + } else if (sThemeImplField != null && sThemeImplThemeKeyField != null) { + themeImpl = sThemeImplField.get(theme); + themeKey = sThemeImplThemeKeyField.get(themeImpl); } else { - themeImpl = sThemeImplField.get(theme); - themeKey = sThemeImplThemeKeyField.get(themeImpl); + themeKey = null; + } + + if (sThemeKeyResIdField == null + || sAssetManagerGetStyleAttributesMethod == null + || themeKey == null) { + return builderMap; } int[] appliedThemeResIds = (int[]) sThemeKeyResIdField.get(themeKey);