Skip to content

fix: erroneous SignatureProcessor resolution of standard non-generic …#2460

Merged
skylot merged 2 commits intoskylot:masterfrom
nerodesu017:nero/fix-signature-processor
Apr 14, 2025
Merged

fix: erroneous SignatureProcessor resolution of standard non-generic …#2460
skylot merged 2 commits intoskylot:masterfrom
nerodesu017:nero/fix-signature-processor

Conversation

@nerodesu017
Copy link
Copy Markdown
Contributor

@nerodesu017 nerodesu017 commented Apr 13, 2025

…types with Annotation Signatures

Description

This PR aims to fix the issue where SignatureProcessor would erroneously resolve the types of fields whose main type is not a standard generic but which also have a Signature Annotation.

Related to #2459

"java.lang.Float",
};
for (String genericType : stdNonGenericTypes) {
if (genericType.equals(ty)) {
Copy link
Copy Markdown
Collaborator

@jpstotz jpstotz Apr 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this equals check works? genericType is a java.lang.String and ty is an ArgType, thus this if expression can never get true.

Also why does the array contains primitive types? At the beginning of the method there is also the isPrimitive() check thus if it is a primitive this code should never be executed.

Copy link
Copy Markdown
Contributor Author

@nerodesu017 nerodesu017 Apr 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.equals does work, it casts it to String automatically, but I will explicitly call .toString just so it is clear.

Well, the type can still be a primitive, but in case of primitives, even with annotations, they don't get erroneously resolved, so I just have a check at the beginning and I return false

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have also modified the test so that our smali file also contains a field with a primitive type to showcase primitives are not an issue and should be skipped.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have re-read your comment and want to clarify why we have the isPrimitive() check at the start and we also check for "primitive" types.

If in our smali file the fields have primitive types but that are expressed using the fully qualified class name (using the L prefix), they are not resolved to be Primitive ArgType's, so we still have to check for them.

Example:

.field public static L:Lint;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You were more than right. I am sorry, but I suck at java. I have managed to solve the issues, re-run the tests locally, and now it should be fine.

@nerodesu017 nerodesu017 force-pushed the nero/fix-signature-processor branch 3 times, most recently from b540c58 to 3111084 Compare April 13, 2025 16:24
@nerodesu017 nerodesu017 force-pushed the nero/fix-signature-processor branch from 3111084 to f6a92fa Compare April 13, 2025 17:05
@nerodesu017 nerodesu017 requested a review from jpstotz April 13, 2025 17:10
@skylot
Copy link
Copy Markdown
Owner

skylot commented Apr 13, 2025

@nerodesu017 please check my view on the original issue in my comment: #2459 (comment)

As a result, I think jadx now correctly process types, but confusing class names clash with primitive type names should be fixed in RenameVisitor in checkNames method:

private static void checkNames(RootNode root) {

@nerodesu017
Copy link
Copy Markdown
Contributor Author

@nerodesu017 please check my view on the original issue in my comment: #2459 (comment)

As a result, I think jadx now correctly process types, but confusing class names clash with primitive type names should be fixed in RenameVisitor in checkNames method:

private static void checkNames(RootNode root) {

I am sorry, but I am not at all familiar with the codebase, as I've said above, nor am I that knowledgeable about Java. I wanted to thank both of you for helping me out, and I have read your comment which made it a bit more clear for me. Using L makes it so it is an actual class name following it.
Now, I wanted to ask: you've suggested I modify the checkNames method from RenameVisitor, but it seems that that runs way after the SignatureProcessor. I was thinking: Maybe I should modify the parsing of the annotation ArgType and throw an error in case of an invalid identifier name given as the class name?

@skylot
Copy link
Copy Markdown
Owner

skylot commented Apr 13, 2025

Maybe I should modify the parsing of the annotation ArgType and throw an error in case of an invalid identifier name given as the class name?

Any identifier is valid in bytecode, because VM don't check names at runtime. And jadx only rename such identifiers and only if options are not forbid this.
Also, right now, jadx renames only known classes (found in app) and that's why types in your examples types not renamed. Main issue here is that renaming unknown or outside classes may break references, and this become unclear what we need to do for such cases.
I checked and jadx will rename such classes if they are known, so looks like there is nothing to do.
As a result, I have no idea how to correctly handle such cases, maybe we can just add a warning.
I will try to find a solution, any suggestions are welcome.

Anyway, further discussion is better to continue in original issue and I will close current PR as it not needed anymore.

@skylot skylot closed this Apr 13, 2025
@skylot skylot reopened this Apr 14, 2025
@skylot skylot merged commit d3a8a43 into skylot:master Apr 14, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants