Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
5d86bf97
Commit
5d86bf97
authored
May 02, 2015
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: fix loop processing after exception handler remove (fix #59)
parent
406d9878
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
94 additions
and
19 deletions
+94
-19
BlockNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/BlockNode.java
+2
-6
TryCatchBlock.java
...e/src/main/java/jadx/core/dex/trycatch/TryCatchBlock.java
+3
-0
BlockUtils.java
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
+43
-13
TestTryCatchInLoop2.java
...ava/jadx/tests/integration/loops/TestTryCatchInLoop2.java
+46
-0
No files found.
jadx-core/src/main/java/jadx/core/dex/nodes/BlockNode.java
View file @
5d86bf97
...
...
@@ -5,6 +5,7 @@ import jadx.core.dex.attributes.AType;
import
jadx.core.dex.attributes.AttrNode
;
import
jadx.core.dex.attributes.nodes.IgnoreEdgeAttr
;
import
jadx.core.dex.attributes.nodes.LoopInfo
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.EmptyBitSet
;
import
jadx.core.utils.InsnUtils
;
...
...
@@ -86,13 +87,8 @@ public class BlockNode extends AttrNode implements IBlock {
}
List
<
BlockNode
>
toRemove
=
new
LinkedList
<
BlockNode
>();
for
(
BlockNode
b
:
sucList
)
{
if
(
b
.
contains
(
AType
.
EXC_HANDLER
))
{
if
(
BlockUtils
.
isBlockMustBeCleared
(
b
))
{
toRemove
.
add
(
b
);
}
else
if
(
b
.
contains
(
AFlag
.
SYNTHETIC
))
{
List
<
BlockNode
>
s
=
b
.
getSuccessors
();
if
(
s
.
size
()
==
1
&&
s
.
get
(
0
).
contains
(
AType
.
EXC_HANDLER
))
{
toRemove
.
add
(
b
);
}
}
}
if
(
block
.
contains
(
AFlag
.
LOOP_END
))
{
...
...
jadx-core/src/main/java/jadx/core/dex/trycatch/TryCatchBlock.java
View file @
5d86bf97
...
...
@@ -6,6 +6,7 @@ import jadx.core.dex.info.ClassInfo;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.Utils
;
import
java.util.ArrayList
;
...
...
@@ -63,6 +64,8 @@ public class TryCatchBlock {
private
void
unbindHandler
(
ExceptionHandler
handler
)
{
for
(
BlockNode
block
:
handler
.
getBlocks
())
{
// skip synthetic loop exit blocks
BlockUtils
.
skipPredSyntheticPaths
(
block
);
block
.
add
(
AFlag
.
SKIP
);
ExcHandlerAttr
excHandlerAttr
=
block
.
get
(
AType
.
EXC_HANDLER
);
if
(
excHandlerAttr
!=
null
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
View file @
5d86bf97
...
...
@@ -72,10 +72,26 @@ public class BlockUtils {
return
null
;
}
public
static
boolean
isBlockMustBeCleared
(
BlockNode
b
)
{
if
(
b
.
contains
(
AType
.
EXC_HANDLER
)
||
b
.
contains
(
AFlag
.
SKIP
))
{
return
true
;
}
if
(
b
.
contains
(
AFlag
.
SYNTHETIC
))
{
List
<
BlockNode
>
s
=
b
.
getSuccessors
();
if
(
s
.
size
()
==
1
&&
s
.
get
(
0
).
contains
(
AType
.
EXC_HANDLER
))
{
return
true
;
}
}
return
false
;
}
/**
* Remove exception handlers from block nodes list
*/
private
static
List
<
BlockNode
>
cleanBlockList
(
List
<
BlockNode
>
list
)
{
List
<
BlockNode
>
ret
=
new
ArrayList
<
BlockNode
>(
list
.
size
());
for
(
BlockNode
block
:
list
)
{
if
(!
block
.
contains
(
AType
.
EXC_HANDLER
))
{
if
(!
isBlockMustBeCleared
(
block
))
{
ret
.
add
(
block
);
}
}
...
...
@@ -83,6 +99,18 @@ public class BlockUtils {
}
/**
* Remove exception handlers from block nodes bitset
*/
public
static
void
cleanBitSet
(
MethodNode
mth
,
BitSet
bs
)
{
for
(
int
i
=
bs
.
nextSetBit
(
0
);
i
>=
0
;
i
=
bs
.
nextSetBit
(
i
+
1
))
{
BlockNode
block
=
mth
.
getBasicBlocks
().
get
(
i
);
if
(
isBlockMustBeCleared
(
block
))
{
bs
.
clear
(
i
);
}
}
}
/**
* Return predecessors list without blocks contains 'IGNORE_EDGE' attribute.
*
* @return new list of filtered predecessors
...
...
@@ -112,18 +140,6 @@ public class BlockUtils {
}
/**
* Remove exception handlers from block nodes bitset
*/
public
static
void
cleanBitSet
(
MethodNode
mth
,
BitSet
bs
)
{
for
(
int
i
=
bs
.
nextSetBit
(
0
);
i
>=
0
;
i
=
bs
.
nextSetBit
(
i
+
1
))
{
BlockNode
block
=
mth
.
getBasicBlocks
().
get
(
i
);
if
(
block
.
contains
(
AType
.
EXC_HANDLER
))
{
bs
.
clear
(
i
);
}
}
}
/**
* Check if instruction contains in block (use == for comparison, not equals)
*/
public
static
boolean
blockContains
(
BlockNode
block
,
InsnNode
insn
)
{
...
...
@@ -462,6 +478,20 @@ public class BlockUtils {
}
/**
* Set 'SKIP' flag for all synthetic predecessors from start block.
*/
public
static
void
skipPredSyntheticPaths
(
BlockNode
block
)
{
for
(
BlockNode
pred
:
block
.
getPredecessors
())
{
if
(
pred
.
contains
(
AFlag
.
SYNTHETIC
)
&&
!
pred
.
contains
(
AType
.
SPLITTER_BLOCK
)
&&
pred
.
getInstructions
().
isEmpty
())
{
pred
.
add
(
AFlag
.
SKIP
);
skipPredSyntheticPaths
(
pred
);
}
}
}
/**
* Return true if on path from start to end no instructions and no branches.
*/
public
static
boolean
isEmptySimplePath
(
BlockNode
start
,
BlockNode
end
)
{
...
...
jadx-core/src/test/java/jadx/tests/integration/loops/TestTryCatchInLoop2.java
0 → 100644
View file @
5d86bf97
package
jadx
.
tests
.
integration
.
loops
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestTryCatchInLoop2
extends
IntegrationTest
{
public
static
class
TestCls
<
T
extends
String
>
{
private
static
class
MyItem
{
int
idx
;
String
name
;
}
private
final
Map
<
Integer
,
MyItem
>
mCache
=
new
HashMap
<
Integer
,
MyItem
>();
void
test
(
MyItem
[]
items
)
{
synchronized
(
this
.
mCache
)
{
for
(
int
i
=
0
;
i
<
items
.
length
;
++
i
)
{
MyItem
existingItem
=
mCache
.
get
(
items
[
i
].
idx
);
if
(
null
==
existingItem
)
{
mCache
.
put
(
items
[
i
].
idx
,
items
[
i
]);
}
else
{
existingItem
.
name
=
items
[
i
].
name
;
}
}
}
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
"synchronized (this.mCache) {"
));
assertThat
(
code
,
containsOne
(
"for (int i = 0; i < items.length; i++) {"
));
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment