Skip to content

Commit

Permalink
Merge pull request #1495 from ganadist/master
Browse files Browse the repository at this point in the history
Make EnumTypeAdapter friendly with obfuscation
  • Loading branch information
eamonnmcmanus authored Aug 4, 2021
2 parents 63e747f + d8c5fcf commit 25f47f8
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 3 deletions.
87 changes: 87 additions & 0 deletions gson/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -69,6 +75,87 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.coderplus.maven.plugins</groupId>
<artifactId>copy-rename-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>pre-obfuscate-class</id>
<phase>process-test-classes</phase>
<goals>
<goal>rename</goal>
</goals>
<configuration>
<fileSets>
<fileSet>
<sourceFile>${project.build.directory}/test-classes/com/google/gson/functional/EnumWithObfuscatedTest.class</sourceFile>
<destinationFile>${project.build.directory}/test-classes-obfuscated-injar/com/google/gson/functional/EnumWithObfuscatedTest.class</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/test-classes/com/google/gson/functional/EnumWithObfuscatedTest$Gender.class</sourceFile>
<destinationFile>${project.build.directory}/test-classes-obfuscated-injar/com/google/gson/functional/EnumWithObfuscatedTest$Gender.class</destinationFile>
</fileSet>
</fileSets>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<executions>
<execution>
<phase>process-test-classes</phase>
<goals><goal>proguard</goal></goals>
</execution>
</executions>
<configuration>
<proguardVersion>6.2.2</proguardVersion>
<obfuscate>true</obfuscate>
<injar>test-classes-obfuscated-injar</injar>
<outjar>test-classes-obfuscated-outjar</outjar>
<inFilter>**/*.class</inFilter>
<proguardInclude>${basedir}/src/test/resources/testcases-proguard.conf</proguardInclude>
<libs>
<lib>${project.build.directory}/classes</lib>
<lib>${java.home}/jmods/java.base.jmod</lib>
</libs>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>6.2.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>post-obfuscate-class</id>
<phase>process-test-classes</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/test-classes/com/google/gson/functional</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/test-classes-obfuscated-outjar/com/google/gson/functional</directory>
<includes>
<include>EnumWithObfuscatedTest.class</include>
<include>EnumWithObfuscatedTest$Gender.class</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
20 changes: 17 additions & 3 deletions gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
package com.google.gson.internal.bind;

import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.BitSet;
Expand Down Expand Up @@ -776,9 +779,20 @@ private static final class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapte

public EnumTypeAdapter(Class<T> classOfT) {
try {
for (T constant : classOfT.getEnumConstants()) {
for (final Field field : classOfT.getDeclaredFields()) {
if (!field.isEnumConstant()) {
continue;
}
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override public Void run() {
field.setAccessible(true);
return null;
}
});
@SuppressWarnings("unchecked")
T constant = (T)(field.get(null));
String name = constant.name();
SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class);
SerializedName annotation = field.getAnnotation(SerializedName.class);
if (annotation != null) {
name = annotation.value();
for (String alternate : annotation.alternate()) {
Expand All @@ -788,7 +802,7 @@ public EnumTypeAdapter(Class<T> classOfT) {
nameToConstant.put(name, constant);
constantToName.put(constant, name);
}
} catch (NoSuchFieldException e) {
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.gson.functional;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;

import junit.framework.TestCase;

/**
* Functional tests for enums with Proguard.
*
* @author Young Cha
*/
public class EnumWithObfuscatedTest extends TestCase {
private Gson gson;

@Override
protected void setUp() throws Exception {
super.setUp();
gson = new Gson();
}

public enum Gender {
@SerializedName("MAIL")
MALE,

@SerializedName("FEMAIL")
FEMALE
}

public void testEnumClassWithObfuscated() {
for (Gender enumConstant: Gender.class.getEnumConstants()) {
try {
Gender.class.getField(enumConstant.name());
fail("Enum is not obfuscated");
} catch (NoSuchFieldException ignore) {
}
}

assertEquals(Gender.MALE, gson.fromJson("\"MAIL\"", Gender.class));
assertEquals("\"MAIL\"", gson.toJson(Gender.MALE, Gender.class));
}
}
20 changes: 20 additions & 0 deletions gson/src/test/resources/testcases-proguard.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Options from Android Gradle Plugins
# https://android.googlesource.com/platform/tools/base/+/refs/heads/studio-master-dev/build-system/gradle-core/src/main/resources/com/android/build/gradle
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
-optimizationpasses 5
-allowaccessmodification
-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep enum com.google.gson.functional.EnumWithObfuscatedTest$Gender
-keep class com.google.gson.functional.EnumWithObfuscatedTest {
public void test*();
protected void setUp();
}

-dontwarn com.google.gson.functional.EnumWithObfuscatedTest
-dontwarn junit.framework.TestCase

0 comments on commit 25f47f8

Please sign in to comment.