redex icon indicating copy to clipboard operation
redex copied to clipboard

RenameClassesPassV2's error when handling Ldalvik/annotation/Signature;

Open fengruisd opened this issue 3 years ago • 1 comments

I am trying RenameClassesPassV2 on my app and encountered a runtime crash. The crash happened on Landroidx/lifecycle/LiveData;

Here is LiveData's source code

public abstract class LiveData<T> {
    // ...
    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
            new SafeIterableMap<>();
    // ...
} 

then there is a signature annotation for mObservers

visibility = 2: system
type_id_item[12324]: Ldalvik/annotation/Signature;
size: 1
element[0]
  name = string_id_item[47109]: value
  valueArg = 0, valueType = 0x1c: array
  size: 5
  element[0]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[6774]: "Landroidx/arch/core/internal/SafeIterableMap<"
  element[1]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[7879]: "Landroidx/lifecycle/Observer<"
  element[2]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[1907]: "-TT;>;"
  element[3]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[7812]: "Landroidx/lifecycle/LiveData<"
  element[4]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[21899]: "TT;>.ObserverWrapper;>;"

RenameClassesPassV2 rename class as below

Landroidx/lifecycle/LiveData -> LX.0CH
Landroidx/lifecycle/LiveData$ObserverWrapper -> LX.10G

rewrite_dalvik_annotation_signature rewrote annotation, but it just did a simple replacement, then the annotation item will be

visibility = 2: system
type_id_item[12324]: Ldalvik/annotation/Signature;
size: 1
element[0]
  name = string_id_item[47109]: value
  valueArg = 0, valueType = 0x1c: array
  size: 5
  element[0]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[6774]: "Landroidx/arch/core/internal/SafeIterableMap<"
  element[1]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[7879]: "Landroidx/lifecycle/Observer<"
  element[2]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[1907]: "-TT;>;"
  element[3]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[7812]: "LX/0CH<"
  element[4]
    valueArg = 1, valueType = 0x17: string
    value = string_id_item[21899]: "TT;>.ObserverWrapper;>;"

when I run the app handled by redex, the runtime crash will happen : ClassNotFoundException LX0CH$ObserverWrapper , actually the class should be LX.10G.
And I think the annotation item should be


visibility = 2: system
type_id_item[12324]: Ldalvik/annotation/Signature;
size: 1
element[0]
 ​name = string_id_item[47109]: value
 ​valueArg = 0, valueType = 0x1c: array
 ​size: 5
 ​element[0]
   ​valueArg = 1, valueType = 0x17: string
   ​value = string_id_item[6774]: "Landroidx/arch/core/internal/SafeIterableMap<"
 ​element[1]
   ​valueArg = 1, valueType = 0x17: string
   ​value = string_id_item[7879]: "Landroidx/lifecycle/Observer<"
 ​element[2]
   ​valueArg = 1, valueType = 0x17: string
   ​value = string_id_item[1907]: "-TT;>;"
 ​element[3]
   ​valueArg = 1, valueType = 0x17: string
   ​value = string_id_item[7812]: "LX/10G;"
 ​element[4]
   ​valueArg = 1, valueType = 0x17: string
   ​value = string_id_item[21899]: ">;"

fengruisd avatar Jul 09 '21 08:07 fengruisd

Hi @fengruisd,

Thanks for reporting this issue, I think your assessment is correct. The current logic to rename the contents of Signature annotations looks at each element of the encoded string array individually, so it won't discover the inner class type. Regarding the type of the renamed class, I believe it might need a type parameter added to it as well, e.g.

 ​element[0]
   ​valueArg = 1, valueType = 0x17: string
   ​value = string_id_item[6774]: "Landroidx/arch/core/internal/SafeIterableMap<"
 ​element[1]
   ​valueArg = 1, valueType = 0x17: string
   ​value = string_id_item[7879]: "Landroidx/lifecycle/Observer<"
 ​element[2]
   ​valueArg = 1, valueType = 0x17: string
   ​value = string_id_item[1907]: "-TT;>;"
 ​element[3]
   ​valueArg = 1, valueType = 0x17: string
   ​value = string_id_item[XXXX]: "LX/10G"
element[4]
  valueArg = 1, valueType = 0x17: string
  value = string_id_item[YYYY]: "<TT;>>;"

which will complicate the logic here somewhat. The renamer will need to accumulate all the parts of the type and all the type parameters separately, reconstitute the type using $s to look it up, and then put it back together with the type parameters.

I will raise it with the team to see who can help address it. Patches are also welcome!

Meanwhile, to unblock yourself, I would recommend including androidx.lifecycle in RenameClassesPassV2's dont_rename_package config:

"RenameClassesPassV2": {
  "dont_rename_packages": [
    "androidx/lifecycle/",
  ]
}

amnn avatar Jul 09 '21 09:07 amnn