Skip to content

Commit

Permalink
Remove AccessController usage for enum adapter (#2704)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Marcono1234 authored Jun 18, 2024
1 parent d4d6744 commit 00028fb
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 23 deletions.
34 changes: 11 additions & 23 deletions gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions gson/src/test/java/com/google/gson/functional/EnumTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit 00028fb

Please sign in to comment.