From 00028fb5a7f3fc9b72d77b2d028a58e3155dadec Mon Sep 17 00:00:00 2001
From: Marcono1234 <Marcono1234@users.noreply.github.com>
Date: Wed, 19 Jun 2024 01:02:29 +0200
Subject: [PATCH] Remove `AccessController` usage for enum adapter (#2704)

* Remove `AccessController` usage for enum adapter

SecurityManager and AccessController are marked as deprecated for removal
in the latest JDK versions, see https://openjdk.org/jeps/411.
Additionally this code was originally added providently but it is not clear
if or how many users actually depend on it.

* Add test using JDK enum class
---
 .../gson/internal/bind/TypeAdapters.java      | 34 ++++++-------------
 .../com/google/gson/functional/EnumTest.java  | 11 ++++++
 2 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
index 53803bea32..75177a2134 100644
--- a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
+++ b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
@@ -43,8 +43,6 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.BitSet;
@@ -962,27 +960,17 @@ public EnumTypeAdapter(final Class<T> classOfT) {
       try {
         // Uses reflection to find enum constants to work around name mismatches for obfuscated
         // classes
-        // Reflection access might throw SecurityException, therefore run this in privileged
-        // context; should be acceptable because this only retrieves enum constants, but does not
-        // expose anything else
-        Field[] constantFields =
-            AccessController.doPrivileged(
-                new PrivilegedAction<Field[]>() {
-                  @Override
-                  public Field[] run() {
-                    Field[] fields = classOfT.getDeclaredFields();
-                    ArrayList<Field> constantFieldsList = new ArrayList<>(fields.length);
-                    for (Field f : fields) {
-                      if (f.isEnumConstant()) {
-                        constantFieldsList.add(f);
-                      }
-                    }
-
-                    Field[] constantFields = constantFieldsList.toArray(new Field[0]);
-                    AccessibleObject.setAccessible(constantFields, true);
-                    return constantFields;
-                  }
-                });
+        Field[] fields = classOfT.getDeclaredFields();
+        ArrayList<Field> constantFieldsList = new ArrayList<>(fields.length);
+        for (Field f : fields) {
+          if (f.isEnumConstant()) {
+            constantFieldsList.add(f);
+          }
+        }
+
+        Field[] constantFields = constantFieldsList.toArray(new Field[0]);
+        AccessibleObject.setAccessible(constantFields, true);
+
         for (Field constantField : constantFields) {
           @SuppressWarnings("unchecked")
           T constant = (T) constantField.get(null);
diff --git a/gson/src/test/java/com/google/gson/functional/EnumTest.java b/gson/src/test/java/com/google/gson/functional/EnumTest.java
index 835fb5086b..990a6463e8 100644
--- a/gson/src/test/java/com/google/gson/functional/EnumTest.java
+++ b/gson/src/test/java/com/google/gson/functional/EnumTest.java
@@ -308,4 +308,15 @@ public String toString() {
       return toString;
     }
   }
+
+  /**
+   * Verifies that the enum adapter works for a public JDK enum class and no {@code
+   * InaccessibleObjectException} is thrown, despite using reflection internally to account for the
+   * constant names possibly being obfuscated.
+   */
+  @Test
+  public void testJdkEnum() {
+    assertThat(gson.toJson(Thread.State.NEW)).isEqualTo("\"NEW\"");
+    assertThat(gson.fromJson("\"NEW\"", Thread.State.class)).isEqualTo(Thread.State.NEW);
+  }
 }