redex icon indicating copy to clipboard operation
redex copied to clipboard

AnnoKillPass: crash on Gson

Open bill-lia opened this issue 3 years ago • 1 comments

my code as below

public class PublishExtensionModel {
    @SerializedName("ss")
    LiveData<String> ss = new MutableLiveData<>();
}
PublishExtensionModel model = new PublishExtensionModel();
String s = new Gson().toJson(model);

my redex.config as below:

  "AnnoKillPass" : {
    "force_kill_annos" : [
      "Ldalvik/annotation/EnclosingClass;",
      "Ldalvik/annotation/EnclosingMethod;",
      "Ldalvik/annotation/InnerClass;",
      "Ldalvik/annotation/MemberClasses;",
      "Ldalvik/annotation/Throws;"
    ]
  }

and then 100% crash

java.lang.AssertionError: illegal type variable reference
        at libcore.reflect.TypeVariableImpl.resolve(TypeVariableImpl.java:111)
        at libcore.reflect.TypeVariableImpl.getGenericDeclaration(TypeVariableImpl.java:125)
        at libcore.reflect.TypeVariableImpl.hashCode(TypeVariableImpl.java:47)
        at java.util.HashMap.hash(HashMap.java:338)
        at java.util.HashMap.containsKey(HashMap.java:595)
        at java.util.HashSet.contains(HashSet.java:203)
        at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:346)
        at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381)
        at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:337)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:160)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.Gson.toJson(Gson.java:696)
        at com.google.gson.Gson.toJson(Gson.java:683)
        at com.google.gson.Gson.toJson(Gson.java:638)
        at com.google.gson.Gson.toJson(Gson.java:618)
        at com.xxx.redexplugin.demo.gson.PublishExtensionModel.toString(PublishExtensionModel.java:15)

we analysed and found Gson may use some system annotations. so we cann't remove "Ldalvik/annotation/EnclosingClass;"

    private static GenericDeclaration nextLayer(GenericDeclaration decl) {
        if (decl instanceof Class) {
            // FIXME: Is the following hierarchy correct?:
            Class cl = (Class)decl;
            Method m = cl.getEnclosingMethod();
            decl = (GenericDeclaration) m != null ? m : cl.getEnclosingConstructor();
            if (decl != null) {
                return decl;
            }
            return cl.getEnclosingClass();
        } else if (decl instanceof Method) {
            return ((Method)decl).getDeclaringClass();
        } else if (decl instanceof Constructor) {
            return ((Constructor)decl).getDeclaringClass();
        } else {
            throw new AssertionError();
        }
    }

but as we all know, facebook only keep "Ldalvik/annotation/AnnotationDefault;" and "Ldalvik/annotation/Signature;" so how should we do when face those case?

bill-lia avatar Jun 22 '21 07:06 bill-lia

Hi, the provided Redex configs are given as examples. It's not guaranteed that they will work perfectly with any input. As a potential fix, there are other options on the pass that you can use to selectively keep system annotations. https://github.com/facebook/redex/blob/2a53d58274bf787bfb0cdf4279950580d4048cf9/opt/annokill/AnnoKill.h#L100

thezhangwei avatar Jun 23 '21 00:06 thezhangwei