From 84e05008ae61346abc52a0d9b37de85ec7c78d86 Mon Sep 17 00:00:00 2001 From: Ryan Kurtz Date: Mon, 10 Feb 2025 08:18:21 -0500 Subject: [PATCH] GP-5348: Fixed a PyGhidra issue that prevented accessing Java getters/setters as properties on non-public classes (Closes #7450) --- .../pyghidra/property/PropertyUtils.java | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/Ghidra/Features/PyGhidra/src/main/java/ghidra/pyghidra/property/PropertyUtils.java b/Ghidra/Features/PyGhidra/src/main/java/ghidra/pyghidra/property/PropertyUtils.java index 13e3a86ee3..536d4438ff 100644 --- a/Ghidra/Features/PyGhidra/src/main/java/ghidra/pyghidra/property/PropertyUtils.java +++ b/Ghidra/Features/PyGhidra/src/main/java/ghidra/pyghidra/property/PropertyUtils.java @@ -20,9 +20,7 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -126,10 +124,26 @@ public class PropertyUtils { } private static Stream getMethods(Class cls) { - // customizations added using JClass._customize are inherited - // therfore we only care about the ones declared by this class - return Arrays.stream(cls.getDeclaredMethods()) + if (isPublic(cls)) { + return Arrays.stream(cls.getMethods()); + } + Class base = cls; + while (!isPublic(base)) { + base = base.getSuperclass(); + } + Stream head = Arrays.stream(base.getMethods()) .filter(PropertyUtils::methodFilter); + Stream tail = Stream.concat( + Arrays.stream(base.getInterfaces()), + Arrays.stream(cls.getInterfaces())) + .sorted(Comparator.comparing(Class::getSimpleName)) + .distinct() + .map(Class::getDeclaredMethods) + .flatMap(Arrays::stream) + .filter(PropertyUtils::methodFilter); + return Stream.concat(head, tail) + .sorted(Comparator.comparing(Method::toGenericString)) + .distinct(); } private static boolean methodFilter(Method m) { @@ -192,6 +206,10 @@ public class PropertyUtils { } } + private static boolean isPublic(Class cls) { + return Modifier.isPublic(cls.getModifiers()); + } + private static boolean isPublic(Method m) { int mod = m.getModifiers(); return Modifier.isPublic(mod) && !Modifier.isStatic(mod);