Skip to content

Commit

Permalink
fix: correct detection of exits in synchronized block (#942)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Aug 9, 2020
1 parent 593a32a commit d6ad21f
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package jadx.core.dex.regions;

import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;

import jadx.core.dex.nodes.IContainer;
Expand All @@ -10,7 +10,7 @@
public final class SynchronizedRegion extends AbstractRegion {

private final InsnNode enterInsn;
private final List<InsnNode> exitInsns = new LinkedList<>();
private final List<InsnNode> exitInsns = new ArrayList<>();
private final Region region;

public SynchronizedRegion(IRegion parent, InsnNode insn) {
Expand Down
16 changes: 10 additions & 6 deletions jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -538,17 +537,22 @@ private static void collectWhileDominates(BlockNode dominator, BlockNode child,
}

public static List<BlockNode> buildSimplePath(BlockNode block) {
List<BlockNode> list = new LinkedList<>();
BlockNode currentBlock = block;
if (block == null) {
return Collections.emptyList();
}
List<BlockNode> list = new ArrayList<>();
if (block.getCleanSuccessors().size() >= 2) {
return Collections.emptyList();
}
list.add(block);

BlockNode currentBlock = getNextBlock(block);
while (currentBlock != null
&& currentBlock.getCleanSuccessors().size() < 2
&& currentBlock.getPredecessors().size() == 1) {
list.add(currentBlock);
currentBlock = getNextBlock(currentBlock);
}
if (list.isEmpty()) {
return Collections.emptyList();
}
return list;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package jadx.tests.integration.synchronize;

import org.junit.jupiter.api.Test;

import jadx.tests.api.SmaliTest;

import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;

public class TestSynchronized4 extends SmaliTest {

// @formatter:off
/*
public boolean test(int i) {
synchronized (this.obj) {
if (isZero(i)) {
return call(obj, i);
}
System.out.println();
return getField() == null;
}
}
*/
// @formatter:on

@Test
public void test() {
assertThat(getClassNodeFromSmali())
.code()
.containsOne("synchronized (this.obj) {");
}
}
105 changes: 105 additions & 0 deletions jadx-core/src/test/smali/synchronize/TestSynchronized4.smali
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
.class public Lsynchronize/TestSynchronized4;
.super Ljava/lang/Object;

.field private final obj:Ljava/lang/Object;

.method public constructor <init>()V
.registers 2

invoke-direct {p0}, Ljava/lang/Object;-><init>()V

new-instance v0, Ljava/lang/Object;

invoke-direct {v0}, Ljava/lang/Object;-><init>()V

iput-object v0, p0, Lsynchronize/TestSynchronized4;->obj:Ljava/lang/Object;

return-void
.end method

.method public test(I)Z
.registers 4

iget-object v1, p0, Lsynchronize/TestSynchronized4;->obj:Ljava/lang/Object;

monitor-enter v1

:try_start_3
invoke-direct {p0, p1}, Lsynchronize/TestSynchronized4;->isZero(I)Z
move-result v0

if-eqz v0, :cond_11

iget-object v0, p0, Lsynchronize/TestSynchronized4;->obj:Ljava/lang/Object;

invoke-direct {p0, v0, p1}, Lsynchronize/TestSynchronized4;->call(Ljava/lang/Object;I)Z
move-result v0

monitor-exit v1

:goto_10
return v0

:cond_11
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

invoke-virtual {v0}, Ljava/io/PrintStream;->println()V

invoke-direct {p0}, Lsynchronize/TestSynchronized4;->getField()Ljava/lang/Object;

move-result-object v0

if-nez v0, :cond_22

const/4 v0, 0x1

:goto_1d
monitor-exit v1
return v0

:catchall_1f
move-exception v0

monitor-exit v1
:try_end_21
.catchall {:try_start_3 .. :try_end_21} :catchall_1f

throw v0

:cond_22
const/4 v0, 0x0

goto :goto_1d
.end method

.method private call(Ljava/lang/Object;I)Z
.registers 4

const/4 v0, 0x0

return v0
.end method

.method private getField()Ljava/lang/Object;
.registers 2

const/4 v0, 0x0

return-object v0
.end method

.method private isZero(I)Z
.registers 3

if-nez p1, :cond_4

const/4 v0, 0x1

:goto_3
return v0

:cond_4
const/4 v0, 0x0

goto :goto_3
.end method

0 comments on commit d6ad21f

Please sign in to comment.