-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Fix visibility access modifies for methods (see discussions in #370 and #387): * all virtual methods become public * direct methods become private (instead constructors and static methods for now) * such modifications perform by default and can be disabled by the option in preferences (`--respect-bytecode-access-modifiers` in jadx-cli) * if changed to method added comment (`Access modifiers changed, original: private`)
- Loading branch information
Showing
18 changed files
with
324 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
jadx-core/src/main/java/jadx/core/dex/visitors/FixAccessModifiers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package jadx.core.dex.visitors; | ||
|
||
import com.android.dx.rop.code.AccessFlags; | ||
|
||
import jadx.core.dex.attributes.AType; | ||
import jadx.core.dex.info.AccessInfo; | ||
import jadx.core.dex.nodes.MethodNode; | ||
import jadx.core.dex.nodes.RootNode; | ||
|
||
@JadxVisitor( | ||
name = "FixAccessModifiers", | ||
desc = "Change class and method access modifiers if needed", | ||
runAfter = ModVisitor.class | ||
) | ||
public class FixAccessModifiers extends AbstractVisitor { | ||
|
||
private boolean respectAccessModifiers; | ||
|
||
@Override | ||
public void init(RootNode root) { | ||
this.respectAccessModifiers = root.getArgs().isRespectBytecodeAccModifiers(); | ||
} | ||
|
||
@Override | ||
public void visit(MethodNode mth) { | ||
if (respectAccessModifiers) { | ||
return; | ||
} | ||
AccessInfo accessFlags = mth.getAccessFlags(); | ||
int newVisFlag = fixVisibility(mth, accessFlags); | ||
if (newVisFlag != 0) { | ||
AccessInfo newAccFlags = accessFlags.changeVisibility(newVisFlag); | ||
if (newAccFlags != accessFlags) { | ||
mth.setAccFlags(newAccFlags); | ||
mth.addAttr(AType.COMMENTS, "Access modifiers changed, original: " + accessFlags.rawString()); | ||
} | ||
} | ||
} | ||
|
||
private int fixVisibility(MethodNode mth, AccessInfo accessFlags) { | ||
if (mth.isVirtual()) { | ||
// make virtual methods public | ||
return AccessFlags.ACC_PUBLIC; | ||
} else { | ||
if (accessFlags.isAbstract()) { | ||
// make abstract methods public | ||
return AccessFlags.ACC_PUBLIC; | ||
} | ||
if (accessFlags.isConstructor() || accessFlags.isStatic()) { | ||
// TODO: make public if used outside | ||
return 0; | ||
} | ||
// make other direct methods private | ||
return AccessFlags.ACC_PRIVATE; | ||
} | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
jadx-core/src/test/java/jadx/core/dex/info/AccessInfoTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package jadx.core.dex.info; | ||
|
||
import com.android.dx.rop.code.AccessFlags; | ||
import org.junit.Test; | ||
|
||
import jadx.core.dex.info.AccessInfo.AFType; | ||
|
||
import static org.hamcrest.Matchers.is; | ||
import static org.junit.Assert.assertSame; | ||
import static org.junit.Assert.assertThat; | ||
|
||
public class AccessInfoTest { | ||
|
||
@Test | ||
public void changeVisibility() { | ||
AccessInfo accessInfo = new AccessInfo(AccessFlags.ACC_PROTECTED | AccessFlags.ACC_STATIC, AFType.METHOD); | ||
AccessInfo result = accessInfo.changeVisibility(AccessFlags.ACC_PUBLIC); | ||
|
||
assertThat(result.isPublic(), is(true)); | ||
assertThat(result.isPrivate(), is(false)); | ||
assertThat(result.isProtected(), is(false)); | ||
|
||
assertThat(result.isStatic(), is(true)); | ||
} | ||
|
||
@Test | ||
public void changeVisibilityNoOp() { | ||
AccessInfo accessInfo = new AccessInfo(AccessFlags.ACC_PUBLIC, AFType.METHOD); | ||
AccessInfo result = accessInfo.changeVisibility(AccessFlags.ACC_PUBLIC); | ||
assertSame(accessInfo, result); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
jadx-core/src/test/java/jadx/tests/integration/others/TestBadMethodAccessModifiers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package jadx.tests.integration.others; | ||
|
||
import org.junit.Test; | ||
|
||
import jadx.core.dex.nodes.ClassNode; | ||
import jadx.tests.api.SmaliTest; | ||
|
||
import static jadx.tests.api.utils.JadxMatchers.containsOne; | ||
import static org.hamcrest.Matchers.containsString; | ||
import static org.hamcrest.Matchers.not; | ||
import static org.junit.Assert.assertThat; | ||
|
||
public class TestBadMethodAccessModifiers extends SmaliTest { | ||
/* | ||
public static class TestCls { | ||
public abstract class A { | ||
public abstract void test(); | ||
} | ||
public class B extends A { | ||
protected void test() { | ||
} | ||
} | ||
} | ||
*/ | ||
@Test | ||
public void test() { | ||
ClassNode cls = getClassNodeFromSmaliFiles("others", "TestBadMethodAccessModifiers", "TestCls", | ||
"TestCls$A", "TestCls$B", "TestCls"); | ||
String code = cls.getCode().toString(); | ||
|
||
assertThat(code, not(containsString("protected void test() {"))); | ||
assertThat(code, containsOne("public void test() {")); | ||
} | ||
} |
Oops, something went wrong.