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
69252ce7
Commit
69252ce7
authored
Jan 12, 2015
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: fix processing 'try/catch' in 'if' block
parent
df115251
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
97 additions
and
30 deletions
+97
-30
DepthRegionTraversal.java
.../jadx/core/dex/visitors/regions/DepthRegionTraversal.java
+21
-9
ProcessTryCatchRegions.java
...adx/core/dex/visitors/regions/ProcessTryCatchRegions.java
+24
-21
TestTryCatchInIf.java
...ava/jadx/tests/integration/trycatch/TestTryCatchInIf.java
+52
-0
No files found.
jadx-core/src/main/java/jadx/core/dex/visitors/regions/DepthRegionTraversal.java
View file @
69252ce7
...
...
@@ -18,18 +18,30 @@ public class DepthRegionTraversal {
traverseInternal
(
mth
,
visitor
,
mth
.
getRegion
());
}
public
static
void
traverseIncludingExcHandlers
(
MethodNode
mth
,
IRegionVisitor
visitor
)
{
traverseInternal
(
mth
,
visitor
,
mth
.
getRegion
());
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
{
traverseInternal
(
mth
,
visitor
,
h
.
getHandlerRegion
());
}
public
static
void
traverseIterative
(
MethodNode
mth
,
IRegionIterativeVisitor
visitor
)
{
boolean
repeat
;
int
k
=
0
;
do
{
repeat
=
traverseIterativeStepInternal
(
mth
,
visitor
,
mth
.
getRegion
());
if
(
k
++
>
ITERATIVE_LIMIT
)
{
throw
new
JadxOverflowException
(
"Iterative traversal limit reached, method: "
+
mth
);
}
}
while
(
repeat
);
}
public
static
void
traverseI
terative
(
MethodNode
mth
,
IRegionIterativeVisitor
visitor
)
{
public
static
void
traverseI
ncludingExcHandlers
(
MethodNode
mth
,
IRegionIterativeVisitor
visitor
)
{
boolean
repeat
;
int
k
=
0
;
do
{
repeat
=
traverseIterativeInternal
(
mth
,
visitor
,
mth
.
getRegion
());
repeat
=
traverseIterativeStepInternal
(
mth
,
visitor
,
mth
.
getRegion
());
if
(!
repeat
)
{
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
{
repeat
=
traverseIterativeStepInternal
(
mth
,
visitor
,
h
.
getHandlerRegion
());
if
(
repeat
)
{
break
;
}
}
}
if
(
k
++
>
ITERATIVE_LIMIT
)
{
throw
new
JadxOverflowException
(
"Iterative traversal limit reached, method: "
+
mth
);
}
...
...
@@ -49,7 +61,7 @@ public class DepthRegionTraversal {
}
}
private
static
boolean
traverseIterativeInternal
(
MethodNode
mth
,
IRegionIterativeVisitor
visitor
,
private
static
boolean
traverseIterative
Step
Internal
(
MethodNode
mth
,
IRegionIterativeVisitor
visitor
,
IContainer
container
)
{
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
...
...
@@ -57,7 +69,7 @@ public class DepthRegionTraversal {
return
true
;
}
for
(
IContainer
subCont
:
region
.
getSubBlocks
())
{
if
(
traverseIterativeInternal
(
mth
,
visitor
,
subCont
))
{
if
(
traverseIterative
Step
Internal
(
mth
,
visitor
,
subCont
))
{
return
true
;
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessTryCatchRegions.java
View file @
69252ce7
...
...
@@ -2,6 +2,7 @@ package jadx.core.dex.visitors.regions;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.IBranchRegion
;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.MethodNode
;
...
...
@@ -42,18 +43,14 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
final
Map
<
BlockNode
,
TryCatchBlock
>
tryBlocksMap
=
new
HashMap
<
BlockNode
,
TryCatchBlock
>(
2
);
searchTryCatchDominators
(
mth
,
tryBlocksMap
);
int
k
=
0
;
while
(!
tryBlocksMap
.
isEmpty
())
{
DepthRegionTraversal
.
traverseIncludingExcHandlers
(
mth
,
new
AbstractRegionVisitor
()
{
@Override
public
void
leaveRegion
(
MethodNode
mth
,
IRegion
region
)
{
checkAndWrap
(
mth
,
tryBlocksMap
,
region
);
}
});
if
(
k
++
>
100
)
{
throw
new
JadxRuntimeException
(
"Try/catch wrap count limit reached in "
+
mth
);
IRegionIterativeVisitor
visitor
=
new
IRegionIterativeVisitor
()
{
@Override
public
boolean
visitRegion
(
MethodNode
mth
,
IRegion
region
)
{
boolean
changed
=
checkAndWrap
(
mth
,
tryBlocksMap
,
region
);
return
changed
&&
!
tryBlocksMap
.
isEmpty
();
}
}
};
DepthRegionTraversal
.
traverseIncludingExcHandlers
(
mth
,
visitor
);
}
private
static
void
searchTryCatchDominators
(
MethodNode
mth
,
Map
<
BlockNode
,
TryCatchBlock
>
tryBlocksMap
)
{
...
...
@@ -105,7 +102,7 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
}
}
private
static
void
checkAndWrap
(
MethodNode
mth
,
Map
<
BlockNode
,
TryCatchBlock
>
tryBlocksMap
,
IRegion
region
)
{
private
static
boolean
checkAndWrap
(
MethodNode
mth
,
Map
<
BlockNode
,
TryCatchBlock
>
tryBlocksMap
,
IRegion
region
)
{
// search dominator blocks in this region (don't need to go deeper)
for
(
Map
.
Entry
<
BlockNode
,
TryCatchBlock
>
entry
:
tryBlocksMap
.
entrySet
())
{
BlockNode
dominator
=
entry
.
getKey
();
...
...
@@ -115,23 +112,29 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
ErrorsCounter
.
methodError
(
mth
,
"Can't wrap try/catch for "
+
region
);
}
tryBlocksMap
.
remove
(
dominator
);
return
;
return
true
;
}
}
return
false
;
}
/**
* Extract all block dominated by 'dominator' to separate region and mark as try/catch block
*/
private
static
boolean
wrapBlocks
(
IRegion
replaceRegion
,
TryCatchBlock
tb
,
BlockNode
dominator
)
{
IRegion
region
=
replaceRegion
;
if
(
region
instanceof
LoopRegion
)
{
LoopRegion
loop
=
(
LoopRegion
)
region
;
region
=
loop
.
getBody
();
if
(
replaceRegion
==
null
)
{
return
false
;
}
if
(
replaceRegion
instanceof
LoopRegion
)
{
LoopRegion
loop
=
(
LoopRegion
)
replaceRegion
;
return
wrapBlocks
(
loop
.
getBody
(),
tb
,
dominator
);
}
if
(
replaceRegion
instanceof
IBranchRegion
)
{
return
wrapBlocks
(
replaceRegion
.
getParent
(),
tb
,
dominator
);
}
Region
tryRegion
=
new
Region
(
region
);
List
<
IContainer
>
subBlocks
=
region
.
getSubBlocks
();
Region
tryRegion
=
new
Region
(
re
placeRe
gion
);
List
<
IContainer
>
subBlocks
=
re
placeRe
gion
.
getSubBlocks
();
for
(
IContainer
cont
:
subBlocks
)
{
if
(
RegionUtils
.
isDominatedBy
(
dominator
,
cont
))
{
if
(
isHandlerPath
(
tb
,
cont
))
{
...
...
@@ -144,13 +147,13 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
return
false
;
}
TryCatchRegion
tryCatchRegion
=
new
TryCatchRegion
(
region
,
tryRegion
);
TryCatchRegion
tryCatchRegion
=
new
TryCatchRegion
(
re
placeRe
gion
,
tryRegion
);
tryRegion
.
setParent
(
tryCatchRegion
);
tryCatchRegion
.
setTryCatchBlock
(
tb
.
getCatchAttr
().
getTryBlock
());
// replace first node by region
IContainer
firstNode
=
tryRegion
.
getSubBlocks
().
get
(
0
);
if
(!
region
.
replaceSubBlock
(
firstNode
,
tryCatchRegion
))
{
if
(!
re
placeRe
gion
.
replaceSubBlock
(
firstNode
,
tryCatchRegion
))
{
return
false
;
}
subBlocks
.
removeAll
(
tryRegion
.
getSubBlocks
());
...
...
jadx-core/src/test/java/jadx/tests/integration/trycatch/TestTryCatchInIf.java
0 → 100644
View file @
69252ce7
package
jadx
.
tests
.
integration
.
trycatch
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestTryCatchInIf
extends
IntegrationTest
{
public
static
class
TestCls
{
private
String
test
(
String
name
,
String
value
)
{
if
(
value
!=
null
)
{
try
{
int
key
;
if
(
value
.
startsWith
(
"0x"
))
{
value
=
value
.
substring
(
2
);
key
=
Integer
.
parseInt
(
value
,
16
);
}
else
{
key
=
Integer
.
parseInt
(
value
);
}
return
name
+
"="
+
key
;
}
catch
(
NumberFormatException
e
)
{
return
"Failed to parse number"
;
}
}
System
.
out
.
println
(
"?"
);
return
null
;
}
public
void
check
()
{
assertEquals
(
null
,
test
(
"n"
,
null
));
assertEquals
(
"n=7"
,
test
(
"n"
,
"7"
));
assertEquals
(
"n=77"
,
test
(
"n"
,
"0x"
+
Integer
.
toHexString
(
77
)));
assertEquals
(
"Failed to parse number"
,
test
(
"n"
,
"abc"
));
assertEquals
(
"Failed to parse number"
,
test
(
"n"
,
"0xabX"
));
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
"try {"
));
assertThat
(
code
,
containsOne
(
"} catch (NumberFormatException e) {"
));
}
}
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